Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
165 lines (124 sloc) 5.71 KB

Invitation to Scala

Michael Bar-Sinai

Tech talk at the IQSS@Harvard 2013-06-27

  1. Intro

    • Based in part on Scala for the impatient by Cay Horstmann, Scala for java programmers tutorial at Typesafe.com, and Mayer Goldberg's advanced programming class at BGU.
    • To get the full experience, have a scala REPL ready. It's available from the command line after you insall scala.
    • Get scala at: http://www.scala-lang.org
  2. Presentation:

    1. 10k feet view of scala
      • clean design (e.g. map is a type of a collection)
      • No statements - just expressions
      • Statically typed ("system language"), concise and friendly syntax ("scripting language")
    2. Odersky: Stop trying to make java better, and make a better java
    3. JVM: All your favorite libs are there
    4. Collections: cf Java’s Minimum API, maximum impact (i.e. no last() on lists)
    5. Lang Features: comprehensive type system, continuations, more
    6. Java: 1996, ruby: ... 1995, Python: 1989
  3. Procedural vs. Functional

    • philosophy, no wrong answers... or answer at all
    1. Procedural: Alan Turing
    2. Discourse: Data Crunching, “mechanical engineering mindset”, “Person in the Mailroom”
    3. Functional: Alonzo Church, Haskell Brooks Curry
      • a.k.a Lambda Calculus.
      • plumbing mindset
    4. State vs. concurrency, abstraction over processing unit
    5. Hype alert
    6. Question: Where's OOP on this?
  4. REPL into

    • try: 1.to(10), 1 to 10

    • val vs var: vals - values - can't change. vars - variables - can.

    • Function definitions, unicode identifiers def sum( i:Int* ):Int = { return i.sum }, we can call this function "∑"

    • Arrays are functions IntT. Maps are similar.

        val array = Array(1,2,3)
        array(2)
        res0: Int = 3
      

    Note that we don't use [] but (). This is more mathematical and less hardware oriented.

    • Basic string operations: *, format
    • Example for clean design: String are sequences of characters. Show size as well as length, and str(idx)
      • splitAt. Present the Tuple data type
  5. How long is the longest English word

    1. Get the wordset.
      val words = io.Source.fromFile("/usr/share/dict/words").getLines.toSet
      This is the path in OSX, on other systems it may be on a different path.

    2. Let's take a proc-ish for loop and morph it into functional form

       var maxLen = 0
       for ( w <- words ) {
       	if ( maxLen < w.length ) {
       		maxLen = w.length
       	}
       }
       println( "maxLen is %d".format(maxLen) )
      
      • In scala:

        words.map( (w:String) => { w.length } ).max

      • No need for the braces, really, since it's just one line

        words.map( (w:String) => w.length).max

      • words is a set of Strings, so clearly w is a string, no need to state its type explicitly

        words.map( (w) => w.length )

      • We only use w once, why name it? We can use the _ magic char:

        words.map( _.length ).max

      • Note how this "tells the story better" than the for loop.

    3. other basic ops: filter, splitAt, zip

    4. cf. Java's "Min API Max Impact" design philosophy, vs Scala's "max API max Impact" approach

    5. print longest words:

       words.groupBy( _.length ).maxBy( _._1 )._2.foreach( println(_) )
      
    6. Parallel processing

      • subset the words - it's going to take a while otheriwse.

          val subset = words.filter( _ => scala.util.Random.nextDouble <= 0.10 )
        
      • subset.map( w => (w, subset.filter( _.startsWith(w)) ) )

      • parallel version: we add .par to allow for parallel processing. This is possible as the above process does not mutate shared state.

          subset.par.map( w => (w, subset.filter( _.startsWith(w)) ) )
        
      • also mention lazy view - returns a collection that calculates the values when requested.

    7. find word merges ("what shall we stream?")

       def unmerge( w:String ) = (1 until w.length).map( w.splitAt(_) ).
       						   filter( t => (words contains t._1) && (words contains t._2) )
      

      words: helloworld butterfly fortoff

    8. List Actions (slide): fold, reduce, aggregate

      • Short list into of 1 :: Nil, "a" :: 2 :: Nil etc. Note that ops that end with : are right-associative. So 1 +: list is invoking method +: of list, with parameter 1, as in list.+:(1).

      • File: fold.scala

      • sample: break string into char-non-char

          import java.lang.Character._
        
          def break( w:String ) = w.foldLeft[List[String]](Nil)(
              (l,c) => {
                  if ( l.isEmpty ) c.toString :: Nil
                  else if ( isLetter(l.last.last) == isLetter(c) )
                          l.dropRight(1) :+ l.last + c
                      else
                          l :+ c.toString
                  })
        
  6. Expressions as refined story tellers

    • Code as prose (not poetry!)
    • Different ways to tell the story.
  7. Concise class syntax

    1. File: classes.scala.
    2. Differences, mutability, functions with no () for getters. Convention no () => no mutation
    3. The blurring of method invocation vs field access
    4. On 2nd slide: name_= has no “=” => void return type (Unit)
  8. Traits and multiple inheritance

    • File: multiple-inheritance.scala (must)
    • Mixing and type creation on the declaration point
    • order matters
  9. No static, use Objects and companion objects

    • File: objects.scala
  10. Pattern matching

    • better way to tell the story
    • Almost Declarative
  11. Option[T] - as patten matching, as a collection of one

    • REPL:

        var map = Map('a->1, 'b->2, 'c->3)
      
    • Show map('a) map('c) and get() versions.

    • Also, show isEmpty and isDefined, and foreach

    • Finally, n.getOrElse(v)

  12. Function composition, Currying

    • File: functional.scala

    • Multi-parameter functions are syntactic sugar(!!!!)

    • example from Play!2 fwk

    • REPL:

        val mult3 = encache( logWhen( _*3, "Multiplying") )
        mult3(4)
        mult3(4)
      
  13. (Slides to end)