Tuesday, November 8, 2011

Reading scala's non-alphanumeric syntax

Welcome to Scala for Quants, the sporadic rants of a newbie. As for the language, Scala By Example is Odersky's nice introduction. The Scala Tour is a good primer on traits amongst other things which will get OO people off and running if you don't care for the functional aspects. (Traits are the major, or minor, departure from Java and C++ depending on how you look at it - justified here in the context of the long running inheritance debate).

Scala is pretty easy to read for the most part but what tripped me up at first was the non-alphanumeric syntax. My expanding cheat sheet: 

1. On some uses of  => 
  • ()=>B,  =>B define functions with no arguments equivalent to Function0[B]
  • x: =>A denotes a call-by-name parameter when in a function (see pass-by-name), or simply a declaration of a variable x returning A that must be called without parentheses. It is the same thing. 
  •  case 0=>, case i:Int =>, case Foo(a,b)=>, case Foo(a,b) if a==b => appear in match statements including those pattern matching case classes.  
  • import java.util{Date=>UDate} imports and renames java.util.Date. 
2. On some uses of _ 

"I don't really have a good conception of what wildcards are" - Martin Odersky (interview)
  • import.java_util{Date=>_} will exclude a symbol from import
  • case _ is the default in a match statement (c.f. "otherwise")
  • Characters +,-,! and ~ can be used as prefix operators in any class by defining unary_+ etc
  • var y:Int = _  is a default initial value. Without the wildcard you will be declaring an abstract variable (see abstract types in the Scala Tour)
  • case <body>{b @ _*}</body> =>  is an example of matching multiple elements in an case statement embedding XML (see Jim McBeath's primer)
  • _3 can be used to access the 3'rd element of a tuple, for example  x._1
  • Existential types. A wildcard in a type binds to the closest enclosing type application (see scala-lang) so that List[_] is equivalent, for example, to List[T] forSome {type T }. 

 3. On some uses of :, ::, ::: 

  • In declarations. var a: Int = 7, val n = 5, val n:Int  define mutable, immutable and abstract variables respectively. 
  • These also may be used in match statements, as in case: i:Int, and function declarations, as in def(i:Int)
  •  x: =>A denotes a call-by-name parameter when in a function (see pass-by-name), or simply a declaration of a variable x returning A that must be called without parentheses. It is the same thing.
  • 1::List(2,3) is the cons operator that prepends and element to a list, as explained in scala list examples
  • oneList:::twoList is list concatenation
4. On some uses of <-,  <:, <%, :>


  • for (n <- 0 to 6; e = n%2; if e==0 ) yield n*n  
  • for ((a,b) <- list) yield a+b
  • for (x <- 0 to 4; y <- 0 until 3) yield (x,y) 
  • class Set[A <: Ordered[A]] is an upper bound 
  • trait Set[ A <% Ordered[A]]  is a (weaker) view bound indicating that A must be convertible by an implicit conversion

5. On some uses of % 
  • T<%U means type U is a view bound for T, as above.
6. On use of /: 
7. On use of * 
  •  def printf(format:String, args:Any*): String  is an example of the use of Vararg parameters
8. On some uses of + 
  • class Stack[+A]  {   indicates that subtyping is covariant in that parameter
9. On some uses of #::, #:::

  • fibs: Stream[BigInt] = BigInt(1) #:: BigInt(2) is an alternate way to build streams (see Stream docs) consWrapper is an implicit def adding #:: for cons and #::: for concat

References & further reading

In this reminder of the syntax I'm borrowing heavily from this already terse syntax primer by Jim McBeath. As Jim notes, symbol names can use  :, \, *, +, ~ and pretty much whatever you want, but the precedence is defined by the first character. See also the Scala cheat sheet and Scala API




3 comments:

  1. Hi, I was just reading through this guide and I think it's very helpful (especially the section on "_", that thing is crazy...)

    I have one minor correction: you say that "%" is used to create temporary variables inside "for"... I don't think this is correct. The sample you showed is just creating a new variable, "e", with value "n mod 2", so if e == 0, n is even, e == 1, n is odd. I think this is why the variable is called "e" - it stands for "even". It is then checked for equality to 0 in order to filter the list to only even numbers. The "for" comprehension just allows you to leave out "val" when declaring values inline, which is why the "e" appears to come out of nowhere.

    ReplyDelete
  2. Great, I was looking for a primer. Peter, are you doing the coursera course?

    ReplyDelete