Download presentation
Presentation is loading. Please wait.
Published byKerry Newton Modified over 9 years ago
1
Scala Technion – Institute of Technology Software Design (236700) Based on slides by: Sagie Davidovich, Assaf Israel Author: Gal Lalouche - Technion 2015 © 1
2
What is Scala? Scala is a static object-functional language It supports fully object-oriented code Classes, methods, inheritance, visibility modifiers,… It is actually more object-oriented than Java, due to lack of primitives, no static members It supports fully functional code Lambdas, Closure, Currying, pattern matching, lazy evaluation, tail recursion,… Most importantly, it allows the developer to mix and match the two Currying on methods, inheriting functions, … Compiles to Java bytecode So it’s easy to call Java from Scala and vice-versa Author: Gal Lalouche - Technion 2015 © 2
3
A note on the “new” features in Java 8 All the new features in Java 8 have been in Scala for years Higher order functions optional values Lambda Expressions The syntactic sugar of Functional Interfaces can be implemented using implicit default methods on interfaces are actually weak traits Streams and easy parallelization Author: Gal Lalouche - Technion 2015 © 3
4
Java: Scala: Java vs Scala code Author: Gal Lalouche - Technion 2015 © 4 class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public boolean canDrink() { return age >= 21; } public String getFirstName() { return name.split(" ")[0]; } } class Person (val name: String, val age: Int) { def canDrink = age >= 21 val getFirstName: String = name split " " apply 0 }
5
Java: Scala: Case classes Author: Gal Lalouche - Technion 2015 © 5 case class Person(id: Long) // includes getters/hash/equals/toString public class Person { long id; @Override public String toString() { return "Person [id=" + id + "]"; } @Override public int hashCode() { return result = 31 + (id ^ (id >>> 32)); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; return id != other.id; }
6
Java vs. Scala, at a glance Java 8 Has primitives No operator overloading Statements and expressions Has static methods and members Some type inference Library collections are mutable default methods Basic switch functionality Basic foreach functionality No extension methods Has checked exceptions Type Erasure (JVM property) Little to no syntactic sugar Scala Everything is an object No concept of "operators", just methods Everything is an expression Uses a companion object/Singleton Stronger type inference Collections are immutable by default traits Powerful pattern matching (a la ML) Powerful for comprehensions Can define implicit coercions Doesn’t have checked exceptions Can get around type erasure A lot (too much?) of syntactic sugar 6
7
Everything is an object Author: Gal Lalouche - Technion 2015 © 7 Scala has no primitive types Int is the type of integers and Double is the type of Double Precision All classes extends Any ( this is called a unified type system ) Nothing extends everything (this is called a bottom type) 1 + 2 is actually syntactic sugar for 1.+(2) Scala allows you to forgoe the. and parenthesis under certain conditions This also means that operator overloading is supported implicitly Simply define a method named + or *, or / or pretty much anything… For example, XML parsing: val forecast = weather \ "channel" \\ "item" \ "forecast"
8
Everything is an expression 8 In Scala, all statements are actually expressions Although some may be of type Unit ( Scala’s void) val x: Int = if (flag) 10 else 20 // no need for ?: val compound = { // doSomeCalculation … $ // last argument is considered the return value } val y: Seq[Int] = for (i <- 0 to 10) yield i // list comprehensions var z = 0 val unit: Unit = (z = 10) val file = try { readFile() } catch { case _: Exception => readOtherFile() }
9
Object companion Author: Gal Lalouche - Technion 2015 © 9 Scala has no static members / methods Instead, it uses the Singleton pattern and the object keyword Wait, isn’t Singleton evil? Well, usually… But objects are more powerful than simple static methods, since they can also be passed around, extend classes, etc. Java Scala Author: Gal Lalouche - Technion 2015 © class Person { String name; static boolean isLegal(String name) { //… } class Person(val name: String) { } object Person { def isLegal(name: String) = //… }
10
Type inference 10 Scala has strong type inference (though not as strong as Haskell/ML) For variables For methods For Lambdas We can also state the explicit return type to have it enforced by the compiler var x = 3 // discouraged in Scala val str = "Hello world!" // str’s reference cannot be changed def getString = { return "Hello world!" } List("1","2","3") map (i => i.toInt()) def getString: String = 4 // won’t compile val getInt: Int = "foobar" // won’t compile
11
Immutability 11 So you want to write immutable code in Java… We can use the final ( val in Scala) modifier, but that only applies to the reference itself What about the reference d object? It can be mutable! If we want our classes to be truly immutable we have to work hard We can use immutable objects, but most of the standard java classes and data structures are mutable This means we have to resort to defensive copying, which is verbose, slow and error-prone In Scala, all data structures are immutable (“persistent”) by default This also gives us free generic covariance (i.e., List[Int] extends List[Any])
12
Traits 12 Scala replaces interfaces with traits Traits are behavioural units, designed for software reuse Can be composed to create new traits An alternative to multiple inheritance (e.g., C++) and mixins (e.g., Ruby) Difference between Traits, Mixins and Multiple Inheritance Composed traits are flat, mixins are linear and multiple inheritance is a directed acyclic graph Traits only have a default constructor Trait conflicts are solved explicitly by the programmer
13
Traits – Conflict resolution 13 Trait conflicts are resolved explicitly Conflicts can only arise when there are two implementations with the same signature Since there are no constructors, and all conflicts are resolved explicitly, the model is much simple than multiple inheritance trait Hodor { def speak = "Hodor!" } trait Stark { def speak = "Winter is coming" } class StarkHodor extends Hodor with Stark { override def speak = "Hodor is coming!" // we can also use super[Hodor].speak }
14
Traits vs. default Methods 14 Traits can be viewed as more powerful default methods default methods cannot implement non-default methods Traits can have state interface Bar { void bar(); } interface Foo { default void bar() {…} } class FooBar implements Foo, Bar { // the method bar is considered in conflict and needs to resolved } trait Counter { var x = 0 }
15
Traits vs. default Methods (cont.)s 15 Trait composition can be used to provide required implementation trait Bar { def bar // this is a required method } trait Foo { def bar = {…} // this is a provide } class FooBar extends Foo with Bar { // doesn’t need to implement bar }
16
Traits vs. default Methods (cont.) 16 Traits can be composed in runtime (this actually borrows from mixins, i.e., conflicts are resolved linearly ) Traits can access the implementing class instance. A trait can require more than just methods from its implementing class; it can also impose lower bounds This is also used for dependency injection (the “cake pattern”) trait Dancer { def dance = … } class Cat { … } val dancingCat = new Cat with Dancer dancingCat.dance
17
Pattern matching Author: Gal Lalouche - Technion 2015 © 17 Scala has a powerful pattern matching mechanism Simple switch Type matching Author: Gal Lalouche - Technion 2015 © val y = 10 val x = y match { case 3 => … case 4 => … case _ => … //default } val x = y match { case s: String => … case i: Int => … case d: Double => … case tuple: (Int, String) => … } // no match will throw an exception
18
Pattern matching – sealed classes Author: Gal Lalouche - Technion 2015 © 18 Sealed classes can only be extended in the same source file This generates a compile error for none-exhaustive search Author: Gal Lalouche - Technion 2015 © sealed abstract class LogMessage case class StringMessage(message:String) extends LogMessage case class ExceptionMessage(exception:Throwable) extends LogMessage case class BothMessage(message:String, exception:Throwable) extends LogMessage class Logger { def debug(l:LogMessage) = log(10,l) def info(l:LogMessage) = log(5,l) def error(l:LogMessage) = log(1,l) def log(level:Int, l:LogMessage): Unit = l match { case StringMessage(msg) => println(msg) case ExceptionMessage(exception:Error) => exception.printStackTrace }
19
Pattern matching (cont.) Author: Gal Lalouche - Technion 2015 © 19 Functional progamming Regular expressions Much more… Author: Gal Lalouche - Technion 2015 © def contains[T](list: List[T], x: T): Boolean { case Nil => false case e :: xs => if (e == x) true else contains(xs, x) } val Name = new Regex("""(\w+)\s+(\w+)""") "Gal Lalouche" match { case Name(firstName, lastName) => println(firstName + " " + lastName) case _ => println("No match") }
20
Thing we don’t have time to cover Author: Gal Lalouche - Technion 2015 © 20 We only scratched the surface Implicit methods Implicit parameters For comprehensions Lazy evaluations Views (similar to stream, but lazier ) Actors (expressive distributed model) Much, much more… Author: Gal Lalouche - Technion 2015 ©
21
If you want to know more… Author: Gal Lalouche - Technion 2015 © 21 Suggested Reading: Programming in Scala (The de-facto guide) Programming in Scala Scala in Depth Scala in Depth See more here: http://www.scala-lang.org/documentation/books.htmlhttp://www.scala-lang.org/documentation/books.html Coursera: Functional Programming Principles in Scala (by the language creator) Functional Programming Principles in Scala Principles of Reactive Programming (advanced course, by the language creator and several API designers) Principles of Reactive Programming Author: Gal Lalouche - Technion 2015 ©
22
So is Scala perfect? Author: Gal Lalouche - Technion 2015 © 22 No language is perfect Scala takes the “everything but the kitchen sink” approach This gives us great power But W ith Great Power, Comes Great Responsibility! Author: Gal Lalouche - Technion 2015 ©
23
So is Scala perfect? (cont.) Author: Gal Lalouche - Technion 2015 © 23 All java code looks pretty much the same There no macros, no extension methods, little to no syntactic sugar (especially before Java 8) You always know where the method comes from With the exception of static imports This makes Java very verbose … …but also very simple to read Author: Gal Lalouche - Technion 2015 ©
24
“Too much syntactic sugar causes cancer of the semi-colons” Author: Gal Lalouche - Technion 2015 © 24 Scala has much built into the language (i.e., not part of a library) Java‘s map : Scala’s map : Author: Gal Lalouche - Technion 2015 © // sum numbers 1 to 100 var sum = 0; for (i <- to 100) sum += i (for (i <- 1 to 100) yield i) sum 1.to(100).reduce((x: Int, y: Int) => x.+(y)) 1.to(100).reduce((x, y) => x + y) 1 to 100 reduce (_ + _) Stream map(Function mapper) map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
25
“Too much syntactic sugar causes cancer of the semi-colons” (cont.) Author: Gal Lalouche - Technion 2015 © 25 It is very easy to create DSLs in Scala Scalatest (a unit-testing framework) The above code compiles But what’s going on here? is should a method? is be ? what is equal or in ? Author: Gal Lalouche - Technion 2015 © "A List" should "pop values in last-in-first-out order" in { val $ = new MutableList[Int] $ add 1 $ add 2 $ at 0 should be equal 1 $ at 1 should be equal 2 }
26
“Too much syntactic sugar causes cancer of the semi-colons” (cont.) Author: Gal Lalouche - Technion 2015 © 26 You can define new control structures You can create Python-like syntax Author: Gal Lalouche - Technion 2015 © def unless(b: Boolean)(f: => Unit) { if (!b) f } //… unless(x < 10) { println("x >= 10") } implicit def richBoolean(b: Boolean) = new { def or(other: Boolean) = b || other def and(other: Boolean) = b && other } if ((b or c) and d) { // … }
27
“Too much syntactic sugar causes cancer of the semi-colons” (cont.) Author: Gal Lalouche - Technion 2015 © 27 ProcessBuilder API Author: Gal Lalouche - Technion 2015 ©
28
Summary Author: Gal Lalouche - Technion 2015 © 28 Scala combines functional and object oriented approaches It is lightweight and expressive, supports DSL with ease, and fully interoperable with Java However, when a language let’s you do everything, developers also have to know everything Especially when working in teams Syntactic sugar is cool when working alone, but can quickly get out of hand Author: Gal Lalouche - Technion 2015 ©
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.