About Martijn Verburg

Martijn (aka "The Diabolical Developer") is the co-founder and CTO of jClarity. He's a London Java Community leader, founder of the "Adopt a JSR" and "Adopt OpenJDK" programmes, a speaker at major conferences and the co-author of the Well-Grounded Java Developer.

Java Lambda Syntax Alternatives

The discussion on the lambda-dev mailing list has started to address the issue of what the Java language syntax for lambdas / function literals ought to look like. Let’s look at a slightly non-trivial example and try to tease the issues out.

The Perl people have a nice example of something which uses function references in a somewhat functional way – they call it the Schwartzian Transform (but I believe it’s originally a Lisp trick sometimes called decorate-sort-undecorate). As there are just us JVM chickens here, I rewrote it in Clojure (it’s actually one of my examples in Chapter 9 of the book).

Here’s a snippet of Clojure code which defines a function to perform the Schwartzian transform. Basically, it provides a very simple way of sorting a list based on an auxiliary function (called a “keying function”) provided by the caller.

(defn schwarz [x f]
  (map #(nth %1 0)
       (sort-by #(nth %1 1)
                (map #(let [w %1]
                     (list w (f w)) ) x))))

The code is doing three separate steps – creation of a list consisting of pairs (the original values paired up with the value obtained by applying the keying function to the original values), then sorting the pairs based on the values of the keying function. Finally a new list is constructed by taking only the original value from each pair in the sorted list-of-pairs (and discarding the keying function values).

What might this look like in the various proposed Java syntax variants? Let’s take a quick look at each one (note that because Java’s type system is much more static, a lot of our type declarations are more than a little long-winded):

// Strawman, with round brackets for single-expression lambdas
public List<T> schwarz(List<T> x, Function<T, Pair<T,V extends Comparable<T>>> f) {
return map(#(T w)(makelist(w, f.apply(w))), x)
       .sort(#(Pair<T, V extends Comparable<T>> l)(l.get(1)))
       .map(#(Pair<T, V extends Comparable<T>> l)(l.get(0)));
}

// Strawman, with braces for all lambdas
public List<T> schwarz(List<T> x, Function<T, Pair<T,V extends Comparable<T>>> f) {
return map(#(T w){makelist(w, f.apply(w))}, x)
       .sort(#(Pair<T, V extends Comparable<T>> l){l.get(1)})
       .map(#(Pair<T, V extends Comparable<T>> l){l.get(0)});
}

// BGGA
public List<T> schwarz(List<T> x, Function<T, Pair<T,V>> f) {
return map({T w -> makelist(w, f.apply(w))}, x)
       .sort({Pair<T, V extends Comparable<T>> l -> l.get(1)})
       .map({Pair<T, V extends Comparable<T>> l -> l.get(0)});
}

// SotL
public List<T> schwarz(List<T> x, Function<T, Pair<T,V>> f) {
return map(#{T w -> makelist(w, f.apply(w))}, x)
       .sort(#{Pair<T, V extends Comparable<T>> l -> l.get(1)})
       .map(#{Pair<T, V extends Comparable<T>> l -> l.get(0)});
}

// Redmond
public List<T> schwarz(List<T> x, Function<T, Pair<T,V extends Comparable<T>>> f) {
return map((T w) -> {makelist(w, f.apply(w))}, x)
       .sort((Pair<T,V extends Comparable<T>> l) -> {l.get(1)})
       .map((Pair<T, V extends Comparable<T>> l) -> {l.get(0)});
}

How to evaluate them? My criteria are:

  1. Needs to start with a visible identifying mark, so that lambdas stand out from the surrounding code. The # is a handy character for this.
  2. Needs to use the {} delimiting syntax. Closures are a kind of block, so they should be block-like in code.
  3. Needs to be all in one piece, so the syntax has a visual consistency and the lambda appears as a single unit.
  4. Preferably, needs to have a specialized short form for function literals which take no parameters (nullary lambdas).

Based on these criteria, Redmond is the worst possible choice for me – and my experience writing Scala for the book bears this out – I found Scala’s function literals much harder to use without problems than those in other languages. BGGA is a little better, but I don’t like the lack of a simple identifying mark that tells me “Hello! I’m a lambda”.

This brings it down to a choice to between SotL and Strawman with always-brace. The choice of these two is somewhat arbitrary. Strawman-always-brace looks, to my eyes like a true Java method declaration, but with the “magic name” # – whereas SotL is genuinely new syntax, but feels closer to the Redmond and BGGA styles – so could well be an acceptable compromise for developers who are comfortable with those forms.

Pulling it all together, my preferred choices are:

  1. SotLhttp://www.blogger.com/img/blank.gif
  2. Strawman-always-brace
  3. BGGA
  4. Strawman-single-expression-round
  5. Redmond

Please use the comments (below or at the original source) to tell us what you make of this issue. Of course, this won’t be in Java 7 – but it’s not too early to start thinking about Java 8 and the future.

Reference: Lambda Syntax Alternatives from our JCG partners at the Java 7 Developer Blog.

Related Articles :
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You'll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You'll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


− two = 3



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books
Get tutored by the Geeks! JCG Academy is a fact... Join Now
Hello. Add your message here.