• Save
Xebicon2013 scala vsjava_final
Upcoming SlideShare
Loading in...5
×
 

Xebicon2013 scala vsjava_final

on

  • 445 views

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

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

Statistics

Views

Total Views
445
Views on SlideShare
445
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Today, we are trying to find an answer about the slightly exaggerated question whether ‘Java 8 can kill Scala’ In order to do that we will look at the most influential language features Java 8 will introduce and compare them to Scala.Today I am going to talk about the new language features of Java 8 in comparison to Scala.Because I believe that by comparing different language paradigm’s we not only can broaden our horizion but can also gain a lot of insipring.First I’d like to know more about you, the audience. - Who’s primary language is Java?- Who has ever written a line of Scala code?- Who considers him/herself to be familiar with functional programming?
  • First let’s look at key characteristics of ScalaHybrid language: incorporates both paradigm to the full extentStrong typing: typechecker at compile team elimiates a great deal of errors and therefore makes large codebases managable
  • Let’s take a little detour and First let’s figure out what benefits Functions offer us.
  • To figure this out we look at an imperative example in Java and transform it into a functional representationWhenever duplication is involved there must be a better solutionExplain problems
  • Abstract the expression in the if statementCreate a controlstructure that works with this abstractionPredicate is used to customize the generic control structureI’ll use this term throughout my presentation that’s why I would like to clarify its meaning
  • Reuse of control structureProblem with this approach is that the anonymous inner class sytnax is very verbose.
  • All of these implementation use an internal iteration, calling the single method of the functional interface to customize the behaviourThe Functional Concept exists in Java but there was no language support for it.
  • Until now, Java did not have language support for this style of programming. This changes with Lambda’sSnippet above and below is semantically exactly identical.The Lambda represents the essence of the anonymous class above: the method signature of op and an implementation.Lambda Expression can be used everywhere where a functional interface is used:What is a functional interface?In that sense a Lambda expression is simply a piece of syntactic sugar.With Lambda’s Java has finally gained the key ingredient for functional programming
  • Full blown expressionWhat is type inference: compiler trickUse colon colonMethod reference is a means to extract a method out of an existing class.Take an existing method and apply it’s implementation everywhere were we would use a functional interface.
  • Full blown expressionWhat is type inference: compiler trickUse colon colonMethod reference is a means to extract a method out of an existing class.Take an existing method and apply it’s implementation everywhere were we would use a functional interface.
  • Scala’s type inference goes much further than the one Java offers.Scala’s type inference is considerably more complete.
  • When it comes to method references Scala does not need a special sytax for that.Methods and functions are closely related in Scala
  • When it comes to method references Scala does not need a special sytax for that.Benefit: you get type inference for freeFor a beginner the _ syntax might be a bit confusing; however when you program more often it will become familiar very quickly
  • The features Lambda’s offer are all available in Scalaas well. They even almost look identical.What are higher order functions?
  • Scala: There is no need to choose a corresponding functional interface: Due to Scala’s Type Inference combined with Functions as ‘First Class Citizens’ approach this is not necessary:
  • So let’s sum up the differences we have figured out so far. (between lambdas/method references and Scala functions)This is not very surprising because Scala was designed as a functional language from scratch whereas in Java functional capabilities are added to the language in a late stage.Scala’s Function allow you to fully leverage the functional programming paradigmScala’s Function support the full feature set needed to do hard-core functional programming.
  • For creating some contrast let’s look at a normal piece of Java code whose structure must look very familiar to a Java developer
  • When we look at this representation on the contrary we should be able to understand what’s going on by simple reading it, as if it was a text.This piece of code is considerably easier to understand than the previous sample. Why? Because we program here on a different abstraction level.We use higher level buildingblocks (higher order functions) that are customized by means of Lambda’s. Because we can chain these building blocks we can achieve the same result as in the previous slide with considerably less lines of codeThe main benefit Lambda’s and corresponding higher order functions offer are that we program on a different abstraction level. More readable, because we program on a different abstraction levelWe have re-usable buildingblocks we can chain together to compute the desired computation.Compute a list containing the names of top-grade students sorted by their grade.
  • That’s not all: Let’s look at a limitation introduces by external iterations.
  • There is no reason why this piece of code cannot be executed in parallel.
  • Not only a pitty but at a certain point in time not acceptable anymore.
  • Because now we have this different abstraction level, the underlying implementation can change.
  • When you do hard-core functional programming you will embrace immutability.Functional programming supports immutable paradigmWorking with Scala collections is a great experience. Lambda expressions will make the gap smaller.
  • After having looked at Lambda expressions let’s go one step further: How can we bring Lambda support to java.util.Collection interface without breaking backwards compatiblity?Java Design team had to come with a solution, to deal with this backwards compatiblity issue
  • This was an important question for the Java 8 designer to answerOnly then Lambda expression really add benefit
  • Java also knows multiple inheritance of types
  • The characteristics have no common hierarchy but ortagonal
  • Constrain which class to mix inThis constraint has advantages: it gives you access to the mixed in class
  • Constrain which class to mix inThis constraint has advantages: it gives you access to the mixed in class
  • Constrain which class to mix inThis constraint has advantages: it gives you access to the mixed in class
  • Constrain which class to mix inThis constraint has advantages: it gives you access to the mixed in class
  • Show in repl
  • Stackable: prevent the classical diamond problem known from classical multiple inheritanceYou end up with a non-deterministic situation
  • Let’s take a step backAre Virtual Extension Methods a good choice for the problem at hand?That means only the creator of the interface is able to add extensions.
  • The implicit conversion mechanism works quite simple:whenever the compiler encounters a method that does not belong to a type it looks for an implicit conversion in scope.If the Scala compiler encounters a method or class it does not know it looks for an implicit conversion method or class
  • Implicits are used in various areas of the Scala code, one usage area is bridge different API’s
  • This is not a robust application of implicits, for illustrative purposes only
  • If the Scala compiler encounters a method or class it does not know it looks for an implicit conversion method or class
  • JSR335: makes the gap with modern jvm languages considerably smallerHowever, 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 languageSo is are the Java 8 featues a Scala killer? Definitely not. They are additions and therefore not as well integrated as in Scala where they are core class constructs. My personal conclusion is that Java 8 is good for Java and Scala. Why: Java more popular, gap van Java naarScala smaller

Xebicon2013 scala vsjava_final Xebicon2013 scala vsjava_final Presentation Transcript

  • Is Java 8 a Scala killer?Urs Peterupeter@xebia.com@urs_peterhttp://bit.ly/xc_is
  • Born in 2003 – 10 years oldSponsored by EPFL(École Polytechnique Fédérale de Lausanne – Switzerland)Some Facts about Scala
  • Also co-designed Generic Java,and built the current generation of javac.Creator: Martin OderskySome Facts about Scala
  • Scala is fully interoperable with JavaSome Facts about Scala
  • Scala is used in many worldclass companies &applicationsSome Facts about Scala
  • There is a company behind ScalaSome Facts about Scala
  • …that offers a supported StackSome Facts about Scala
  • Recently joined Typesafe:Some Facts about Scala
  • Java1.7Lightweight SyntaxStrong TypingFunctionalObject OrientedSome Facts about Scala
  • May 2013Some Facts about ScalaThoughtworks Technology RadarScalaPlay Framework
  • • 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
  • 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
  • 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
  • Java 8 Lambda’s versusScala FunctionsWhat’s so fun about Functional Programming anyway?
  • 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
  • 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
  • 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
  • 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?
  • 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
  • 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
  • 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()
  • 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);
  • 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)
  • 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
  • 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 )
  • 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}
  • 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
  • Taking off with FunctionalProgramming
  • 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
  • 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
  • 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
  • Higher Order FunctionsParallelismAutomatic collection conversionFast immutable data structuresOtherDetailed Comparison:Collections & Lambda’s/FunctionsScalaCollectionsAutomatic conversionfrom Java to ScalacollectionsJava 8Collections
  • 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
  • …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
  • 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)
  • 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?
  • Possible Ship implementations:Base MechanicFighterCommanderThe Limits ofSingle inheritance
  • Implementation Challenge: Single inheritance won’t workGun Shield MedicBaseCommanderFighterMechanicThe Limits ofSingle inheritance
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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");
  • Welcome to Scala Implicits…or the ‘pimp my library pattern’
  • 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
  • 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
  • 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?
  • 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.
  • Q & Adef ask(question: Any) = question match {case "?" => "Another layer of abstraction"case "???" => "It depends"case _ => 42}Evalutationhttp://bit.ly/xc_is