Things you disagree with in the java language

I like varargs being arrays inside the method - my pet hate is that it shouldn’t be possible to pass in an array to the call. For a library writer it means you still have to check for null or defensively copy the array, even when 99% of the time that isn’t required because the array has just been created for you! >:(

My hyperbole meter just blew its mountings! :wink:

I read the “removing JNI boilerplate” (which is also a pet hate) as bringing something like JNA into core - ie. a direct binding through something like libffi / dyncall. I may be completely wrong with that!

All these spinoffs of Java like Kotlin and Scala all share one particularly irksome trait, which is that they keep changing things for the sake of changing things. Eg. removal of semicolons to terminate statements, the use of the word “fun” to introduce a function declaration when we already have a way. Why can’t someone make Java++, where all the lexical bits of Java are preserved and all the annoying unneccesary syntax that bothers us is fixed.

The things I’d off the top of my head which would make it so I had to type less crap are:

  1. scoped access modifiers for fields eg. public { … }
  2. automatic casting eg. Object x = … ; String y = x; // no need to write narrowing cast as it HAS to be a String to run
  3. all the little things in Coin I’ve been waiting for like ?.
  4. iterable arrays
  5. that nifty default implementation thing for interfaces
  6. structs. Haha.
  7. interface methods to actually have access modifiers that work
    bonus 8. pre and post conditions (“DBC beyond a simple assertion feature”)

Cas :slight_smile:

@princec - Mostly totally with you there! Don’t like 2 though - recipe for disaster if you ask me. And not sure what you want from 4?

#2 - can you concoct a real example with a disaster in it?
#4 - I just wanted the array type to implement Iterable, so I can at least pass in arrays to functions that want Iterables.

Cas :slight_smile:

Has no-one done a solution to 8 using annotations and annotation pre-processing? Sounds like the kind of thing that could be done without a core language change.

Edit: Anyone tried OVal?


 // mailingAddress must either be the delivery address or the invoice address 
  @Assert(expr = "_value ==_this.deliveryAddress || _value == _this.invoiceAddress", lang = "groovy")
  public String mailingAddress;

I guess that means you can go crazy with annotations and have them validate at compile and runtime, then turn them off for ‘release’ builds?

It depends what the other side of that Object x = … statement, and whether you can be certain it’s always a String (and if so, why not assign it to String or just reverse the assignments?). I like the fact that you have to be explicit about narrow casting so it’s explicitly treated as different to normal assignment. And if you’re not 100% it should probably be wrapped in an instanceof check or possibly a try / catch.

Ah, makes sense, though it’s not hard to use a wrapper if you really need it.

It made sense in C++ where you can basically turn anything into anything else but in Java it’s enforced at runtime. At compile time I’m being therefore forced to make a redundant assertion. I can’t see a class of mistakes that it prevents. The compiler will still complain if you attempt a cast that is illegal eg.


String x = ...;
char[] y = x; // Compile error just the same as if you tried char[] y = (char[]) x;

Cas :slight_smile:

Note sure I agree. Casts in java are operations, while in C/C++ they are more “pretend these bytes represent this, rather than what i said it was previously”. They really change things. I like compilers to catch things rather than just rely on run time errors.

That’s what I’m saying… compiler already catches anything actually illegal, and then you’re just forced to type a cast unnecessarily beyond that. In the same manner that <> means “just use the right signature to make this generic work”, I’m saying, just use the right cast to make this compile.

In the same vein as null deference analysis a decent compiler implementation could even be told to warn or error when it can infer the cast cannot possibly be made, or even if the cast is not guaranteed succesful at runtime through inference. Either way, I’m fed up of polluting the simplicity of the meaning of my code with bloody casts. At least generics have removed some of them.

Cas :slight_smile:

As delt0r said, we’re talking about an operation. A standard or widening assignment doesn’t cast the object so can’t throw a ClassCastException; a narrowing one can. The semantics are different, so the syntax being different is a good thing in my opinion. Simplifying syntax good - increasing the scope for breaking things in the process less so.

Ah, but if I was attempting to be misleading (for some strange reason) I wouldn’t have pointed to a presentation that contradicts a “bulletpoint” from some other presentation that I misinterpreted. I assumed this point was dead from spasi’s numbers. I wish there was an easy way to track features that make it into mainline.

@cas: structs - That hand wavy presentation say in version 10+! So if all goes well, in 2017! (excuse me if I don’t hold my breath…but at least they’re thinking about it…finally)

I’m fine with #2 as is, but things like: if (obj instanceof Foo) { casting to Foo inside this block is silly}

Semicolons in Kotlin are optional. Also, once you start writing code without semicolons, you also start wondering why the hell you’re forced to type them in Java. They’re ok for the really few cases where they’re necessary and totally useless everywhere else. In properly formatted Java code anyway.

Keywords like “fun” are needed once you move types to the right hand side of declarations. I’m no expert on compilers, but I think left vs right isn’t simply a matter of aesthetics, it enables more powerful/flexible features to be built.

[quote=“princec,post:142,topic:39645”]
2. Kotlin has safe-casts. Code like:

val foo : Any = ...
if ( foo is String ) {
    println(foo.length)
}

works without an explicit cast. As far as the compiler is concerned, the foo variable is a String inside that if block and an Object outside. The compiler is clever enough to automatically cast much more complex usages than this simple example.

  1. Kotlin’s null-safety is top of the line. Elvis, safe calls, safe casts are all available.

  2. Object arrays can be used as Iterable in Kotlin (primitive ones cannot).

  3. Extension functions are much more powerful than default interface implementations.

hmm … yeah, I like the Kotlin way! Java doing automatic casts within an instanceof block I’d be happy with. Forcing the developer to deal with what happens if the cast fails is a good thing.

The difference so far as I can make out is… with forcing explicit casts we’re insisting the developer patronises the compiler by asserting that he/she knows what he/she is doing. Without explicit casting we are saying to the compiler effectively that we are unaware that this cast operation might fail and therefore we are poor stupid humans.

However, the runtime catches the problem.

The same argument goes for checked vs. unchecked exceptions. The whole idea of forcing people to catch checked exceptions is daft, especially when it ends up with this appearing everywhere:


try {
...
} catch (Exception e) {
e.printStackTrace(System.err); // This is not handling, this is IGNORING
// or worse.. TODO: handle exception but output nothing until someone writes some code
}

Again, as all exceptions are caught and meticulously detailed by the runtime, all we’re doing is polluting readable code with failure handling everywhere when there is actually already a perfectly robust failure handling mechanism in the JVM. As an example of just how lame this is look no further than RemoteException.

You may attempt to make a counterargument that expected exceptions (oxymoronic) need to be handled correctly, but then you have to assume that any method call can fail at any time for any reason through the long list of unchecked exceptions that can already be thrown anyway (eg. NPE, CCE, IOOBE, OOME, etc).

Final nail in the coffin is that C# does without them and they have mysteriously suffered a grand total of 0 problems as a result.

Cas :slight_smile:

Almost every one of those wishlist features is in Scala (including structs as of 2.10, though getting them to always be stack-allocated is now in the JVM’s court). The “elvis operator” is really flatmap over Option, since null itself is really a second-class citizen.

Actually, every language that isn’t java does fine without checked exceptions – far as I can tell, java’s the only one. Ocaml has a compiler feature that lets you turn them on much in the same way as asserts, and I think Ada has something similar, and that’s really how Java should have done it too.

For struct to be really useful (as far as I’m concerned) they have to be backed by the VM and requires the addition of proper array of structs.

I’m sorry, which side are you arguing with that?! ;D

I’m not sure I agree they’re that similar. Personally I think checked exceptions have their place, but unfortunately are far too widely used. Don’t have too much of a problem with them when they’re about outward facing code (user input, IO, etc.) Beats dealing with error codes!

[quote=“sproingie,post:133,topic:39645”]
Complex pattern matching will be implemented at a later time afaik.

[quote=“sproingie,post:133,topic:39645”]
I spent some time last night implementing some basic monads in Kotlin. It was pretty straightforward with a few wrapper classes and a bunch of extension methods. The way I understand it (please let me know if I’m wrong), monads is a design pattern really, not a language feature. Handy features like LINQ and the yield operator make the code easier to read, but they’re not really needed to have monads in a language. Anything that can be done with yield can also be done with forEach/map/flatMap. LINQ is nice of course, but it’s as far away as you can get from Java.

Kotlin is really young, even Jetbrains won’t be using it in production for at least a few more months. They’re still working on “low-level” features (e.g data classes atm). The most important fact about Kotlin is that they’re trying to keep it simple. It has everything you’d expect from a modern language, plus a few clever extras, but it’s still something a Java dev can pick up easily. It’s for the exact opposite reason that I think Scala won’t ever become mainstream.

True, monads aren’t necessarily a language feature, but Scala has for-comprehensions, C# has LINQ, and of course Haskell has do-notation and they go a long way toward making monads actually pleasant to use – and I might add, simple. If Java wanted to do something similar, I imagine it could simply extend its foreach syntax to anything that can be fmap’d … not that that sort of thing would ever happen, mind you.