Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
JAVA8 / SCALA
Difference points & innovation streams
Ruslan Shevchenko. <ruslan@shevchenko.kiev.ua>
https://github.com/rssh
@rssh1
JAVA / SCALA
ā€¢ Java & Scala signiļ¬cantly different
ā€¢ Exists innovations: scala => java & java=>scala
ā€¢ What language I must learn ?
ā€¢ All of them !
SCALA JAVA8
public class Person
{
private String firstName;
private String lastName;
String getFirstName()
{ return firstName; }
void setFirstName(String v)
{ firstName = v; }
ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦.
int hashCode() {
if (firstName==null) {
if (secondName==null) {
return 0;
} else {
return secondName.hashCode();
}
} else{
if (secondName==null) {
}
}
}
boolean equals() { ā€¦. }
}
case class Person
(
firstName: String
lastName: String
)
SCALA JAVA8
public class Person
extends DTOBase
{
public String firstName;
public String lastName;
}
case class Person
(
firstName: String
lastName: String
)
SCALA => JAVA
Similar:
lambda-expressions
traits / default methods
collections API with hight-order functions
LAMBDA EXPRESSIONS
list.sort((x,y)-> {
int cmp = x.lastName.compareTo(y.lastName);
return cmp!=0 ? cmp : x.ļ¬rstName.compareTo(y.ļ¬rstName)
}
list.sort((x,y) => {
val cmp = x.lastName.compareTo(y.lastName)
if (cmp!=0) cmp else x.ļ¬rstName.compareTo(y.lastName)
}
Java
Scala
LAMBDA EXPRESSIONS
var (maxFirstLen, maxSecondLen) = (0,0)
list.foreach{
x => maxFirstLen = max(maxFirstLen, x.ļ¬rstName.length)
maxSecondLen = max(maxSecondLen, x.secondName.length)
}
Java
Scala
Closures canā€™t modify environment context
ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦.
TRAITS/DEFAULT METHODS
trait AsyncInput[T]
{
def onReceive(acceptor:T=>()): Unit
def read: Future[T] = {
Promise p = Promise[T]()
onReceive(p.complete(_))
p.future
}
}
interface AsyncInput<T>
{
void onReceive(Acceptor<T> acceptor)
default void read(): Future<T> {
ļ¬nal CompletableFuture<T> promise =
new CompletableFuture<>();
onReceive( x -> promise.complete(x) );
return promise;
}
}
Scala Java
TRAITS/DEFAULT METHODS
trait LoggedAsyncInput[T]
{
this:AsyncInput =>
override def onReceive(acceptor:T => ()) =
super.onReceive(x => {
println(sā€œreceived:${x}ā€)
acceptor(x) })
}
Scala
Java
aspects ? ā€¦
TRAITS/DEFAULT METHODS
trait LoggedAsyncInput[T]
{
override def onReceive(acceptor:T => ()) =
super.onReceive(x => {
println(sā€œreceived:${x}ā€)
acceptor(x) })
}
Scala
Java
aspects ? ā€¦
trait MyToString
{
override def toString = sā€[${super.toString}]ā€
}
TRAITS/DEFAULT METHODS
Java default interface:
dispatch across class/interface hierarchy
Scala traits
building hierarchy with process of linearization
STREAMING COLLECTIONS
persons.stream().ļ¬lter(
x -> x.ļ¬rstName.equals(ā€Jonā€)
).collect(Collectors.toList())
persons.ļ¬lter(_.ļ¬rstName == ā€œJonā€)
Java
Scala
STREAMING COLLECTIONS
persons.stream().ļ¬lter(
x -> x.ļ¬rstName.equals(ā€Jonā€)
).collect(Collectors.toList())
Java
Reason - existing API
Donā€™t want to mix old and new API in one
Operation composition without reiterating.
PARALLEL
persons.parallelStream().ļ¬lter(
x -> x.ļ¬rstName.equals(ā€Jonā€)
).collect(Collectors.toList())
persons.par.ļ¬lter(_.ļ¬rstName == ā€œJonā€)
Java
Scala
SQL
..??***8dc
persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€)
Scala (slick)
Java ?
?
SQL
..??***8dc
persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€)
Scala (slick)
Java (http://jinq.org)
dbStream(em,Person.class).ļ¬lter(
x -> x.ļ¬rstName.equals(ā€œJonā€)
).list
SQL (INSIDE ?)
persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€).toList
Scala (slick)
TableQuery[Expr[Person]]
Expr[String], Expr[StringConstant] => Expr[Boolean]
SQL (INSIDE ?)
persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€).toList
Scala (slick)
TableQuery[Expr[Person]]
Expr[String], Expr[StringConstant] => Expr[Boolean]
Query[Expr[T]], Expr[Boolean] => Query[Expr[T]]
Query { ā€¦ generateSql( .. ) }
SQL (INSIDE)
..??***8dc
Java (http://jinq.org)
dbStream(em,Person.class).ļ¬lter(
x -> x.ļ¬rstName.equals(ā€œJonā€)
).list
DbStream<Person>
Person => Boolean
SQL (INSIDE)
..??***8dc
Java (http://jinq.org)
dbStream(em,Person.class).ļ¬lter(
x -> x.ļ¬rstName.equals(ā€œJonā€)
).list
Person => Boolean
for sql generation we need:
analyse bytecode
symbolic interpretation
collect trace
generate sql
// runtime-only, not very fast
SQL (INSIDE)
Java (http://jinq.org)
// runtime-only, not very fast
complex, state-of-the-art technology
all work is in runtime
unable to check function correctness in compile-time
Scala (slick)
relatively simple
compile-time analysis, runtime generation
veriļ¬cation in compile time
JAVA => SCALA: SAM
trait AsyncInputOutput[T]
{
def onReceive(acceptor:T=>()): Unit
def onSend(generator: ()=>T): Unit
}
interface AsyncInputOutput<T>
{
void onReceive(Acceptor<T> acceptor)
void onSend(Generator<T> generator)
ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦
}
Scala Java
SAM
ā€¢ SAM-type =Type with Single Abstract Method
ā€¢ Method require SAM-type => we can pass lambda-
expression to one.
ā€¢ In scala:
ā€¢ 2.11 ā€” with -Xexperimental
ā€¢ 2.12 ā€” by default
SAM
trait AsyncInputOutput[T]
{
Function1.class
def onReceive(acceptor:T=>()): Unit
Function1.class
def onSend(generator: ()=>T): Unit
}
interface AsyncInputOutput<T>
{
Acceptor.class
void onReceive(Acceptor<T> acceptor)
Generator.class
void onSend(Generator<T> generator)
ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦
}
Scala: JVM Java
JIT inlining impossible Jit inlining is possible
SCALA=>JAVA; JAVA=>SCALA
ā€¢ Java use ā€˜additionalā€™ streaming API [not ideal, better
than before]
ā€¢ Scala library canā€™t utilize SAM conversion [not ideal,
better than before]
ā€¢ So, we have place for something 3-rd ?
ā€¢ Evolution: all ā€˜idealā€™ shifts ā€¦.
FUTURE EVOLUTION
ā€¢ 2 Groups
ā€¢ which will be integrated in java 9,10, 11, .. if exists.
ā€¢ [ FORTRAN 90 is object-oriented. Do you know this (?)]
ā€¢ case classes, type inheritance.
ā€¢ which represent essential different aspect, not present in java
CASE CLASSES
..??***8dc
case class Person(ļ¬rstName: String, lastName: String)
p match {
case Person(ā€œJonā€,ā€Galtā€ ) => ā€œHi, who are you ?ā€
case Person(ļ¬rstName, lastName) =>
sā€Hi, ${ļ¬rstName}, ${lastName}ā€
case _ => ā€œYou are not personā€
}
ML-style pattern matching, 1973
scala,
kotlin,
ceylon,
swift
FUTURE EVOLUTION
ā€¢ essential different aspect, not present in java:
ā€¢ internal DSL
ā€¢ ļ¬‚exible syntax
ā€¢ call by name
ā€¢ macros
ā€¢ Variance
ā€¢ strong typing
ā€¢ implicit context
FLEXIBLE SYNTAX
..??***8dc
def +++(x:Int, y:Int) = x*x*y*y
1 to 100 == 1.to(100)
future(1) тŠ° future{1}
def until(cond: =>Boolean)(body: => Unit): Unit
CALL BY NAME
..??***8dc
def dountil(cond: =>Boolean)(body: => Unit): Unit =
{
var quit = false;
while(!quit) {
body
quit = !cond
}
}
First introduced in Algol 68
var x = 0
dountil(x != 10)(x+=1)
OWN SYNTAX
..??***8dc
object Do
{
def apply(body: =>Unit) = new DoBody(body)
}
class DoBody(body: => Unit)
{
def until(cond: =>Boolean): Unit =
{ body; while(!cond) body }
}
Do { x = x+1 } until (x<10)
BASIC DSL:)
..??***8dc
object Lunar extends Baysick {
def main(args:Array[String]) = {
10 PRINT "Welcome to Baysick Lunar Lander v0.9"
20 LET ('dist := 100)
30 LET ('v := 1)
40 LET ('fuel := 1000)
50 LET ('mass := 1000)
60 PRINT "You are drifting towards the moon."
70 PRINT "You must decide how much fuel to burn."
80 PRINT "To accelerate enter a positive number"
90 PRINT "To decelerate a negative"
100 PRINT "Distance " % 'dist % "km, " % "Velocity " % 'v % "km/s, " % "Fuel " % 'fuel
110 INPUT 'burn
120 IF ABS('burn) <= 'fuelTHEN 150
130 PRINT "You don't have that much fuel"
140 GOTO 100
ogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/
..??***8dccollection.foreach(x => doSomething)
ā€˜FORā€™ SPECIAL SYNTAX
..??***8dcfor( x <- collection) doSomething
=
..??***8dc
for(x <- fun1 if (x.isGood);
y <- fun2(x) ) yield z(x,y)
=
..??***8dc
fun1.withFilter(_.isGood).
ļ¬‚atMap(x =>
fun2.map(y=>z(x,y)))
..??***8dccollection.foreach(x => doSomething)
ā€˜FORā€™ SPECIAL SYNTAX
..??***8dcfor( x <- collection) doSomething
=
..??***8dc
for(x <- collection)
yield something =
..??***8dccollection.map( x => something)
ā€˜FORā€™ SPECIAL SYNTAX
..??***8dc
=
..??**8dc
for(r <- rows;
c <- cell(r) ) ā€¦.
rows.ļ¬‚atMap(r =>
cell.map(c =>ā€¦.))
..??***8dcfor(x <- c if p(x)) ā€¦. =
..??***8dcc.withFilter(x->p(x)) ā€¦
..??***8dccollection.foreach(x => doSomething)
ā€˜FORā€™ SPECIAL SYNTAX
..??***8dcfor( x <- collection) doSomething
=
..??***8dc
for(x <- fun1 if (x.isGood);
y <- fun2(x) ) yield z(x,y)
=
..??***8dc
fun1.withFilter(_.isGood).
ļ¬‚atMap(x =>
fun2.map(y=>z(x,y)))
FOR-SYNTAX
ā€¢ own foreach: possible to use ā€˜forā€™
ā€¢ ā€˜Monadic interfacesā€™
ā€¢ //foreach, map, ļ¬‚atMap, withFilter
ā€¢ // scala-virtualized (not in standard)
ā€¢ deļ¬ne own function for all syntax constructions
IMPLICIT
implicit def f(x): y
Use x as y
add ā€˜ownā€™ methods to existing classes
pass context
deļ¬ne type-guided expressions
FUTURE: MONADIC
..??***8dc
for( x <- Future{ calculate x };
y <- Future{ calculate y } ) yield x(x,y)
Future[T]
foreach ā€” do something after competition
map
ļ¬‚atMap ā€” future composition
MACROS
..??***8dc
object Log {
def apply(msg: String): Unit = macro applyImpl
def applyImpl(c: Context)(msg: c.Expr[String]):c.Expr[Unit] =
{
import c.universe._
val tree = q"""if (Log.enabled) {
Log.log(${msg})
}
"""
c.Expr[Unit](tree)
}
Log(msg)
if (Log.enabled) {
Log.log(msg)
}
MACROS
Reduce boilerplate code
Fast code generation for HPC
Deep AST transformations
example: async
ASYNC AS MACROS
..??***8dc
async {
val x = async{ long-running-code-x }
val y = async{ long-running-code-y }
val z = await(x) + await(y)
}
Rewritten as state machine without blocking
Implemented as library (without language change)
async: T => Future[T ]
await: Future[T] =>T
MACROS
async/await
jscala (generate javascript)
miniboxing (analog @specialized)
JAVA/SCALA
ā€¢ Java - stable domain, mapped to classes and objects.
ā€¢ Scala - in complex area, where new level of
abstractions needed.
ā€¢ In the beginning of PL
evolution, but totally new dimension
THANKS FOR ATTENTION
Ruslan Shevchenko <ruslan@shevchenko.kiev.ua>
@rssh1
https://github.com/rssh

More Related Content

JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream

  • 1. JAVA8 / SCALA Difference points & innovation streams Ruslan Shevchenko. <ruslan@shevchenko.kiev.ua> https://github.com/rssh @rssh1
  • 2. JAVA / SCALA ā€¢ Java & Scala signiļ¬cantly different ā€¢ Exists innovations: scala => java & java=>scala ā€¢ What language I must learn ? ā€¢ All of them !
  • 3. SCALA JAVA8 public class Person { private String firstName; private String lastName; String getFirstName() { return firstName; } void setFirstName(String v) { firstName = v; } ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦. int hashCode() { if (firstName==null) { if (secondName==null) { return 0; } else { return secondName.hashCode(); } } else{ if (secondName==null) { } } } boolean equals() { ā€¦. } } case class Person ( firstName: String lastName: String )
  • 4. SCALA JAVA8 public class Person extends DTOBase { public String firstName; public String lastName; } case class Person ( firstName: String lastName: String )
  • 5. SCALA => JAVA Similar: lambda-expressions traits / default methods collections API with hight-order functions
  • 6. LAMBDA EXPRESSIONS list.sort((x,y)-> { int cmp = x.lastName.compareTo(y.lastName); return cmp!=0 ? cmp : x.ļ¬rstName.compareTo(y.ļ¬rstName) } list.sort((x,y) => { val cmp = x.lastName.compareTo(y.lastName) if (cmp!=0) cmp else x.ļ¬rstName.compareTo(y.lastName) } Java Scala
  • 7. LAMBDA EXPRESSIONS var (maxFirstLen, maxSecondLen) = (0,0) list.foreach{ x => maxFirstLen = max(maxFirstLen, x.ļ¬rstName.length) maxSecondLen = max(maxSecondLen, x.secondName.length) } Java Scala Closures canā€™t modify environment context ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦.
  • 8. TRAITS/DEFAULT METHODS trait AsyncInput[T] { def onReceive(acceptor:T=>()): Unit def read: Future[T] = { Promise p = Promise[T]() onReceive(p.complete(_)) p.future } } interface AsyncInput<T> { void onReceive(Acceptor<T> acceptor) default void read(): Future<T> { ļ¬nal CompletableFuture<T> promise = new CompletableFuture<>(); onReceive( x -> promise.complete(x) ); return promise; } } Scala Java
  • 9. TRAITS/DEFAULT METHODS trait LoggedAsyncInput[T] { this:AsyncInput => override def onReceive(acceptor:T => ()) = super.onReceive(x => { println(sā€œreceived:${x}ā€) acceptor(x) }) } Scala Java aspects ? ā€¦
  • 10. TRAITS/DEFAULT METHODS trait LoggedAsyncInput[T] { override def onReceive(acceptor:T => ()) = super.onReceive(x => { println(sā€œreceived:${x}ā€) acceptor(x) }) } Scala Java aspects ? ā€¦ trait MyToString { override def toString = sā€[${super.toString}]ā€ }
  • 11. TRAITS/DEFAULT METHODS Java default interface: dispatch across class/interface hierarchy Scala traits building hierarchy with process of linearization
  • 12. STREAMING COLLECTIONS persons.stream().ļ¬lter( x -> x.ļ¬rstName.equals(ā€Jonā€) ).collect(Collectors.toList()) persons.ļ¬lter(_.ļ¬rstName == ā€œJonā€) Java Scala
  • 13. STREAMING COLLECTIONS persons.stream().ļ¬lter( x -> x.ļ¬rstName.equals(ā€Jonā€) ).collect(Collectors.toList()) Java Reason - existing API Donā€™t want to mix old and new API in one Operation composition without reiterating.
  • 16. SQL ..??***8dc persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€) Scala (slick) Java (http://jinq.org) dbStream(em,Person.class).ļ¬lter( x -> x.ļ¬rstName.equals(ā€œJonā€) ).list
  • 17. SQL (INSIDE ?) persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€).toList Scala (slick) TableQuery[Expr[Person]] Expr[String], Expr[StringConstant] => Expr[Boolean]
  • 18. SQL (INSIDE ?) persons.ļ¬lter(_.ļ¬rstName === ā€œJonā€).toList Scala (slick) TableQuery[Expr[Person]] Expr[String], Expr[StringConstant] => Expr[Boolean] Query[Expr[T]], Expr[Boolean] => Query[Expr[T]] Query { ā€¦ generateSql( .. ) }
  • 19. SQL (INSIDE) ..??***8dc Java (http://jinq.org) dbStream(em,Person.class).ļ¬lter( x -> x.ļ¬rstName.equals(ā€œJonā€) ).list DbStream<Person> Person => Boolean
  • 20. SQL (INSIDE) ..??***8dc Java (http://jinq.org) dbStream(em,Person.class).ļ¬lter( x -> x.ļ¬rstName.equals(ā€œJonā€) ).list Person => Boolean for sql generation we need: analyse bytecode symbolic interpretation collect trace generate sql // runtime-only, not very fast
  • 21. SQL (INSIDE) Java (http://jinq.org) // runtime-only, not very fast complex, state-of-the-art technology all work is in runtime unable to check function correctness in compile-time Scala (slick) relatively simple compile-time analysis, runtime generation veriļ¬cation in compile time
  • 22. JAVA => SCALA: SAM trait AsyncInputOutput[T] { def onReceive(acceptor:T=>()): Unit def onSend(generator: ()=>T): Unit } interface AsyncInputOutput<T> { void onReceive(Acceptor<T> acceptor) void onSend(Generator<T> generator) ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ } Scala Java
  • 23. SAM ā€¢ SAM-type =Type with Single Abstract Method ā€¢ Method require SAM-type => we can pass lambda- expression to one. ā€¢ In scala: ā€¢ 2.11 ā€” with -Xexperimental ā€¢ 2.12 ā€” by default
  • 24. SAM trait AsyncInputOutput[T] { Function1.class def onReceive(acceptor:T=>()): Unit Function1.class def onSend(generator: ()=>T): Unit } interface AsyncInputOutput<T> { Acceptor.class void onReceive(Acceptor<T> acceptor) Generator.class void onSend(Generator<T> generator) ā€¦ā€¦ā€¦ā€¦ā€¦ā€¦ } Scala: JVM Java JIT inlining impossible Jit inlining is possible
  • 25. SCALA=>JAVA; JAVA=>SCALA ā€¢ Java use ā€˜additionalā€™ streaming API [not ideal, better than before] ā€¢ Scala library canā€™t utilize SAM conversion [not ideal, better than before] ā€¢ So, we have place for something 3-rd ? ā€¢ Evolution: all ā€˜idealā€™ shifts ā€¦.
  • 26. FUTURE EVOLUTION ā€¢ 2 Groups ā€¢ which will be integrated in java 9,10, 11, .. if exists. ā€¢ [ FORTRAN 90 is object-oriented. Do you know this (?)] ā€¢ case classes, type inheritance. ā€¢ which represent essential different aspect, not present in java
  • 27. CASE CLASSES ..??***8dc case class Person(ļ¬rstName: String, lastName: String) p match { case Person(ā€œJonā€,ā€Galtā€ ) => ā€œHi, who are you ?ā€ case Person(ļ¬rstName, lastName) => sā€Hi, ${ļ¬rstName}, ${lastName}ā€ case _ => ā€œYou are not personā€ } ML-style pattern matching, 1973 scala, kotlin, ceylon, swift
  • 28. FUTURE EVOLUTION ā€¢ essential different aspect, not present in java: ā€¢ internal DSL ā€¢ ļ¬‚exible syntax ā€¢ call by name ā€¢ macros ā€¢ Variance ā€¢ strong typing ā€¢ implicit context
  • 29. FLEXIBLE SYNTAX ..??***8dc def +++(x:Int, y:Int) = x*x*y*y 1 to 100 == 1.to(100) future(1) тŠ° future{1} def until(cond: =>Boolean)(body: => Unit): Unit
  • 30. CALL BY NAME ..??***8dc def dountil(cond: =>Boolean)(body: => Unit): Unit = { var quit = false; while(!quit) { body quit = !cond } } First introduced in Algol 68 var x = 0 dountil(x != 10)(x+=1)
  • 31. OWN SYNTAX ..??***8dc object Do { def apply(body: =>Unit) = new DoBody(body) } class DoBody(body: => Unit) { def until(cond: =>Boolean): Unit = { body; while(!cond) body } } Do { x = x+1 } until (x<10)
  • 32. BASIC DSL:) ..??***8dc object Lunar extends Baysick { def main(args:Array[String]) = { 10 PRINT "Welcome to Baysick Lunar Lander v0.9" 20 LET ('dist := 100) 30 LET ('v := 1) 40 LET ('fuel := 1000) 50 LET ('mass := 1000) 60 PRINT "You are drifting towards the moon." 70 PRINT "You must decide how much fuel to burn." 80 PRINT "To accelerate enter a positive number" 90 PRINT "To decelerate a negative" 100 PRINT "Distance " % 'dist % "km, " % "Velocity " % 'v % "km/s, " % "Fuel " % 'fuel 110 INPUT 'burn 120 IF ABS('burn) <= 'fuelTHEN 150 130 PRINT "You don't have that much fuel" 140 GOTO 100 ogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/
  • 33. ..??***8dccollection.foreach(x => doSomething) ā€˜FORā€™ SPECIAL SYNTAX ..??***8dcfor( x <- collection) doSomething = ..??***8dc for(x <- fun1 if (x.isGood); y <- fun2(x) ) yield z(x,y) = ..??***8dc fun1.withFilter(_.isGood). ļ¬‚atMap(x => fun2.map(y=>z(x,y)))
  • 34. ..??***8dccollection.foreach(x => doSomething) ā€˜FORā€™ SPECIAL SYNTAX ..??***8dcfor( x <- collection) doSomething = ..??***8dc for(x <- collection) yield something = ..??***8dccollection.map( x => something)
  • 35. ā€˜FORā€™ SPECIAL SYNTAX ..??***8dc = ..??**8dc for(r <- rows; c <- cell(r) ) ā€¦. rows.ļ¬‚atMap(r => cell.map(c =>ā€¦.)) ..??***8dcfor(x <- c if p(x)) ā€¦. = ..??***8dcc.withFilter(x->p(x)) ā€¦
  • 36. ..??***8dccollection.foreach(x => doSomething) ā€˜FORā€™ SPECIAL SYNTAX ..??***8dcfor( x <- collection) doSomething = ..??***8dc for(x <- fun1 if (x.isGood); y <- fun2(x) ) yield z(x,y) = ..??***8dc fun1.withFilter(_.isGood). ļ¬‚atMap(x => fun2.map(y=>z(x,y)))
  • 37. FOR-SYNTAX ā€¢ own foreach: possible to use ā€˜forā€™ ā€¢ ā€˜Monadic interfacesā€™ ā€¢ //foreach, map, ļ¬‚atMap, withFilter ā€¢ // scala-virtualized (not in standard) ā€¢ deļ¬ne own function for all syntax constructions
  • 38. IMPLICIT implicit def f(x): y Use x as y add ā€˜ownā€™ methods to existing classes pass context deļ¬ne type-guided expressions
  • 39. FUTURE: MONADIC ..??***8dc for( x <- Future{ calculate x }; y <- Future{ calculate y } ) yield x(x,y) Future[T] foreach ā€” do something after competition map ļ¬‚atMap ā€” future composition
  • 40. MACROS ..??***8dc object Log { def apply(msg: String): Unit = macro applyImpl def applyImpl(c: Context)(msg: c.Expr[String]):c.Expr[Unit] = { import c.universe._ val tree = q"""if (Log.enabled) { Log.log(${msg}) } """ c.Expr[Unit](tree) } Log(msg) if (Log.enabled) { Log.log(msg) }
  • 41. MACROS Reduce boilerplate code Fast code generation for HPC Deep AST transformations example: async
  • 42. ASYNC AS MACROS ..??***8dc async { val x = async{ long-running-code-x } val y = async{ long-running-code-y } val z = await(x) + await(y) } Rewritten as state machine without blocking Implemented as library (without language change) async: T => Future[T ] await: Future[T] =>T
  • 44. JAVA/SCALA ā€¢ Java - stable domain, mapped to classes and objects. ā€¢ Scala - in complex area, where new level of abstractions needed. ā€¢ In the beginning of PL evolution, but totally new dimension
  • 45. THANKS FOR ATTENTION Ruslan Shevchenko <ruslan@shevchenko.kiev.ua> @rssh1 https://github.com/rssh