Most of this improvement is due to being able to write in a functional manner vs the imperative style of looping and state manipulation
We will now elaborate…
The Love Game in 4 lines of code…
var loves = "loves" . toList map ( x => "roger federer maria sharapova" . toList count ( x == _ )) while (loves . length > 1) loves = loves zip ( loves tail ) map { x => x . _1 + x . _2 } println ( "3 line compatibility = " + loves . head * 2 + " %" )
History
Scala was created at the École Polytechnique Fédérale de Lausanne (EPFL) in 2001 by Martin Odersky .
It was released publicly on the Java platform in January 2004, and on the .NET platform in June the same year. A second version of the language was released in March 2006.
General purpose
Express common programming patterns in a concise , elegant , and type-safe way
Stands for “scalable language.”
Designed to grow with the demands of its users.
Wide range of programming tasks, from small scripts to building large systems.
Smoothly integrates features of object-oriented and functional languages.
Interoperable with Java . Both ways.
Aims to make the most common case, easy.
It is both a scripting language and a compiled one.
Imutability and lack of side effects are key to distributed paralleism which are features of functional languages - a modern issue facing IT today with multi core process.
So - compatibility, brevity, high-level abstractions
Woah. (Scala Features)
Scala is object-oriented
Everything is an object!
every value, even primitives, are an object
Every function is an object
Most operators are actually methods! (operator overloading)
2 * (4 + 6) is actually compiled to (4.+(6)).*(2)
Types and behaviour of objects are described by classes and traits
Multiple inheritance solution with mixins of traits
Strong type system – type inference, generics
singleton objects,
Traits
Uniform access principle - “…client code should not be affected by a decision to implement some attribute as a field or as a method.”
Woah. (Scala Features)
Scala is functional
every function is a value
Higher-order functions
Anonymous functions
Function currying / partial functions
(multiple parameter lists)
Lazy evaluation
Infinite ranges
built-in support for pattern matching
Woah. (Scala Features)
Scala is statically typed
Not dynamic – No speed trade off’s (Compared to Groovy and Ruby), but less flexible at runtime (can be argued either way)
But - Local type inference mechanism – don’t need to specify types if they can be inferred
Generics (parameterised types)
Scala is extensible (scalable)
Implicit type conversions
Allows language extensions - empowers you to create new language constructs
The much beloved “Pimp my Library pattern”
Unique combination of language mechanisms makes it easy to smoothly add new language constructs in the form of libraries
Interoperates with Java and .NET (.NET support is ‘rough’ atm)
Optional semi colons, often option parenthesis and ‘dots’
Built in language support for XML processing through natural extention of pattern matching
Great community
Active mailing list – Martin himself replied to my query about Regex Parsers
Recursive version
For demonstration purposes, we will work with my original recursive (slightly longer) version
val initialList = "loves" . toList . map ( x => "roger federer maria sharapova" . toList . count ( x == _ ))
def loveReduce ( numbers : List [ Int ]): Int = numbers match {
case head :: Nil => head * 2
case _ => loveReduce ( numbers . zip ( numbers . tail ). map { case ( a , b ) => a + b })
Line by line… The Map Function and Higher-Order Functions
val initialList = "loves" .toList.map( F(x) )
[ 1, 2, 3, 4]
F(x) ------
[ f(1), f(2), f(3), f(4) ]
If F(x) = x^2 we get :
[ f(1), f(4), f(9), f(16) ]
F(x) = "roger federer maria sharapova" .toList.count( H(y,x) )
H(y,x) = y == x
val initialList = "loves" .toList.map( x => "roger federer maria sharapova" .toList.count( y => y == x ))
Method Signatures
public int loveReduce(List<Integer> numbers) {…}
def loveReduce (…)…
def loveReduce ( numbers : List [ Int ]): Int …
(Need to specify return type only for recursive functions, otherwise the compiler invokes the type inference mechanism)
def loveReduce ( numbers : List [ Int ]): Int = numbers match {…}
Don’t need surrounding braces as it’s a single statement
Recall – Java Case statements
// checks if a number between 1 and 10 is prime
int number = 4;
switch ( number ) {
case 1 : return true ;
case 2 : return true ;
case 3 : return true ;
case 5 : return true ;
case 7 : return true ;
default : return false ;
}
Recall – Java Case statements
If each case statement doesn’t return, need to also include break statements to prevent unwanted fall through
switch ( number ) {
case 1 : object . operation1 ( number );
break ;
case 2 : object . operation2 ( number );
break ;
case 3 : object . operation3 ( number );
break ;
case 5 : object . operation4 ( number );
break ;
case 7 : object . operation5 ( number );
break ;
default : object.defaultOp ( number );
}
Pattern Matching in Scala – Java case statements on steroids
Generalised form of case statement
But more powerfull
No ‘fall through’ (common case)
// checks if a number between 1 and 10 is prime
number match {
case 1 => return true;
case 2 => return true;
case 3 => return true;
case 5 => return true;
case 7 => return true;
case _ => return false; //similar to Java’s default case
}
Case statements in Scala
But we can do better…
Drop the semicolons, of course
Drop the return statements
Again, scala’s type inference kicks in – return value of function is simply last resolved statement
// checks if a number between 1 and 10 is prime
number match {
case 1 => true
case 2 => true
case 3 => true
case 5 => true
case 7 => true
case _ => false
}
Clean eh?
Pattern matching
List constructor – the ‘cons’ notation – “::”
head :: tail // matches 1 or more (can also use foo :: bar )
foo :: 2 // 2 element list where 2nd element is integer 2
head :: Nil // Nil (is an object – extends List) represents an empty list – matches 1 element list
x :: xs // matches 1 or more
Nil and :: are actually case Classes!
remember, there is nearly no restriction on characters used for class and method names etc
Any method which takes a single parameter can be used as an infix operator – but :: (cons) when used in pattern matching is a special case
That is, the infix operator “::” here, is treated as a constructor pattern ::(foo, bar)
From scala-lang.org: Case classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching .
Checks the entire tree of the objects match
Can do things like: case Foo ( x , Bar ( y )) if x == y => true
numbers match {
case head :: Nil => head * 2
case _ => {…}
}
Recursion in Functional Scala
Who can describe what a recursive function is?
Recursion in computer programming defines a function in terms of itself.
Recursion: *see Recursion .
def loveReduce ( ... )...{
...
... loveReduce ( g(x) )
}
Our reduce function
For g(x) we need to return a list one element smaller in order for our recursion to work (i.e. reduce )
Step 1
numbers.zip(numbers.tail)
Step 2
.map{ x => x._1 + x._2 }
Nicer syntax – using a match expresion in place of a function literal
.map{ case (a,b) => a + b }
“ A match expression can be used anywhere a function literal can be used. Essentially, a match expression is a function literal, only more general.”
Recursion in Functional Scala
loveReduce(numbers.zip(numbers.tail)
.map{ case (a, b) => a+b})
Each call, calls loveReduce, with a list one element smaller (due to the zip call)
Putting it all together -> Recursion
def loveReduce ( numbers :List [ Int ]) :Int =
numbers match {
case head :: Nil => head * 2
case _ => loveReduce ( numbers . zip ( numbers . tail )
. map { case ( a , b ) => a + b })
}
NB: Don’t need surrounding curly braces because it’s a single statement
var loves = "loves" . toList map ( x => "roger federer maria sharapova" . toList count ( x == _ ))
while ( loves . length > 1 )
loves = loves zip ( loves tail ) map { x => x . _1 + x . _2 }
println ( "3 line compatibility = " + loves . head * 2 + " %" )
For the cynics out there… smaller Java implementation
public static int loveMatch ( String name1 , String name2 , String compWord ) {
int [] tally = new int [ compWord . length ()];
for ( char c : ( name1 + name2 ). toCharArray ())
for ( int t = 0 ; t < tally . length ; t ++)
if ( c == compWord . charAt ( t )) tally [ t ]++;
for ( int i = tally . length - 1 ; i >= 0 ; i --)
for ( int j = 0 ; j < i ; j ++)
tally [ j ] += tally [ j + 1 ];
return tally [ 0 ] * 2 ;
}
And for the side ball….
C#.NET LINQ
var loves = “ loves ” . Select ( x => “ roger federer maria sharapova ” . Count ( c => x == c )). ToList ();
while ( loves . Count > 1 )
loves = Enumerable . Range ( 0 , loves . Count - 1 ). Select ( i => loves [ i ] + loves [ i + 1 ]). ToList ();
Console . WriteLine ( loves . Single () * 2 );
More Scala to come…
Pimp my library!
Implicit conversion functions
Examples:
MyRichString
E.g. JScience interface
Measure length = Measure .valueOf(50, SI .CENTI( SI .METER)).plus( Measure .valueOf(25.0, SI .METER));
Measure lengthInCentimeters = length .to( SI .CENTI( SI .METER));
System.out .println ( "length in centimeters is " + lengthInCentimeters.getEstimatedValue());
VS
var len = 50 .centimeters + 25 .meters
println(" length in centimeters is " + len)
More Scala to come…
Class properties VS instance variables
Static?
Currying
the technique of transforming a function that takes multiple arguments into a function that takes a single argument (the other arguments having been specified by the curry).
Advanced Pattern Matching and Case Classes
Actors Library
concurrent processes that communicate by exchanging messages.
Combinator Parsing
Define language parsers out of context free grammar definitions
With the advent of multi-core processors concurrent programming is becoming indispensable.
Actors are basically concurrent processes that communicate by exchanging messages, instead of sharing state.
Companion objects and Static
Singleton and Static considered harmful
Static methods cannot be polymorphic
Inheritance problems
So - all static members are now grouped in their own ‘object’
Scala’s “companion ‘object’” (singleton object)
More and more and more….
Nested Functions
By-name parameters
Lazy evaluation
Logging – no more stupid ( if ( log.isEnabled() ) protection! )
Private packages
LiftWeb (Rails/Grails like web app for Scala)
The Option type – optional values – Some or None
First-class Properties coming…
Properties are objects (OO sense)
Govern access to a (possibly calculated) field.
Properties can have other methods in addition to get/set logic, such as registering event listeners.
Writing new control structures
val file = new File ( "date.txt" )
withPrintWriter ( file ) {
writer => writer.println ( new java.util.Date )
}
More Technologies are out there!
Expand your mind!
Online Ajax HelpRequestList program in 9 lines!!
Groovy on Grails
Maven the modular build system Connoisseur!
Groovy Builder and G-Strings
Groovy Command Line Interpreter
Groovy Wicket builder
Polygot programming
a computer program or script written in a valid form of multiple programming languages , which performs the same operations or output independently of the programming language used to compile or interpret it.
Git
a distributed revision control / software configuration management project created by Linus Torvalds , initially for the Linux kernel development.
0 comments
Post a comment