SCALA Created with the goal of being a better general purpose language Inspired by the criticism of Java shortcomings Both Object Oriented and Functional Compiles into Java bytecode and runs on the JVM Interoperable with Java Very strong static type system (richer than Java's)
a problem: functions versus objects << In Scala, functions are objects. >> Programs can be constructed through both the definition and composition of objects and functions.
its free variables. Allows a function access to non-local variables when invoked outside its scope. def start(x: Int) = { def increment(y: Int) = { x + y } increment }
of a function of multiple parameters into a chain of functions that accept one or more parameters. In Scala, any function of multiple parameters can be curried. scala> val multipleParams = (x: Int, y: Double, z: String) => x + y + z multipleParams: (Int, Double, String) => String = < function3 > scala> val separateParams = multipleParams.curried separateParams: Int => (Double => (String => String)) = < function1 >
delays the evaluation of an expression until its value is needed. Can lead to smaller memory footprint Can increase performance Allows building infinite data structures (i.e.: streams - tail is evaluated only on demand)
constituents of a pattern. Match expressions make manipulations of complex data structures convenient and expressive. expr match { case pattern01 => result01 //there is no fall through to the next alterna case pattern02 => result02 //match expressions return a value }
state No static class members Methods provide operations Access modifiers declare visibility Singleton Objects as First-Class Objects Inheritance Single Inheritance Multiple: Mix-in as many traits as you want
mutable fields scala> :javap p Rational Compiled from "<console>" public class Rational { private final int n; public int n(); } scala> :javap p Rational Compiled from "<console>" public class Rational { private int n; public int n(); public void n_$eq(int); }
fields by adding val or var before them class Rational(val n: Int, val d: Int) { def add(that: Rational) = { new Rational(n * that.d, d * that.n, d * that.d) } }
is restricted using private Protected makes a member visible within its enclosing class and subclasses - more restrictive Access is relaxed up to a given entity by using a qualifier The strictest restriction can be achieved using the this qualifier
first-class objects replacing static (e.g. holding constants) Use the object keyword to define a singleton object object Rational { val denominator = 1 } scala> Rational.denominator res0: Int = 1
/ trait share the same name, file & package, they are called companions Companions can access their private members - except for this, there is no relation at all class Rational (val n: Int, val d: Int) object Rational { val denominator = 1 }
package level Each package is allowed to have one package object Any definitions placed in a package object are considered members of the package itself; they can easily be imported by other members // numbers/package.scala package object numbers { val denominator = 1 }
same name with a companion class is called a standalone object Any standalone object with a main method of the proper signature can be used as the entry point into an application: object NumbersApp { def main(args: Array[String]) { println(“Hello, World!”) } }
to define explicitly the main method To use this trait, write "extends App" a er the name of your singleton object The singleton object inherits the main method properly defined by App The code between the curly braces is collected into the primary constructor of the singleton object object NumbersApp extends App { println(“Hello, World!”) }
val one = Rational(1) one: Rational = Rational(1,1) No need for new to create new instances Nice implementations of toString, equals & hashCode Class params are promoted to immutable fields automatically copy method is automatically implemented Use case classes in pattern matching (see FP Features)
Rational.apply(1) res1: Rational = Rational(1,1) Each case class has a companion object with an apply method The apply method is used as a factory method Calling apply works for any object