The concept of a module is different from the instantiation of that concept.
Java has always had modules. A method is a module, so is a class and so is a package. A module is a unit of organisation in which internal details are hidden, and that communicates with other modules via agreed contracts. For example, a method is a module because it has hidden internals (the code and local variables) and a contract (the parameters and return type). Modules can be composed out of lower-level modules, e.g. classes contain methods.
What's missing in core Java (pre-9) is a deployable module. All the above kinds of module are not deployable units that can be copied around. Java does have a deployable artifact called a JAR file, but these are not modules because they have no encapsulation or contract: at runtime JAR files disappear, all merging together into a single "classpath".
OSGi addressed the lack of deployable modules in 1998 with the concept of a "bundle". These are physically JAR files and they contain packages, but OSGi defines additional metadata along with a runtime system to support encapsulation and contracts at that level.
Java 9 addresses the lack of deployable modules in a similar way to OSGi. Arguably this was completely unnecessary because OSGi exists and works, but that's a whole different discussion...
Unfortunately Java 9 muddies the waters by naming the new module concept just a "module". This does not mean that methods, classes and packages stop being modules! A J9 "module" is just another instantiation of the module concept. Like OSGi bundles, J9 modules are made out of packages and they are physical artifacts (usually JAR files again) that can be copied around. The runtime system understands and reifies them.
Summary: yes J9 modules and packages are semantically separate notions. Obviously Java has to retain its existing package concept for backwards compatibility. Note that the word "package" is used quite differently in Java than in other languages or in package management systems like RPM. The new J9 modules (and OSGi bundles) are much more like packages in RPM than Java packages ever were.
In general, it is a bad sign if you need to change the language to add a new datatype or operation. That means that the language is lacking some feature, preventing you from expressing your program.
You are proposing to change the language and add a complex
type. As @Thomas Eding
hinted at above: why stop there? What about quaternions? They arise quite frequently in quantum physics and 3D graphics. They are probably even more useful than complex numbers. What about rational numbers? Real (not floating point) numbers? Natural numbers? Integers (not int
modulo 232, but real arbitrary-size integers)?
No. You can't keep piling on features on top of features. The language will crumble under its own weight.
The feature we really need is Value Types. And what do you know? They are already in the works, and will probably appear in Java 11 at the latest. Value types would allow you to implement the semantics of complex
as a library. And the semantics of quaternions, octonions, big decimals, rationals, tuples, structs, records, money, dates, … all without having to change the language.
I admit, it would only allow you to implement the semantics, though.
In order to implement the syntax, we would need two additional features:
- operator overloading (already exists in the language, but not user-defined)
- user-defined literals (exist in C++, Scala, some other languages)
Operator overloading would allow you to write c1 + c2
instead of c1.plus(c2)
. User-defined literals would allow you to write 2i
instead of new Complex(0, 2)
. The combination of both would allow you to write 2 + 3i
instead of new Complex(2, 3)
.
Maybe we'll get that. Maybe we don't. Scala has both shown that operator overloading and user-defined operators can be done very tastefully, and it also has shown that they can be overused and abused. Look at SBT's DSL for an extremely tasteful and well-balanced use of operator overloading.
The really cool thing is that if we were to get Value Types, User-Defined Literals and Operator Overloading, while that would certainly add complexity to the language, it would at the same time allow us to remove all 8 primitives from the language and implement them as a library! Which in turn would greatly simplify the language.
That's a very good sign for a good language feature: if adding it actually makes the language smaller. This is not true for your proposal, which is basically to add yet another specialized one-off type to the already existing specialized one-off primitives.
Best Answer
Generally speaking, the primitive operators in C (and by extension C++) are designed to be implementable by simple hardware in roughly a single instruction. Something like exponentiation often requires software support; so it's not there by default.
Also, it's provided by the standard library of the language in the form of
std::pow
.Finally, doing this for integer datatypes wouldn't make much sense, because most even small values for exponentiation blow out the range required for int, that is up to 65,535. Sure, you could do this for doubles and floats but not ints, but why make the language inconsistent for a rarely used feature?