Wednesday 24 December 2008

Scala, an introduction

Scala - "Scalable Java": a new Language which combines both Object Orientated and Functional programming paradigms.

Scala is an extension of Java and runs on the JVM. Scala draws from languages such as Java, Smalltalk, Erlang and many others.

Scala site: http://www.scala-lang.org/

Downloads: http://www.scala-lang.org/downloads

Installation, using the IzPack Scala installer jar, run: java -jar scala-x-installer.jar


Scala - main features:
  • Integrates with Java (is an extension of Java), and shares libraries and primitive types
  • Compiles to Java byte code - runs on JVM (also can be run on .Net)
  • Imperative and functional support
  • Object Orientated (classes, objects)
  • Functional (functions as first class objects, referential transparency)
  • Statically typed
  • Type inference (more concise code that looks more like Dynamic/duck typed, but has the benefits of static / strong typing)
  • Supports closures and function literals
  • Concurrency model using Erlang Actors system (a 'safer' concurrency model)
Scala can be run stand alone, using the command line interpreter - using the "scala" command.

Scala also has plugin support for NetBeans, Eclipse and InteliJ


Syntax Overview:
  • Type inference means most type declarations can be omitted (but can still be explicitly declared).
  • Variables are defined as name : type rather than type name as per Java
  • Semicolons are often optional
  • Does not specify or define operators. +-*/ etc are valid method names are defined as such for appropriate types
  • var and val keywords - val declares a constant type (like Java's final, not reassignable), var declares a variable that can be reassigned. val, like var can still be mutable however, if the type is mutable.
  • Functions, declared using def keyword. e.g. def myFunction(x: Type1, y: Type2) : ReturnType
  • Pre and post increment/decrement (i++, ++i, i--, --i) are not supported, use i = i + 1 or i += 1
  • Recommended indentation is 2 spaces
  • Imperative for loops not supported, the functional equivalent, a for Expression is used instead
  • Arryays are indexed using (n) not [n]
  • Type parameters are specified using [type]. If both type and index are used, the ordering is [type](params)
  • Scala supports infix as method calls. e.g. 1 + 2 is equivalent to 1.+(2) where + is not a special operator, but a regular method
  • Applying () to an object (recipient) is equivalent to calling .apply() on it. e.g. myThing(i) is equivalent to myThing.apply(i)
  • The receiver of an = operator is equivalent to calling .update. e.g. myThing(i) = value is equivalent to myThing.update(i, value)
  • Method association is by default to the left, unless the method ends with a colon : e.g. 1 + 2 applies + to 1 giving 1.+(2) whereas x :: y applies :: (cons) to y, giving y.::(x)
  • The List type supports ::: (concat) and :: (cons, prepend), both apply the operation and return the resulting new List
  • Arrays are always mutable, lists are always immutable. Sets and maps can be either, the default is immutable (from the trait scala.collection.immutable) but the mutable equivalents can be imported from scala.collection.mutable
  • The -> method provides Implicit Conversion. e.g. x -> y is x.->y which returns a key/value tuple containing x as the key and y as the value

Some simple Functional examples:

Print all command line arguments, using foreach, passing println function:

Verbose:
args.foreach((arg: String) => println(arg))

Type inference on arg:
args.foreach(arg => pringln(arg))

Concise:
args.foreach(println)

The last example is a shorthand that can be applied when a function literal cosists of one statement that takes one argument - known as a Partially Applied Function.


For Expressions:

Replacing imperative for loops, the syntax is of the form:

for (arg <- args)
println(arg)


Note: In the above for expression example, arg is a val (final/const) not a var, and a new val variable is created for each "iteration".

or

for (i <- 1 to 30) ...


Declaring Arrays:

Very concisely:

val myArray = Array("value1", "value2")

defines a string array (type inference) of size 2

This is equivalent to:

val myArray = Array.apply("value1", "value2")

where apply is called on the Array Companion Object

More Verbosely the array could also be declared more traditionally as:

val myArray = new Array[String](2)

or even

val myArray : Array[String] = new Array[String](2)

but the former concise approach is the Scala recommended way, the later hints at the underlying Java roots.

Lists:

Defining new lists is easy with the cons method, as follows:

val myList = 3 :: 2 :: 4 :: 5 :: Nil // Nil is the Empty List, also so is List()

Note: The Nil (empty List) is needed so that working from right to left, the :: method is defined on Nil, which first gives Nil.::(5) returning List(5) which then gives 5.::(4) resulting in List(4, 5), and so on. Without the Nil there is a syntax error as :: (cons) is not defined on 5 (which is of type integer).


Examples:

Factorial ! - Simple factorial, defined in a functional way:

def factorial(value : int) : int = { if (value == 0) 1 else value * factorial(value - 1) }

scala> factorial(10)
res15: int = 3628800


Triangle Numbers:

def tri(x : Int) : Int = { if (x == 0) 0 else x + tri(x-1) }

scala> tri(4)
res14: Int = 10


Scala for scripting:

Scala scripts can be run using scala myscript.scala

Additionally, Scala can be used as a self contained scripting language by invoking the scala command line interpreter with the script, as follows:

On 'nix platforms

#!/bin/sh
exec scala "$0" "$@"
!#
println("Hello world, hello " + args(0))

Don't forget to give the script execute permissions (chmod +x myscipt)

Execute: myscript Louis

A similar thing can be achieved on Windows...


Scala with build systems:


With Ant:

http://www.scala-lang.org/node/98


With Maven:

http://scala-blogs.org/2008/01/maven-for-scala.html


Further Resources:

Books:

Artima book (excellent): http://www.artima.com/shop/programming_in_scala released 17th Nov 2008, by Martin Odersky, Lex Spoon, and Bill Venners.

Source code for book examples: http://booksites.artima.com/programming_in_scala/progInScalaExamples1EdV6.zip

Browse book examples: http://booksites.artima.com/programming_in_scala/examples

OReilly Programming Scala: http://programming-scala.labs.oreilly.com/


Blogs:

http://www.scala-blogs.org/

Blog on Monads: http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html


Articles:

Java refugees: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-1


Build tools:

SBT: http://code.google.com/p/simple-build-tool/


Interesting Blog about Scala and Lift (using Maven and Jetty).

http://scala-blogs.org/2007/12/dynamic-web-applications-with-lift-and.html


SIDs (software improvement Documents):

http://www.scala-lang.org/sids


Monads:

http://projects.tmorris.net/public/what-does-monad-mean/artifacts/1.1/chunk-html/ar01s04s04.html

http://vimeo.com/8729673


IRC channel: #scala on irc.freenode.net


(Also (unrelated): pastie - http://pastie.org/ is handy for pasting those odd snippets of code around on the internet/IRC).


Interesting blog about Scala type-safe SQL / DB - SQuery - http://szeiger.de/blog/2008/12/21/a-type-safe-database-query-dsl-for-scala/

Updated (13-09-2009): Came across this useful presentation: http://www.slideshare.net/astubbs/scala-language-intro-inspired-by-the-love-game?src=embed


99 Scala problems - an adaption of the 99 Prolog problems into Scala:

http://aperiodic.net/phil/scala/s-99/#p10


.

No comments: