Scala: language principles

  • läuft auf JVM und benutzt Java Datentypen und KlassenLibrary
    • scalac compiler
    • scala interpreter und executor
      • ohne Argumente als Interpreter
      • alle compiler optionen sind erlaubt: scala -depreciation
      • :help im Interpreter
      • :load file um ein File zu interpretieren
      • im Gegensatz zum Compiler, müssen benutzte Sachen vorher deklariert werden
  • syntax weniger strikt als java,
    • ; werden erraten, **
    • ( ) und Punkte sind nicht immer nötig, z.B. kann folgendermassen Abkgekekürzt werden
      • o.m(a) als o m a
      • f(a,b) als a f b, Prio uns Assoziativität hängt syntax von f bzw. m ab
      • o.m() als o m
      • f() as f
    • Methoden/FunktionsNamen können Namen oder Folgen von Spezialzeichen sein
    • == ist die überschreibbare inhaltliche Gleichheit, eq die PointerGleichheit
    • Kommentare mit // oder /* ... */, doc comments mit /** .... */
    • Annotations, vordefiniert z.B. @serializable
  • extensibilität: z.B. Operator overloading, eigene KontrollKonstrukte
  • funktional und OO
  • alles ist ein Objekt, auch Methoden und Funktionen
    • anonyme Funktion (x: Int) => x * x
    • geschachtelte Funktionen mit Closures
    • Parameter by value a: Int oder by name a: => Int, da wird Ausdruck bei jeder Erwähnung ausgewertet: def e(i: => Int) = {println("evaluating"); try { i} catch {case e => println("catch " + e); -123 }}
  • Object ⇔ Class ⇔ Trait
    • val, var, def, class, object definiert je Konstante, Variable, Methode, Klasse,
    • object (Klasse mit Singleton - aber innerhalb scope, ist ein Modul und auch Ersatz für statische KlassenKonstrukte)
    • trait Abstrakte Klasse für Mixin Komposition (ersetzt Interfaces, implementiert Art von multiple Inheritance)
    • if für Statements und Expressions, genauer Statments und Expressions werden einheitlich behandelt: Unit ist Statement ohne return value
  • basic Types
    • Byte..String
    • Unit: no value
    • Null empty reference
    • Nothing, Any, AnyRef
    • Tuples (a, "abc")._2
    • Arrays, 0-relativ, mit Parameter Types, aber mit Function Syntax: var a = new Array[String](3); a(1)="soLaLa" (eckige Klammern sind für typeParameters!)
    • Lists: Nil als leere Liste, A::x as append, x:::A als prepend
      • ranges 3 to 7
      • PatternMatching für Listen def r2(A:List[Int]) = A match {case Nil => List(-99);case x::Nil => List(x*x);case s => -98::s}
      • for mit Filtern for (e <- 2 to 22 if e %2==1; if e%3==0) println(e)
    • Map: val m = Map(1 -> "eins", 2 -> "zwei") , m(1) ⇒eins und (5) ⇒exception,
      • aber get braucht None und Some: m.get(1) ⇒Some(zwei) und m.get(5) ⇒None
  • packages können (wie in C#) geschachtelt werden
  • Patterns
    • case classes/Objects ==> mit entsprechendem Patternmatching in Verarbeitung
      abstract class Nat 
      case object Zero extends Nat
      case class Succ(pre: Nat) extends Nat
      def p2I(n: Nat) : Int = n match {    
           case Zero => 0                       
           case Succ(p) => 1 + p2I(p) }         
      scala> p2I(Succ(Succ(Succ(Zero))))     
      res67: Int = 3 
    • Pattern Guards: case (x,_) if x>= 17 => ... und _ als Wildcard
    • sealed, Compiler macht Warning, wenn match nicht alle cases enthält
  • Polymorphismus
    • universal
      • parametrisch
      • inclusion (inheritance)
    • ad hoc
      • overloading (Richtigen Operator je nach OperandenTypen aussuchen)
      • coercion (implicit type conversion when needed) ==> implicit def ... um Implizite Konversion zu definieren, CompileFehler falls nicht eindeutig
  • implicit
    • Funktionen für implizite TypenKonversion wie oben
    • implizite Parameter dürfen weggelassen werden ==> sieht aus wie verschiedene Signaturen
  • Relatins between types
    • type equivalence
    • <: conformance relation (subtype <: supertype)
    • Co/Contra/variance annotions für type parameters: X[+COVAR, -CONTRA]: if COVAR' <: COVAR and CONTRA <: CONTRA' then X[COVAR', CONTRA'] <: X[COVAR, CONTRA]
    • damit können upper und lower bounds für Typen deklariert werden
  • Parser
    • in scala.util.parsing.combinator.Parsers sind viele Parser Konbinatoren definiert
  • XML kann direkt einer Variabeln zugewiesen werden oder seamless als tree verarbeitet werden
  • GUI via scala.swing
  • concurrent programming via java.lang.Runnable etc.
    • scala.concurrent enthält MailBox als oo Concurrent Konstrukt, Actors und vieles mehr