a feature comparison urs peter [email protected] @urs_peter vs
TRANSCRIPT
![Page 2: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/2.jpg)
Born in 2003 – 10 years old
Sponsored by EPFL(École Polytechnique Fédérale de Lausanne – Switzerland)
Some Facts about Scala
![Page 3: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/3.jpg)
Also co-designed Generic Java, and built the current generation of javac.
Creator: Martin Odersky
Some Facts about Scala
![Page 4: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/4.jpg)
Scala is fully interoperable with Java
Some Facts about Scala
![Page 5: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/5.jpg)
Scala has a REPL(Command line tool for Read-Eval-Print Loop)
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).Type in expressions to have them evaluated.Type :help for more information.
scala>
Some Facts about Scala
![Page 6: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/6.jpg)
Scala is used in many worldclass companies & applications
Some Facts about Scala
![Page 7: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/7.jpg)
IDE’s are mature
Some Facts about Scala
![Page 8: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/8.jpg)
There is a company behind Scala
Some Facts about Scala
![Page 9: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/9.jpg)
…that offers a supported Stack
Some Facts about Scala
![Page 10: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/10.jpg)
Recently joined Typesafe:
Some Facts about Scala
![Page 11: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/11.jpg)
Some Facts about Scala
Thoughtworks Technology Radar
March 2012
October 2012
![Page 12: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/12.jpg)
Java 8
• Major Language Improvements (JSR 335):– Lambda Expressions / Method References– Virtual Extension Methods
• Schedule:– 2013/02/21 M7 – 2013/07/05 M8 (Final Release Candidate) – 2013/09/09 GA (General Availability)
![Page 13: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/13.jpg)
Java 8 Lambda’s versus Scala Functions
What’s so fun about Functional Programming anyway?
![Page 14: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/14.jpg)
List<Integer> numbers = Arrays.asList(1,2,3);
Filter even numbers
Filter odd numbersDuplicationVariation
List<Integer> res = new ArrayList<>();for (Integer i : numbers) { if( i % 2 == 0 ) res.add(i);}return res;
List<Integer> res = new ArrayList<>();for (Integer i : numbers) { if( i % 2 != 0 ) res.add(i);}return res;
From Imperative to Functional in Java
![Page 15: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/15.jpg)
interface Predicate<T> { public boolean op(T item);}
The Function: Varying computation
The Loop: Generic Control Structure
public List<T> filter(List<T> items, Predicate<? super T> predicate) { List<T> res = new ArrayList<>(); for(T item : items) { if(predicate.op(item)){ res.add(item); } } return res;}
List<Integer> res = new ArrayList<>();for (Integer i : numbers) { if( i % 2 == 0 ) res.add(i);}return res;
From Imperative to Functional in Java
Generic Control Structure==
Higher Order Function
![Page 16: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/16.jpg)
List<Integer> numbers = Arrays.asList(1, 2, 3);
Filter even numbers
Filter odd numbers
List<Integer> result = filter(numbers, new Predicate<Integer>() { public boolean op(Integer item) { return item % 2 == 0; }});
List<Integer> result = filter(numbers, new Predicate<Integer>() { public boolean op(Integer item) { return item % 2 != 0; }});
From Imperative to Functional in Java
![Page 17: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/17.jpg)
Take Spring:
Take Google Guava:
jdbcTemplate.queryForObject("select * from student where id = ?", new Object[]{1212l}, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new Student(rs.getString("name"), rs.getInt("age")); }});
Iterables.filter(persons, new Predicate<Person>() { public boolean apply(Person p) {
return p.getAge() > 18; }
});
Can you see it?
Is the Functional Concept new in Java?
![Page 18: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/18.jpg)
Before (< Java 8)
List<Integer> result = filter(numbers, new Predicate<Integer>() { public boolean op(Integer i) { return i % 2 == 0; }});
After (>= Java 8)
Lambda Expressions can be used for ‘Functional Interfaces’ (here Predicate)
that have a single method (here: boolean op(T f)).
List<Integer> result = filter(numbers, (Integer i) -> i % 2 == 0 );
Functional Programming with Lambda’s
Lambda Expression ==
Syntactic sugar
![Page 19: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/19.jpg)
List<Integer> result = filter(numbers, (Integer i) -> i % 2 == 0);
List<Integer> result = filter(numbers, i -> i % 2 == 0);
No need to define the type since it can be
inferred by the compiler.
Lambda Features at one Glance
Java 8
Complete Lambda Expression
Lambda Expression with Type Inference
![Page 20: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/20.jpg)
Turn an existing static method with the same signature as
the functional interface into a closure, using ::
Method Referenceat one Glance
Java 8
Boolean::booleanValue refers to the instance that
the filter is iterating through.
Static Method References
Instance Method References
List<Boolean> trueOrFalse = Arrays.asList(true, false);
List<Boolean> trueOnly = filter(trueOrFalse, Boolean::booleanValue );
public class NumUtils {public static boolean isEven(Integer i) {
return i % 2 == 0; }}List<Integer> result = filter(numbers, NumUtils::isEven );
(Integer i) -> NumUtils.isEven(i)
(Boolean b) -> b.booleanValue()
![Page 21: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/21.jpg)
Complete Lambda Expression
Java 8
Scala
Java 8 Lambda Expressions versus Scala Functions
val result = filter(numbers, (i:Int) => i % 2 == 0)
List<Integer> result = filter(numbers, (Integer i) -> i % 2 == 0);
![Page 22: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/22.jpg)
List<Integer> result = filter(numbers, i -> i % 2 == 0);
Lambda with type inference
Java 8
Scala
Java 8 Lambda Expressions versus Scala Functions
val result = filter(numbers, i => i % 2 == 0)
![Page 23: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/23.jpg)
List<Integer> result = filter(numbers, NumUtils::isEven);
Static Method References
Java 8
val result = filter(numbers, NumUtils.isEven)
Scala Every method that is not called with its arguments is automatically turned into a
Function. Methods == Functions
Java 8 Lambda Expressions versus Scala Functions
![Page 24: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/24.jpg)
List<Boolean> trueOnly = filter(trueOrFalse, Boolean::booleanValue);
Instance Method References
Java 8
Java 8 Lambda Expressions versus Scala Functions
Scala
Scala uses the _ (underscore) to refer to the current instance that
is iterated through
val trueOnly = filter(trueOrFalse, _.booleanValue )
![Page 25: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/25.jpg)
So, what’s the difference?
trait Seq[T] {
def filter(f:T => Boolean):Seq[T] ...
Higher Order Functions reveal the difference:
interface Predicate<T> { public boolean op(T t);}
Java 8
Scala
interface Collection<T> {
public Collection<T> filter(Predicate<T> p); ...
Scala has a function syntax.
Every Higher Order Function needs a specific Functional Interface in Java 8.
The compiler transforms this syntax to a generic Function object. Therefore, no
Functional Interface needs to be defined.
class Function1[I, R] { def apply(i:I): R}
![Page 26: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/26.jpg)
So, what’s the difference?
val evenFilter = (i:Int) => i % 2 == 0
//evenFilter has type: Int => Booleannumbers.filter(evenFilter)
Predicate<Integer> evenFilter = (Integer i) -> i % 2 == 0;Predicate<Integer> evenFilter = NumUtils::isEven;
numbers.filter(evenFilter);
Using Lambda’s/Functions as Objects reveal the difference too:
A Lambda always needs to be assigned to a matching Functional Interface in Java 8.
Due to Scala’s Type Inference combined with Functions as ‘First Class Citizens’ approach this is not necessary:
Java 8
Scala
![Page 27: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/27.jpg)
Detailed ComparisonJava 8 Lambda Expressions
Syntax is limited to calling Higher Order FunctionsFunctions are interfaces with one method
Lambda’s are Syntactic Sugar for Functional Interfaces
Scala Functions
Have a syntax for defining and calling
Higher Order Functions
Functions are objects with methods
Rich Function Features:– Function Composition – Currying– Call-by-name arguments– PartialFunctions– Pattern matching
Functions are First Class Citizens fully supporting the Functional Programming Paradigm
![Page 28: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/28.jpg)
Impressions of Functional Programming in Scala
val add = (i:Int) => (j:Int) => i + j
val multiply = (x:Int) => (y:Int) => x * y
val prettyPrint = (i:Int) => s"the result is $i"
val combi = add(5) compose multiply(2) andThen prettyPrint
//combi has type: Int => String combi(10)> the result is 25 compose and andThen
are methods of the Scala Function object
Scala’s Functions are composable:
![Page 29: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/29.jpg)
Impressions of Functional Programming in Scala
Java 8 supports only ‘full’ method references: Math::min
Scala methods and functions can be partially applied:
val limiter = Math.min(100, _:Int)
//limiter has type: Int => Intlimiter(200)> 100
Call-by-name arguments allow you to add code blocks:def debug(msg: => String) = {
if(isDebugEnabled) logger.debug(msg) }
//The concatenation only takes place if debug is enableddebug("expensive concat" * 1000)
Java 8 always expects a lambda: debug(() -> "a" + "b" ...)
Scala
Scala
![Page 30: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/30.jpg)
Taking off with Lambda’s
![Page 31: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/31.jpg)
Iterations in Java are ‘external’ by default…
What is going on here?
List<Student> students = ...;List<Student> topGrades = new ArrayList<Student>();List<String> result = new ArrayList<String>();for(Student student : students){
if(student.getGrade() >= 9) {topGrades.add(student);
} }}Collections.sort(topGrades, new Comparator<Student>() { public int compare(Student student1, Student student2) { return student1.getGrade().compareTo(student2.getGrade()); }});for(Student student : topGrades){
result.add(student.getFirstName() + " " + student.getLastName());}
Java
![Page 32: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/32.jpg)
Advantages:• Re-use of generic, higher level control structures• Less error prone• More expressive and readable• Chainable
Internal Iteration: When Lambda’s/Functions start to shine
Ah, now I get it:List<Student> students = ...List<String> topGrades =
students.filter(s -> s.getScore() >= 9) .sortedBy(Student::getLastName)
.map(s -> s.getFirstName() + " " + s.getLastName()) .into(new ArrayList<>());
Java 8
![Page 33: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/33.jpg)
Internal Iteration: When Lambda’s/Functions start to shine
val students = ... val topGrades =
students.filter(_.score >= 9).sortBy(_.name).map(p => p.firstName + " " + p.lastName)
Java 8
ScalaNo need to use the into() method. This happens in Scala ‘automagically’
List<Student> students = ...List<String> topGrades =
students.filter(s -> s.getScore() >= 9) .sortedBy(Student::getLastName)
.map(s -> s.getFirstName() + " " + s.getLastName()) .into(new ArrayList<>());
![Page 34: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/34.jpg)
Find longest word in a huuuuge text file
List<String> lines = //get many many lines
int lengthLongestWord = 0;for(String line : lines) {
for(String word : line.split(" ")) {if(word.length() > lengthLongestWord) {
lengthLongestWord = word.length();}
}}
What’s the problem with the for loops ?
But wait: there is more
Java
![Page 35: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/35.jpg)
Find longest word in a huuuuge text file
they cannot be executed in parallel!
But wait: there is more
List<String> lines = //get many many lines
int lengthLongestWord = 0;for(String line : lines) {
for(String word : line.split(" ")) {if(word.length() > lengthLongestWord) {
lengthLongestWord = word.length();}
}}
Java
![Page 36: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/36.jpg)
Pattern WORD_REGEX = java.util.regex.Pattern.compile("\\w+");
List<String> lines = //get many many lines
int wordCount = 0;for(String line :lines) { Matcher matcher = WORD_REGEX.matcher(line); while (matcher.find()) wordCount++;}
Find longest word in a huuuuge text file
Sequential
Parallel(assuming a quad core machine)
Time t
Thread 1
Thread 1
Thread 2
Thread 3
Thread 4
Done parallel
Done sequential
But wait: there is more
![Page 37: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/37.jpg)
Find longest word in a huuuuge text file
List<String> lines = //get many many linesint lengthLongestWord = lines.parallel()
.map(line -> line.split(" ")
.map(String::length)
.reduce(Math::max)).reduce(Math::max);
Java 8
val lines = //get many many lines val lengthLongestWord = lines.par
.map(_.split(" ").map(_.length).max).max
Scala
Parallel Collections to the rescue
![Page 38: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/38.jpg)
Higher Order Functions
ParallelismAutomatic collection conversion
Fast immutable data structures
Other
Detailed Comparison: Collections & Lambda’s/Functions
Scala Collections
Automatic conversion from Java to Scala collections
Java 8 Collections
![Page 39: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/39.jpg)
Impressions of Scala’s Collection usage: Autoconversion
val result = BitSet(1,2,3).map(_.toString)
> result: SortedSet("1", "2", "3")
Automagic Collection Conversion
With start out with container: BitSet containg Bytes
End up with container: SortedSet containing String
![Page 40: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/40.jpg)
Impressions of Scala’s Collection usage: Tuples
A Tuple is generic datacontainer//a simple tupleval myTuple = (1, “two”)
Tuples are pattern matchable
//the match populates the variables ‘first’ and ‘second’val(first, second) = myTuple > first = 1> second = “two”
![Page 41: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/41.jpg)
Impressions of Scala’s Collection usage: Tuples
val zipped = List(1,2).zip(List(“one”, “two”))
> zipped: List((1, “one”), (2, “two”))
Tuples are widely used in Collections
val (topGrades, otherGrades) = student.partition(_.grade >= 9)
> topGrades: List(Student(“Joe”, 9), ...)> otherGrades: List(Student(“Jack”, 7), ...)
![Page 42: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/42.jpg)
How is it possible to add Higher Order Functions (e.g. filter map foreach etc.) to the java.util.Collection interface without breaking backwards compatibility?
interface Collection<T> {
public Collection<T> filter(Predicate<T> p);
public <R> Collection<R> map(Mapper<T, R> m);
... ‘Old’ Java code (prior Java 8) running in JRE 8 would have to implement all the
new methods that offer ‘internal iteration’ with Lambda’s.
Back to Java 8:How to make it fit?
Java 8
![Page 43: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/43.jpg)
…with default implementations for interfaces aka Virtual Extension Methods!
interface Collection<T> {
public default Collection<T> filter(Predicate<? super T> p) { Collection<T> res = new ArrayList<>(); for(T item : this) { if(p.test(item)) {
res.add(item); } } return res; } ...
Back to Java 8:How to make it fit?
Java 8
![Page 44: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/44.jpg)
A closer look at Java 8’Virtual Extension Methods
• Primary motivator is API evolution (Backwards compatibility for Lambda’s in
Collections)• Useful mechanism by itself:
Enables Multiple Inheritance of behavior• Inspired by Scala traits (among others)
![Page 45: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/45.jpg)
Let’s model the domain for a ‘futuristic’ game
GunfireAt(s:Ship)
Shieldhit() //50%
Medicrepair(s:Ship)
Shiphealth:Integer
hit()
Possible characteristics of a Ship:
s.health = 10repaired += 1health - 1s.hit()
health - 2
Do we need Multiple Inheritance?
![Page 46: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/46.jpg)
Possible Ship implementations:
Base MechanicFighterCommander
The Limits of Single inheritance
![Page 47: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/47.jpg)
Implementation Challenge: Single inheritance won’t work
Gun Shield Medic
Base
Commander
Fighter
Mechanic
The Limits of Single inheritance
![Page 48: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/48.jpg)
Adding Behavior to a Ship (Scala)
class Ship(var health:Int = 0) { def hit() = health -= 2 }
trait Gun { def fireAt(s:Ship) = s.hit}
A trait is an interface with an implementation (behavior and/or state)
val goodFighter = new Ship(10) with Gunval evilFighter = new Ship(10) with Gun
goodFighter.fireAt(evilFighter)
println(evilFighter.health)> 8
It can be ‘mixed-in’ with a class using the keyword: with
ScalaMultiple Inheritance of Behavior
![Page 49: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/49.jpg)
Adding Behavior to a Ship (Java 8)
class Ship { int health = 0; //constructor, getters, setters, hit method }
interface Gun { default void fireAt(Ship s) { s.hit(); }}
class Fighter extends Ship implements Gun {…}Fighter goodFighter = new Fighter(10);Fighter evilFighter = new Fighter(10);
goodFighter.fireAt(evilFighter);
println(evilFighter.getHealth());> 8
Works with Virtual Extension Methods
Java 8Multiple Inheritance of Behavior
![Page 50: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/50.jpg)
Change Behavior of Ship (Scala)
class Ship(var health:Int = 0) { def hit() = health -= 2 }
trait Shield { self:Ship => override def hit() = self.health -= 1}
val commander = new Ship(10) with Gun with Shieldval evilFighter = new Ship(10) with Gun
evilFighter.fireAt(commander)
println(commander.health)> 9
Trait’s can have a self-type. The self-type tells with which class this trait can be ‘mixed’.
The self-type provides access to the ‘mixed-in’ class
Traits can override methods of the ‘mixed-in’ class
ScalaMultiple Inheritance of Behavior
![Page 51: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/51.jpg)
Change Behavior of Ship (Java 8)
val commander = new Ship(10) with Gun with Shieldval evilFighter = new Ship(10) with Gun
evilFighter.fireAt(commander)
println(commander.health)> 9
class Ship(var health:Int = 0) { def hit() = health -= 2 }
trait Shield { self:Ship => override def hit() = self.health -= 1} Does not work with Virtual
Extension Methods (VEM)
Why?• VEM cannot override methods of
a class (they are overridden)• VEM have no self-types
Java 8Multiple Inheritance of Behavior
![Page 52: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/52.jpg)
Adding State and Behavior to Ship (Scala)
trait Medic {var repaired = 0def repair(s:Ship) = {
s.health = 10repaired += 1
}}
val medic = new Ship(10) with Shield with Medicval brokenShip = new Ship(1) with Gun
medic.repair(brokenShip)
println(brokenShip.health)> 10println(medic.repaired)> 1
A trait can have state.
ScalaMultiple Inheritance of State
![Page 53: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/53.jpg)
val medic = new Ship(10) with Shield with Medicval brokenShip = new Ship(1) with Gun
medic.repair(brokenShip)
println(brokenShip.health)> 10println(medic.repaired)> 1
Adding State and Behavior to Ship (Java 8)
trait Medic {var repaired = 0def repair(s:Ship) = {
s.health = 10repaired += 1
}}
Does not work with Virtual Extension Methods (VEM)
Why?• VEM cannot have state
Java 8Multiple Inheritance of State
![Page 54: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/54.jpg)
Implementation in Scala with traits:
val base = new Ship(100) with Gun with Shield with Medic val fighter = new Ship(10) with Gun val commander = new Ship(50) with Gun with Shield val mechanic = new Ship(20) with Shield with Medic
No duplicationPerfectly modularTypes are preserved Execution and initialization is predictable
assert(base.isInstanceOf[Medic])
Multiple Inheritance Done Right
![Page 55: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/55.jpg)
Have methods
Have fields
Access implementing class in a typesafe way
Override methods
Stackable (call to super is linearized)
Intent
ScalaTraits
Multiple inheritance‘without the issues’
Java 8Virtual
Extension Methods
Grow the language
Scala Traits vs Java 8 Virtual Extension Methods
![Page 56: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/56.jpg)
Is there no better way to “Grow the language”?
• What we really want is ‘a mechanism’ that adds ‘new methods’ to ‘existing classes’
• Virtual Extension Methods solve this problem on the interface level: – When we extend the interface with defaults, all classes
inheriting from this interface gain the functionality– E.g. Arrays.asList(1,2,3).forEach(i -> println(i));
• Drawback: limited to interfaces• But how about:
I want to extend existing classes by myself too!
"You win %2.2f%n".format(333333.3333);
new java.util.Date().toString("yyyy-MM-dd");
![Page 57: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/57.jpg)
Welcome to Scala Implicits
…or the ‘pimp my library pattern’
![Page 58: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/58.jpg)
Implicits in Practice
implicit class RichDate(val date:Date) extends AnyVal { def toString(pat:String):String = new SimpleDateFormat(pat).format(date)}
new java.util.Date().toString("yyyy-MM-dd")
Add a new method to an existing class (pimp my library):
Scala
//compiler turns this into: RichDate.methods$.toString(new Date(), "yyyy-MM-dd")
Scala
![Page 59: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/59.jpg)
Lambda’s for Collections: Scala solved it before…
import collection.JavaConversions._ java.util.Arrays.asList(1,2,3).foreach(i => println(i))
java.util.Arrays.asList(1,2,3).filter(_ % 2 == 0)
Import JavaConversions and you are done:
Now we have all Higher Order Functions like
foreach, filter, map etc. available
The JavaConversions object contains implicits that
convert a java.util.Collection into a
Scala’s counterpart.
Scala
![Page 60: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/60.jpg)
Implicits can do more…
Implicitly convert from one type to another (here String to Date):
implicit def fromDateStr(dateStr:String):Date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr)
val d:Date = "2013-02-15"
//compiler turns this into: val d:Date = fromDateStr("2013-02-15")
![Page 61: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/61.jpg)
How about converting ‘Functional Interfaces’ into ‘First Class Functions’?
implicit def convertFun[T](fun:T => Boolean) = new Predicate[T]() { def apply(in:T):Boolean = fun(in)
Now we can use a Scala Function in the Google
API (instead of the Guava Predicate)
import com.google.common.collect._Collections2.filter(Arrays.asList(1,2,3), (i:Int) => i % 2 == 0 )
Convert a Scala Function into a Google Guava
Predicate
![Page 62: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/62.jpg)
If Java 8 had chosen for implicits…
• A proven mechanism was added to add new methods to existing classes without being limited to interfaces
• API designers AND API users would be able to add new methods to existing classes
• Bridging of API’s – like Google Guava to Java Collections – would be possible
• Last but not least: the implicit mechanism is not new in Java: Remember autoboxing?
![Page 63: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/63.jpg)
Roundup
• The new language features of Java 8 are definitely an improvement
• Java 8 could have been more powerful if Implicits were chosen above Virtual Extension Methods for preserving backwards compatibility
• Comparing the new Java 8 features to Scala:– Java 8 catches up with Scala but is not as feature rich and complete
(Functions & Multiple Inheritance)– However, Java 8 cannot be expected to be as advanced as Scala,
because:• Java is burdened with considerable backwards compatibility constraints• Java was not designed from scratch to be a functional or multiple
inheritance language
![Page 64: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/64.jpg)
Q & A
def ask(question: Any) = question match { case "?" => "Another layer of abstraction" case "???" => "It depends" case _ => 42 }
@urs_peter
![Page 65: A Feature Comparison Urs Peter upeter@xebia.com @urs_peter vs](https://reader035.vdocuments.us/reader035/viewer/2022062516/56649e205503460f94b0c817/html5/thumbnails/65.jpg)
Dependency Injection
Functional Programming Object
Orientation
API refinement & bridging
Lightweight & expressiveRobust-
nessDSLs
Parallel Programming
Functions
Multiple inheritance with Traits
Pattern Matching
Collections
Classes and Objects
Parser Combinators
Type inference
Options
Actors
Infix notationImplicits
Nestable For loops
Implicits
We haven’t covered it all…