Nashorn and Lambda, What the Hey!

Yesterday, Brian Goetz (Lambda architect) suggested that I produce an example of Lambda being used from Nashorn.  Since, I've been heads down in Nashorn, I really haven't played with Lambda that much.  After looking at some examples from Stuart Marks,  I figured, what the hey, it doesn't look that hard.  Details of the Lambda APIs are available at JDK 8 b92 API .

Many constructs are familiar to JavaScript developers.  The main things to note;
  • where you can use a Lambda you can use a JavaScript function
  • JavaScript arrays need to be converted to Java collections
  • JavaScript syntax requires the '.' end a phrase, not start one (forces continuation)
Other than that, the JavaScript source and Java source looks very much the same.

#!/usr/bin/env jjs -scripting

var copyright = <<<EOS;
/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
EOS

var Collectors = java.util.stream.Collectors;

// Break the copyright into tokens.
var tokens = copyright.split(/\s+/);

// Convert to ArrayList.
var list = new java.util.ArrayList();
tokens.map(function(e) list.add(e));

// The JavaScript collection for the result.
var result = [];

// Parallelize some of the activity.
list.parallelStream().
    // Select only words.
    filter(function(t) t.match(/^[A-Za-z]+$/)).
    // Make case comparable.
    map(function(t) t.toLowerCase()).
    // Fold duplicates.
    collect(Collectors.groupingBy(function(t) t)).
    // Move results to JavaScript collection.
    forEach(function(t) result.push(t));

// Sort the result.
result.sort();

print(result);
The result;
a,above,advised,all,and,any,are,arising,be,binary,business,but,by,caused,code,
conditions,consequential,contributors,copyright,damages,derived,disclaimer,
documentation,endorse,even,event,express,fitness,following,for,form,from,
goods,holders,however,if,implied,in,is,its,liable,limited,list,loss,materials,
may,merchantability,must,name,names,negligence,neither,no,nor,not,of,on,or,
oracle,other,out,owner,particular,permitted,possibility,prior,procurement,
products,promote,provided,purpose,redistribution,redistributions,reproduce,
retain,rights,shall,software,source,specific,strict,substitute,such,that,
the,theory,this,to,tort,use,used,warranties,way,whether,with,without,written

Comments:

Brian pointed out after I posted, that I could replace collect(Collectors.groupingBy(function(t) t)). with distinct().

Posted by jlaskey on June 19, 2013 at 12:54 PM PDT #

I'm a bit confused by the function definitions, e.g. "function(t) t":

* why are there no curly braces?
* why doesn't this require the "return" keyword?
* is this valid ECMAScript, or is this something Nashorn-specific? I just had a quick look in the ECMAScript specification & couldn't find anything like this.

Thanks for shedding some light on this.

Posted by Anthony on June 19, 2013 at 02:29 PM PDT #

This is a Nashorn extended syntax notation, primarily designed for use with SAM and Lambda. In ES6 we will allow the arrow notation as well; (t) => t.match(/^[A-Za-z]+$/) . You can suppress Nashorn extended syntax with --no-syntax-extensions, and write using standard notation; function(t) => { return t.match(/^[A-Za-z]+$/); } .

Posted by jlaskey on June 19, 2013 at 02:48 PM PDT #

Mozilla JavaScript 1.7+ support the "closure expressions" as well.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1.8#Expression_closures_%28Merge_into_own_page.2Fsection%29

Posted by sundararajan on June 19, 2013 at 08:06 PM PDT #

@jlaskey could you please elaborate on why you decided to go with a new syntax for supporting Java8 lambda expressions("Nashorn extended syntax notation") instead of using ES6's arrow syntax for this purpose as well?

Posted by guest on July 04, 2013 at 06:19 AM PDT #

One of the goals set for JDK8 Nashorn was to implement ECMAScript 5.1. We also had a goal to replace Rhino, so we had to carry some features from Rhino, which included expression closures (was introduced in JavaScript 1.8.) The arrow notation will come as we add ES6 features. It will not make JDK8 but will show up after (deliberate non-commitment to when.)

Posted by jlaskey on July 04, 2013 at 09:20 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Technical discussions and status of the Nashorn JavaScript Project.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today