Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Xebicon2013 scala vsjava_final

780 views

Published on

Presentation about the new language features of Java 8, mainly lambda's and default methods in comparison to Scala.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Xebicon2013 scala vsjava_final

  1. 1. Is Java 8 a Scala killer?Urs Peterupeter@xebia.com@urs_peterhttp://bit.ly/xc_is
  2. 2. Born in 2003 – 10 years oldSponsored by EPFL(École Polytechnique Fédérale de Lausanne – Switzerland)Some Facts about Scala
  3. 3. Also co-designed Generic Java,and built the current generation of javac.Creator: Martin OderskySome Facts about Scala
  4. 4. Scala is fully interoperable with JavaSome Facts about Scala
  5. 5. Scala is used in many worldclass companies &applicationsSome Facts about Scala
  6. 6. There is a company behind ScalaSome Facts about Scala
  7. 7. …that offers a supported StackSome Facts about Scala
  8. 8. Recently joined Typesafe:Some Facts about Scala
  9. 9. Java1.7Lightweight SyntaxStrong TypingFunctionalObject OrientedSome Facts about Scala
  10. 10. May 2013Some Facts about ScalaThoughtworks Technology RadarScalaPlay Framework
  11. 11. • JSRs– JSR 335 Lambda Expressions and Virtual ExtensionMethods (in debate since 2008)– JSR 308 Annotations on Java Types– JSR 310 Date and Time API• Schedule:– 2013/02/21 M7– 2013/07/05 M8 (Final Release Candidate)– 2013/09/09 GA (General Availability)– Spring 2014Java 8
  12. 12. Java 8• JSRs– JSR 335 Lambda Expressions and Virtual ExtensionMethods (in debate since 2008)– JSR 308 Annotations on Java Types– JSR 310 Date and Time API• Schedule:– 2013/02/21 M7– 2013/07/05 M8 (Final Release Candidate)– 2013/09/09 GA (General Availability)– Spring 2014
  13. 13. Java• JSRs– JSR 335 Lambda Expressions and Virtual ExtensionMethods (in debate since 2008)– JSR 308 Annotations on Java Types– JSR 310 Date and Time API• Schedule:– 2013/02/21 M7– 2013/07/05 M8 (Final Release Candidate)– 2013/09/09 GA (General Availability)– Spring 20148
  14. 14. Java 8 Lambda’s versusScala FunctionsWhat’s so fun about Functional Programming anyway?
  15. 15. List<Integer> numbers = Arrays.asList(1,2,3);Filter even numbersFilter odd numbersDuplicationVariationList<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 toFunctional in Java
  16. 16. interface Predicate<T> {public boolean op(T item);}The Function: Varying computationThe Loop: Generic Control Structurepublic 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 toFunctional in JavaGeneric Control Structure==Higher Order Function
  17. 17. List<Integer> numbers = Arrays.asList(1, 2, 3);Filter even numbersFilter odd numbersList<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 toFunctional in Java
  18. 18. 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?
  19. 19. 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’sLambda Expression==Syntactic sugar
  20. 20. List<Integer> result = filter(numbers, (Integer i) -> i % 2 == 0);List<Integer> result = filter(numbers, i -> i % 2 == 0);No need to define thetype since it can beinferred by the compiler.Lambda Featuresat one GlanceJava 8Complete Lambda ExpressionLambda Expression with Type Inference
  21. 21. Turn an existing static methodwith the same signature asthe functional interface into aclosure, using ::Method Referenceat one GlanceJava 8Boolean::booleanValuerefers to the instance thatthe filter is iterating through.Static Method ReferencesInstance Method ReferencesList<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()
  22. 22. Complete Lambda ExpressionJava 8ScalaJava 8 Lambda Expressionsversus Scala Functionsval result = filter(numbers, (i:Int) => i % 2 == 0)List<Integer> result = filter(numbers, (Integer i) -> i % 2 == 0);
  23. 23. List<Integer> result = filter(numbers, i -> i % 2 == 0);Lambda with type inferenceJava 8ScalaJava 8 Lambda Expressionsversus Scala Functionsval result = filter(numbers, i => i % 2 == 0)
  24. 24. List<Integer> result = filter(numbers, NumUtils::isEven);Static Method ReferencesJava 8val result = filter(numbers, NumUtils.isEven)Scala Every method that is notcalled with its arguments isautomatically turned into aFunction.Methods == FunctionsJava 8 Lambda Expressionsversus Scala Functions
  25. 25. List<Boolean> trueOnly = filter(trueOrFalse, Boolean::booleanValue);Instance Method ReferencesJava 8Java 8 Lambda Expressionsversus Scala FunctionsScalaScala uses the _ (underscore) torefer to the current instance thatis iterated throughval trueOnly = filter(trueOrFalse, _.booleanValue )
  26. 26. 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 8Scalainterface Collection<T> {public Collection<T> filter(Predicate<T> p);...Scala has afunction syntax.Every Higher Order Function needs aspecific Functional Interface in Java 8.The compiler transforms this syntax to ageneric Function object. Therefore, noFunctional Interface needs to be defined.class Function1[I, R] {def apply(i:I): R}
  27. 27. Detailed ComparisonJava 8 Lambda ExpressionsSyntax is limited to calling HigherOrder FunctionsFunctions are interfaces with onemethodLambda’s are Syntactic Sugar forFunctional InterfacesScala FunctionsHave a syntax for defining andcalling Higher Order FunctionsFunctions are objects with methodsRich Function Features:– Function Composition– Currying– Call-by-name arguments– PartialFunctions– Pattern matchingFunctions are First Class Citizensfully supporting the FunctionalProgramming Paradigm
  28. 28. Taking off with FunctionalProgramming
  29. 29. Iterations in Java are ‘external’ bydefault…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
  30. 30. Advantages:• Re-use of generic, higher level control structures• Less error prone• More expressive and readable• ChainableInternal Iteration: WhenLambda’s/Functions start to shineAh, 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 8Not yetavailable
  31. 31. Internal Iteration: WhenLambda’s/Functions start to shineval students = ...val topGrades =students.filter(_.score >= 9).sortBy(_.lastName).map(s => s.firstName + " " + s.lastName)Java 8ScalaNo need to use the into()method. This happens inScala ‘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<>());Not yetavailable
  32. 32. Higher Order FunctionsParallelismAutomatic collection conversionFast immutable data structuresOtherDetailed Comparison:Collections & Lambda’s/FunctionsScalaCollectionsAutomatic conversionfrom Java to ScalacollectionsJava 8Collections
  33. 33. How is it possible to add Higher Order Functions(e.g. filter map foreach etc.) to the java.util.Collection interface withoutbreaking 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 inJRE 8 would have to implement all thenew methods that offer ‘internaliteration’ with Lambda’s.Back to Java 8:How to make it fit?Java 8
  34. 34. …with default implementations for interfacesaka 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
  35. 35. A closer look at Java 8’Virtual Extension Methods• Primary motivator is API evolution(Backwards compatibility for Lambda’s inCollections)• Useful mechanism by itself:Enables Multiple Inheritance of behavior• Inspired by Scala traits (among others)
  36. 36. Let’s model the domain for a ‘futuristic’ gameGunfireAt(s:Ship)Shieldhit() //50%Medicrepair(s:Ship)Shiphealth:Integerhit()Possible characteristics of a Ship:s.health = 10repaired += 1health - 1s.hit()health - 2Do we need Multiple Inheritance?
  37. 37. Possible Ship implementations:Base MechanicFighterCommanderThe Limits ofSingle inheritance
  38. 38. Implementation Challenge: Single inheritance won’t workGun Shield MedicBaseCommanderFighterMechanicThe Limits ofSingle inheritance
  39. 39. 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 withan implementation(behavior and/or state)val goodFighter = new Ship(10) with Gunval evilFighter = new Ship(10) with GungoodFighter.fireAt(evilFighter)println(evilFighter.health)> 8It can be ‘mixed-in’ with aclass using the keyword:withScalaMultiple Inheritance of Behavior
  40. 40. 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());> 8Works with VirtualExtension MethodsJava 8Multiple Inheritance of Behavior
  41. 41. 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 GunevilFighter.fireAt(commander)println(commander.health)> 9Trait’s can have a self-type. The self-type tellswith which class this traitcan be ‘mixed’.The self-type providesaccess to the ‘mixed-in’classTraits can overridemethods of the‘mixed-in’ classScalaMultiple Inheritance of Behavior
  42. 42. Change Behavior of Ship (Java 8)val commander = new Ship(10) with Gun with Shieldval evilFighter = new Ship(10) with GunevilFighter.fireAt(commander)println(commander.health)> 9class Ship(var health:Int = 0) {def hit() = health -= 2}trait Shield {self:Ship =>override def hit() = self.health -= 1}Does not work with VirtualExtension Methods (VEM)Why?• VEM cannot override methods ofa class (they are overridden)• VEM have no self-typesJava 8Multiple Inheritance of Behavior
  43. 43. 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 Gunmedic.repair(brokenShip)println(brokenShip.health)> 10println(medic.repaired)> 1A trait can have state.ScalaMultiple Inheritance of State
  44. 44. val medic = new Ship(10) with Shield with Medicval brokenShip = new Ship(1) with Gunmedic.repair(brokenShip)println(brokenShip.health)> 10println(medic.repaired)> 1Adding State and Behavior to Ship (Java 8)trait Medic {var repaired = 0def repair(s:Ship) = {s.health = 10repaired += 1}}Does not work with VirtualExtension Methods (VEM)Why?• VEM cannot have stateJava 8Multiple Inheritance of State
  45. 45. Have methodsHave fieldsAccess implementingclass in a typesafe wayOverride methodsStackable(call to super is linearized)IntentScalaTraitsMultiple inheritance‘without the issues’Java 8Virtual Extension MethodsGrow thelanguageScala Traits vsJava 8 Virtual Extension Methods
  46. 46. Is there no better way to“Grow the language”?• What we really want is ‘a mechanism’ that adds ‘newmethods’ to ‘existing classes’• Virtual Extension Methods solve this problem on theinterface level:– When we extend the interface with defaults, all classes inheritingfrom 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 existingclasses by myself too!"You win %2.2f%n".format(333333.3333);new java.util.Date().toString("yyyy-MM-dd");
  47. 47. Welcome to Scala Implicits…or the ‘pimp my library pattern’
  48. 48. Implicits in Practiceimplicit 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
  49. 49. 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 HigherOrder Functions likeforeach, filter, map etc.availableThe JavaConversions objectcontains implicits thatconvert a java.util.Collectioninto a Scala’s counterpart.Scala
  50. 50. If Java 8 had chosen for implicits…• A proven mechanism was added to add newmethods to existing classes without being limited tointerfaces• API designers AND API users would be able to addnew methods to existing classes• Bridging of API’s – like Google Guava to JavaCollections – would be possible• Last but not least: the implicit mechanism is not newin Java: How about: Autoboxing, Lambda’s?
  51. 51. Lambda’s/FunctionsMultiple InheritanceIs Java 8 a Scala killer?ScalaJava 8Syntactic sugar forFunctional InterfacesFunctions as FirstClass CitizensOf Behaviour Of Behaviour andState ‘without theissues’Extend existing classes - Implicits• The features of JSR 335 (Lambda’s and Virtual Extension Methods)are definitely an improvement;• Choosing Implicits above Virtual Extension Methods for preservingbackwards compatibility would have made Java 8 more powerful;• Java 8’ new language constructs are not as features rich andcomplete as in Scala.
  52. 52. Q & Adef ask(question: Any) = question match {case "?" => "Another layer of abstraction"case "???" => "It depends"case _ => 42}Evalutationhttp://bit.ly/xc_is

×