Saturday, January 12, 2008

Lazy streams in Java, Groovy, JavaScript, JRuby

This is a follow up to my last blog: Functional constructs Java 7, Groovy, Commons

I have finished coding the first part of the lazy streams for ShapeLogic. They are going to be key for the declarative programming query interface to ShapeLogic. As a proof of concept I wanted to see how easy it would be to implement a lazy stream of Fibonacci numbers. So far I have tested my framework with definitions written in:
  1. Groovy
  2. JavaScript
  3. JRuby
  4. Java
It is essential that lazy streams are are easy to define so they can be put in a flat file or a database. I was very satisfied with the concise definitions of the Fibonacci streams in the different languages:

Lazy Fibonacci stream in Groovy

new FunctionStream("fibo","def fibo_FUNCTION_ = { fibo.get(it-2) + fibo.get(it-1) };",1,1);

fibo is the name the lazy stream has in the context / name space
fibo_FUNCTION_ it is a naming convention that the function that is use to create the stream has this name
1,1 is the first part of the lazy stream

Lazy Fibonacci stream in JRuby

new FunctionStream("fibo","jruby",null,"def fibo_FUNCTION_(it) return $fibo.get(it-2) + $fibo.get(it-1) end",1,1)

Lazy Fibonacci stream in JavaScript

new FunctionStream("fibo","javascript",null,"function fibo_FUNCTION_(it) { return parseInt(fibo.get(it-2) ) + parseInt(fibo.get(it-1))};",1,1);

Scripting using JSR 223

I added a formula language for users to an enterprise Java system a few years back using Antlr and BeanShell. JSR 223 is dramatically easier to work with, but there are still some problems.

The only scripting language that works out of the box with Java 6 is JavaScript. To get others to work you have to download jsr223-engines.zip from:
https://scripting.dev.java.net/servlets/ProjectDocumentList
For each language you want to use there is a engine jar file.
E.g. jruby-engine.jar.
They have to be on your path. So does the jar file implementing the language.

JSR 223 and Maven 2 problems

JSR 223 does not work well with Maven 2. The engine jar file does not reside in the Maven repository so you have to separately install them into you local Maven repository. Here is the command to install JRuby:
~/bin/maven-2.0.8/bin/mvn install:install-file -Dfile=jruby-engine.jar -DgroupId=org.jruby -DartifactId=jruby-engine -Dversion=1.0.1 -Dpackaging=jar

Scripting languages currently under JSR 223

beanshell, browserjs, ejs, freemarker, groovy, jacl, jaskell, java, javascript, jawk, jelly, jep, jexl, jruby, jst, judo, juel, jython, ognl, pnuts, scheme, sleep, velocity, xpath, xslt.
These languages should in theory work with ShapeLogic, without any additional code.

Other implementations of lazy streams

  1. BaseStream: That is the abstract base class with most of the lazy stream functionality
  2. IteratorStream: Generates elements using Java Iterator
  3. TransformerStream: Generates elements using Java interface
  4. FunctionStream: Generates elements using JRS 223 as described above

Next step for functional constructs for ShapeLogic

  1. Filter that is easy to define in external text using scripting
  2. Transformer transforming one lazy stream to the next
  3. Query interface from where a result can be retrieved
-Sami Badawi

No comments: