polyglot jvm
DESCRIPTION
My talk about Polyglot JVM. A Quick Tour of Java Virtual Machine Languages: Java, Groovy, Scala, Clojure. Codemotion http://codemotion.es/ 24.03.2012TRANSCRIPT
Polyglot JVM
A Quick Tour of JVM Languages
Working at OSOCO
Small but outstanding software development shop
Groovy and Grails hackers
on EC2 cloud nine
TDD mantra singers
Quality preachers
Java Platform
_____________________________________ / /| |------------------------------------| | | Java Programming Language | | |------------------------------------| | | Libraries & APIS | | |------------------------------------| | | Java Virtual Machine | | |------------------------------------|/
> 200 languages on JVM
JavaGroovy
Scala
Clojure
JRubyJPython
JavaFX
Rhino
Oxygene KotlinFantom
GosuCeylon
Xtend
Mirah
The Da Vinci Machine Project
We are extending the JVM with first-class architectural support for languages other than Java, especially dynamic languages. This project will prototype a number of extensions to the JVM, so that it can run non-Java languages efficiently, with a performance level comparable to that of Java itself.
The Da Vinci Machine Project
JSR 223: Scripting for the Java Platform
JSR 292: Supporting Dynamically Typed Languages on the Java Platform
New JDK 7 instruction: invokedynamic
Polyglot Programming
Ola Bini Programming Pyramid
/\ / \ / \ /------\ / \ / \ /------------\ / \ / \ /------------------\
Stable
DSL
Dynamic
Ola Bini Programming Pyramid
Domain-Specific (DSL, web templating) Specific part of the application
Dynamic (Groovy, Clojure) Rapid, productive, flexible development or funcionality
Stable (Java, Scala) Core funcionality, stable, well-tested, performance
Civilization advances by extending the number of important operations which we can perform without thinking about them.
Alfred North Whitehead
New languages
New ways to think about problems
Language Clasification
functional | | | | -----------------+----------------- static | dynamic | | | not functional
StackOverflow Questions
| 8,268 | __ | | | | | | 3,847 | | | __ 2,762 | | | | | __ | | | | | | | | | | | | | | |------+--+------+--+------+--+------
StackOverflow Questions
| | | | | | | | 222,722 | | | 8,268 | | | __ | | | | | | | | | | 3,847 | | | | | __ 2,762 | | | | | | | __ | | | | | | | | | | | | | | | | | | | | |------+--+------+--+------+--+------+--+-
Indeed Job Trends
| 0,06 | __ | | | | | | 0,03 | | | __ | | | | | 0,01 | | | | | __ | | | | | | | |------+--+------+--+------+--+------
Indeed Job Trends
| | | | | | | | 3,40 | | | 0,06 | | | __ | | | | | | | | | | 0,03 | | | | | __ | | | | | | | 0,01 | | | | | | | __ | | | | | | | | | | | |------+--+------+--+------+--+------+--+-
All of them
● Everything is an object● Operator overloading● Native syntax for collection classes● Regular expressions as first class citizens● Closures● Facilities to build DSLs
Groovy
● Dynamic Language● Object-Oriented● Designed for the JVM● Inspired by Python, Ruby and Smalltalk● Good integration with Java● 2003
Hello Groovy
println 'Hello World'
Scripting
Typically dynamic languages No need to define variable before you use them. Many type conversion
Most scripting languages are interpreted Perform the script compilation and execution within the same process
Fast results for small jobs Write application faster Execute commands repeatedly
Groovy Beans
class Person { String name Integer age}
def person = new Person(name: 'John', age: 30)
def name = person.nameperson.age = 35
Static vs. Dynamic
Static typing A programming language is said to use static typing when type checking is performed during compile time as opposed to runtime
Dynamic typing A programming language is said to be dynamically typed when the majority of its type checking is performed at runtime as opposed to at compile time
Optional Typing
Integer object
object = 4
object = 'noun'ERRORorg.codehaus.groovy.runtime.typehandling.GroovyCastException
Optional Typing
def object
object = 4object = 'noun'object = trueobject = [1, 'noun', true]object = [1: 'noun']
Java Groovy→
import java.util.List;import java.util.ArrayList;
public class Filter { public static void main(String[] args) { List names = new ArrayList(); names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); System.out.println(names);
Filter filter = new Filter(); List shortNames = filter.filterLongerThan(names, 3); System.out.println(shortNames.size()); for (String item : shortNames) { System.out.println(item); } }...
Java Groovy→
...
private List filterLongerThan(List strings, int length) { List result = new ArrayList(); for (String item : strings) { if (item.length() <= length) { result.add(item); } } return result; }}
Java Groovy→
def names = ["Ted", "Fred"] << "Jed" << "Ned"println names
def shortNames = names.findAll { it.size() <= 3 }println shortNames.size()shortNames.each { name -> println name }
Static language
interface Animal { def quack()}
class Duck implements Animal { def quack() { println "I am a Duck" }}
class Frog implements Animal { def quack() { println "I am a Frog" }}
Polymorphism
Animal animal
animal = new Duck()animal.quack()===> I am a Duck animal = new Frog()animal.quack()===> I am a Frog
Dynamic language
class Duck { def quack() { println "I am a Duck" }}
class Frog { def quack() { println "I am a Frog" }}
Duck typing
def animal
animal = new Duck()animal.quack()===> I am a Duck animal = new Frog()animal.quack()===> I am a Frog
Dynamic Method Call
class Dog { def bark() { println "woof!" } def jump() { println "boing!" }}
def doAction(animal, action) { animal."$action"()}
Dynamic Method Call
someObject."$methodName"()
def rex = new Dog()
doAction(rex, "bark") ===> woof!
doAction(rex, "jump") ===> boing!
Metaprogramming
Programs that write or manipulateother programs Compile time
● Groovy AST
Runtime● Hook into method dispaching● Dynamically create methods/properties● Dynamic execution of expressions
AST Transformations
@Singletonclass Singleton {}
@EqualsAndHashCodeclass Person { String name, lastName}
@Immutableclass Coordinates { Double latitude, longitude}
Method Missing
class Dog { def bark() { println "woof!" } def jump() { println "boing!" }}
def rex = new Dog()rex.sit()ERROR groovy.lang.MissingMethodException
Method Missing
class Dog { def bark() { println "woof!" } def jump() { println "boing!" }
def methodMissing(String name, args) { println "sit!" }}
rex.sit()===> sit!
Adding methods to aclass at runtime
4.toRoman()
ERROR groovy.lang.MissingMethodException
Adding methods to aclass at runtime
SomeObject.metaClass.newMethod = { -> // do something}
Integer.metaClass.toRoman = { -> println 'IV'}
4.toRoman()===> IV
Scala
● Object-Oriented and Functional Language● Stronger type system● Designed for the JVM● Concurrency: Actors● Many advanced language features● As fast as Java● 2003
Hello Scala
object HelloWorld { def main(args: Array[String]) { println("Hello World") }}
Scala Types
scala> 1 + 1res1: Int = 2
scala> (1).+(1)res2: Int = 2
scala> "a" + "b"res3: java.lang.String = ab
scala> "abc".sizeres4: Int = 3
Classes
class Person(name: String, age: Int)
val person = new Person("John", 30)
Objects
object Singleton { def start = println("Start")}
scala> Singleton.startStart
Anatomy of a Function
def max (x: Int, y: Int): Int = { if (x > y) x else y}
Type Inference
// JavaMap<String, List<Integer>> map = new HashMap<String, List<Integer>>()
// Java 7Map<String, List<Integer>> map = new HashMap<>()
// Scalaval map = new HashMap[String, List[Int]]
Variable Declaration
var mutable = "I am mutable"mutable = "Touch me, change me..."
val immutable = "I am not mutable"immutable = "Can't touch this"error: reassignment to val
Immutability
Simple Immutable objects can only be in exactly one state, the state in which it was created
Always consistent Less prone to errors and more secure
Immutable objects can be shared freely Freedom to cache
Inherently thread-safe
Imperative vs. Declarative
Imperative: how to achieve our goal Take the next customer from a list. If the customer lives in Spain, show their details. If there are more customers in the list, go to the beginning
Declarative: what we want to achieve Show customer details of every customer living in Spain
Mutability
val listOneToTen: List[Int] = { var list: List[Int] = List() var i: Int = 1 while (i <= 10) { list :+= i i += 1 } list}
Immutability
def listToTen(i: Int): List[Int] = { if (i <= 10) i :: listToTen(i + 1) else Nil}
val listOneToTen = listToTen(1)
Range
scala> println(listOneToTen)List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(1 to 10) toList
Mixin Traits
class Person(val name: String)
trait Power { def fly() = println("Fly")}
class SuperHero(override val name:String) extends Person(name) with Power
val superMan = new SuperHero("SuperMan")scala> superMan.flyFly
Pattern Matching
def determineType(x:Any) = x match { case s: String => println("String") case l: List[_] => println("List") case l: Map[_,_] => println("Map") case _ => println("Unhandled type!")}
def factorial(n: Int): Int = n match { case 0 => 1 case x if x > 0 => factorial(n - 1) * n}
Clojure
● Clojure is LISP● Dynamic language● Designed for the JVM● Code is data● Powerful macros● Good interoperability with Java● Clojure is fast● Concurrency. Shared Transactional Memory● 2007
Why Functional Programming?
Referential transparency Unit testing Debbuging Parallelization Modularity and composition Increases the quality of code Abstractions
λλ
λλ
λλ
λ
Hello Clojure
(println "Hello World")
Prefix notation
(+ 1 2)=> 3
(+ 1 2 3 4 5)=> 15
(< 1 2 3 4 5)=> true
Anatomy of a Function
(defn biggest "Find the maximum of two numbers" [x y] (if (> x y) x y))
Anatomy of a Function
(def biggest "Find the maximum of two numbers" (fn [x y] (if (> x y) x y)))
Function Composition
(defn square [x] (* x x))
(square 21)=> 441(square (+ 2 5))=> 49
Function Composition
(defn sum-of-squares [x y] (+ (square x) (square y)))
(sum-of-squares 3 4)=> 25
Immutability
(def my-list '(1 2 3))
+---+ +---+ +---+| 1 | ---> | 2 | ---> | 3 |+---+ +---+ +---+
(def new-list (conj my-list 0))
+-----------------------------++---+ | +---+ +---+ +---+ || 0 | --->| | 1 | ---> | 2 | ---> | 3 | |+---+ | +---+ +---+ +---+ | +-----------------------------+
Lazy Evaluation
Only does as much work as necessary Delays the evaluation of the expression until it's needed
CPU efficient The value is not calculated or assigned until the value is requested
Manage potentially infinite data structures Only a manageable subset of the data will actually be used
Infinite Sequences
(take 3 (repeat "Hello"))=> ("Hello" "Hello" "Hello")
(take 5 (cycle [1 2 3]))=> (1 2 3 1 2)
(take 5 (drop 2 (cycle [1 2 3])))(->> [1 2 3] (cycle) (drop 2) (take 5))(1 2 3 1 2 3 1 2 3 …=> (3 1 2 3 1)
Clojure STM
(def my-account (ref 1000.))(def other-account (ref 5000.))
(defn transfer [from to amount] (dosync (alter from - amount) (alter to + amount)))
(transfer other-account my-account 1000.)
Thank you! @ArturoHerrero