Top Banner
Comparing JVM languages José Manuel Ortega Candel | @jmortegac 26-27 June 2015
69

Comparing JVM languages

Aug 06, 2015

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Comparing JVM languages

Comparing JVM languages

José Manuel Ortega Candel | @jmortegac

26-27 June 2015

Page 2: Comparing JVM languages

INDEX

Functional programming and closures 2

Language classification 1

Java 8 new features 3

Scala, Groovy, Kotlin, Clojure and Ceylon 4

Advantages and drawbacks 5

Comparing features 6

Page 3: Comparing JVM languages

Language classification

FUNCTIONAL NOT FUNCTIONAL

STATIC

DYNAMIC

Page 4: Comparing JVM languages

Functional programming

•Data structure persistent and immutable

•Closures

•Higher order functions •Pass functions to functions as parameter •Create functions within functions •Return functions from other functions

•Functions as first class values

Page 5: Comparing JVM languages

Closures

•Reduce amount of “boiler plate” code

•Eliminate the boilerplate code of anonymous inner classes

•Allow the use of idiomatic functional programming code

•Allow the creation of custom control structures

• In Java 8 closures are just syntactic sugar for defining anonymous inner classes

Page 6: Comparing JVM languages

Java 8 new features

Lambda expressions

Closures

Streams

Enhaced collections

Processing data in parallel

Pattern Filter-Map-Reduce

Annotations types

Methods References

(String s)-> System.out.println(s)

System.out::println

Page 7: Comparing JVM languages

Streams

Page 8: Comparing JVM languages

Filter-Map-Reduce

Book book=new Book(123455,"Beginning Java 8");

Book book1=new Book(3232332,"Java 8 Advanced");

Book book2=new Book(43434343,"Groovy Advanced");

List<Book> books=Arrays.asList(book,book1,book2);

Predicate<Book> condition=(it) -> it.getTitle().contains("Java");

String jsonFormat=books

.stream()

.filter(condition)

.map(Book::toJSON)

.collect(Collectors.joining(", "));

[{isbn:123455,title:'Beginning Java 8'}, {isbn:3232332,title:'Java 8 Advanced'}]

Page 9: Comparing JVM languages

Parallel Streams

List myList = .. Stream stream = myList.stream();

Stream parallelStream = myList.parallelStream();

Stream parallel = stream.parallel();

• Streams are sequential by default

• With Parallel you can optimize number of threads

• More efficient with bigger collections

Page 10: Comparing JVM languages

Sequential vs Parallel

books.parallelStream().filter((it) -> it.getTitle().contains("Java")).

forEach((it)->System.out.println(it+" "+Thread.currentThread()));

Book{isbn=3232332, title='Java 8 Advanced'} Thread[main,5,main]

Book{isbn=123455, title='Beginning Java 8'} Thread[main,5,main]

books.stream().filter((it) -> it.getTitle().contains("Java")).

forEach((it)->System.out.println(it+" "+Thread.currentThread()));

Book{isbn=3232332, title='Java 8 Advanced'} Thread[main,5,main]

Book{isbn=123455, title='Beginning Java 8'} Thread[ForkJoinPool.commonPool-

worker-2,5,main]

Page 11: Comparing JVM languages

Scala

Combines the paradigms of functional programming and object-oriented

Statically typed No types primitives like Java

Everything is an Object, including functions

Performance equivalent to Java

Page 12: Comparing JVM languages

Scala features

Pattern matching

Closures,lambdas,anonymous functions

Traits and mixins for multiple inheritance

Operator overloading

Support Data Paralell like Java 8

Concurrency models(Akka,actors)

Inmutable and mutable data structures

Page 13: Comparing JVM languages

Scala examples

def factorial(n : Int): Int = n match{

case 0 => 1

case x if x >0 => factorial(n-1) *n

}

val languages = List("Scala", "Groovy", "Clojure", "Kotlin")

val headList = languages.head // Scala

val tailList = languages.tail; //List( "Groovy", "Clojure", "Kotlin")

val empty = languages.isEmpty //false

def orderList(xs: List[String]): List[String] =

if (xs.isEmpty) Nil

else insert(xs.head, isort(xs.tail)

@BeanProperty

Annotation which is read by the Scala

compiler to generate getter and setter

class Bean {

@scala.reflect.BeanProperty

var name: String

}

val someNumbers = List(-11, -10, -5, 0, 5, 10)

someNumbers.filter((x) => x > 0)

someNumbers.filter(_ > 0)

List[Int] = List(5, 10)

scala.collection.immutable

Page 14: Comparing JVM languages

Inmutability in Scala

scala> var languages = Set("Scala", "Kotlin")

languages : scala.collection.immutable.Set[java.lang.String] =

Set(Scala, Kotlin)

scala> languages += "Clojure"

scala> languages

res: scala.collection.immutable.Set[java.lang.String] =

Set(Scala, Kotlin, Clojure)

scala> languages -= " Kotlin "

scala> languages

res: scala.collection.immutable.Set[java.lang.String] =

Set(Scala, Clojure)

• You can add elements in a inmutable collection

Page 15: Comparing JVM languages

Java 8 vs Scala

Page 16: Comparing JVM languages

Java 8 vs Scala streams

bookList.parallelStream().filter(b -> b.title.equals(”Clojure”))

.collect(Collectors.toList())

bookList.par.filter(_.title == “Clojure”)

bookList.par.filter( b =>b.title == “Clojure”)

val bookFilter = bookList.par.filter(_.title.contains("Groovy"))

.foreach{i=> println(Thread.currentThread) } Thread[ForkJoinPool-1-worker-3,5,main]

Thread[ForkJoinPool-1-worker-5,5,main]

Page 17: Comparing JVM languages

Kotlin

Object-oriented with functional elements

Developed by JetBrains

Statically typed like Scala Smarts casts

Elvis operator(?) for checking null like Groovy

Type inference

100 % interoperability with Java

Page 18: Comparing JVM languages

Kotlin syntax & rules

Inmutable/Mutable variables

No new keyword for create objects

No primitive types

No static members

Primary constructors

No fields, just properties

By default, all classes are final

Page 19: Comparing JVM languages

Kotlin

Smart casts Maps

val languages = mapOf("Java" to "Gosling",

"Scala" to "Odersky","Groovy" to "Strachan")

for((language,author) in languages){

println("$author made $language")

}

fun eval(e: Expr): Double = when (e) {

is Num-> e.value.toDouble()

is Sum -> eval(e.left) + eval(e.right)

else ->

throw IllegalArgumentException("Unknown

expression")

}

val mapLanguages = hashMapOf<String, String>()

mapLanguages.put("Java", "Gosling")

mapLanguages.put("Scala", "Odersky")

for ((key, value) in mapLanguages) {

println("key = $key, value = $value")

}

fun patternMatching(x:Any) {

when (x) {

is Int -> print(x)

is List<*> ->{print(x.count())}

is String -> print(x.length())

!is Number -> print("Not even a number")

else -> print("can't do anything")

}

}

Page 20: Comparing JVM languages

Kotlin

Operator overloading Default & name arguments

println(product(2))

println(product(2,3))

println(format(text="kotlin"))

println(format(text="kotlin", upperCase= true))

2

6

kotlin

KOTLIN

fun product(a:Int,b:Int=1):Int{

return a.times(b);

}

fun format(text:String,upperCase:Boolean=

false):String {

return if (upperCase) text.toUpperCase() else text

}

Page 21: Comparing JVM languages

Kotlin

Iterators fun iterateOverCollection(collection: Collection<Int>) {

for (element in collection) {}

}

fun iterateOverString() {

for (c in "abcd") {}

"abcd".iterator()

}

fun iteratingOverMap(map: Map<Int, String>) {

for ((key, value) in map) {}

}

Page 22: Comparing JVM languages

Kotlin

Data classes Data annotation changes behavior of hashCode, equals, toString functions

public class Book (var isbn:Int, var title:String)

fun main(args: Array<String>) {

//Books

val book = Book(123456, "Beginning Kotlin")

val book2 = Book(123456, "Beginning Kotlin")

println(book);

println(book.hashCode());

println(book2.hashCode());

println(book.equals(book2));

if (book == book2)

println("Same Book");

if (book != book2)

println("Diferent Book");

}

books.Book@2a84aee7

713338599

168423058

false

Diferent Book

data public class Book (var isbn:Int, var title:String)

fun main(args: Array<String>) {

//Books

val book = Book(123456, "Beginning Kotlin")

val book2 = Book(123456, "Beginning Kotlin")

println(book);

println(book.hashCode());

println(book2.hashCode());

println(book.equals(book2));

if (book == book2)

println("Same Book");

if (book != book2)

println("Diferent Book");

Book(isbn=123456,

title=Beginning Kotlin)

1848623012

1848623012

true

Same Book

Page 23: Comparing JVM languages

Kotlin

Classes constructor • It is not necessary define a constructor like in Java

• You can use the class definition to pass the properties and

default values data public class Book (var isbn:Int, var title:String="My Default Book")

fun main(args: Array<String>) {

val book = Book(123456)

println(book.title);

}

Page 24: Comparing JVM languages

Kotlin

Higher order functions • Lambda expressions

• it implicit parameter

val filter = books filter({ b: Book -> b.title.contains(“Kotlin") })

val book = Book(123455, "Beginning Java 8")

val book1 = Book(3232332, "Java 8 Advanced")

val book2 = Book(43434343, “Kotlin Advanced")

val books = Arrays.asList(book, book1,book2)

Filter[Book(isbn=43434343, title=Kotlin Advanced)]

val filter = books filter({ it.contains(“Kotlin") })

Page 25: Comparing JVM languages

Kotlin collections

val listInmutable

=listOf("Java","Kotlin","Groovy","Scala")

val listMutable=ArrayList<String>()

listMutable.add("Java")

listMutable.add("Kotlin")

Page 26: Comparing JVM languages

Kotlin vs Java list iterate

for ((index,element) in list.withIndex()) {

println(“$index$element”);

}

int index=0

for (String element:list) {

System.out.println(index+””+element);

index++

}

Page 27: Comparing JVM languages

Kotlin smart cast vs Java

if (expr is Number) {

println(expr.getValue());

//expr is automatically cast to Number

}

if (expr instanceof Number) {

System.out.println((Number)expr).getValue());

}

Page 28: Comparing JVM languages

Kotlin vs Java types inference

val longJavaClassName = LongJavaClassName()

LongJavaClassName longJavaClassName =new LongJavaClassName()

Page 29: Comparing JVM languages

Groovy

Java supercharged(syntactic sugar)

Object oriented and dynamic language

Optional typing like Scala and Kotlin

All type checking is at run time

It reduces Java boilerplate code including no

semi colons, no getters/setters, type

inference, null safety, elvis operators

Page 30: Comparing JVM languages

Groovy

Closures with lambda

or it implicit parameter

def upper = { s-> s.toUpperCase()}

def upper = {it.toUpperCase()}

Collections

def languages = ["Java":”James

Gosling”, "Scala":”Martin Odersky”,

"Clojure":”Rich Hickey”,

"Ceylon":”Gavin King”,

"Groovy":”James Strachan”]

languages.each { entry -> println}

languages.each { k,v -> println}

Methods as closures with .& operator

def object

object = 2

object = true

object = [1,2,3]

Optional typing

Page 31: Comparing JVM languages

Groovy

@Memoized annotation @Inmutable annotation

@Memoized

def BigInteger fibRecursiveMemoized(n) {

if (n<2) return 1

else return fibRecursiveMemoized(n-1) +

fibRecursiveMemoized(n-2)

}

TimeIt.code{println(fibonnaci.fibRecursive(40))}

TimeIt.code{println(fibonnaci.fibRecursiveMemoized(40))}

165580141

Time taken 42.083165464 seconds

165580141

Time taken 0.061408655 seconds //with memoize

import groovy.transform.Immutable

@Immutable class Language {

String title;

Long isbn;

}

def l1 = new Language (title:'Beginning Groovy',isbn:100)

def l2 = new Language (title:'Groovy advanced',isbn:200)

l1.title = 'Groovy for dummies'

// Should fail with groovy.lang.ReadOnlyPropertyException

Page 32: Comparing JVM languages

Groovy

Time execution

class TimeIt {

def static code(codeBlock){

def start = System.nanoTime()

try{

codeBlock()

}finally{

def end = System.nanoTime()

println "Time taken ${(end-start)/1e9} seconds"

}

}

}

Page 33: Comparing JVM languages

Groovy

Parsing and creating XML

Page 34: Comparing JVM languages

Groovy Advantages Disadvantages

Java Collections Non-lazy evaluation

Closures

(like Lambda expressions in Java 8)

It's performance isn't great

(but it's improving)

Filter – Map – Reduce in streams

Easy interoperability with Java

Static and dynamic typing

@TypeChecked

@CompileStatic

Metaprogramming

Page 35: Comparing JVM languages

Java Groovy

def languages = ["Java", "Scala", "Clojure",

"Kotlin", "Ceylon","Groovy"]

def filter = languages.stream()

.findAll { it.size()>5 }

.collect { it.toUpperCase()}

.first()

List<String> languages = Arrays.asList("Java",

"Scala", "Clojure", "Kotlin","Ceylon","Groovy");

Optional<String> bookFiltered = languages.stream()

.filter(s -> s.length()>5 )

.map(s -> s.toUpperCase())

.findFirst();

Page 36: Comparing JVM languages

Clojure

Pure functional language

JVM language based in Lisp

Not Object Oriented

Dynamically typed

All data structure including list ,vectors, maps,

sequences, collections, are inmutable and fully

persistent

The main data structure is the list

The key is the use of High Order Functions

Page 37: Comparing JVM languages

Clojure

Alternate implementations in functions (defn square-or-multiply

"squares a single argument, multiplies two arguments"

([] 0) # without arguments

([x] (* x x)) # one argument

([x y] (* x y))) # two arguments

List operations

(first '(:scala :groovy :clojure))return scala

(rest '(:scala :groovy :clojure))return all elements excepts the first

(cons :kotlin '(:scala :groovy :clojure))add kotlin to head in the list

Page 38: Comparing JVM languages

Clojure

Sequences (defn count-down [n]

(if (<= n 0)

'(0)

(cons n (lazy-seq (count-down (dec n))))))

Filter – Map - Reduce

(filter integer? [1 2.71 3.14 5 42]) => (1 5 42)

(map (fn [n] (* n n)) [1 2 3 4 5]) => (1 4 9 16 25)

(reduce + [1 2 3 4]) => 10

user=> (count-down 8)

(8 7 6 5 4 3 2 1 0)

Page 39: Comparing JVM languages

Clojure

Records

(defrecord Book [isbn title])

(def bookList [(Book. 432423 "Clojure")(Book. 534243 "Kotlin")

(Book. 432424 "Groovy")])

(println "count bookList "(count bookList))

(dorun (for [item bookList]

(println (:title item)(:isbn item))))

(println (filter #(= "Clojure" (get % :title)) bookList))

count bookList 3

Clojure 432423

Kotlin 534243

Groovy 432424

(#user.Book{:isbn 432423, :title

Clojure})

(defrecord Object [prop1 propn])

Page 40: Comparing JVM languages

Clojure

Recursive functions with trampoline and memoize

(defn factorial ([x] (trampoline (factorial (dec x) x)))

([x a] (if (<= x 1) a #(factorial (dec x) (*' x a)))))

(def fibonaci

(memoize (fn [n]

(if (< n 2)

n

(+ (fibonaci (dec n))

(fibonaci (dec (dec n))))))))

(time(println (factorial 20)))

(time(println (fibonaci 30)))

"Elapsed time: 0.692549 msecs"

832040

"Elapsed time: 1.263175 msecs"

"Elapsed time: 24.574218 msecs"

832040

"Elapsed time: 118.678434 msecs"

2432902008176640000

Page 41: Comparing JVM languages

Clojure Advantages Disadvantages

Very simple Not Object oriented

The language has little elements

compared with other languages

Difficult to decipher stacktraces and errors

Excellent concurrency support Requires a new way to solve problems

Easy interoperability with java There are no variables

Powerful language features

(macros,protocols)

Thre is no inheritance concept

Clojure programs run very quickly No mecanism for avoid NullPointerException

JVM is highly optimized

Page 42: Comparing JVM languages

Clojure vs Java

Code reducing

(defn blank [str]

(every#? (Character/isWhitespace %)

str))

public class StringUtils {

public static boolean isBlank(String str) {

int strLen;

if (str == null || (strLen = str.length()) == 0) {

return true;

}

for (int i = 0; i < strLen; i++) {

if ((Character.isWhitespace(str.charAt(i)))) {

return true;

}}

return false;

}}

Page 43: Comparing JVM languages

Ceylon

Is very similar to Java, reducing verbosity

Object oriented with functional features

Strong static typing with type inference

Explicit module system

Comparing with Java

Eliminates static, public, protected, private

Add new modifiers like variable, shared, local

Shared is used for make visibility outside in other

modules(like public in Java)

Arrays are replaced by sequences

Page 44: Comparing JVM languages

Ceylon

Sequence languages = Sequence("Java",

"Groovy","Clojure","Kotlin");

//Check if the sequence is empty

if(nonempty languages){

String? firstElementValue = languages.value(1);

String? firstElement = languages.first;

}

Sequence more =

join(languages,Sequence("Ceylon","Scala"));

Sequences Generics & Union types

Iterable<String|Boolean> list =

{“string”,true,false}

ArrayList<Integer|Float> list =

ArrayList<Integer|Float>

(1, 2, 1.0, 2.0)

Page 45: Comparing JVM languages

Comparing featues

• Reducing verbosity

• Variables definition

• Null-safety

• Optional types

• Lambdas

• Pattern matching

• Traits

• Java interoperability

Page 46: Comparing JVM languages

Reducing Java verbosity Reducing Boilerplate Code

class MyClass{

private int index;

private String name;

public MyClass(int index, String name){

this.index = index;

this.name = name;

}

}

case class MyClass(index: Int, name: String)

public class MyClass(var index:Integer,var name:String){

}

class MyClass {

int index

String name

}

class MyClass(index,name) {

shared Integer index;

shared String name;

}

(defstruct MyClass :index :name)

Page 47: Comparing JVM languages

Variables definition

• In Kotlin and Scala you can define 2 types • var myMutableVariable

• val myInmutableVariable

• In Ceylon we have variable modifier for mutable

variable Integer count=0;

count++; //OK

Integer count=0;

count++;//ERROR

val name: Type = initializer // final “variable”

var name: Type = initializer // mutable variable

Page 48: Comparing JVM languages

Null-safety

• Operator ? used in Kotlin,Groovy,Ceylon

• Avoid NullPointerException

var b : String? = "b"

b = null // valid null assignment

val l = b?.length()

Elvis Operator(?:) and Safe navigation (?.)

def displayName = user.name ? user.name : "Anonymous“

def streetName = user?.address?.street

String? argument = process.arguments.first;

if (exists argument) { //checking null values

}

Page 49: Comparing JVM languages

Optional Types

Optional<Object> optional = findObject(id);

//check if Optional object has value

if (optional.isPresent()) {

System.out.println(optional.get());

}

Type safe Option[T] in Scala

New class java.util.Optional

Page 50: Comparing JVM languages

Optional Type in Scala

private val languages = Map(1 -> Language(1, "Java", Some("Gosling")),

2 -> Language(2, "Scala", Some("Odersky")))

def findById(id: Int): Option[Language] = languages.get(id)

def findAll = languages.values

def main(args: Array[String]) {

val language = Optional.findById(1)

if (language.isDefined) {

println(language.get.name)

}

}

val language = Optional.findById(3) None

Page 51: Comparing JVM languages

Optional Type in Scala

val languages =Map("Java"->"Gosling","Scala"->"Odersky")

languages:scala.collection.immutale.Map[java.lang.String,java.lang.String]

languages get "Scala"

Option[java.lang.String] = Some(Odersky)

languages get "Groovy"

Option[java.lang.String] = None

Page 52: Comparing JVM languages

Lambdas in streams

List<Book> books=Arrays.asList(book,book1,book2);

Optional<String> bookFiltered =

books.stream()

.filter(b -> b.getTitle().contains("Groovy"))

.map(b -> b.getTitle().toUpperCase())

.findFirst();

val books = Arrays.asList(book,book1,book2)

val bookFiltered : String? =

books.sequence()

.filter { b->b.title.contains("Groovy")}

.map { b->b.title.toUpperCase() }

.firstOrNull()

def bookfilter= books.

findAll { b->b.title.contains(" Groovy ") }

.sort { b->b.isbn }

.collect { b->b.title.toUpperCase() }

.find()

val bookList = List(book1,book2,book3);

val bookFilter = bookList

.filter(b=>b.title.contains("Groovy"))

.map(book => book.title)

Page 53: Comparing JVM languages

Pattern matching

• Is a generalization of Java switch/case

def generalSize(x: Any) = x match {

case s: String => s.length

case m: Map[_, _] => m.size

case _ => -1

}

scala> generalSize("abc")

res: Int = 3

scala> generalSize(Map(1 -> 'a', 2 -> 'b'))

res: Int = 2

fun fib(n: Int): Int {

return when (n) {

1, 2 -> 1

else -> fib(n - 1) + fib(n - 2)

}

}

fun patternMatching(x:Any) {

when (x) {

is Int -> print(x)

is List<*> ->{print(x.size())}

is String -> print("String")

!is Number -> print("Not even a number")

else -> print("can't do anything")

}

}

Page 54: Comparing JVM languages

Traits vs Java interfaces

Traits allow declare method definitions

A trait is an interface with an implementation(behavior and/or state)

Traits support “multiple inheritance”

One class can inherit from many traits

Page 55: Comparing JVM languages

Traits.Code in interfaces

trait Publication {

int number

def getNumberPublication(){

return (number)

}

}

trait Location {

String description

def getInfoPublication(){

return (description)

}

}

class MyBook implements Publication,Location{

Integer isbn

String title

def getInfoBook(){

return (isbn+ " "+title)

}

}

trait Publication {

def description() = println(“Description”)

}

class Book(var isbn:Int,var title:String) extends Publication{

def getInfoBook(){

return (isbn+ " "+title)

}

}

trait Publication{

var number:String

fun getNumberPublication(){

println(number)

}

}

class Book:Publication {

}

Page 56: Comparing JVM languages

Java interoperability object list extends App {

import java.util.ArrayList

var list : ArrayList[String] = new ArrayList[String]()

list.add("hello")

list.add("world")

println(list)

}

import collection.JavaConversions._

java.util.Arrays.asList(1,2,3).

foreach(i =>println(i))

java.util.Arrays.asList(1,2,3).

filter(_ % 2 ==0)

fun list(source: List<Int>):ArrayList<Int> {

val list = ArrayList<Int>()

for (item in source)

list.add(item)

for (i in 0..source.size() - 1)

list[i] = source[i]

return list

}

(ns clojure-http-server.core

(:require [clojure.string])

(:import (java.net ServerSocket SocketException)

(java.util Date)

(java.io PrintWriter BufferedReader

InputStreamReader BufferedOutputStream)))

Page 57: Comparing JVM languages

Java interoperability

import scala.beans.BeanProperty

class Language(

@BeanProperty var name: String,

@BeanProperty var author: String) {

}

public static void main(String[] args) {

Language l1 = new Language(“Java",”Gosling”);

Language l2 = new Language(“Scala",”Odersky”);

ArrayList<Language> list = new ArrayList<>();

list.add(l1);

list.add(l2);

}

Page 58: Comparing JVM languages

List Partitions

• We can use partition over a list for obtain 2 lists

scala> List(1, 2, 3, 4, 5) partition (_ % 2 == 0)

res: (List[Int], List[Int]) = (List(2, 4),List(1, 3, 5))

// partition the values 1 to 10 into a pair of lists of even and odd numbers

assertEquals(Pair(listOf(2, 4, 6, 8, 10), listOf(1, 3, 5, 7, 9)), (1..10)

.partition{ it % 2 == 0 })

Page 59: Comparing JVM languages

Read file and print lines import scala.io.Source

for (line <- Source.fromFile(“file.txt”).getLines())

println(line.length +" "+ line)

import java.nio.file.*;

import java.util.stream.Stream;

Path dict = Paths.get(“file.txt”);

Stream<String> linesStream = Files.lines(dict);

linesStream.forEach(System.out::println);

val dict = Paths.get(“file.txt")

val linesStream = Files.lines(dict)

val lines = linesStream.forEach{println(it)};

Page 60: Comparing JVM languages

Read file and print lines

(defn read-file [file]

(with-open [rdr (clojure.java.io/reader file)]

(doseq [line (line-seq rdr)]

(println line))))

(read-file (file “file.txt"))

Files.lines(Paths.get(“file.txt")).forEach{println it};

Page 61: Comparing JVM languages

Performance in recursion

(defn factorial ([x] (trampoline (factorial (dec x) x)))

([x a] (if (<= x 1) a #(factorial (dec x) (*' x a)))))

@TailRecursive

def fact(BigInteger n,acumulator = 1G) {

if (n <2){

acumulator

}else{

fact(n-1,n*acumulator)

}

}

@scala.annotation.tailrec

def factorialrec(fact:BigInt,number:BigInt=1):BigInt = {

if (fact<2) return number

else factorialrec(fact-1,fact*number)

}

Page 62: Comparing JVM languages

Comparing features

Higher Order Functions

Mixin/traits

Pattern matching

Implicit casts

Nullables / Optionals

Modules

Promote inmutability

Lambdas

Page 63: Comparing JVM languages

Palindrome

(use 'clojure.java.io)

(defn palindrome? [s]

(let [sl (.toLowerCase s)]

(= sl (apply str (reverse sl)))))

(defn find-palindromes[s]

(filter palindrome? (clojure.string/split s #" ")))

fun isPalindrome(s : String) : Boolean {

return s== s.reverse()

}

fun findPalindrome(s:List<String>): List<String>{

return s.filter {isPalindrome(it)}.map {it}

}

def isPalindrome(x:String) = x==x.reverse

def findPalindrome(s:Seq[String]) = s find isPalindrome

def isPalindrome(s) {

def s1 = s.toLowerCase()

s1 == s1.reverse()

}

def findAllPalindrome(list) {

list.findAll{isPalindrome(it)}

}

Page 64: Comparing JVM languages

Conclusions

Full interoperability with Java Reducing Java verbosity These languages allow developer be more productive comparing with java Pragmatic Programmer advice: When you learn a new language, you learn a new way to think.

Page 67: Comparing JVM languages

Resources

• http://vschart.com/compare/kotlin/vs/clojure/vs/scala

Page 69: Comparing JVM languages

Thank you! José Manuel Ortega Candel | @jmortegac