So what about Eclipse's Xtend?

Some Examples

Https Example

// Java @Override public void start() { vertx.createHttpClient() .setSSL(true) .setTrustAll(true) .setPort(4443) .setHost("localhost") .getNow("/", new Handler<HttpClientResponse>() { public void handle(HttpClientResponse response) { response.dataHandler(new Handler<Buffer>() { public void handle(Buffer data) { System.out.println(data); } }); } }); }

// Xtend override start() { vertx.createHttpClient => [ SSL = true trustAll = true port = 4443 host = "localhost" getNow("/") [ dataHandler [ data | println( data ) ] ] ] }

SSL = true

it.setSSL(true)

getNow("/") [ dataHandler [ data | println( data ) ] ]

If the last argument of a feature call is a lambda expression it can be passed after the method call. A lambda expression automatically coerces to the expected target type if it's an interface with just one method (which is a common idiom not only in vert.x).

getNow("/") [ dataHandler [ println( it ) ] ]

// JAVA public void start() { vertx.createHttpServer() .setSSL(true) .setKeyStorePath("server-keystore.jks") .setKeyStorePassword("wibble") .requestHandler(new Handler<HttpServerRequest>() { public void handle(HttpServerRequest req) { System.out.println("Got request: " + req.uri); System.out.println("Headers are: "); for (String key : req.headers().keySet()) { System.out.println(key + ":" + req.headers().get(key)); } req.response.headers().put("Content-Type", "text/html; charset=UTF-8"); req.response.setChunked(true); req.response.write("<html><body><h1>Hello from vert.x!</h1></body></html>", "UTF-8").end(); } }).listen(4443); }

// Xtend override start() { vertx.createHttpServer => [ SSL = true keyStorePath = "server-keystore.jks" keyStorePassword = "wibble" requestHandler [ println("Got request: " + uri) println("Headers are: ") for (it : headers.entrySet) { println(key + ":" + value) } response.headers.put("Content-Type", "text/html; charset=UTF-8") response.chunked = true response.write(''' <html> <body> <h1>Hello from vert.x!</h1> </body> </html> ''', "UTF-8").end ] listen(4443) ] }

You can use the variable name it every where. For instance in a for loop like in the code snippet above.



every where. For instance in a for loop like in the code snippet above. Xtend supports multiline string literals. The common literals using single quote or double quote can be multiline as well, but by using triple single quotes you get smart whitespace handling. That is the indentation before the tag will be pruned for all lines, i.e. the result will be well formatted. Also the triple quotes allow for having interpolation expressions, which are not used in this example.

Can we do even more?

class JsonExample extends Verticle { override start() { val eb = vertx.eventBus val pa = 'vertx.mongopersistor' val albums = _( _( 'artist'- 'The Wurzels', 'genre'- 'Scrumpy and Western', 'title'- 'I Am A Cider Drinker', 'price'- 0.99, 'categories'- _('action', 'comedy') ), _( 'artist'- 'Vanilla Ice', 'genre'- 'Hip Hop', 'title'- 'Ice Ice Baby', 'price'- 0.01 ), _( 'artist'- 'Ena Baga', 'genre'- 'Easy Listening', 'title'- 'The Happy Hammond', 'price'- 0.50 ), _( 'artist'- 'The Tweets', 'genre'- 'Bird related songs', 'title'- 'The Birdy Song', 'price'- 1.20 ) ) // First delete everything eb.send(pa, _('action'- 'delete', 'collection'- 'albums', 'matcher'- _())) eb.send(pa, _('action'- 'delete', 'collection'- 'users', 'matcher'- _())) // Insert albums - in real life price would probably be // stored in a different collection, but, hey, this is a demo. for (album : albums) { eb.send(pa, _( 'action'- 'save', 'collection'- 'albums', 'document'- album )) } // And a user eb.send(pa, _( 'action'- 'save', 'collection'- 'users', 'document'- _( 'firstname'- 'Tim', 'lastname'- 'Fox', 'email'- 'tim@localhost.com', 'username'- 'tim', 'password'- 'password' ) )) } }

def static <T> Pair<String,T> operator_minus(String key, T value) { new Pair(key, value) } def static JsonArray _(Object ... entries) { val result = new JsonArray for (e : entries) { switch e { String : result.addString(e) Number : result.addNumber(e) Boolean : result.addBoolean(e) JsonObject : result.addObject(e) JsonArray : result.addArray(e) } } return result } def static JsonObject _(Pair<String, ?> ... entries) { val result = new JsonObject for (e : entries) { switch value : e.value { String : result.putString(e.key, value) Number : result.putNumber(e.key, value) Boolean : result.putBoolean(e.key, value) JsonObject : result.putObject(e.key, value) JsonArray : result.putArray(e.key, value) } } return result }