Language support for BigDecimal - Java SE (Archived)

Add operators for BigDecimal, using the methods for calculation is a real pain.

This is the same operator overloading as it is done for the native types.
I know that a general operator overloading is a very controversial feature. For me it has it's right mainly in the arithmetic domain, so I would restrict it to that.
My main goal is a improved readability of financial calculations done e.g. with BigDecimal. Any broader support e.g. for all descendants of Number is welcome.

I'm favourable to extra language-level operator support for critical types, like BigInteger and BigDecimal (and maybe also arrays/matrices, new J2SE classes like Complex that I'd like to have in Mustang too, etc.).
for BigDecimal, though, many operations support extra arguments for rounding mode / scale / MathContext.  I guess this is a good case for annotations:
#MathContext(DECIMAL_128)
public class Test {
  public BigDecimal m1 (BigDecimal a, BigDecimal b,
                   #MathContext MathContext m) {
    return m2(a,b,m) * m3(b);
  }
  public BigDecimal m2 (BigDecimal a, BigDecimal b,
                   #MathContext MathContext m) {
    return a + b;
  }
  public BigDecimal m3 (BigDecimal a) {
    return -b;
  }
}
In this example, the #MathContext tag in the class sets a default context for the entire class.  The same tag, in the arguments 'mc', states that all BigDecimnal operators inside the methods m1,m2 should use that context, i.e. m3() translates to "return a.add(b, mc)".  Methods not having an explicit math context (neither a parameter or variable tagged by #MathContext, nor a static #mathContext tag in the method itself), like m3(), will use the closer static #MathContext, in this case the one set in the class.  If no context at all is found, then javac translates the operators to the methods that don't take a context.

No this is not operator overloading.
This is native support for infinite precision numbers and maybe complex ones as well (might as well).
Java supports Strings and arrays with language syntax. Since business apps seem to be the major use for Java it would make sense to extend native support for inifinite precision numbers (like Lisp and Smalltalk have). A simple way to do this is adding support for BigDecimal.
This is the first idea I've seen in the new features forum that actually makes sense to make. It WOULD save a lot of headaches and complications.

It would be nice if there was primitive types for BigDecimal and BigInteger so we could have basic arithmetic operators for them while not making it inconsistent with the rest of the language.
- Behrang

BigInteger and BigDecimal are objects that internally have arrays. The space occupied by these objects cannot be determined at forehand. How do you expect that a primitive is treated when it is put on the stack?

[i]Never mind. Should have read the post once more before posting :-)[/i]
Message was edited/deleted by: patrikbeno

Aah... you're right... Had forgotten that these classes have not fixed size internal representations.

Related

Operator Overload: Why Not?

I was reading about C# (didn't read much, but it looked like a hell of a Java rip-off), and then saw that C# supported operator overloading, which isn't supported in Java. The code seemed quite simple, and I'm wondering about why exactly operator overloading shouldn't be supported. How could it be without screwing up much portability and all that? Being accepted only by using an empty interface (OperatorOverload?), which tells the compiler to accept such modifications? And, by the way, C# allowed only to overload certain operators (can't remember all of them, but =, ==, += and all wasn't supported), new ones could not be created, and priority couldn't be changed, only what the operator would do. The example code was something like this:
/*
* Write it like if it was a normal method, but with the 
* name operator plus the operator to be overloaded. Examples:
* operator+ (overloads +), operator* (overloads *).
*/
public Distance operator+(Distance d1, Distance d2) {
  return d1.add(d2);
}
// ...
// Other method
public void foo(Distance d1, Distance d2) {
  Distance d = d1 + d2;
  //...
}Any suggestions? If you think it shouldn't be supported by any means, why not? 
The original creators of Java disliked operator overloading because they found that it's often confusing. In some places it makes sense, but they felt like in a lot of places, it was being used incorrectly, and was on the whole making things worse rather than better.
After all, there's no reason that instead of overriding '+', you can't do
public int plus (...) {
}
And just call obj.plus()
It just keeps everything simpler, cleaner, and easier to understand 
Op Overloading is anarchy. Its like the GOTO statement, very powerful if used correctly, but is mostly missused and leads to confusing hard to maintain code. 
Moreover, since Java object are reference, adding by example them should be theorically like adding pointers so that they pointed to another address.
I don't think it would be coorect to see such a thing in Java since you never have to worry about what an object being a reference or by value, which is not the case in C# that kept the pointers/byvalue difference.
I may be wrong though. 
The original creators of Java disliked operator
overloading because they found that it's often
confusing. In some places it makes sense, but they
felt like in a lot of places, it was being used
incorrectly, and was on the whole making things worse
rather than better.This is quite likely correct.
After all, there's no reason that instead of
overriding '+', you can't do
public int plus (...) {
}
And just call obj.plus()
It just keeps everything simpler, cleaner, and easier
to understandHere's a line of code I wrote:ivGrossProfitPercentage =
  caseRetail.subtract(cost).multiply(
    new BigDecimal(100)).divide(
    caseRetail, GROSS_PROFIT_PERCENTAGE_DECIMALS, BigDecimal.ROUND_HALF_UP);I don't think that any of "simpler, cleaner, and easier to understand" apply to this code.
Moreover, since Java object are reference, adding by example them >>should be theorically like adding pointers so that they pointed to >>another address.This is most likely the real reason.
The original creators of Java disliked operator
overloading because they found that it's often
confusing. In some places it makes sense, but they
felt like in a lot of places, it was being used
incorrectly, and was on the whole making things worse
rather than better.
After all, there's no reason that instead of
overriding '+', you can't do
public int plus (...) {
}
And just call obj.plus()
It just keeps everything simpler, cleaner, and easier
to understandWithout operator overloading:
public static final Complex I = new Complex(0,1);
// some methods such as log, times, plus, minus, neg...
public static Complex asin(Complex z) {
  return neg(I).times(log(I.times(z).add(sqrt(neg(z.times(z)).add(1)))));
}With operator overloading:
public static final Complex I = new Complex(0,1);
// some methods such as log, times, plus, neg...
// ...
// overloading +, - and *
// ...
public static Complex asin(Complex z) {
  return neg(I) * log(I*z + sqrt(1 - z*z));
}The latter seems much more simpler than the bracket nightmare the former was. And the code necessary to overload was easy to spot. Any programmer can screw up if careless. Some languages are more error-prone, with obscure features. Java tries to make things easier to the programmer. I agree that operator overloading can be confusing, but with the right restrictions it can be useful for the programmer. C# doesn't allow overloading for many operators (= was one, now I'm not so sure about ==, +=, /= ...), priority can't be modified, and new operators can't be created. It didn't look much error-prone to me. Make the programmer have to implement an empty interface OperatorOverload, or something like that. It seems like a good feature for a language to have. 
Moreover, since Java object are reference, adding by
example them should be theorically like adding
pointers so that they pointed to another address.The idea of adding two Complexes, for example, is to generate a third Complex with a value equal to the sum of the first two.
I don't think it would be coorect to see such a thing
in Java since you never have to worry about what an
object being a reference or by value, which is not the
case in C# that kept the pointers/byvalue difference.
I may be wrong though.It's not a question of pointers or reference, if just a question of making code more readable. The idea is to define what the addition (subtraction, division...) of two Objects would mean. For a String it would mean something different than for a Complex, or a Double. A String is an excellent example for an addition overloading. Overloading makes scientific applications much more easier, at least (brackets, brackets, tons and tons of brackets...).
Gotta go now, but I'll be back soon! 
It does indeed seem to come down to semantics (what else is there?).
However, we can all post bad code as a counter example to any approach!
One school of thought would describe both examples as crude, demonstrating nothing more than the ability to apply a formula verbatim. The use of explanatory intermediate variables would reduce the complexity of both, albeit more considerably for the former example.
Having said that it certainly shouldn't be assumed that a developer will be able to understand the formulae that they're implementing.
String addition is the traditional example of operator overloading and without it many applications would become overly verbose so there's definitely recognition of its value in Java.
The danger is perhaps the weird and wonderful things that people will opt to do with these things. I must admit that I see no real danger in operator overloading as there's currently no precedent for it other than String addition for which there is no ability to overload anyway. That said, however, there's very little to be gained from it.
As for complexity of scientific algorithms you've always got the ability to delegate to code written in a more suitable language or even to write an interpreter... (!) 
Excellent points. The only gain is reducing semantics. The same results could be achieved by calling all the necessary methods, risking a "bracket nightmare", or creating intermediate variables to lower the chance of forgetting a bracket and better reading of the code. But assigning intermediate variables can waste considerable time and memory. When you use an overloaded operator, you're essentially calling a method. It make your code more readable, without wasting extra memory with intermediate variables.
The problem is the tremendous potential of a mistaken overloading screwing up the whole program. Possibilities of reducing the risk level:
- Don't allow all the operators to be overloaded. In fact, only a few should be. new, instanceof and = are examples of operators that shouldn't be overloaded.
- Don't allow operator overloading for primitive types, only for objects.
- The operator's priority can't be changed; only it's functionality.
Of course such a modification should have restrictions, but I still think operator overloading would be an useful feature. Thanks for the opinions, through. And, about being better to use another language to make scientific applications: the idea of making a programming language is for it to have all applications possible, without adding too much complexity to do it. Java is the best language for such, but it isn't that good for scientific calculations. Of course, all the classes needed can be created when necessary, and JIT compilers can reduce execution time, but operator overloading would make such thing even easier to accomplish. With the right restrictions, it would be a good addition for the Java language.
isn't this called "Polish" or "reverse Polish" notation.
there was an old HP calculator that required data entry
Value1 <store>
Value2 <store>
Operator
so there is historical precedence for this type of structure
Value1 = new BigInteger( "7" );
Value2 = new BigInteger( "5" );
Value3 = new BigInteger( "3" );
Value4 = Value1.add( Value2.multiply( Value3.add( new BigInteger( "9" ) ) ) ); 
The only useful example I have ever seen regarding operator overloading is for complex number manipulation, and most people never write code that manipulates complex numbers.
Most people don't bother to read documentation, and it's comforting to know you can look at the code and understand what's happening without considering the possibility that the syntax elements in the expressions may have had their meanings redefined. 
polish notation is what we are used to in equations and maths formulea
ie a=b+c
has the form
operand operator operand
it uses precedence and parenthesis to define non natural percedence
reverse polish notation uses
operand operand operator
the bove would be written as..
b c + a =
parenthesis and precedence are irrelevant
note that it is eminently suitable for matsh calculators that use stacks
method
read next token, if its an operand, push the accumulator
if its an operator, perform operation on top of stack and accumulator, store result in accumulator
trivial for a calculator/processor to read and use but terrible for us mortals
one method of writing a(polish notation) esxpression parser/calculator is frst translate to reverse polish 
>>
It just keeps everything simpler, cleaner, andeasier
to understandHere's a line of code I
wrote:
ivGrossProfitPercentage =
caseRetail.subtract(cost).multiply(
new BigDecimal(100)).divide(
caseRetail, GROSS_PROFIT_PERCENTAGE_DECIMALS,
LS, BigDecimal.ROUND_HALF_UP);
I don't think
that any of "simpler, cleaner, and easier to
understand" apply to this code.Cool, now tell me what the following code does...
  Display display;
  {
    Database d;
    d["accounts"]++;
    d["accounts"][d, d.name] << "Ed Smith";
    d["accounts"]["shortName"]++;
    d["orders"][d, d.ref]= d["accounts"];
  }  // Yes the bracket is required here.
  display(d);  // Note 'display' is an object instance.
>>>
It just keeps everything simpler, cleaner, andeasier
to understandHere's a line of code I
wrote:
ivGrossProfitPercentage =
caseRetail.subtract(cost).multiply(
new BigDecimal(100)).divide(
caseRetail, GROSS_PROFIT_PERCENTAGE_DECIMALS,
LS, BigDecimal.ROUND_HALF_UP);
I don't think
that any of "simpler, cleaner, and easier to
understand" apply to this code.Cool, now tell me what the following code does...
Display display;
{
Database d;
d["accounts"]++;
d["accounts"][d, d.name] << "Ed Smith";
d["accounts"]["shortName"]++;
d["orders"][d, d.ref]= d["accounts"];
}  // Yes the bracket is required here.
display(d);  // Note 'display' is an object
t instance.I have no idea. Like most everybody else, I just want to have good operator overloading and not bad operator overloading. So in the example I gave above I would prefer to writeivGrossProfitPercentage = (caseRetail - cost) * 100 / caseRetail;Let me just point out that in a differently designed language this wouldn't require operator overloading at all. I should simply be able to declare BigDecimal as a subclass of (say) Number, a class that encompasses all kinds of numbers and that already has numeric operators defined for it. Just like String already has + defined for it.

Extending Generics to primitive types

The current generics proposal has section discussing why primitives were omitted. A variety of approaches are discussed, all of which have problems. However I think there is another approach which is not mentioned in that document. My proposal is effectively a hybrid between the homogeneous and heteorogenous approaches. For generic classes where the parameter types are all 'Objects' the treatment is exactly as in the current proposal.
A type parameter can allow either certain types of primitive or objects (constrained by class/interface), but never both. For a primitive type parameter the constraint can be 'number' (any of the numerical primitives), 'integer' (any integral primitive), or 'real' (float or double). This means that we know what operations are permitted on instances of the type. When an instance of a class with a primitive type parameter is required the ordinary byte code will have to be generated from the generic code. The code to perform this expansion can be written in Java and loaded dynamically when needed --- so the overhead is only paid if you use it. Memory constrained environments could have the code expanded ahead of time. Note that the expansion is only done with regard to the primitive parameters and not any object parameters.
So to take the java.util.Arrays class for example, the sort methods could be reduced to two:
a) for Object[] arguments
b) for number[] (primitive) arguments
This would expand to exactly the same code as we have know (assuming you used all the primitive variants). So the memory cost would be (size of generic byte code)+(size of expanded byte code for variants used)+(size of expansion code) - (size of original byte code for all variants).
A hook would be required in the JVM to invoke the expansion code when required but this would be trivial.
This is a very rough proposal just to indicate that a low cost solution is possible. It maintains the existing separation between primitive and object types, which will no doubt offend the purists. It would allow us to write basic methods for the primitive number types just once instead of 7 times as at present.
There are quite a few extra wrinkles required to make this a fully fledged proposal (e.g. a MIN_VALUE property on the parameterised type).
Comments? 
Just to flesh this out a bit more, define a few 'special' classes in java.lang:
public abstract class number {
number() {}
public abstract number MIN_VALUE();
public abstract number MAX_VALUE();
};
public abstract class integer extends number {
integer() {}
public abstract integer MIN_VALUE();
public abstract integer MAX_VALUE();
};
public abstract class real extends number {
real() {}
public abstract real MIN_VALUE();
public abstract real MAX_VALUE();
public abstract real NaN();
public abstract real NEGATIVE_INFINITY();
public abstract real POSITIVE_INFINITY();
};
The 'number' class is not a subclass of Object (because it is a place holder for primitives).
Then byte, short, char, int and long would all be considered subclasses of 'integer', float and double would be subclasses of 'real'. The non public constructors would prevent further subclasses.
We can then use the existing syntax in the generics proposal. Then we might declare the sorting and find methods in java.util.Arrays as follows:
public class Arrays {
public static <T implements number> void sort(T[] a, int offset, int length);
public static <T implements Comparable> void sort(T[] a, int offset, int length);
// backward compatibility
public static void sort(int[] a, int offset, int length) {
<int>sort(a, offset, length);
}
}
Then in the first case T can only be replaced by a primitive type (because no Object type extends or implements number), while in the second no primitive can be used because they aren't objects (nor implement Comparable). In implementing the first method we can use any operators which are common to all number primitives.
The use of the three fake classes (number, integer and real) avoids the need for any additional syntax or reserved words.
Erm... I'm not sure I understand you, but I'm sure I want to. This sounds interesting.
Let me get this straight, and correct me if i'm wrong:
1. Object types behave as under the current proposal.
2. Primitive types generate extra classes, C++ style.
3. There are special class names that group the primitives, if you wish.
You can specify the type and even limited bounds of primitive types accepted in a generic type. So you could make a class that only accepted real numbers >= 0, or only booleans, or whatever.
Is that what you're saying? 
That is pretty much the idea. The constraints on primitives don't go as far as restricting range to (say) positive values. Also boolean can't be used --- what could you do with a type that could be either boolean or some number primitive? It could be extended to do this, I just can't see the point.
No restrictions on numbers? Oh, ok.
The point of using boolean as a generic parameter? I don't know. It could be argued that there was very relatively little point in allowing generics on primitives at all.
It could also be argued by some (such as the C# designers) that boxing/unboxing primitives into their Integer, Double, etc objects would be good enough for most people's needs, while preventing any of the extraneous garbage that accompanies most attempts to make generics on primitives.
Me, i'm sitting on the fence, waiting for the next big step in object orientation to come along, and doodling strange object/class/type networks on the woodwork. 
How about having .java files compiled to bytecode?
I can compile generic class first, then use .class for compilation with its specification.
What bytecode would you use for 'number' class having '+' operator to produce bytecode? 
Any methods involving numeric generic types would have to be processed (replacing the generic type with the actual type) before use. This processing could readily identify operations involving generic arguments, so any of the existing numeric '+' operators could be used with the correct one being substituted as part of the processing. 
I'm glad the whole idea of primitives in relation to generics has come up, because I think there is a significant link between the two. Basically, adding generics adds a powerful new tool to the object oriented nature of Java. However, Java primitives are not object oriented and aren't compatible with generics. Hence we have mthornton's suggestion on how to make generics compatible with primitives.
I would suggest that it be approached from the other end -- Making primitives compatible with Objects. There are several places this has been discussed, including bug report
http://developer.java.sun.com/developer/bugParade/bugs/4452158.html
and even JSR 65 http://jcp.org/jsr/detail/65.jsp is related to the issue.
I have, as a hobby messed around with trying to specify how this could be done, and I believe it is definitely possible to allow automatic boxing/unboxing of literals and Objects by the compiler, but there's no real discussion on the topic.
I wonder if there is enough interest in the Java community for a serious JSR to be put together defining the language change that would be needed to make primitives object-compatible, and therefore generics-compatible. 
I would suggest that it be approached from the other
end -- Making primitives compatible with Objects.
There are several places this has been discussed,
including bug reportWhile this is possible, there are lots of awkward details which make it much more difficult than it first appears. I don't think it is possible to eliminate the differences between primitives and Objects without a performance cost that some would find unacceptable.
It would be possible to allow user definable value classes in some form and apply automatic boxing/unboxing when these were used in a reference context. However there would still be two distinct categories of Object --- this is not the totally unified system that some seek.
James Gosling has made a proposal of this type here: http://java.sun.com/people/jag/FP.html#classes
That paragraph is a good summary of a few of the pitfalls of the pure-object approach. However, I think it's interesting that he also hits on some good ideas that could lead to solutions as well.
I'm guessing that java will never go this route, simply because the language has too much momentum, and to throw a wrench in the works would be too painful at this point. However, if it was ever going to happen, I think that now would be the time, so that generics could use primitives as well.
I have ideas for solving the problems with this issue, however it is my feeling that no one really cares, so there's no real point except as a mental excercise... 
Some people do care, but they are a small minority. Half of those who do care really want something like SmallTalk but with the popularity of Java.
As a mathematician I would like to see efficient classes (for complex and similar types) as well as the extension of generics to primitive types. Sadly it doesn't look like happening. 
I think that there really are two different kinds of objects---reference and value---or more correctly, there are two different kinds of VARIABLES.
Making everything homogeneous is nice, but when the reality isn't, one shouldn't.
The fact is that there is an essential difference between value and reference variables and there always will be.
Now you can make the choice in your language whether or not you can make that specification when you declare the variable, or when you declare the type.
The first way is more 'consistent' but it is probably harder. Eiffel does this with the 'expanded' keyword which specifies a value type.
However, it is generally more idiomatic and more compatible with the use of the unfortunate Java primitives to say that generally variables that "point" or "contain" an object of a certain type 98% of the time want to do it one way or the other. Also there may be other restrictions on value types anyway so that they are not as one-to-one substitutable. For example for performance reasons you generally would want the total storage necessary for an instance to be a compile-time constant, if you wanted say value variables to be elements of a large array.
Obviously an example is the canonical complex numbers which you almost always want to use in a value context.
Eiffel thus allows you to use "expanded" as a keyword in the class definition.
This way the Java primitives should be brought "inside" the class system and they would be "value" or "immutable" classes. 
I think that to make numeric operations work like functions (e.g. bind a + opperator to doubles or complex), you need to make a few language changes. I think most of it can be handled in the compiler.
1) Methods invokable upon more than one object.
Currently we can invoke stuff as a.fooBar(b,c,...), but for operator overloading to be nice we need (a, b).fooBar(c, ...) and potentialy (a, b, c).fooBar(...) as well.
2) Tuple types are the natural way to model the (a, b) things - these would be defined as (type/class/interface1, type/class/interface2, ...) and any variables within elipses that are castable to the apropreate types can be considered an instance of that tuple.
This differs from creating a class Foo { public Bar bar; public Baz baz; } because we can make tuples by just putting variables in elipses, and the type of the tuple is infered from their types.
It should be possible to bind methods to these tuples e.g.
public tuple (Foo foo, Bar bar) {
public Baz plus() {
return foo.getInt() + bar.getInt();
}
}
3) Intersection types of the form [Foo, Bar, ...] where at most one of the types is a class, and any/all of them are interfaces. This allows you to write methods like:
public void writeFoo([Foo, Serializable] foo) {
// serialize foo out
...
}
In this case, the parameter foo must be /both/ an instance of Foo and implement Serializable. This will allow you to naturally define things like matricies over scalars and other fun strucutres. It wouldn't hurt for a lot of other coding, either like defining a field as '[FileFilter, Comparable] filter' or for mixing in a commit/rollback interface '[Foo, Commitable] data'.
4) The issue of passing primatives arround and boxing/unboxing seems to be partly about the way that some objects have identity defined by their fields and some by their object reference. When passing primatives arround currently, it's realy a bit like calling primativeHandle.clone() implicitly on the argument (if such an operation existed on primatives). When you say 2++, you don't actualy modify the machine-wide #2 entity to be #3, you replace the number in a variable with a new number. I'm sure all this stuff about objectifying primatives and primitivising objects could be largely handled by the compiler if it just looked at mutability and the equals method apropreately. Also, if something is final, then you don't need to hold a per-array-slot type - the type can go in the head data of the array, along with the array length. Would we need/want a directive to say - is an instance of vs is exactly this class?
Just some musings, but their all relevant to compilers and templating and function binding.
Matthew
Did anyone else notice that in the release about what's coming up in 1.5 they mention not only generics, but automatic primitive boxing/unboxing...
I am very interested in hearing more about this, and see how the two might be related... 
Did anyone else notice that in the release about
what's coming up in 1.5 they mention not only
generics, but automatic primitive boxing/unboxing...
I am very interested in hearing more about this, and
see how the two might be related...Huh? Where? Show me!

Proper Number abstractions and arithmetics

Hey y'all!
I saw the operator overloading thread, and wanted to comment, however this is really a bit of topic, so I put it on top level.
Operator overloading:
Coming from Smalltalk, I really don't care if we can't have operators. I can live with 'add(  )' if I can't get a '+'. All the same from my point of view.
Some words about java.lang.Number and it's cousins:
I currently translate a financial application from Smalltalk to Java and find it really frustrating. Sure, Java offers BigDecimal for precise storage and calculation of decimal numbers, however it is not really compatible with any of the other number classes. You usually have to do a lot of cumbersome conversion. In my experience the Number classes only share superclass and a few useless methods defined there. Why is there for example no common abstraction for Integer, Long and BigInteger?
1. In Smalltalk we interchangeably do computations on Float, SmallInteger, LargeInteger, ScaledDecimal, Fraction etc. The implementation will figure out the correct way to perform the computation and what Number class the result should be.
2. In addition it will handle overflow, so that when some SmallInteger calculations exceed the range of the type the result will be LargeInteger.
3. Polymorphic converters are defined on all classes so I can send asDecimal to any number class and it will figure out what to do.
To be able to these kinds of things in Java you basically have to create a utility method
public static Number add(Number a, Number b)
{
   if(a instanceof Integer)
     etc....
}
or when some type decides the outcome
public static BigDecimal add(BigDecimal a,Number b)
Why can't we have
public Number add(Number operand)
public Number multiply(Number operand)
public Number divide(Number operand) /* neither integer
nor floating point division, produce result based on actual types as you would if you saw a / b in a real world math textbook */
public Number isInteger() /* Whether I can be converted to an integer without loss of precision */
etc.
on all the Number classes?
If you want more control over the calculations there could be an addtional Configuration parameter, where you can declare number of decimal digits and so on for the advanced guys out there.
Maybe even an interface Computable
public Computable add(Computable c)
public Integer asInteger()
etc.
so that domain objects, complex numbers, "pi", "e", etc. could also support arithmetic semantics without inheriting from Number
what do you say?
By the way, all of this is meant for the Number types (autoboxed or not). If you believe primitives are a wonderful thing, don't bother commenting.
Martin Skarsaune, Norway
Unlike some languages, Java doesn't support classes knowing about their derived children.
So you can't have the system determine the actual method to be called on the actual child class if the method isn't an overridden version of a method in the parent class.
Learn Java, don't try to turn Java into SmallTalk.
jwenting, the proposed support could easily be provided for a closed collection of Number classes. Allowing custom Number classes to be included would be more difficult, but not impractical. However the simpler option would probably suffice for many potential users.
So just add Fraction and BigFraction classes and then hard code the arithmetic methods to behave in the obvious manner. So Integer div Integer results in either a (Big)Fraction or an Integer.
The existing MathContext class could be extended to provide additional control where required.
It is also worth looking at the Numeric classes in the jScience library: http://www.jscience.org/
mthornton: thanks for the tip!
jwenting: I guess you may be right about the problems of supporting arbitrary custom classes directly from the standard Number classes, if so they should support a quite restricted interface, or maybe nothing at all . For the n Number classes in the JDK, one should easily be able to support the n x n combinations of calculations. A standard library should care about giving it's clients the most powerful interface, not impose CPU level restrictions. In any case the good ol' operators and primitives will still be there for computer science classes ;-)
I don't think it's a sin to look at other languages. Hey, if C# hadn't given Java some competition, I'd bet you half the great stuff in tiger wouldn't be there. I think Tiger and the Mustang discussion so far is quite ambitious at making Java a better language. Sure, it's growing bigger and more complex but it never worried me that I never needed half the packages in the JDK, as long as I find what I need in there.
Martin

Where next for Java?

What are Sun's plans for future changes to the Java language and API? I can think of a few cool things that Sun could go for:
* Tuples, a la Python, Prolog, and others.
* Multi-dimensional arrays (jagged arrays suck, am I right?)
* Better support for the Collections API in Swing.
* A first-class calendar component for swing, like JCalendar or the MFC calendar.
* Currying! Just kidding.
* Operators for BigDecimal and BigInteger, and java.lang.Math support for them too.
* Some sort of a SortedList collection, for lists that have to stay sorted.
That's just my little want-list for Java 1.6. I'd regard any one of these as a HUGE enhancement to Java. Thanks for reading! 
This could get dirty! How about
1) complex numbers as primitives
2) operator overloading (this would allow item 6 on your list)
3) multiple inheritance
Time to put on my armour. 
1) complex numbers as primitives
2) operator overloading (this would allow item 6 on
your list)
3) multiple inheritance1) shouldn't be too difficult, and it would parallel the treatment of BigInteger and BigDecimal as primitives. A general extension of Java's mathematical versatility.
3) -- I'd prefer mixins to multiple inheritance. Mixins fit the Java philosophy better. 
1) shouldn't be too difficult, and it would parallel
the treatment of BigInteger and BigDecimal as
primitives. A general extension of Java's
mathematical versatility.Although I like the idea of adding BigInteger and BigDecimal as primitives, the inquisition will hate it! I have been on the rack a couple of times for just suggesting adding 'complex' as a primitive!
>
3) -- I'd prefer mixins to multiple inheritance.
Mixins fit the Java philosophy better.What is a 'mixin'? Do you have a reference?
A mixin is like a data member whose methods get exposed as part of the owning object. The idea is that if your class needs to implement some interface, you can use an object that already implements that interface to do it.
Suppose I have a class Foo that needs to implement interface Heuvos:
class Foo implements Heuvos {
...
}Rather than implement the methods of Heuvos directly, Foo uses another object -- the mixin -- to implement that functionality.
class Foo implements Heuvos {
    mixin Heuvos h;
  
    public Foo(Heuvos input) {
        h = input;
    }
}See? The object gets mixed into our class, and handles the implementation of the Heuvos interface. It's like multiple inheritance, but without the potential problems with constructors and cyclic inheritance. Plus, you can decide at runtime what object will provide the implementation -- this makes the technique extraordinarily flexible.
Personally, I think Mixins would be a great addition to Java. It would be a non-trivial addition to the language, but boy is it ever a powerful one! 
http://www-106.ibm.com/developerworks/java/library/j-diag1203/
This is a much better description of mixins. In short, they rock. 
* Multi-dimensional arrays (jagged arrays suck, am I
right?)What is wrong with jagged arrays?/Whats the benerfit of having true Multi-dimensional arrays ?
* Operators for BigDecimal and BigInteger, and
java.lang.Math support for them too.Mmm, as long as it stays with just Big<Number>, sure, but with no way of it being abused.
What is wrong with jagged arrays?/Whats the benerfit
of having true Multi-dimensional arrays ?True multidimensional arrays are much safer than simulating them with jagged arrays. They are easier to initialize, and are much more subject to optimization. They also have less overhead, since you don't have to have a pointer for each row of the array.
Mmm, as long as it stays with just Big<Number>, sure,
but with no way of it being abused.As much as the old C++ programmer in me desires operator overloading, I DO understand Sun's decision to leave it out. Still, there are select cases where Sun could have used operators on objects. BigDecimal and BigInteger would be ideal candidates for operators, as would a complex number primitive. StringBuffer could easily have its own operators, just like the String class. When Sun adds the measurements and units library to Java, measurement objects will be excellent candidates for having their own operators. The same could be said about a vector/matrix library, if Sun ever creates one. 
http://www-106.ibm.com/developerworks/java/library/j-di
g1203/
This is a much better description of mixins. In
short, they rock.Thanks Mark. 'mixins' look interesting so I shall spend some time on them.
why don't you kids get together and create a new language called Java++... 
What is wrong with jagged arrays?/Whats the benerfit of having true Multi-dimensional arrays ?True multidimensional arrays are much safer than simulating them with jagged arrays. They are easier
to initialize, and are much more subject to optimization. They also have less overhead, since you
don't have to have a pointer for each row of the array.Strange remark... what would you call a row in a 3D array ?
They are easier to initializeLooking at C# (only briefly mind you):
int[,] three = new [3,3];
vs the java "faked"
int [][] three = new[3][3];No real difference in init.
vector/matrix library, if Sun ever creates one.See Java3D for a vector/matrix lib.
* Currying! Just kidding.Hurry-hurry spoils the Curry. Currying in Java be not a haskell, er, hassle:
interface Binary {
    Object op(Object a, Object b);
}
interface Unary {
    Object op(Object c);
}
interface Curried {
    Unary op(Object d);
}
class Curry {
    static public Curried lambda(final Binary bin) {
        return new Curried() {
            public Unary op(final Object d) {
                return new Unary() {
                    public Object op(Object c) {
                        return bin.op(d, c);
                    }
                };
            }
        };
    }
}
why don't you kids get together and create a new
language called Java++...Isn't that just what is happening as Java migrates from 1.0 to 1.1 to 1.3 ... to 1.6? If we are not adding new features then what would be the point of the new versions? Even if you are just improving the speed or code size it is still Java++.

Suggestion for Improving Number

Hello Oracle Java community,
I've recently encountered some difficulties using the abstract class java.lang.Number, and have a suggestion for improvement.
I'm writing a class that computes statistical information on a list of numbers - it would be nice to not couple this class to Integer, Double, BigDecimal, or any other wrapper by using generics. I saw that there is a nice superclass that all Number objects inherit from.
I came up with:
--------
public class Statistics<T extends Number> {
private List<T> data;
// statistical data that i wish to find and store, such as median, mean, standard dev, etc
public synchronized void setData(List<T> data) {
this.data = data;
if (this.data != null && !this.data.isEmpty()) calculateStatistics();
}
private void calculateStatistics() {
// Welcome to instanceof and casting hell...
}
//...
}
------
h4. It would be nice to have richer functionality from the Number class, say to do mathematical operations with them or compare them.
h4. After all, in the real world it is possible to do so.
h4. Real numbers are much like BigDecimal. Why not take the idea of BigDecimal, and make that the parent of Integer, BigInteger, Double, Short, Byte, Float (I'm probably forgetting a few)? All of those are limited forms of real numbers. It would make comparison between Number datatypes easy, would probably remove all of that duplicated arithmetic code between all of the children of Number, and also allow Numbers to be used in powerful generic ways. The parent/replacement of BigDecimal could even be named RealNumber, which stays true to its math domain.
As a side note, I'm solving this problem by taking an initial step to convert the List<whatever type of Number that the user enters> into a List<BigDecimal> by getting the toString() value of each element when cast as a Number.
-------
private List<BigDecimal> convertData(List<T> data) {
ArrayList<BigDecimal> converted = new ArrayList<BigDecimal>();
for (T element : data) {
converted.add(new BigDecimal(((Number) element).toString()));
}
return converted;
}
-------
Criticism is always welcome.
Thanks for your time and thoughts.
-James Genac 
Seems to me you would have a lot of trouble writing an equals() method for this RealNumber class.
Remember that for BigDecimal, 2.0 is not equal to 2.00 because they have different scales (see the API docs for details). So that would mean that whenever you compared a Double object to a BigDecimal object, you would have to somehow figure out what scale would be suitable for that Double. Or perhaps you could always return false, regardless of the values of the two objects. In one case you are in danger of going down the road where equals() isn't transitive, and in the other case you are in danger of making the equals() method meaningless.
Personally if they ever rewrite Java to get rid of legacy stuff, I would like to see things like int and float, which expose hardware dependencies and idiosyncrasies, be removed in favour of more generalized Number classes which don't remind you all the time that you're using 8-bit bytes for integer data and IEEE-754 (or whatever it is) for non-integer data. But of course that doesn't help you with the current question. 
Another reason not to do so is to save memory. When a small number can be represented with a Byte, you don't want to use a BigDecimal to represent it since BigDecimal uses more bytes. In terms of efficient memory utilization and hence the performance, you should look for the smallest data type that is sufficient for you. The common parent class idea sounds good in terms of modeling mathematical number type relationships to the computer domain, but the parent type then should be capable of representing all types - generally consuming more bytes and more CPU cycles than needed for the job at hand. 
Thanks for the replies and good points.
It's fine that the .equals() method doesn't determine that 2.00 is equal to 2.0 because that's what the compareTo() method is for - numerical equivalency. equals() can be numerical and scale equivalency. Even if the .equals() method would be for solely numerical equivalency, a subclass of RealNumber representing a scale-significant number could implement the numeric and scale dependent version of .equals().
As for the size, good point. BigDecimal does eat more memory than something like Byte. Then again, if performance is what you're after, you're simply not going to beat primitives. The objective of wrappers was not to perform well, but to allow them to be modeled into modern data structures and to be more flexible. Not to say that a heavily-used java standard library class shouldn't be optimally performing, but performance tradeoffs are to be expected.
Also, to your point, legacy systems that are used to running near their max heap size may get pushed over the edge if they use a lot of wrappers. If there is no way to efficiently represent real numbers in a way that is comparable to say, Integers, Shorts, or Bytes, then it cannot be done.
Edited by: James Genac on Sep 29, 2012 8:44 AM 
How compareTo() came into existence is from Comparable interface. As I understand, Comparable came into existence since Collections API has sorting functions - which needs to be run with a matching Comparable object that knows how to determine which element is larger than the other (not limited to objects representing numbers, you might sort a list of Persons). Hence, compareTo() is not solely meant for the comparison of numbers. Existence of the method in BigDecimal is just one case.
Subclasses can override the equals() method, but that cannot be implemented in a cleaner manner and leads to a very poor design. For example, you might want to compare an Integer and a Float. So the Integer class's equals() method need to have some if-else structure to determine the other type and then compare. Same holds true for the Float class's equals() method as well. Ultimately, Everything becomes a mess. All subclasses of RealNumber needs to know about all other subclasses of RealNumber. And you will not be able to introduce new subtypes and expect the equals() method to work correctly.
To avoid this, you need to depend on a single representation form for all types of numbers. If that's the case, you might just live with something like BigDecimal and not use Byte, Float, Integer,... (which we kind of do in some cases - for example to represent monetary amounts). So we can live without Byte, Float, Integer,...
Then we need some utility classes that would contain some number type specific functions to work with primitives. So we will also have Byte, Float, Integer... unrelated to BigDecimal.
Clearly, the wrapper types are there not because of the need to represent real world number types, but because of the need to represent computer domain number types. Hence, they have been organized not according to relationships found in real world number types. Many of us find this way of modelling sufficient and have an understanding about the limitations. But if you need to model the real world number relationships for some special reason, you might write some new classes. Then again there will be real world aspects that you will not be able to model easily. So you will model some aspects and neglect the other.

Categories

Resources