If you could change Java, the language, what would you change?

#1 get rid of primitives - unboxing where possible should be a compiler problem. Number types would behave like strings, so would have operators like + and - minus defined. I could therefore do this :


Integer five = 5;
Integer ten = 5 * 2; //Equivalent to five.multiplyBy(2);

Would mean methods like the 4 Math.abs methods could be reduced to one.

#2 I would have standard date class(es) that are much better like the pig’s ear that is Date and Calendar.

#3 I would have a way of removing boilerplate code - bound properties, closing resources that throw checked exceptions etc… The proposals for closures seem to promise this but I’m undecided as yet.

D.

I’ve got mixed feelings about this: Maybe things get more consistent on one hand (everything objects), but it also makes the syntax less consistent on the other.
And which problem does this solve?

At least your syntax proposal makes things less consistent as I feel it probably should become something like:


Integer five = new Integer(5);
Integer ten = new Integer(5 * 2);
or even
Integer ten = new Integer(5).multiplyBy(new Integer(2));

More consistent, but less readable of course :slight_smile:

And I think the compiler will have a hard time getting the same performance out of something like this instead of primitives. I feel lots of object overhead coming our way, String-like constant pools, more strain on the GC and other things I don’t want.
My opinion is that I’m doing enough number crunching that I want my calculations to be:
a) readable
b) fast, with guaranteed no object overhead whatsoever (I’m not sure a compiler would be able to get rid of that overhead in all cases).

And again, what do you gain by having primitives as Objects? If it’s collections and such, there’s already autoboxing there (which introduced a couple of new performance pitfalls).
Math, numbers etc are such a well defined concept that I personally don’t see any benefit in having them represented as objects.

Unless maybe I’m missing your point? If so, do explain :slight_smile:

have you seen http://jcp.org/en/jsr/detail?id=310 ?

Your counter example still appears to have primitives (the arguements for the constructors).
In terms of consistency the analogy would be String :

String s = "blah";

[quote]And which problem does this solve?
[/quote]
Two I think.
#1 if I write a bit of number crunching code, and I don’t care whether the parameters are floats or doubles (or in fact ints or longs), I can define those parameters to be the Number class. I can then write readable math code using +*/-. The compiler could under-the-hood turn stuff into primitives to make it just as fast.
I imagine there is lots of game code out there that has primitive types in their signatures, changing from say float to double could be very painful but this way it wouldn’t.
Taking it further you could define interfaces such as Addable, Divisible etc… so more complex objects such as Vectors could participate. Where this descends into operator overloading I’m not sure.

#2 Methods that take any input, currently have to have a version for Object plus all the primitive types. e.g JUnits assertEquals, could be condensed from 20 to 2 methods.

[quote]And I think the compiler will have a hard time getting the same performance out of something like this instead of primitives.
[/quote]
My idea is that the compiler would be more clever and be able to convert to primitives where necessary. However I don’t write compilers so I don’t know if this is feasible.

Thoughts?
D.

You are aware, that the above compiles fine with 1.5, are you? The only difference is, that the second line is not equivalent to five.multiplyBy(2) but to Integer ten= new Integer(5*2), but since you can even write


	Integer five= 5;
	Integer two= 2;
	Integer ten= five*two;

I think this doesn’t matter…

And there goes strong type checking out the window.

[quote]And there goes strong type checking out the window.
[/quote]
Most things running on the JVM a couple of years from now will be scripting languages anyways. A Number class as described would be exactly the kind of thing they will need.

How so? I would call it ‘using a higher layer of abstraction’

Most games do a load of maths with say floats. The code doesn’t really care it’s using floats - it would look the same if it were crunching doubles. Therefore if you could write your methods using a higher level abstraction, e.g. Number it would work for both floats and doubles. Therefore if you decide to change your game to use doubles instead of vice-versa, it is much easier. Also library code written this way could be used for games that uses doubles or floats - it is more reusable.
Of course to do this, you need to not use primitives as they are not polymorphic.

D.

Apart from the operator overloading, it exists - java.lang.Number

Something I found today about calling DLL’s without JNI:

https://jna.dev.java.net/

But I haven’t looked into it (nor can I ever see myself using it :P).

While this is true for java’s type system as it is, it is not necessarily true in general. There are strong type systems where you don’t have to decide whether you’re using floats or ints in an expression, this is inferred by the compiler automatically. Some functional languages like Haskell have this feature and it works great (in most situations). This feature is called type classes which has nothing to do with OO-classes.

For example 34 + 4 * 2 would have a type (Num a) => a, which tells us that it gives us a polymorphic type a (any type a), wich is in the ‘Num’ class. Had I used a ‘floating point’ somewhere, e.g. 34 + 4 * 2.2, the type would’ve been (Num a, Fractional a) => a. Note that Fractional also implies Num, so one can leave out the ‘Num’ class.

You might be right for #2 (“Methods that take any input, currently have to have a version for Object plus all the primitive types. e.g JUnits assertEquals, could be condensed from 20 to 2 methods”). I don’t understand what exactly he wants to have here, so it would be hard to judge wether it would be possible with a strong type system.

–gideon

This is my problem :


final class Range {
  private final Number min;
  private final Number max;

  Range(Number min, Number max) {
    this.min = min;
    this.max = max;
  }

  public Number size() {
    //How to implement?
    // return max.minus(min); //would be nice
    // return max.doubleValue() - min.doubleValue(); //Loses accuracy on not floating point types
  }
}

I want this class to work for int, floats, doubles, BigIntegers, bytes etc… So if my range is an int range (min and max are ints) then size returns an int, if my range is a double range, then size returns a double. How do I implement the size method?
The ways I can see are ugly - mutliple implementations of the size method either as subclasses or a big if statement - yuck.
This is not an isolated problem, check out Rectangle, Rectangle2D.Double,and Rectangle2D.Float and Point, Point2D.Double and Point2D.Float.

This ugly, verbose and error prone and I would change it.

D.

What I would really like is the ‘unsigned’ keyword, and to change the fact that all kinds of operations are always implicitly cast to int.
For example I want to be able to write:

unsigned byte someByte = someOtherByte << 1;

Oooh, wouldn’t it also be totally excellent to have binary, byte and short literals too?
eg.


byte b = 245b;
short s = 1234s;
int wibble = %100101010111;

Cas :slight_smile:

Yes, having to write

byte b = (byte) 254;

is just annoying.

bynary annotation, like byte b = %01101100

an interactive shell like python has.

[quote]This is my problem :

Code:

final class Range {
private final Number min;
private final Number max;

Range(Number min, Number max) {
this.min = min;
this.max = max;
}

public Number size() {
//How to implement?
// return max.minus(min); //would be nice
// return max.doubleValue() - min.doubleValue(); //Loses accuracy on not floating point types
}
}

I want this class to work for int, floats, doubles, BigIntegers, bytes etc… So if my range is an int range (min and max are ints) then size returns an int, if my range is a double range, then size returns a double. How do I implement the size method?
The ways I can see are ugly - mutliple implementations of the size method either as subclasses or a big if statement - yuck.
This is not an isolated problem, check out Rectangle, Rectangle2D.Double,and Rectangle2D.Float and Point, Point2D.Double and Point2D.Float.

This ugly, verbose and error prone and I would change it.
[/quote]
How about:

final class Range<N extends Number> {
  private final N min;
  private final N max;

  Range(N min, N max) {
    this.min = min;
    this.max = max;
  }

  public N size() {
    return (N)(max - min);
  }
}

I didn’t compile it; so there might be problems.

You’d think that would work, wouldn’t you - shame autoboxing was implemented as a hacky after-thought.
The ‘-’ operator is defined for all of the Number classes sub-classes, but not for the Number class itself, hence it doesn’t compile.

Would it make sense to add abstract minus, mulitply and add methods to Number? e.g :


class Number {
  public abstract <T extends Number> T minus(T other);
  //Similarly add and multiple
}


class Integer {
    public Integer minus(Integer i) {
      return valueOf(intValue() - i.intValue()); //preserving immutabilitiy
    }
  //Similarly add and multiple
}


class Double {
    public Integer minus(Double d) {
      return valueOf(doubleValue() - d.doubleValue()); //preserving immutabilitiy
    }
  //Similarly add and multiple
}

Not compiled this either, but I think it works and it makes sense to me to have such operations on the Number class, in fact they seem conspicuous by there absence. Comments welcomed.
D.

I think that makes a lot of sense! Or provide an utility class…