Transcript
Page 1: Starting with Scala : Frontier Developer's Meetup December 2010

Derek Chen-BeckerDerek Chen-BeckerSenior Network EngineerSenior Network Engineer

CPI CorporationCPI Corporation

Starting with ScalaStarting with Scala

Frontier Developers' MeetupFrontier Developers' MeetupDecember 9December 9thth, 2010, 2010Boulder, COBoulder, CO

Page 2: Starting with Scala : Frontier Developer's Meetup December 2010

Scala's Pedigree

Created by Martin Odersky (EPFL), of GJ, and later Javac v5 fame

Page 3: Starting with Scala : Frontier Developer's Meetup December 2010

Scala's History

Jan 04 Jan 05 Jan 06 Jan 07 Jan 08 Jan 09 Jan 10

1.1.

1.0

1.2.

0.0

1.3.

0.2

1.4.

0.0

2.1.

0 2.2.

02.

3.0

2.4.

02.

5.0

2.6.

0 2.7.

0

2.8.

0

2.8.

1

Scala History

2.7.1 - 2.7.7

Page 4: Starting with Scala : Frontier Developer's Meetup December 2010

More Info on Scala

Home page: http://www.scala-lang.org/Excellent community

[email protected]://chat.freenode.net/scalahttp://scala.sygneca.com/ (Wiki)

Page 5: Starting with Scala : Frontier Developer's Meetup December 2010

Scala in Print

Page 6: Starting with Scala : Frontier Developer's Meetup December 2010

Scala in the Real World

Page 7: Starting with Scala : Frontier Developer's Meetup December 2010

Scala and the JVM

Compiles to 100% Java BytecodeGenerally works flawlessly with JavaLeverages JIT: performance ±5% of Java

Full access to existing Java ecosystemCLR (.Net) port in progress

Page 8: Starting with Scala : Frontier Developer's Meetup December 2010

About This Talk

Scala 2.8.0+Significant changes to libraryI'm still coming up to speed on them

This is not a lecture

Page 9: Starting with Scala : Frontier Developer's Meetup December 2010

Act INo Time Like the Present

Page 10: Starting with Scala : Frontier Developer's Meetup December 2010

The Scala REPL

Read, Evaluate, Print, LoopYou need a JVM (1.6+ preferred) with “java” in your path or JAVA_HOME setDownload the latest binaries from http://www.scala-lang.org/downloadsUnpack wherever, go to bin subdirectoryType “scala<enter>”

Page 11: Starting with Scala : Frontier Developer's Meetup December 2010

Play Along at Home!

http://www.simplyscala.com/

Page 12: Starting with Scala : Frontier Developer's Meetup December 2010

Act IISo, What is Scala?

Page 13: Starting with Scala : Frontier Developer's Meetup December 2010

Three Very Common Keywords

val – defines an immutable value or referencevar – defines a mutable valuedef – defines a function/method

Page 14: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Concerned with Mutability

Immutable data structures reduce (but not eliminate) concurrency issuesCombined with actors make a powerful approach to parallel tasksStrong library and language support

Page 15: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Strongly Typed...

val foo : Int = 12

var bar : String = "twelve"

def baz (in : Int) : Double = in.toDouble

Page 16: Starting with Scala : Frontier Developer's Meetup December 2010

...But Can Usually Figure Types Out

val foo = 12

var bar = "twelve"

def baz (in : Int) = in.toDouble

Page 17: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Generic

val primes : List[Int] = List(2,3,5,7,11)

scala> primes.grouped(2).toListres16: List[List[Int]] = List(List(2, 3), List(5, 7), List(11))

Page 18: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Object­Oriented

class Foo { def bar () = { "bat" }}

val f = new Foo

Page 19: Starting with Scala : Frontier Developer's Meetup December 2010

I Mean Really Object­Oriented

scala> (12.5).min(47) res17: Double = 12.5

scala> 3825.toHexStringres18: String = ef1

scala> '5'.isWhitespaceres19: Boolean = false

Primitives are treated as 1st class objects

Page 20: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Functional

val greet = (name : String) => "Hello, %s!".format(name)

greet(“Fred”)res27: String = Hello, Fred!

val greet = "Hello, %s!".format(_ : String)

Page 21: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Functional Everywhere

def doubleMe (f : () => Any) { println(f()); println(f());}

scala> doubleMe(System.nanoTime) 15885045173037341588504517365296

Page 22: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Closurific

def counter (name : String) = { var i = 0; { () => i += 1 name + ":" + i } }

Page 23: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Concise...

public class Person { private String name; private int age;

public Person(String name, int age) { super(); this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public void setAge(int age) { this.age = age; }

public int hashCode() {...} public String toString() {...} public boolean equals() {...} }

VScase class Person(name : String, var age : Int)

Page 24: Starting with Scala : Frontier Developer's Meetup December 2010

...But Maintains Uniform Access

case class Person(val name : String, private var curAge : Int) { def age = curAge def age_= (a : Int) { curAge = a }}

Page 25: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is DSL­Friendly (be reasonable)

class Vector[T](data : Array[T]){ def + (that : Vector[T]) = {} def - (that : Vector[T]) = {} ... def ⊗ (that : Vector[T]) = {}}

val product = A B⊗val product = A. (B)⊗

Page 26: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is Optional

val exists: Option[Int]= Some(42)val notHere: Option[Int] = None

scala> exists.map(_ * 2).getOrElse(12) res0: Int = 84

scala> notHere.map(_ * 2).getOrElse(12)res1: Int = 12

Page 27: Starting with Scala : Frontier Developer's Meetup December 2010

Scala Likes Tuples (Heterogeneous)

scala> val state = (12, "Empty", RED)state: (Int, java.lang.String, java.awt.Color) = (12,Empty,java.awt.Color[r=255,g=0,b=0])

scala> val (count, description, color) = statecount: Int = 12description: java.lang.String = Emptycolor: java.awt.Color = java.awt.Color[r=255,g=0,b=0]

Page 28: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is XML­Friendly

def personToXml(p : Person) = <person name={p.name} age={p.age.toString} />

Page 29: Starting with Scala : Frontier Developer's Meetup December 2010

Scala is High­Level...

val people = List(Person("Fred", 30), Person("Ted", 25), Person("Ed", 41))

people.foreach (println)

Page 30: Starting with Scala : Frontier Developer's Meetup December 2010

Letting You Get to the Real Work

// One line of magic...implicit val orderPeople = Ordering.by((_:Person).age)

// ...allows powerful constructsval (oldest,youngest) = (people.max,people.min)

Page 31: Starting with Scala : Frontier Developer's Meetup December 2010

Act IIIScala OO Fundamentals

Page 32: Starting with Scala : Frontier Developer's Meetup December 2010

Packages

package net.foo { ...}

package net.foo

Page 33: Starting with Scala : Frontier Developer's Meetup December 2010

Imports

import java.io.Fileimport java.net._import java.awt.{Image, Color => JCol, Dialog => _}

Page 34: Starting with Scala : Frontier Developer's Meetup December 2010

Packages Nest...

package net.foo==

package net { package foo { ... }}

Page 35: Starting with Scala : Frontier Developer's Meetup December 2010

Sometimes in Unexpected Ways (< 2.8)

package net.foo { import java.net.URL}

Page 36: Starting with Scala : Frontier Developer's Meetup December 2010

The Scala OO Quadfecta

class object

trait

case class/object

Page 37: Starting with Scala : Frontier Developer's Meetup December 2010

Traits Are Good

Somewhat analogous to interfaces...

trait Comparable[T] { def < (that : T) : Boolean def <= (that : T) : Boolean def > (that : T) : Boolean def >= (that : T) : Boolean}

Page 38: Starting with Scala : Frontier Developer's Meetup December 2010

Traits are Really Awesome

...But they can carry implementation

trait Comparable[T <: Comparable[T]] { self : T => def < (that : T) : Boolean def <= (that : T) = this < that || this == a def > (that : T) = that < this def >= (that : T) = that <= this}

Page 39: Starting with Scala : Frontier Developer's Meetup December 2010

Traits can be Composed

trait Atrait Btrait C

class Base extends A with B with C

Page 40: Starting with Scala : Frontier Developer's Meetup December 2010

Class Linearization : Base Trait

trait Pet { def greeting : String def eat() : Unit}

Page 41: Starting with Scala : Frontier Developer's Meetup December 2010

Class Linearization : Extension Traits

trait Dog extends Pet { def greeting = "Woof" def eat() {...}}

trait Mute extends Pet { override val greeting = ""}

Page 42: Starting with Scala : Frontier Developer's Meetup December 2010

Class Linearization : Composition

class Dingo extends Dog with Mute

scala> (new Dingo).greetingres0: java.lang.String =

Page 43: Starting with Scala : Frontier Developer's Meetup December 2010

Scala Objects

“An object definition defines a single object of a new class” (Scala Reference, §5.4

object Friendly { var publicInt = 0 def hi = println("Hi!")}

Page 44: Starting with Scala : Frontier Developer's Meetup December 2010

Objects hold Static Methods

object MyApp { def main (args : Array[String]) { ... }}

Page 45: Starting with Scala : Frontier Developer's Meetup December 2010

Objects are Scoped VM Singletons

class Outer { object Inner { var foo = "foo" }}

Page 46: Starting with Scala : Frontier Developer's Meetup December 2010

Objects as Factories

object Person { def apply(name : String, age : Int) : Person = new Person(name,age)}

val fred = Person("Fred", 20)

Page 47: Starting with Scala : Frontier Developer's Meetup December 2010

Objects as Factories, Continued

object Person { ... def apply(name : String) : Person = new Person(name, 1)}

val babyFred = Person("Fred")

Page 48: Starting with Scala : Frontier Developer's Meetup December 2010

Named and Default Arguments

object Person { def apply(name : String, age : Int = 1) : Person = new Person(name,age)}

val fredBaby = Person(name = "Fred")

Page 49: Starting with Scala : Frontier Developer's Meetup December 2010

Case Classes (and Objects)

case class Car (name : String, gears : Int)

scala> val myCar = Car("Corolla", 4)myCar: Car = Car(Corolla,4)

scala> myCar.name res0: String = Corolla

Page 50: Starting with Scala : Frontier Developer's Meetup December 2010

Case Class Automation

Factory method (apply)toStringhashCodeequals (and therefore ==)Constructor params become vals, can be turned into vars

Page 51: Starting with Scala : Frontier Developer's Meetup December 2010

Case Class Bonii : Copy

scala> val myCar = Car("Corolla", 4)myCar: Car = Car(Corolla,4)

scala> val myOtherCar = myCar.copy(name = "Forester")myOtherCar: Car = Car(Forester,4)

Page 52: Starting with Scala : Frontier Developer's Meetup December 2010

Case Class Bonii : Extraction

scala> val myCar = Car("Corolla", 4)myCar: Car = Car(Corolla,4)

// “_” here means “don't bother”scala> val Car(_,gears) = myCargears: Int = 4

Page 53: Starting with Scala : Frontier Developer's Meetup December 2010

Act IVFunctional is Your Friend

Page 54: Starting with Scala : Frontier Developer's Meetup December 2010

Start With Some Basic Functions

foreachmapflatMapfilterexiststakeWhiledropWhile

Page 55: Starting with Scala : Frontier Developer's Meetup December 2010

Composing Functions == Power

people.flatMap(first => people.filter(_ != first). map(List(first,_)))

Page 56: Starting with Scala : Frontier Developer's Meetup December 2010

For Comprehensions

for (first <- people; second <- people if first != second) yield List(first,second)

Page 57: Starting with Scala : Frontier Developer's Meetup December 2010

Currying

def scaler (factor : Int) (value : Int) = factor * value

val times2 = scaler(2) _times2(12) // == 24

Provide N argument lists, but only use 1 to N-1 of them to define a new function

Page 58: Starting with Scala : Frontier Developer's Meetup December 2010

“By Name” Arguments

def myWhile (condition : => Boolean) (f : => Unit) { if (condition) { f; myWhile(condition)(f) }}

Page 59: Starting with Scala : Frontier Developer's Meetup December 2010

“By Name” Use Case : Logging

if (logger.isDebugEnabled) { logger.debug("Foo: " + foo)}

Page 60: Starting with Scala : Frontier Developer's Meetup December 2010

“By Name” Use Case : Logging

if (logger.isDebugEnabled) { logger.debug("Foo: " + foo)}

THIS SUCKS

Page 61: Starting with Scala : Frontier Developer's Meetup December 2010

“By Name” to the Rescue

def debug (msg : => String) { if (this.debugEnabled) { println(msg) }}

https://github.com/weiglewilczek/slf4s

Page 62: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Switch on Steroids

“case _” here is the default casedef literalMatch (in: Any) { in match { case 1 => doBar("One") case "test" => doBar("test") case 'x' => doBar("x") case 2.2f => doBar("float") case _ => doBar("lemon curry?") }}

Page 63: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Alternate Matches

Using “|” allows multi-match cases

def literalMatch (in: Any) { in match { case 1 | 2 | 3 => doBar("One to three") case "this" | "that" => doBar("the other") case _ => doBar("lemon curry?") }}

Page 64: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : XML

def xmlMatch (in : Any) = in match { case <people>{bar @ _*}</people> => bar.foreach(println) case _ => // NOOP}

Page 65: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Case Classes

def caseMatch (a : Any) = a match { case Person(name, age) => println("%s is %d”. format(name,age))}

Page 66: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Type Matches

def typeMatch (in: Any) { in match { case i : Int => doBar("Int : " + i) case s : String => doBar(s) case _ => // NOOP }}

Page 67: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Generics

Erasure is not your friend

def typeMatch (in: Any) { in match { case ls : List[String] => doBar("danger!") case li : List[Int] => doBar("never happens") case _ => // NOOP }}

Page 68: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Guards

def guardMatch (in: Any) { in match { case i : Int if i > 12 && i < 47 => doBar("Int : " + i) case _ => // NOOP }}

Page 69: Starting with Scala : Frontier Developer's Meetup December 2010

Pattern Matching : Generics Workaround

Like duck tape : ugly, but effective

def typeMatch (in: Any) { in match { case ls : List[_] if ls.forall(_.isInstanceOf[String]) => doBar("Strings!") case li : List[_] => doBar("Some kind of List") case _ => // NOOP }}

Page 70: Starting with Scala : Frontier Developer's Meetup December 2010

More More Info on Scala

Home page: http://www.scala-lang.org/Excellent community

[email protected]://chat.freenode.net/scalahttp://scala.sygneca.com/ (Wiki)


Top Related