DOSUG Scala Basic Concepts 0805

32
Scala Basic Concepts Tom Flaherty - Axiom Architectures, LLC [email protected] The Scala Approach Be completely interoperable with Java. Combine OO object-oriented and FP functional programming concepts. Improve on Java with: A uniform class hierarchy. Pattern matching and higher-order functions. Novel ways to abstract and compose programs. Open source Has been available since Jan 2004. Production version 1.0 since 2006 Currently: > 2000 downloads per month.

description

Scala Syntax Pattern Matching Math Expressions Language Comparison Applicability

Transcript of DOSUG Scala Basic Concepts 0805

Page 1: DOSUG Scala Basic Concepts 0805

Scala Basic Concepts

Tom Flaherty - Axiom Architectures, [email protected]

The Scala Approach• Be completely interoperable with Java.• Combine OO object-oriented and FP functional programming concepts.• Improve on Java with:

• A uniform class hierarchy.• Pattern matching and higher-order functions.• Novel ways to abstract and compose programs.

• Open source• Has been available since Jan 2004.• Production version 1.0 since 2006• Currently: > 2000 downloads per month.

www.princexml.com
Prince - Personal Edition
This document was created with Prince, a great way of getting web content onto paper.
Page 2: DOSUG Scala Basic Concepts 0805

Scala is Interoperable• Scala programs interoperate seamlessly with Java class libraries

• Method calls.• Field accesses.• Passing multi-dimensional arrays - great for Java scientific libraries.• Class inheritance - Scala can extend Java classes.• Interface implementation.• Reflection and Serialization from a JVM perspective.

• The object reflective database db4o works in Scala.

• Annotations• ScalaDoc works like JavaDoc

• All work as in Java.• Scala programs compile to JVM byte codes and are distributed as Jar files.

Page 3: DOSUG Scala Basic Concepts 0805

First Exampleblue - Keywords primitives String Arraypurple - Imported Scala and Java classesbold - Declared classes and methodsgreen - Constants and string literals

• Scala’s syntax resembles Java’s, but there are also some differences.object Example1 // Singleton all methods and fields static{

def main( args:Array[String] ) : unit = // Same as main( String[] args ) in Java{ // Type Array[String] instead of String[] s

val b = new StringBuilder() // Create a Java StringBuilderfor( i <- 0 until args.length ) // Scala for loop does not specify increment{

if( i > 0 )b.append(" ")

b.append( args(i).toUpperCase ) // indexing (i) instead of [i]}println( b.toString )

}}

object Example2 // A functional rewrite of Example1{

def main( args:Array[String] ) : unit ={

println( args, map(_.toUpperCase), mkString " " ) // map applies toUpperCase}

}

Page 4: DOSUG Scala Basic Concepts 0805

Syntax• Scala Keywords - behave for the most part like their Java counterparts

abstract case catch class def do else extends false final finallyfor forSome if implicit import lazy match new null object overridepackage private protected requires return sealed super this throwtrait try true type val var while with yield_ : = => <<: <% >: # @

• Class Declarationstrait BaseTrait { ... }abstract class AbstractClass( arg1:atype, ... ) extends BaseTrait { ... }class ConcreteClass( arg1:atype, ... ) extends AbstractClass( arg1:atype, ... ) { ... }class MixinClass( arg1:atype, ... ) extends AbstractClass with Trait1 { ... }

• Class arguments specify the primary constructor.• The class body is executed at instance creation.• Primary arguments can be passed up its super class.• Other constructors are declared by def this( arg1:atype, ... ) = { ... }• Traits do not have constructors therefore do not have arg lists

• Method Field Declarationsdef method( arg1:atype, ... ) : rtype = { } // Method declarationvar field:type = value // Mutable fieldval field:type = value // Immutable field often initialized by class argument

Page 5: DOSUG Scala Basic Concepts 0805

object• Classes in Scala cannot have static members.• Instead, Scala has singleton objects which is initialized the first time it is accessed.• A companion object has the same name as a class and is defined in the same file.• A class and its companion object can access each other’s private members.• A class and its companion object are mapped as a Java class in byte codes.object Element // A companion factory object which hides subclass elements{// Factory methods

def apply( x:double ) : Element = new DoubleElement( x )def apply( c:char, width:int, height:int ) : Element = new UniformElement( c, width, height)def apply( line:String ) : Element = new LineElement( line )

}

class Element {...} // Companion classclass DoubleElement( x:double ) extends Element {...}class UniformElement( c:char, width:int, height:int ) extends Element {...}class LineElement( line:String ) extends Element {...}

// The Element.apply factory methods are called to instanciate the subclassesval element1 = Element( 0.5 )val element2 = Element( 'c', 50, 100 )val element3 = Element( "line" )

Page 6: DOSUG Scala Basic Concepts 0805

A Uniform Class HierarchyAny

AnyVal - Scala's base class for all Java primitives and unitdouble float long int short char byte boolean unit

AnyRef (java.lang.Object)String (java.lang.String)

(all other Java Classes ...)(all other Scala Classes ...)Iterable (base Class for Scala collection classes)

SeqArrayList

scala.Null is treated as a subtype of all AnyRef classesscala.Nothing is treated as a subtype of all Any classes

• Primitives are treated as "first class objects" and not wrapped into classes.• A a major step to Scala's strong typing and to Parameterized Types• a:Array[int](len) is mapped to int[len] a• Java's primitive class wrappers are not needed, can be accessed java.lang.Integer• The Scala compiler intelligently applies base methods to primitives.• 5.toString "5".toInt

Page 7: DOSUG Scala Basic Concepts 0805

Traitstrait Ordered[A]{

def compare( a:A ) : int // Abstract method Thin partdef < ( a:A ) : boolean = compare(a) < 0 // Concrete methods Thick partdef > ( a:A ) : boolean = compare(a) > 0def <= ( a:A ) : boolean = compare(a) <= 0def >= ( a:A ) : boolean = compare(a) >= 0

}

• Similar to interfaces in Java• Define object types by specifying the signature of the supported methods.• A class can mix in any number of traits.• The mixin class can be assigned to or passed as any if its trait types.• Traits can not be constructed so traits do not have default constructor arguments.• Traits with purely abstract methods map directly to Java interfaces.

• Unlike Java, Scala also has concrete implementations of methods in traits.• The Thick and Thin Approach to Trait Design

• First define a small number of abstract methods - the Thin part.• Then implement a potentially large number of concrete methods - the Thick part.

• All implemented in terms of the abstract methods.• Then the mixin class:

• Implements the thin abstract methods.• Has access to all the thick concrete methods.

• Scala avoids the Diamond of Death with:• The compiler uses the override keyword to identify methods.• Stackable modifications are automatically implemented in the compiler by linearization.

• The interpretation of super is deferred, where as in other languages it is fixed.• The method called comes from the last trait mixed in.

Page 8: DOSUG Scala Basic Concepts 0805

• Parameterized Typestrait Option[A] {} // any class, trait or method can be parameterizedclass MyClass[A,B] // with [type] appended to its name{

type S = String // Redefines type for this classdef polyMeth[C]( i:int ) : String // a polymophic methoddef lowBound[Q:>A]( i:int ) : String // Requires that S be supertype of A

} // Scala removes parameterized wildcards.

• Closures• S => T is mapped to the trait Function1[S,T] { def apply(x:S) : T }• ( d:double, i:int ) => double // a closure signature

• Tail Recursiondef approximate( guess:double ) : double ={

if( isGoodEnough(guess) ) // stopping criteria essential for recursionreturn guess

else // approxmiate must be the last statementapproximate( improve(guess) ) // for Scala to promote tail recursion

} // The JVM limits other optimizations

• Equality== structural equality calls equals()eq referencial equality

• Tuple - Groups things with parentheses for multiple returns and patterns.val tup = ( 1, "two", 3.0, obj ) // tup._1 == 1, tup._2 equals == "two" // One based

• Controlif else while do {} while // All behave as in Java except for

Page 9: DOSUG Scala Basic Concepts 0805

For• For Loops

• A generator <- specifies the enumerator that is typed from the source.• An if statement in a for serves as filter. Multiple generators and filters can be specified

val list:List[String] = new List("aa", "bb", "cc")val array:Array[double] = new Array(1.0, 2.0, 3.0)for( s <- list ) {} // iterate with String elementsfor( d <- array ) {} // iterate with double elementsfor( i <- until array.length ) {} // index through arrayfor( i <- 0 to 9 ) {} // index 0 to 9 inclusivefor( i <- 0 until 10; if( i%2==0 ) {} // index evens 0 2 4 6 8 with a filtervar i = 0 // Java's for( int i = 0; i < 10; i++ )while( i < 10 ) // Scala requires a while

{ ...; i += i } // to specify the increment

• For Comprehensions work with collections that yield new collections• map flatmap filter are the basic higher order functions in collections.

// map apply a function to all elements in List[A] and return a new List[B]def map[A,B]( list:List[A], func:A=>B ) : List[B] =

for( e <- list ) yield func(e)

// flatmap perform map and should an element be a list concatenate it into one flat listdef flatMap[A,B]( list:List[A], func: A => List[B] ) : List[B] =

for( x <- list; y <- func(x) ) yield y

// filter return a new list containing only those elements that are true for predicate preddef filter[A]( list:List[A], pred:A=>boolean ) : List[A] =

for( x <- list if pred(x) ) yield x

// A comprehension can have multiple loops. Returns List(2,3,4,6).for( val e1 <- List(1,2); val e2 <- List(2,3) ) yield e1 * e2

Page 10: DOSUG Scala Basic Concepts 0805

Performance• How large is the overhead introduced by the Scala to Java?• At first sight the Scala adds boilerplate to byte codes with:

• Forwarding method calls.• Ancillary objects.• Inner anonymous classes.

• Fortunately:• Modern JIT compilers remove the boilerplate.• So average execution times are comparable with Java’s.• However startup times are longer because of the number of class files generated.• Efforts are underway to reduce the number of class files.

Page 11: DOSUG Scala Basic Concepts 0805

The JVM as a Compilation Target• The JVM has turned out to be a good platform for Scala.• Important aspects:

• High-performance memory system with automatic garbage collection.• Aggressive JIT optimizations of function stacks

• Two wishes for a future version of the JVM:• More direct support for tail recursion optimization.• Extend the class file format with true support for inner classes.

Page 12: DOSUG Scala Basic Concepts 0805

ADTs - Algebraic Data Types• Functional languages have:

• Pattern matching.• Concise and canonical manipulation of data structures.• ADTs where data is accessed by deconstruction and pattern matching.

• OO theorists contend that:• ADTs violate the purity of the OO.• ADTs are not extensible.• Pattern matching breaks encapsulation.• Pattern matching violates representation independence.

• Scala's pattern matching provides:• Purity: All pattern cases are classes or objects.• Extensibility: You can define more cases elsewhere.• Encapsulation: Only selected parameters within case classes are revealed.• Representation Independence: Provided by extractors

Page 13: DOSUG Scala Basic Concepts 0805

Extractors• All extractors return Some[T] or None derived from Option[T]

• Multiple values are placed in a tuple [(String,String)]abstract class Option[+T]case class Some[T]( t:T ) extends Option[T]case object None extends Option[Nothing]

• Extractors are objects with unapply(...) methods.• unapply(...) is called implicitly to extract parameters for pattern matching.• Extractors examine internal parameters in a controlled fashion.• case classes automatically create extractors.• Java classes can be wrapped with extractors.object EMail extends String{

// The construction method (optional)def apply( user:String, domain:String ) : String = user + "@" + domain

// The extraction method unapply reverses construction// by pulling EMail apart into Strings

def unapply( str:String ) : Option[(String,String)] ={

val parts = str split "@"if( parts.length == 2 ) Some(parts(0),parts(1)) else None

}}

Page 14: DOSUG Scala Basic Concepts 0805

JSON Parsing• JSON Grammar in a simple EBNF form

str = StringLitdbl = NumericLitdat = obj | arr | str | dbl | "true" | "false" | "null"mem = str ":" dattop = obj | arrobj = "{" mem {"," mem} "}"arr = "[" dat {"," dat} "]"

• JSON Parserclass JSONParser extends StdTokenParsers with ImplicitConversions{

type Tokens = Lexer // Configure lexical parsingval lexical = new Tokenslexical.reserved ++= List( "true", "false", "null" ) // Keywordslexical.delimiters ++= List( "{", "}", "[", "]", ":", "," )

def str = accept("string", { case lexical.StringLit(n) => n} )def dbl = accept("number", { case lexical.NumericLit(n) => n.toDouble} )def dat : Parser[Any] = ( obj|arr|str|num|"true"^^^true|"false"^^^false|"null"^^^null )def mem = str ~ (":" ~> dat) ^^ { case x ~ y => (x,y) }def top = obj | arrdef obj = "{" ~> repsep( ent, "," ) <~ "}"def arr = "[" ~> repsep( dat, "," ) <~ "]" }

• Parsing Operators and Methods"..." literal rep(P) repetition * zero or more"...".r regular expression rep1(P) repetition + one or moreP ~ Q sequential composition repsep(P,Q) interleaved repetition zero or more.~> <~ squential ignore repsep1(P,Q) interleaved repetition one or moreP | Q alternative P^^F = F(R) apply function F to parsing result Ropt(P) optional ? P^^^ {} conversion

Page 15: DOSUG Scala Basic Concepts 0805

abstract class Expabstract class Exp extends

Ascii with Lambda with MathML with Calculate with Differentiate with Simplify{

// Implicit converts int and double to Num(n) for streamlined operator overloadingimplicit def int2Exp( i:int ) : Exp = Num(i.toDouble)implicit def dbl2Exp( d:double ) : Exp = Num(d)implicit def str2Exp( s:String ) : Exp = Var(s)

// An internal DSL consisting of operators from low to high precedencedef + ( v:Exp ) : Exp = Add(this,v) // this+vdef - ( v:Exp ) : Exp = Sub(this,v) // this-vdef * ( v:Exp ) : Exp = Mul(this,v) // this*vdef / ( v:Exp ) : Exp = Div(this,v) // this/vdef ~^ ( v:Exp ) : Exp = Pow(this,v) // this~^v // ~^ for high precedencedef unary_- : Exp = Neg(this) // -this

}

// ADTs pattern matchingcase class Num( n:double ) extends Exp // wrap double into an Expressioncase class Var( s:String ) extends Exp // wrap String into an Expressioncase class Add( u:Exp, v:Exp ) extends Exp // u + v binary opcase class Sub( u:Exp, v:Exp ) extends Exp // u - v binary opcase class Mul( u:Exp, v:Exp ) extends Exp // u * v binary opcase class Div( u:Exp, v:Exp ) extends Exp // u / v binary opcase class Pow( u:Exp, v:Exp ) extends Exp // u ^ v binary opcase class Neg( u:Exp ) extends Exp // -u unary opcase class Par( u:Exp ) extends Exp // (u) Parenthesescase class Dif( u:Exp ) extends Exp // Differentialcase class Err( e:String ) extends Exp // Error

Page 16: DOSUG Scala Basic Concepts 0805

object Parse// ........................... AcsiiMath ........................................// 1/x 1/(x+y) (w*x*y*z)/(x*y*z) (x+y)^3 a*x^2+b*x+c// x*dx d(u*v) v*du+u*dv

object Parse extends StdTokenParsers{

type Tokens = StdLexicalval lexical = new StdLexical

lexical.delimiters ++= List( "(",")","+","-","^","/","*" )lexical.reserved += ("d")

def NUM : Parser[Num] = NumericLit ^^ { (s:String) => Num(s.toDouble) }def VAR : Parser[Exp] = ident ^^ { (s:String) => variable(s) }def par : Parser[Exp] = "(" ~> exp <~ ")" ^^ { (u:Exp) => Par(u) } // (u) Par(u)def neg : Parser[Exp] = "-" ~ exp ^^ { case "-" ~ u => Neg(u) } // -u Neg(u)

def beg : Parser[Exp] = NUM | VAR | par | negdef pow : Parser[Exp] = beg * ( "^" ^^^ { (u:Exp,v:Exp) => Pow(u,v) } ) // u ^ vdef mul : Parser[Exp] = pow * ( "*" ^^^ { (u:Exp,v:Exp) => Mul(u,v) } ) // u * vdef div : Parser[Exp] = mul * ( "/" ^^^ { (u:Exp,v:Exp) => Div(u,v) } ) // u / vdef add : Parser[Exp] = div * ( "+" ^^^ { (u:Exp,v:Exp) => Add(u,v) } ) // u + vdef sub : Parser[Exp] = add * ( "-" ^^^ { (u:Exp,v:Exp) => Sub(u,v) } ) // u - vdef exp : Parser[Exp] = sub | failure("Ascii.Parse") // All Expressions and failure

Page 17: DOSUG Scala Basic Concepts 0805

object Parse (continued)def parse( str:String ) : Exp = exp( new lexical.Scanner(str) ) match{

case Success( expr, _ ) => exprcase Failure( msg, trc ) => Err( "Ascii.Parse Failure::" + str + "::" + msg )case Error( msg, trc ) => Err( "Ascii.Parse Error ::" + str + "::" + msg )case _ => Err( "Ascii.Parse Unknown::" + str + "::" )

}

def apply( str:String ) : parse( str ) // exp = Parse(str)

def variable( s:String ) : Exp ={

if( s.charAt(0)=='d' && s.length==2 )Dif(Var(s.charAt(1).toString)) // converts dx to Dif(x)

elseVar(s) // Otherwise Var(x)

}}

Page 18: DOSUG Scala Basic Concepts 0805

trait Calculatetrait Calculate{

this:Exp => // self type - this trait is an extension of Exptype Assign = String => doubleval NaN = Math.NaN_DOUBLE

// a is passeddef calc( a:Assign ) : double = this match{

case Num(n) => ncase Var(s) => a(s) //case Add(u,v) => u.calc(a) + v.calc(a)case Sub(u,v) => u.calc(a) - v.calc(a)case Mul(u,v) => u.calc(a) * v.calc(a)case Div(u,v) => div(a,u,v)case Pow(u,v) => Math.Pow( u.calc(a), v.calc(a) )case Neg(u) => -u.calc(a)case Par(u) => u.calc(a)case Dif(u) => NaNcase Err(u) => NaNcase _ => NaN

}

def div( a:Assign, u:Exp, v:Exp ) : double ={ var d = v.calc(a); return if( d==0.0 ) NaN else u.calc(a) / d }

}

Page 19: DOSUG Scala Basic Concepts 0805

trait Simplifytrait Simplify{

this:Exp => // self type - this trait is an extension of Exp

def sim( exp:Exp ) : Exp = exp match{

case Num(d) => expcase Var(s) => expcase Add(u,v) => add(u,v)case Sub(u,v) => sub(u,v)case Mul(u,v) => mul(u,v)case Div(u,v) => div(u,v)case Pow(u,v) => pow(u,v)case Neg(u) => Neg(sim(u))case Par(u) => Par(sim(u))case Dif(u) => Dif(sim(u))case Err(u) => expcase _ => exp

}def sim : Exp = sim(this) // Allows exp.sim to be called

def mul( u:Exp, v:Exp ) : Exp = (u,v) match // (u,v) is a tuple{

case( u, Num(1) ) => sim(u) // tuple patternscase( Num(1), v ) => sim(v)case( Num(a), Num(b) ) => Num(a*b)case _ => sim(u)*sim(v)

}

Page 20: DOSUG Scala Basic Concepts 0805

trait Simplify (continued)def div( u:Exp, v:Exp ) : Exp = (u,v) match{

case( u, Num(1) ) => sim(u)case( u, Num(0) ) => Err(u/Num(0))case( Num(a), Num(b) ) => Num(a/b)case _ => if(u==v) 1 else factor(noparen(u),noparen(v))

}def add( u:Exp, v:Exp ) : Exp = (u,v) match{

case( u, Num(0) ) => sim(u)case( Num(0), v ) => sim(v)case( Num(a), Num(b) ) => Num(a+b)case _ => sim(u)+sim(v)

}def sub( u:Exp, v:Exp ) : Exp = (u,v) match{

case( u, Num(0) ) => sim(u)case( Num(0), v ) => sim(-v)case( Num(a), Num(b) ) => Num(a-b)case( u, Neg(b) ) => sim( sim(u)+sim(b) )case _ => sim(u)-sim(v)

}def pow( u:Exp, v:Exp ) : Exp = (u,v) match{

case( u, Num(1) ) => sim(u)case( u, Num(0) ) => 1case( Num(1), v ) => 1case( Num(0), v ) => 0case( Num(a), Num(b) ) => Num(Math.Pow(a,b))case _ => sim(u)~^sim(v)

}}

Page 21: DOSUG Scala Basic Concepts 0805

trait Differentiatetrait Differentiate{

this:Exp =>

def dif : Exp = d(this)

def d( e:Exp ) : Exp = e match // All the math ADTs are shown here{

case Num(n) => 0 // Differential of a constant is zerocase Var(s) => Dif(Var(s)) // x becomes dxcase Add(u,v) => d(u) + d(v) // Add(d(u),d(v))case Sub(u,v) => d(u) - d(v) // Sub(d(u),d(v))case Mul(u,v) => v*d(u)+u*d(v) // Add(Mul(v,d(u)),Mul(u,d(v)))case Div(u,v) => (v*d(u)-u*d(v))/(v~^2)case Pow(u,v) => v * u~^(v-1) * d(u)case Neg(u) => -d(u) // Neg(d(u))case Par(u) => Par(d(u)) // Par(d(u))case Dif(u) => Dif(d(u)) // 2rd Difcase Err(u) => Dif(Err(e))

Page 22: DOSUG Scala Basic Concepts 0805

trait Differentiate (extended)case Ln(u) => d(u)/u // Div(d(u)/u)case LogB(u,r) => LogB(Ee,r)*d(u)/ucase Root(u,r) => d(u) / Par( r * Root(u,r) )case E(u) => E(u) * d(u)case Sqrt(u) => d(u) / Par( Sqrt(u) * 2 )case Sin(u) => Cos(u) * d(u)case Cos(u) => -(Sin(u) * d(u))case Tan(u) => -(Sec(u)~^2 * d(u))case Csc(u) => -(Csc(u)*Cot(u) * d(u))case Sec(u) => Sec(u)*Tan(u) * d(u)case Cot(u) => -(Csc(u)~^2 * d(u))case ASin(u) => d(u)/Sqrt( 1 - u~^2 )case ACos(u) => -(d(u)/Sqrt( 1 - u~^2 ))case ATan(u) => d(u)/Par( 1 + u~^2 )case ACot(u) => -(d(u)/Par( 1 + u~^2 ))case ACsc(u) => -(d(u)/Par(u*Sqrt( u~^2 - 1)))case ASec(u) => d(u)/Par(u*Sqrt( u~^2 - 1))case Itg(u) => ucase Vex(a) => Vex(exp).map( a => a.dif )case _ => Err(Dif(e))

}}

Page 23: DOSUG Scala Basic Concepts 0805

Runsa=6 b=3Cal::a+b 9Cal::a-b 3Cal::a*b 18Cal::a/b 2Cal::a^b 216Cal::a/0 NaN

Lam::(w*x*y*x)/(z*x*y) Div(Par(Mul(Mul(Mul(Var(w),Var(x)),Var(y)),Var(x))),Par(Mul(Mul(Var(z),Var(x)),Var(y))))Lam::(x+y)^3 Pow(Par(Add(Var(x),Var(y))),Num(3.0))

Dif::x*y y*dx+x*dy

Dif::x*y*z z*(y*dx+x*dy)+x*y*dzSim::x*y*z z*y*dx+z*x*dy+x*y*dz

Dif::x^3 3*x^(3-1)*dxSim::x^3 3*x^2*dx

Sim::(x+y)/(x+y) 1Sim::(x+y)^3/(x+y)^3 1Sim::(x+y)*(a+b)/(x+y) a+bSim::(x+y)/((x+y)*(a+b)) 1/(a+b)Sim::(w*x*y*z)/(x*y*z) wSim::(x*y*z)/(x*y*z*w) 1/wSim::(w*x*y)/(z*x*y) w/z

Page 24: DOSUG Scala Basic Concepts 0805

A Brief Look at Actors• Actor

trait Actor extends Thread with MailBox // A simplified representation or Actor{

def act() : unitdef ! ( msg:Any ) : unit = send(msg)override def run() : unit = act() // override run() in Thread

}

• Implementation is similar to Thread in Java• Extend with Actor instead to Thread• Implement act() instead of run()

// Define messages as ADTs for easy interrogation with pattern matching// Note Any object can be implemented as a messagecase class MsgOne( head:String, body:String )case class MsgTwo( head:String, body:String )

// Message Handlerclass Handler extends Actor{

def act() // Implement abstract method act() from Actor{

loop {react { // react makes actors event based

case MsgOne( head, body ) => ...case MsgTwo( head, body ) => ...case _ => ... // Log error

} } } }

// send (!) message asynchronously; messages are buffered in an actor's mailboxhandler ! message

Page 25: DOSUG Scala Basic Concepts 0805

The Lift Web Framework• Written by David Pollak with 12 committers• Inspired By:

• Seaside highly stateful, very secure, abstracts away the HTTP request/response cycle• Rails Simplest path to common operations• Wicket Stateful and Designer Friendly with web page templates in XHTML

• Lift uses the following features of Scala• Closures for HTML form elements• Traits for persistence, data binding, query building using POJO’s• Pattern Matching for extensible URL matching• Flexible Syntax for embedded DSL’s

• Features• Deploys as a web container.• Easy to install with Maven• Has good tutorials, but needs more in depth documentation.

• Actors have produced impressive results• Complete AJAX concurrency• Skittr a Twittr clone scales to 1 million concurrent actors on a two processor system.

Page 26: DOSUG Scala Basic Concepts 0805

Big or Small Language?• Every language design faces the tension whether it should be big or small:

• Big is good: expressive, easy to use.• Small is good: elegant, easy to learn.• Can a language be both big and small?

• Scala concentrates on abstraction and composition instead of basic language constructs.

Scala and Java ComparisonScala Adds Scala Removes

A pure object system Static members in classes.Operator overloading Special treatment of primitive typesClosures as control abstractions break, continueMixin composition with traits Special treatment of interfacesAbstract type members Parameterized wild cardsPattern Matching .

Page 27: DOSUG Scala Basic Concepts 0805

Scala and Groovy

Both Scala and Groovy:• Compile to the JVM• Seamlessly integrate with all existing Java objects and libraries• Implement Closures• Streamline Syntax by inferring types and removing semicolons.• Reduce Boilerplate• Redefine for loops• Improve on Java collections.• Provide interpreters• Natively support markup languages (XML,HTML)• Support DSLs

Scala and Groovy Differ with:Scala Groovy

Static Typing Dynamic TypingMaintains Java primitives Wraps Java primitivesAdds a new functional paradigm to the JVM. Enhances Java's existing paradigms.Is a complete self contained language. Close interaction with JavaMastery requires a steep learning curve Easy learning curve

Page 28: DOSUG Scala Basic Concepts 0805

Scala Influences• Main influences: Java, C# for their syntax, basic types, and class libraries.• Smalltalk for its uniform class hierarchy.• Beta for systematic nesting .

• Beta comes from the same group that created Simula the first OO language.

• ML, Haskell for many of the functional aspects.• Haskell is the biggest influence.

• OCaml, OHaskel, PLT-Scheme, as combinations of FP and OO.• Pizza, Multi Java, Nice as functional extensions of the Java platform.• Too many influences in details to list them all.

Page 29: DOSUG Scala Basic Concepts 0805

Tool Support and Resources• Scala tool support is extensive and improving rapidly:

• Standalone compiler: scalac• Java productions for interpreting byte code: scalap• Code documentation like Java Doc: scaladoc• Fast background compiler: fsc• Interactive interpreter shell and script runner: scala• Testing frameworks: Sunit and ScalaTest

• IDEs - Eclipse, IntelliJ and Netbeans plugins• Resources

• Scala Site: www.scala-lang.org compiler, libraries, papers, wiki• "Programing in Scala" book in PDF prePrint $27.50 www.artima.com

• Provides an excellent transition from gentle introduction to advance concepts.

• Lift: www.liftweb.net• AsciiMath: www1.chapman.edu/~jipsen/mathml/asciimath.html• Combinator Parsing: http://www.cs.kuleuven.be/publicaties/rapporten/cw/CW491.pdf

• Blogs and Articles:• Artima: www.artima.com• Scala Community: www.scala-lang.org/community/say.html• Planet Scala: www.drmaciver.com/planetscala• Ted Neward: www.ibm.com/developerworks/java/library/j-scala05298.html• Shameless Plug: www.axiom-architectures.blogspot.com• DOSUG presentations: www.slideshow.com

Page 30: DOSUG Scala Basic Concepts 0805

1994 A Heated Debate about Advanced Concepts for JavaPatrick Naughton, one of the original members of the "green team" at Sun from which Java emerged, described inhis personal history of Java a scene in Aspen in July 1994 in which Bill Joy was insisting that closures,continuations and parameterized types be added to Java, back when it was called Oak.

"Bill Joy was often comparing Oak to more complicated and elegant languages like Python and Beta. He wouldoften go on at length about how great Oak would be if he could only add closure, continuations and parameterizedtypes. While we all agreed these were very cool language features, we were all kind of hoping to finish thislanguage in our lifetimes and get on to creating cool applications with it. The more we argued with Bill aboutmaking those changes the more strongly he would fight us. After a while it became a choice between not havingBill involved at all or losing control of the language. James [Gosling] and I got into a rather epic battle with Bill inhis office in Aspen one evening about this issue. He started out by insulting both of us about how poorly Oakcompared to better languages and then he volunteered to resign from being the Live Oak architect if we wantedhim to. James and I agreed that would be best and walked out to go across the street to watch "Speed". What arush."

"The next day, Bill was pretty much his normal old nice guy self again, a little relieved, I think, to be out of therole of being directly responsible for our destiny. Bill is annoyingly smart, and I wouldn't put it past him to haveplanned that whole scenario the night before to force us to defend our positions and take ownership of our project.The interesting thing is that we were right about needing to finish the language even though it had missingfeatures. It was a timing issue, there was only about a three-month window in which the whole Java phenomenoncould have happened. We barely made it. It is also interesting that Bill was absolutely right about what Javaneeds long term. When I go look at the list of things he wanted to add back then, I want them all. He was right, heusually is."

Page 31: DOSUG Scala Basic Concepts 0805

Functional Programming Style• Writing in functional style can be difficult for seasoned OO programmers.

• Behaviour is no longer attached to an object,• Instead it propagates freely in a controlled manner.

• State becomes less important: methods depend on it less.• Immutable objects become natural:

• Why deal with state when a function can simply return a new object?

• Practice Fluidic Programming• In other words, use state sparingly in Scala.

• Functions and immutable objects (think val) help structure code.

Page 32: DOSUG Scala Basic Concepts 0805

Applicability - How to sell Scala to your boss?• Recommend holding off on wholesale adaptation.

• Wrapping Java classes in Scala only goes so far.• Projects become Scala centric with Java serving as libraries. A true hybrid as yet to emerge.• Scala Swing in beta.

• Scala has yet to achieve critical mass with:• Programmer availability.• Getting the Java community around the paradigm shift of merging FP with OO.

• Closures are only the beginning.• Availability of Scala specific open source distributed platforms. Scala needs more Lift.

• First Steps• Identify the advanced concepts that interest you the most.• Start a new Scala project to play around with and experience the impact of your ideas.• Build cool libraries for a wider deployment.

• Characterize Scala as just another library in the areas it excels at:• DSLs via combinator parsing, deconstructing ADTs, FP, Actor Concurrency

• In my case the advanced concepts centered on symbolic mathematic expressions:• A simple external DSL with high school algebra syntax - AsciiMath• Leverage Lisp background - ADTs for representations of math expressions.• A simple internal DSL that leverages infix syntax to avoid getting buried in parenthesis.• Deconstruction and reconstruction to MathML, Simplify, Differentiate, Integrate• Java performance and access to Java scientific libraries: Jama, Colt and JOGL(OpenGL)