Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| 
                    pp:scala-project [2022/01/03 16:39] pdmatei  | 
                
                    pp:scala-project [2022/01/12 11:58] (current) pdmatei  | 
            ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ======= Scala @ PP ======= | ======= Scala @ PP ======= | ||
| + | ===== "Meta ideas" ===== | ||
| + | Test-driven development | ||
| ===== 1. Installation ===== | ===== 1. Installation ===== | ||
| Line 12: | Line 14: | ||
| 2.3. Conditionals | 2.3. Conditionals | ||
| - '' def f(x : Int) = if (x >= 0) x else -x'' | - '' def f(x : Int) = if (x >= 0) x else -x'' | ||
| - | |||
| - boolean expressions (''true'', ''false'', ''!b'', ''&&'', ''||'') | - boolean expressions (''true'', ''false'', ''!b'', ''&&'', ''||'') | ||
| - the "by value" definition using ''val'' | - the "by value" definition using ''val'' | ||
| Line 18: | Line 19: | ||
|  |  | ||
| + | Newton square root estimation | ||
| + | |||
| + | * Blocks - expressions in Scala | ||
| + | * visibility of variables in blocks | ||
| + | * local scoping (similar to let) | ||
| + | * semicolons (optional) | ||
| + | * tail recursion in Scala (only direct recursive calls are optimised @tailrec) | ||
| + | * function types (''f : Int => Int'') | ||
| + | * anonymous functions (''(x: Int, y: Int) => x + y'', '' x => x+x'') | ||
| + | * currying (''def f(x: Int, y: Int)(z: Int):Int = x+y+z'') | ||
| + | * higher-order functions (mapReduce implementation) | ||
| + | |||
| + | * classes and **methods** | ||
| + | <code scala> | ||
| + | class Rational(x: Int, y: Int) { // creates a Type as well as a constructor for the new type | ||
| + | def a = x | ||
| + | def b = y | ||
| + | } | ||
| + | |||
| + | val r = new Rational(1,2) | ||
| + | </code> | ||
| + | * ''toString'' and ''@override'' | ||
| + | * the ''require'' (a precondition on the caller of a function) (equivalent to) and ''assert'' (check the code is right) | ||
| + | * **constructors**: | ||
| + | * multiple constructors: | ||
| + | <code scala> | ||
| + | class ... { | ||
| + | def this(x: Int) = this(x,1) | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | * infix notation for functions | ||
| + | <code scala> | ||
| + | r add s /*same as*/ r.add(s) | ||
| + |  | ||
| + | def < (param : Rational)  /* symbolic identifiers may contain operator symbols */ | ||
| + |  | ||
| + | def unary_- (...) /* to overload negation. Careful, white spaces can be interpreted as identifiers */ | ||
| + |  | ||
| + | /* the precedence of an operator is determined by its first character */ | ||
| + | /* precedence cannot be overridden by the programmer */ | ||
| + |  | ||
| + | </code> | ||
| + | |||
| + | ===== 3. Data representation ====== | ||
| + | |||
| + | * object definitions - singleton classes ''object Empty extends IntSet'' | ||
| + | * companion objects (one object per class) | ||
| + | * annotation ''@main def birthday'' - can be called directly from compilation ''scala birthday ...'' | ||
| + | * ''println(s"Hello $name")'' | ||
| + | * **dynamic binding** | ||
| + | * packages - organising sources - directories (not enforced by the fs) | ||
| + | <code scala> | ||
| + | import pack.Obj | ||
| + | </code> | ||
| + | * traits (similar to interfaces in Java, but can have parameters, contain fields and defined functions) | ||
| + | * object hierarchy in Scala | ||
| + | * exceptions (similar to Scala) | ||
| + | * **ADTs**: | ||
| + | * ''class Cons (val head: Int, val tail: List) extends... ''  - value parameters | ||
| + | * type parameters (square brackets) | ||
| + | * generic functions ''def singleton[T] (elem: T) ...'' | ||
| + | |||
| + | |||
| + | * **Scala is a pure OO language (unlike Java)!!** | ||
| + | * functions are implemented as objects | ||
| + | <code scala> | ||
| + | trait Function1 [A,B]: | ||
| + | def apply(x: A): B | ||
| + | |||
| + | f = new Function1[Int,Int]:  //anonymous class | ||
| + | def apply(x: Int) = x * x | ||
| + | |||
| + | /* anonymous classes are equivalent to blocks that evaluate to an object*/ | ||
| + | { class $anonfun() extends Function1[Int,Int]: | ||
| + | def apply(x: Int) = x * x | ||
| + | $anonfun() | ||
| + |  | ||
| + | def f(x: Int): Boolean = ... | ||
| + | /* the above is not itself a function value. However, if it is used where a Function type is expected | ||
| + | it is converted automatically to the function value: */ | ||
| + | (x: Int) => f(x) | ||
| + | |||
| + | // or expanded to | ||
| + | |||
| + | new Function[Int, Boolean]: | ||
| + | def apply(x: Int) = f(x) | ||
| + | </code> | ||
| + | |||
| + | ===== 4. TDAs ====== | ||
| + | |||
| + | Object-Oriented decomposition (the classical TDAs vs OO) | ||
| + | |||
| + | Functional decompositions (case classes) | ||
| + | |||
| + | <code scala> | ||
| + | def eval(e: Expr): Int = e match | ||
| + | case Number(n) => n | ||
| + | case Sum(e1,e2) => eval(e1) + eval(e2) | ||
| + | </code> | ||
| + | |||
| + | |||
| + | <code scala> | ||
| + | val l = 1 :: 2 :: 3 :: Nil | ||
| + | </code> | ||
| + | |||
| + | **Enums** (TDAs) | ||
| + | <code scala> | ||
| + | enum Expr: | ||
| + | case Var (s: String) | ||
| + | case Number (n: Int) | ||
| + | case Sum(e1: Expr, e2: Expr) | ||
| + | case Prod(e1: Expr, e2: Expr) | ||
| + | </code> | ||
| + | Type bounds in generics | ||
| + | <code scala> | ||
| + | def asseertAllPos [S <: IntSet] (r: S): S = ... | ||
| + | </code> | ||