Com S 541 Lecture -*- Outline -*- * Primitives for computation in Scala based on: Odersky et al.'s An Overview of the Scala Programming Language (EPFL Tech Rep. IC/2004/64) Odersky et al.'s The Scala Language Specification (version 1.0 of Oct 15, 2005) other documents at scala.epfl.ch ** Data Overview (show Fig 1 of the overview paper) ------------------------------------------ TYPES IN SCALA Any (supertype of any type) - AnyVal (value classes) Double, Float, Long, Int, Short, Byte Char, Boolean, Unit - java.lang.Object = AnyRef (reference classes) java.lang.String, ... ScalaObject Iterable Seq List Symbol Ordered ... AllRef (a subtype of all reference classes) All (a subtype of all types) ------------------------------------------ all these are in the package scala unless noted otherwise there are the usual coercions in the numeric types: Byte to Short to Int to Lng to Float to Double and Char to Int ------------------------------------------ OPERATIONS IN ANY TYPE final def !=(v0: Any): Boolean final def ==(v0: Any): Boolean final def asInstanceOf[T0]: T0 def equals(v0: Any): Boolean def hashCode(): Int final def isInstanceOf[T0]: Boolean final def match[T0,T1](v0: (T0) => T1): T1 def toString(): String ------------------------------------------ *** Value Classes (and their literals) ------------------------------------------ VALUE CLASSES All subtypes of scala.AnyVal Numbers - scala.Int (= int) ..., -1, 0, 1, ... - scala.Long (= long) ..., -1L, 0l, 1l, 2L, ... - scala.Short (= short) - scala.Byte (= byte) usual Java operators (+, -, *, %, /, ...) Characters - scala.Char (= char) 'x', '\n' Booleans - scala.Boolean (= boolean) true, false ------------------------------------------ Names following = are type synonyms The package prefix, "scala.", can be omitted. Essentially all values, with their operations, are from Java These are representable without references on the stack *** Reference Data ------------------------------------------ REFERENCE DATA Reference classes in general - java.lang.Object (= scala.AnyRef) (root/top reference class) - scala.AllRef (bottom reference class) null: AllRef Everything from the JDK, including: - java.lang.String "a str\n" all the Java String operations Several scala built-ins: scala package - scala.Object - Symbol 'sym, 'a_sym, scala.Symbol("foo") - scala.xml.Node (for XML) My phone book Janet 555-1212 ... - Predef (predefined stuff, varies between JDK and CLR) - Array[T] - Function (= (a) => b) - Unit () - Pair (= Tuple2), Triple (= Tuple3) Pair(3, 4) - ... ------------------------------------------ Note that functions are just objects, like everything else. Methods of Array: abstract def apply(x0: Int): T abstract def length: Int abstract def update(x0: Int, x1: T): Unit ** primitive expressions *** designators ------------------------------------------ DESIGNATORS Sample names: x this super Selections: p.C.y E.f C.this super[M].y D.super[M].x ------------------------------------------ The super[M].y form names a particular mixin (M) of the current class *** calls Of course, all forms involving subexpressions are also means of combination. ------------------------------------------ METHOD CALLS Basic primitives for computation: E.attr E1.f(1) E2.m(x,y) Sugar: If f is a method in `this' f ==> this.f g(E1, ..., En) ==> this.g(E1, ..., En) ------------------------------------------ Note that attr, f, and m would be defined by a def in the classes of the denotations of E, E1, and E2 ------------------------------------------ FUNCTION CALL SUGARS Application of objects: assuming that f is an object (i.e., that f is not a method) f(E1, ..., En) ==> f.apply(E1, ..., En) ------------------------------------------ ------------------------------------------ INFIX METHOD CALL SUGARS Left associative, for names not ending in a colon (:) w op z ==> e.g., 5 - 4 - 1 ==> (5 - 4) - 1 Right associative, for names ending in a colon (:) E3 --: E4 ==> e.g., 3 :: 4 :: Nil ==> 3 :: (4 :: Nil) ------------------------------------------ There are also precedence rules, as usual, but generalized based on the first character of the operator name desugaring: ... ==> w.op(z) only for operator names not ending in a colon (:) ... ==> E4.--:(E3) only for operator names ending in a colon (:) Pitfalls: infix: can only use infix style if 1 argument (not two) there is also prefix and postfix style note that op: - can't have 2 arguments - can't be a function (i.e., an object, must be a method name) but the name for an infix doesn't have to just be special charcters: can do 3.4 equals 5.2 ------------------------------------------ POSTFIX AND PREFIX METHOD CALL SUGARS Postfix calls: E op ==> e.g., a length ==> a.length Prefix calls: - E ==> E.- + E ==> E.+ ! E ==> E.! ~ E ==> E.~ e.g., - sin(3) ==> sin(3).- ------------------------------------------ Q: What would you guess the desugaring for a postfix op would be? ... ==> E.op can't use arbitrary function or method name prefix as in Haskell: length xs // wrong, use length(xs) Just the 4 given prefix operators, no others! *** object creation ------------------------------------------ OBJECT CREATION Simple constructor calls: new C() new D(x, y) More complex forms later (templates) ------------------------------------------ Can do mixing in and overriding at instantiation time (as in Java anonymous classes), discussed later... Detail (skip): It seems that new C works the same as new C() if the class has a default constructor, as all the following is legal: package misc; object ConstructorTests { val s: String = new String; val s2: String = new String(); class C1; val c: C1 = new C1; val c2: C1 = new C1(); class C3() {}; val c3: C3 = new C3; val c4: C3 = new C3(); class C5(x: Int) { def this() = this(0); } val c5: C5 = new C5; val c6: C5 = new C5(); } *** assignments ------------------------------------------ ASSIGNMENT Primitive - assignment x = E Sugars x = E ==> x.f = E ==> a(i,j) = E ==> ------------------------------------------ ... x_=(E) ... x.f_=(E) ... a.update(i,j,E) Q: Can all assignments be interpreted as method calls, or must some be primitive? *** pattern matching ------------------------------------------ PATTERN MATCHING Uses match method: xs match { case Nil => 0; case x :: xs if e == x => 1 + count(e, xs); case x :: xs => count(e, xs); } ls match { case List(x, y, xs @ _ *) ==> ...; case List(1, x@(('a'|'b')+),y,_) ==> ...; } ------------------------------------------ can use _ as in Haskell to ignore (wild) x: pattern to bind a variable x @-bindings as in Haskell also * and + as in regular expressions | as in regular expressions ? for optional preceeding pattern (Most of these pattern operators are means of combination) Based on the match method in class Any Q: If match is a method, what argument type does it take? (T0) => T1, for some types T0 and T1 Q: So what is the type of a block of case clauses? such a function type So match is a sugar, and so is case *** exceptions ------------------------------------------ EXCEPTIONS (AS IN JAVA or C#) Creation: new IllegalArgumentException() Throwing: throw new IllegalArgumentException() Catching: try { S } catch E try { S } finally E Sugar: try { S } catch E1 finally E2 ==> try{ try { S } catch E1} finally E2 ------------------------------------------ The object thrown has to be a subtype of the type Throwable. *** Return expressions ------------------------------------------ RETURN Returning: return E can only be used inside a method or function ------------------------------------------