Four languages – one process

The previous entry was cut slightly short because I had to head out to dinner. What I was trying to finish was a bit of code to experiment with JRuby, Jython, Rhino, and the new JSR 223 scripting framework.

My first step was to build JRuby from trunk and the Jython 2.5 branch, as well as JSR223 trunk. After a small patch, I got some code working:

package org.verbum;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;

public class LangFun {
public static class Hello {
public void sayHello() {
System.out.println("Hello world!");
}
}
public static void main(String[] args) throws ScriptException {
ScriptEngineManager mgr = new ScriptEngineManager();

Hello greeting = new Hello();

greeting.sayHello();

ScriptContext context = new SimpleScriptContext();
context.setAttribute("greeting", greeting, ScriptContext.ENGINE_SCOPE);          

ScriptEngine javaScript = mgr.getEngineByExtension("js");
javaScript.setContext(context);
javaScript.eval("greeting.sayHello()");

ScriptEngine ruby = mgr.getEngineByExtension("rb");
ruby.setContext(context);
ruby.eval("$greeting.sayHello");

ScriptEngine python = mgr.getEngineByExtension("py");
python.setContext(context);
python.eval("greeting.sayHello()");        
}
}

To run this, you’ll need to link to jruby.jar, jython.jar, rhino.jar, as well as the respective engines from JSR223: jruby-engine.jar, jython-engine.jar, js-engine.jar.
The idea behind this code is pretty simple – we first create a Java object, with a single method. Then we use the JSR223 interface to instantiate an engine for each of the languages, hook up a context object which maps the variable greeting into the global namespace for each language, then call their respective eval methods. The result is what you’d expect:

Hello world!
Hello world!
Hello world!
Hello world!

Pretty cool! Of course, I’m not really stressing the system here with these simple scripts; but given the dramatic progress (really, look at that graph!) of projects like JRuby, the future approaching very quickly.

“Ok, but…”, you might say, “what’s this useful for besides sharing libraries?” The general answer is that the single process, shared memory model is fundamentally more powerful than the multi-process, communicating over bytestream pipes model. You can just do more, with fewer hacks. An example is software like Reinteract – before, it could only support Python. Now, not only could you add an input language chooser to Reinteract; you could actually pass the results from a Python computation increasingly seamlessly into Groovy, Java, or whatever. Personally, I specifically want this for Hotwire. Right now we only support Python well, because the project is based on CPython.

Many new languages for the Free Software community

There was a comment on the last entry mentioning Scala. I’ve only looked at it very briefly. But this is just one of many languages that are now truly, finally part of the Free Software community. The Scripting project has a list of the engines written. But that list is far from complete, because some don’t have the engine glue written yet, and because other languages like Scala are more designed as Java replacements that run on the JVM, rather than “scripting”.

And of course through all of this, venerable Java isn’t standing still – it will likely gain closures. And remember – all of this will soon be available (if it isn’t already) via yum install or apt-get install, etc., all of it entirely Free Software, and increasingly integrated with the operating system and your favorite libraries.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s