Java 7
Java 7 has proposed syntax for what Scala calls two methods:
-
Option.flatMap
In Scala where we would normally write:(a, b, c, d) => for { aa <- a(argsa) bb <- b(argsb) cc <- c(argsc) dd <- d(argsd) } yield f(aa, bb, cc, dd)
While in Java we write:
// ceremony in the absence of closures // has been omitted (and altered slightly) for brevity a(argsa)?.b(argsb)?.c(argsc)?.d(argsd).f();
This syntax denotes the bind operation of
Optionmonad, while Scala’s for-comprehension works for any monad. A pedantic point of note is that, from a particular perspective, Java’s syntax is slightly weaker than monad syntax, in that it is in fact, an applicative functor comprehension (not monad), since subsequent computations do not have access to previously computed values along the chain (if this is confuzzling, never mind — it’s important point otherwise, but not so much here). Scala’s for-comprehensions allow this, but it hasn’t been demonstrated above. - Option.getOrElse
Java calls this ?:, so while in Scala we might write value getOrElse k, or if you prefer Scalaz, value | k, in Java we’d write value ?: k. The Java version maintains the usual lack of safety of null, while Scala uses an algebraic data type.
Among many differences between Scala and Java here, one is that Scala does not introduce syntax for these two specific functions — after all, why would you? Further, what about the zillions of other useful functions? Java has no user-defined call-by-need unification, which means it is not possible to write ?: yourself (even with a different valid Java identifier as a name). I wrote about this once before. I expect this is the reason for introduction of syntax for representing individual functions.
Scala’s representation is also safer, in that it uses a data structure to denote a list with a maximum length of one, rather than a value with type T, oh wait, just kidding, it might be null!
My favourite part of Java’s proposed introduction of syntax for two very specific functions (among hundreds of others), watered down to be not-quite-as-useful, is the assurance that I am still going to hear about how Scala is complex, while Java is not. Fun times.
Edit: Proposed Java syntax.
August 18th, 2011 at 9:46 pm
In Germany we have a saying: “Was der Bauer nicht kennt, frisst er nicht” it means something like: “What we don’t know scares us.”.
August 18th, 2011 at 9:51 pm
Another good post Tony. Although as far as I know, or can tell, the Elvis operator wasn’t actually accepted in Java 7.
http://blogs.oracle.com/darcy/entry/project_coin_final_five
We do have the awesome diamond operator now though.
August 18th, 2011 at 10:19 pm
as I remember, elvis was proposed to java 7 in project coin, but not accepted. (And coin proposal describe null-safe operators as they implemented in groovy).
August 18th, 2011 at 10:39 pm
Perhaps you could check your facts? This syntax is not in Java 7.
That said the Java syntax should be included in Java as it is in Groovy. It would be incredibly popular if it was http://blog.joda.org/2009/01/jdk-7-language-changes-everyone-votes_4547.html . Your example for ?. also makes it perfectly clear why. The “Java” version is a lot more readable than the Scala.
August 18th, 2011 at 10:41 pm
The syntax you describe is not in Java 7. It has been considered, but was rejected. See http://blogs.oracle.com/darcy/entry/project_coin_final_five
August 18th, 2011 at 11:08 pm
Thanks for pointing this stuff out, Tony. I depend on guys like you to tell me what’s in Java these days now that I focus on languages like Scala and Haskell and have (hopefully) said good-bye to Java for good. Ah, were that only true, and I didn’t have to earn money.
August 18th, 2011 at 11:58 pm
Stephen, The Java version is not more readable than the Scala version. I had to omit all the ridiculous Java nonsense to make the point.
Right, the syntax is a proposal.
August 19th, 2011 at 12:28 am
The proposed Java syntax (already in Groovy)
a(argsa)?.b(argsb)?.c(argsc)?.d(argsd).f()is totally different from(a, b, c, d) => for {
aa <- a(argsa)
bb <- b(argsb)
cc <- c(argsc)
dd <- d(argsd)
} yield f(aa, bb, cc, dd)
It’s equivalent to
for {
aa <- a(argsa)
bb <- aa.b(argsb)
cc <- bb.c(argsc)
dd <- cc.d(argsd)
}yield(dd.f())
While the Java version is not as general, it does provide some useful syntactic sugar for a common use case, and it’s a whole lot more concise than the Scala way of doing this. (It would be kinda nice of Scala’s options supported something like this, but that would require one or more completely brand-new langauge concepts in Scala to pull it off.
August 19th, 2011 at 12:32 am
Tony, this is not Java 7. The Java syntax you discuss in this article, while proposed, was rejected long ago. Java 7 was officially released 3 weeks ago. Not sure what the purpose is here.
August 19th, 2011 at 6:56 am
Stephen, I am not sure that I would describe the java syntax as more readable; that seems like a very subjective thing.
To me ?: looks like line noise, whereas getOrElse tells me what it is doing.
August 19th, 2011 at 8:05 am
Ken,
See Scalaz for same without sacrificing the generalisation.
September 27th, 2011 at 12:37 am
The Java syntax you discuss in this article, while proposed, was rejected long ago.
September 28th, 2011 at 6:52 am
Rejected or not, there existed a functioning compiler years ago.