Actual language usage
• Primary programming language
• Con!guration + build system
• Presentation
• Miscellaneous scripting
Table of contents
• How I became a polyglot programmer
• The case for polyglot programming
• Languages, JVM and polyglot apps
• Impedance mismatch
• Glue code
• Language boundaries
• Getting started
An accidental polyglot
flickr: darynbarry
ONEIS architecture
Inte
rnet
Worker JVM
Worker JVM
Worker JVM
Worker JVM
JVM
JavaSandboxed JavaScript
pluginsJava
Java
Scri
pt
Ruby
Jett
y
flickr: dm-set
The case for polyglot
Languages are not equal
• Expressiveness• Performance• Readability• Style
• Static• Dynamic• Functional• WTF
Ola Bini’s pyramid
http://olabini.com/blog/2008/06/fractal-programming/
Why the JVM?
• Great runtime
• Portability
• Common underlying VM for lots of languages
• Interoperability
• Java library for everything
Side note:Don’t forget the CLR
• Good stu" from Microsoft
• Great runtime
• DLR
• APIs
• Di"erent culture
• Trap?
Side note:Don’t forget IPC
• Go old school
• Separate processes
• Common protocol over sockets and pipes
• Thrift, Google Protocol Bu"ers, Avro
• or text over HTTP: XML, JSON, etc
flickr: munksynz
Languages and the JVM
What’s the best language?
• No such thing as the “best” language
• Use the best language for solvingyour problems
• Polyglot is about avoiding compromises
Language choice
• Don’t use two closely related languages
• Don’t forget the standard library
• And some have special featureseg. concurrency libraries
Pick one from each column
Static Dynamic Scripting / DSLs
Java Ruby JavaScript
Scala Groovy Ruby
Clojure Groovy
Jython
Aims
• Work in harmony
• Choose most appropriate language for each task
• Choose carefully as choices are hard to undo
flickr: h080
Impedance mismatch
Impedance mismatch
• Type systems
• Your languages won’t agree on the simplest things:
• Strings, Numbers, Dates, Arrays, null
Strings
• Java: UTF-16 (ish) strings• JavaScript: implementation dependent
• Browsers: UCS-16 usually• JVM: Whatever Java does + optimisations
• Ruby• bytes (1.8), or bytes+encoding (1.9)
• JVM originated languages: Java Strings
Numbers
• Java: primitives, java.lang.Number, etc
• JavaScript: doubles only.Plus odd Number object.
• Ruby:• ints (always Fixnum) with silent promotion to
Bignum• doubles, Rational
Javascript’snull and undefined
var o = {item: null};
if(o.item === undefined) { console.log("0");}if(o.noSuchItem === undefined) { console.log("1");} OUTPUT
1
Javascript’snull and undefined
var o = {item: null};
if(o.item === undefined) { console.log("0");}if(o.noSuchItem === undefined) { console.log("1");}
var undefined = 42;if(o.noSuchItem === undefined) { console.log("2");}
OUTPUT
1
Strings, numbers, dates...
• Impedance mismatch means you haveto think about the boundaries
• Use Groovy?
flickr: samcatchesides
Glue code
Glue code
• Work around impedance mismatch
• Java: The new assembly language
• Rule enforcement & security
• Cheat until your pro!ler says it’s slow
• Serialise/deserialise to common format,eg JSON
undefined is not nullJAVA
public class Host extends ScriptableObject {
public String jsFunction_f(String x) { System.out.println( "x = " + x ); }
}
undefined is not nullJAVA
public class Host extends ScriptableObject {
public String jsFunction_f(String x) { System.out.println( "x = " + x ); }
}
JAVASCRIPT
var h = new Host();
h.f("Hello");h.f(2);h.f(null);
h.f(undefined);
undefined is not nullJAVA
public class Host extends ScriptableObject {
public String jsFunction_f(String x) { System.out.println( "x = " + x ); }
}
JAVASCRIPT
var h = new Host();
h.f("Hello");h.f(2);h.f(null);
h.f(undefined);
VALUES OF X
"Hello""2"null
"undefined"
null and undefined are 0JAVA
public void jsFunction_each(Integer desc, boolean hasDesc,Integer qual, boolean hasQual)
JAVASCRIPT
Store.prototype.each = function(desc, qual) { return this.$store.each(
desc, (desc !== null && desc !== undefined),qual, (qual !== null && qual !== undefined)
); };
Conversions public static Date tryConvertJsDate(Object jsObject) { if(jsObject == null) { return null;} if(nativeDateClass == null) { try { nativeDateClass = Class.forName("org.mozilla.javascript.NativeDate"); } catch(ClassNotFoundException e) { /* ... */ } } if(nativeDateClass.isInstance(jsObject)) { Object d = Context.jsToJava(jsObject, Date.class); if(d != null && d instanceof Date) { return (Date)d; } } return null; }
Calling Java is easy
• Don’t let JavaScript put you o"
• Calling Java APIs from any other language is easy
Create a JPEG with Javaimport java.awt.image.BufferedImage;import java.awt.Graphics2D;import javax.imageio.ImageIO;import java.io.File;
public class MakeImage{ public BufferedImage makeImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, TYPE_INT_RGB); Graphics2D graphics = image.createGraphics(); graphics.drawString("Hello world", w/2, h/2); graphics.dispose(); return image; } public static void main(String args[]) throws Exception { BufferedImage img = (new MakeImage()).makeImage(200, 400); ImageIO.write(img, "jpeg", new File("test.jpeg")); }}
Create a JPEG with JRubyrequire 'java'
class MakeImage java_import java.awt.image.BufferedImage; java_import java.awt.Graphics2D; def make_image(w, h) image = BufferedImage.new(w, h, BufferedImage::TYPE_INT_RGB) graphics = image.create_graphics graphics.draw_string("Hello world", w/2, h/2) graphics.dispose image endend
java_import javax.imageio.ImageIO;java_import java.io.File;
img = MakeImage.new.make_image(200, 400)ImageIO.write(img, "jpeg", File.new("test.jpeg"))
Divided by acommon language
•JRuby: Transparent bridging
•JavaScript: Host objects + bridging
•Groovy: Java is subset of Groovy
•Scala: Write Java with Scala syntax
JSR-223
• Java Scripting API
• Common API for scripting languages on the JVM
• Scripting “engines” available for many languages, variable quality
• Su"ers from impedance mismatch itself
• Functions may return unexpected types
flickr: dinomite
Language boundaries
Ola Bini’s pyramid
http://olabini.com/blog/2008/06/fractal-programming/
Boundaries
• Which language for each module?
• Clear boundaries, not a free-for-all.
• Well de!ned (and documented) interfaces
Java to Ruby
public interface Framework{ void startApplication(); void startBackgroundTasks(); void stopApplication();
Response handleFromJava( HttpServletRequest request, Application app, byte[] body, boolean isRequestSSL);}
Ruby implementation
class Framework
def start_application # ... end
def handle_from_java( servlet_request, application, body, is_ssl) # magic goes here end
end
JavaScript to Ruby(via Java)public interface AppWorkUnit{ public int id();
public Integer actionableById(); public void setActionableById(Integer id); public String jsGetDataRaw(); public void jsSetDataRaw(String data);
public boolean save(); public void destroy();}
Building the team
flickr: AaronLMGoodwin
Hiring polyglots
• Find people who can write code,not people who can write Java.
• Test to see if programming is instinctive, not syntax and trivia.
• Look for people who continuously learn,not those who have learnt.
developers
Finding a polyglot job
• Smaller companies, or smaller teams within large companies
• Early stage projects, not maintenance or enhancements
• Talk to really good recruiters
• Networking!
flickr: holyhoses
Getting started
The Enterprise
• It’s just Java the JVM
• Implement a servlet
• Use tools like Warbler
• TorqueBox
• New job outside the Enterprise
Starting points
• Use JRuby to try out an API
• Use Ruby testing libraries to test your Java
• Use Groovy to a make business rules DSL
• Write a layer of a small project in a dynamic language