Introduction à Scala - Michel Schinz - January 2010

JUG Lausanne
JUG LausanneJUG Lausanne
an introduction
Michel Schinz
What is Scala?
Scala is a programming language that:
• coherently combines the best aspects of
object-oriented and functional programming
languages,
• runs on the JVM and is fully interopeable with
Java – a .NET version is in the works,
• is statically typed and very concise,
• offers a high level of abstraction and good
performances.
Object-oriented
programming in Scala
Rational numbers

First example: model rational numbers n / d where
n and d are integers, and d ≠ 0.
Provide addition, multiplication and comparison
of rationals.
A class for rationals (1)
class Rational(n0: Int, d0: Int) {
require(d0 != 0)
constructor arguments
private def gcd(x: Int, y: Int): Int =
if (y == 0) x else gcd(y, x % y)
no return

no explicit type (Int inferred)

private val g = gcd(n0.abs, d0.abs)
val n: Int = n0 / g public fields
val d: Int = d0 / g (immutable)
def this(n: Int) = this(n, 1)
to be continued…

auxiliary
constructor
A class for rationals (2)
…continued
def +(that: Rational): Rational =
new Rational(this.n * that.d +
that.n * this.d,
public
this.d * that.d)
method
def *(that: Rational): Rational =
new Rational(this.n * that.n,
this.d * that.d)
override def toString: String =
n +"/"+ d
}

parameterless
method
Using rationals
scala> val r1 = new Rational(1, 3)
r1: Rational = 1/3 primary constructor call
inferred type

scala> val r2 = new Rational(5)
r2: Rational = 5/1
auxiliary constructor call
scala> r1 + r2 // or: r1.+(r2)
res0: Rational = 16/3
scala> res0 * r1 // or: res0.*(r1)
res1: Rational = 16/9
A companion for rationals
singleton

companion object for class Rational

object Rational {
def apply(n: Int, d: Int): Rational =
new Rational(n, d)
def apply(n: Int): Rational =
new Rational(n)
val ZERO = new Rational(0)
}
implicitly calls apply

scala> Rational(2,5) + Rational.ZERO
res1: Rational = 2/5
Ordered objects
type parameter

trait Ordered[T] {
def compare(that: T): Int abstract method
def < (that: T): Boolean =
(this compare that) < 0
def <=(that: T): Boolean =
(this compare that) <= 0
def > (that: T): Boolean =
(this compare that) > 0
def >=(that: T): Boolean =
(this compare that) >= 0
}
Ordered rationals
class Rational(n0: Int, d0: Int)
extends Ordered[Rational] {
… as before
provides <, <=, > and >= methods
def compare(that: Rational): Int =
(n * that.d) compare (that.n * d)
}
Cells

Second example: model mutable cells that contain
a single value of some arbitrary type.
Additionally, define logging and undoable
variants.
A class for generic cells
make init available as a field

class Cell[T](val init: T) {
private var v = init
mutable field

def get(): T = v
def set(v1: T): Unit = { v = v1 }
≈ Java’s void

override def toString: String =
"Cell("+ v +")"
}
A trait for logging cells
trait LoggingCell[T] extends Cell[T] {
override def get(): T = {
println("getting "+ this)
super.get()
}
override def set(v1: T): Unit = {
println("setting "+ this +" to "+ v1)
super.set(v1)
}
}
A trait for undoable cells
trait UndoableCell[T] extends Cell[T] {
import collection.mutable.ArrayStack
private var hist = new ArrayStack[T]()
override def set(v1: T): Unit = {
hist.push(super.get())
super.set(v1)
}
def undo(): Unit =
super.set(hist pop)
}
Mixin composition
new Cell(0)

basic integer cell

new Cell(0)
logging integer
with LoggingCell[Int]
cell
new Cell(0)
with LoggingCell[Int]
logging, undoable
with UndoableCell[Int] integer cell (undos are
logged)

new Cell(0)
with UndoableCell[Int]
with LoggingCell[Int]
logging, undoable
integer cell (undos are
not logged)
The Scala library
Optional values
An optional value is either empty, or contains a
single element.
Example use: as a clean replacement for null.
variance (here co-variant)

abstract class Option[+T] {
def isEmpty: Boolean
def get: T

bounded type parameter

def getOrElse[U >: T](d: =>U): U =
if (isEmpty) d else get by-name parameter
…many more methods
}
Optional values (2)
can be matched (see later) & compiler-provided methods

case class Some[+T](x: T)
extends Option[T] {
def isEmpty = false
def get = x
}
case object None subtype of all types
extends Option[Nothing] {
def isEmpty = true
def get = throw new …
}
Using optional values
compiler-provided factory method

scala> val v1 = Some("something")
v1: Some[String] = Some(something)
compiler-provided toString method

scala> val v2 = None
v2: None.type = None
scala> v1 getOrElse "nothing"
res1: String = something
scala> v2 getOrElse "nothing"
res2: String = nothing
Tuples
A tuple of size n contains exactly n heterogenous
elements – i.e. they can be of different types.
Example use: a function that has to return n values
can return them wrapped in a single tuple.
case class Tuple2[+T1,+T2](
_1: T1, _2: T2)
case class Tuple3[+T1,+T2,+T3](
_1: T1, _2: T2, _3: T3)
etc.
Short tuple syntax
Scala offers syntactic shortcuts for tuple values:
(e1, …, en) ≣ Tuplen(e1, …, en)
and for tuple types:
(T1, …, Tn) ≣ Tuplen[T1, …, Tn]
Example:
scala> val p = ("Orwell", 1984)
p: (String, Int) = (Orwell,1984)
scala> p._1 arguments of case classes are fields
res1: String = Orwell
(Im)mutable collections
Options and tuples are immutable.
Standard collections (sequences, sets, maps) are
provided in mutable and immutable variants.
Mutable collections are similar to the ones found
in Java and other imperative languages.
Immutable collections are similar to the ones
found in typical functional languages.
Immutable lists
An immutable list is either empty or composed of
a head element and a tail, which is another list.
abstract class List[+T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
def ::[U >: T](x: U): List[U] =
new ::[U](x, this)
…many more methods
}
Immutable lists (2)
case class ::[T](val head: T,
val tail: List[T])
extends List[T] {
def isEmpty = false
}
case object Nil extends List[Nothing] {
def isEmpty = true
def head: Nothing =
throw new …
def tail: List[Nothing] =
throw new …
}
Sequences, maps and sets
scala> val aSeq = Seq("zero","one","two")
scala> aSeq(1)
res1: String = one
scala> val aMap = Map("zero" -> 0,
"one" -> 1,
"two" -> 2)
scala> aMap("one")
res2: Int = 1
scala> val aSet = Set("zero","one","two")
scala> aSet("one")
res3: Boolean = true
For loops
For loops enable iteration over the elements of
collections, using a syntax that is reminiscent of
SQL queries.
for (user <- users
if (user.isMale
&& user.age > 30))
yield user.name
Pattern matching
Pattern matching
Instances of case classes can easily be
constructed:
scala> Some((1,2))
res: Some[(Int,Int)] = Some((1,2))
Pattern matching makes deconstruction of case
classes similarly easy.
Integer division
def divMod(n: Int, d: Int):
Option[(Int,Int)] = {
if (d == 0)
None
else {
…compute quotient q and remainder r
Some((q, r))
}
}
Using integer division
def testDivMod(n: Int, d: Int) =
divMod(n, d) match {
case Some((q, r)) =>
println("quot: "+ q +" rem: "+ r)
case None =>
println("<no result>")
}
scala> testDivMod(5, 3)
quot: 1 rem: 2
scala> testDivMod(5, 0)
<no result>
Pattern matching lists
Since lists are recursive, it is natural to manipulate
them with recursive functions.
Furthermore, since they are defined as a
disjunction of two cases (non-empty / empty list),
it is natural to use pattern matching to do a case
analysis.
Example: a function to sum a list of integers.
def sum(l: List[Int]): Int = l match {
case h :: t => h + sum(t)
case Nil => 0
}
Typed patterns
Pattern matching can also be used to discriminate
on the type of a value:
supertype of all types

def succAny(x: Any): Any = x match {
case i: Int => i + 1 Int and Long are not
case l: Long => l + 1
case classes
case other => other
}
scala> succAny(2)
res1: Any = 3
scala> succAny("two")
res2: Any = two
Exception handling
Unsurprisingly, exception handling is done using
pattern matching:
try {
val f = new FileInputStream("f.txt")
println(f.read())
f.close()
} catch { _ is a wildcard
case _: FileNotFoundException =>
println("not found")
case e: IOException =>
println("other error: " + e)
}
Functional
programming in Scala
What is FP?
The functional style of programming is one that
relies on mathematical functions as the basic
building block of programs.
In mathematics, a function always returns the
same result when applied to the same arguments.
Therefore, the functional style of programming
strongly discourages the use of side-effects – i.e.
variables and other kinds of mutable data.
What is a FPL?
A functional programming language is one that
encourages the functional style of programming
by:
• offering first-class functions that can be
manipulated like any other value,
• providing lightweight syntax to define
arbitrarily-nested functions,
• discouraging the use of side-effects, for
example by providing libraries of immutable
data-structures.
Why is FP interesting?
Side-effects complicate several classes of
programs, like:
• concurrent programs with shared, mutable
state,
• programs that need to do “time travel”, e.g.
interactive programs with undo, SCMs, …
• programs that need to work on a consistent
state of some data, e.g. a live backup program,
• etc.
A trait for functions
trait Function1[F, T] { f =>
def apply(x: F): T
new name for this
def compose[F2](g: Function1[F2, F])
: Function1[F2, T] =
new Function1[F2, T] {
def apply(x: F2): T =
f.apply(g.apply(x))
}
override def toString = "<fun>"
}
Using functions as values
scala> val succ = new Fun[Int,Int] {
def apply(x: Int) = x + 1 }
succ: …with Function1[Int,Int] = <fun>
scala> val twice = new Fun[Int,Int] {
def apply(x: Int) = x + x }
twice: …with Function1[Int,Int] =<fun>
scala> succ.apply(6)
res1: Int = 7
scala> twice.apply(5)
res2: Int = 10
scala> (succ compose twice).apply(5)
res3: Int = 11
se
!

Using functions as values

W
or

ks

,b

ut

w
ay

to
o

ve
rb
o

scala> val succ = new Fun[Int,Int] {
def apply(x: Int) = x + 1 }
succ: …with Function1[Int,Int] = <fun>
scala> val twice = new Fun[Int,Int] {
def apply(x: Int) = x + x }
twice: …with Function1[Int,Int] =<fun>
scala> succ.apply(6)
res1: Int = 7
scala> twice.apply(5)
res2: Int = 10
scala> (succ compose twice).apply(5)
res3: Int = 11
Functional syntactic sugar
anonymous function

scala> val succ = { x: Int => x + 1 }
succ: (Int) => Int = <function1>
a.k.a. Function1[Int, Int]

scala> val twice = { x: Int => x + x }
twice: (Int) => Int = <function1>
scala> (succ compose twice)(5)
res1: Int = 11
implicit apply
Partial application
Function values can also be created by applying
existing functions or methods to a (possibly empty)
subset of their arguments:
scala> val succ: Int=>Int = _ + 1
succ: (Int) => Int = <function1>
scala> val toStr: Any=>String = _.toString
toStr: (Any) => String = <function1>
scala> toStr(0123)
res0: String = 83
Collections as functions
Most collections are functions:
• Seq[T] has type Int=>T,
• Map[K,V] has type K=>V,
• Set[T] has type T=>Boolean.
This explains the common notation to access their
elements: it’s simply function application!
Operating on collections
Functional values are ideal to operate on
collections. Examples:
scala> val s = Seq(1,2,3,4,5)
scala> s map (_ + 1)
res1: Seq[Int] = List(2, 3, 4, 5, 6)
scala> s reduceLeft (_ * _)
res2: Int = 120
scala> s filter (_ % 2 == 0)
res3: Seq[Int] = List(2, 4)
scala> s count (_ > 3)
res4: Int = 2
scala> s forall (_ < 10)
res5: Boolean = true
Project Euler: problem 8
Solving problem 8
val n = "7316717653133062491922511967442…"
val digits = s.toList map (_.asDigit)
def prods(l: List[Int]): List[Int] =
l match {
case a :: (t@(b :: c :: d :: e :: _)) =>
(a * b * c * d * e) :: prods(t)
case _ =>
List()
}
prods(digits) reduceLeft (_ max _)
For loops translation
The for notation is pure syntactic sugar. The
example:
for (user <- users
if (user.isMale
&& user.age > 30))
yield user.name
is automatically expanded to:
users
.filter(user => user.isMale
&& user.age > 30)
.map(user => user.name)
Implicits
Scala implicits
Scala offers two notions of implicit entities that are
automatically inserted by the compiler in certain
contexts:
• Implicit conversions, which can be applied
automatically to transform a type-incorrect
expression into a type-correct one.
• Implicit parameters, which can be
automatically passed to a function.
Implicit conversions
An implicit conversion from Int to Rational
can be added to the latter’s companion object:
object Rational {
…as before
implicit def i2r(i: Int): Rational =
Rational(i)
}
scala> 2 + Rational(1,3) // i2r(2) + …
res2: Rational = 7/3
scala> Rational(1,3) + 3 // … + i2r(3)
res3: Rational = 10/3
“Pimp my library”
Implicit conversions make it possible to
“augment” existing classes by implicitly wrapping
them – known as the Pimp my library pattern.
This technique is heavily used in the standard
library to improve anemic Java classes (e.g.
String, Integer, Boolean, arrays, etc.).
scala> "1337" strings are really Java strings
res1: java.lang.String = 1337
implicit conversion

scala> "1337".toInt
res2: Int = 1337
Implicit parameters
repeated parameter

def max[T](xs: T*)
(implicit ord: Ordering[T]): T =
xs reduceLeft ord.max
implicitly Ordering.Int

scala> max(4, -2, 12, 25, 7, -1, 2)
res1: Int = 25
scala> max(4, -2, 12, 25, 7, -1, 2)
(Ordering.Int.reverse)
res2: Int = -2
scala> max(1 to 20 : _*)
res3: Int = 20
pass all elements as
separate arguments
Working with XML
data
XML literals
Scala supports XML literals, which are translated
to instances of various classes in scala.xml.
scala> val hello =
<p>Hello <b>world</b></p>
hello: scala.xml.Elem =
<p>Hello <b>world</b></p>
scala> val name = "Roger&Co."
name: java.lang.String = Roger&Co.
scala> val hello = arbitrary Scala expression
<p>Hello <b>{ name }</b></p>
hello: scala.xml.Elem =
<p>Hello <b>Roger&amp;Co.</b></p>
XPath-like queries
scala> val users =
<users>
<user name="Roger" age="12"/>
<user name="Mary" age="44"/>
<user name="Jean" age="12"/>
</users>
scala> users  "@name"
res1: scala.xml.NodeSeq = RogerMaryJean
scala> (users  "@age")
map (_.toString.toInt)
reduceLeft (_ max _)
res2: Int = 44
XML pattern matching
def parseRow(r: xml.Node): (String, Int) =
r match {
case <tr><td>{ name }</td>
<td>{ age }</td></tr> =>
(name.text, age.text.toInt)
}
scala> val table = <table>
<tr><td>Roger</td><td>12</td></tr>
<tr><td>Mary</td><td>44</td></tr>
</table>
scala> (table  "tr") map parseRow
res1: Seq[(String, Int)] =
List((Roger,12), (Mary,44))
Testing with
ScalaCheck
Properties for rationals
The operations we defined on rationals should
satisfy several properties:
• ∀x, y ∈ Q: x + 0 = 0 + x = x
• ∀x, y ∈ Q: x + (y + z) = (x + y) + z
• etc.
ScalaCheck makes it possible to express such
properties and test them on random rationals.
Extensive use of implicits keep the client code
very concise.
Properties for rationals
object RatProps extends Properties("Rat") {
property("+ left unit") =
Prop.forAll((x: Rational) => 0 + x == x)
property("+ right unit") =
Prop.forAll((x: Rational) => x + 0 == x)
property("+ associativity") =
Prop.forAll((x: Rational,
y: Rational,
z: Rational) =>
(x + y) + z == x + (y + z))
}
Generating rationals
ScalaCheck doesn’t know how to generate
arbitrary rationals, but we can easily define a
generator for them:
implicit def arbRat: Arbitrary[Rational] =
Arbitrary {
Gen.sized(sz =>
for (n <- Gen.choose(-sz, sz);
d <- Gen.choose(-sz, sz)
suchThat (_ != 0))
yield Rational(n, d))
}
Testing rationals
%
+
+
+

scala
Rat.+
Rat.+
Rat.+

RatProps
left unit: OK, passed 100 tests.
right unit: OK, passed 100 tests.
associativity: OK, passed 100 tests.

When a property can be falsified (here the incorrect
property ∀x ∈ Q: x = 0), the counter-example is
presented:
! Rat.wrong: Falsified after 0 passed tests.
> ARG_0: 1/2
Further reading
http://www.scala-lang.org/
Two books about Scala:
• Programming in Scala by Odersky, Spoon &
Venners
• Programming Scala by Wampler & Payne
One book about functional programming:
• The Functional Approach to Programming by
Cousineau, Mauny & Callaway
1 sur 62

Recommandé

Principles of functional progrmming in scala par
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scalaehsoon
428 vues49 diapositives
Scala Bootcamp 1 par
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1Knoldus Inc.
1.7K vues41 diapositives
Introducing scala par
Introducing scalaIntroducing scala
Introducing scalaMeetu Maltiar
1.8K vues41 diapositives
Scala categorytheory par
Scala categorytheoryScala categorytheory
Scala categorytheoryKnoldus Inc.
1.4K vues22 diapositives
Getting Started With Scala par
Getting Started With ScalaGetting Started With Scala
Getting Started With ScalaXebia IT Architects
2K vues35 diapositives
Scala collections par
Scala collectionsScala collections
Scala collectionsInphina Technologies
2.9K vues25 diapositives

Contenu connexe

Tendances

Scala Paradigms par
Scala ParadigmsScala Paradigms
Scala ParadigmsTom Flaherty
1.7K vues35 diapositives
Scala collections api expressivity and brevity upgrade from java par
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from javaIndicThreads
677 vues9 diapositives
Scala for curious par
Scala for curiousScala for curious
Scala for curiousTim (dev-tim) Zadorozhniy
514 vues88 diapositives
The Scala Programming Language par
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
1.4K vues34 diapositives
Lecture 5: Functional Programming par
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional ProgrammingEelco Visser
1.1K vues90 diapositives
Pragmatic Real-World Scala (short version) par
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
72.8K vues108 diapositives

Tendances(20)

Scala collections api expressivity and brevity upgrade from java par IndicThreads
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
IndicThreads677 vues
The Scala Programming Language par league
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
league1.4K vues
Lecture 5: Functional Programming par Eelco Visser
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
Eelco Visser1.1K vues
Pragmatic Real-World Scala (short version) par Jonas Bonér
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér72.8K vues
Demystifying functional programming with Scala par Denis
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
Denis 536 vues
Scala Back to Basics: Type Classes par Tomer Gabel
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
Tomer Gabel3.7K vues
Scala: Object-Oriented Meets Functional, by Iulian Dragos par 3Pillar Global
Scala: Object-Oriented Meets Functional, by Iulian DragosScala: Object-Oriented Meets Functional, by Iulian Dragos
Scala: Object-Oriented Meets Functional, by Iulian Dragos
3Pillar Global2.3K vues
Identifiers, keywords and types par Daman Toor
Identifiers, keywords and typesIdentifiers, keywords and types
Identifiers, keywords and types
Daman Toor1.4K vues
An Introduction to Part of C++ STL par 乐群 陈
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
乐群 陈2K vues
Effective way to code in Scala par Knoldus Inc.
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
Knoldus Inc.2.9K vues

En vedette

Scala : language of the future par
Scala : language of the futureScala : language of the future
Scala : language of the futureAnsviaLab
854 vues66 diapositives
Go Programming Language by Google par
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by GoogleUttam Gandhi
3.4K vues20 diapositives
Rust - Fernando Borretti par
Rust - Fernando BorrettiRust - Fernando Borretti
Rust - Fernando BorrettiTryolabs
1.1K vues18 diapositives
Introduction to Go programming language par
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming languageSlawomir Dorzak
5.7K vues25 diapositives
Scala at GenevaJUG by Iulian Dragos par
Scala at GenevaJUG by Iulian DragosScala at GenevaJUG by Iulian Dragos
Scala at GenevaJUG by Iulian DragosGenevaJUG
1.3K vues63 diapositives
Universitélang scala tools par
Universitélang scala toolsUniversitélang scala tools
Universitélang scala toolsFabrice Sznajderman
504 vues40 diapositives

En vedette(20)

Scala : language of the future par AnsviaLab
Scala : language of the futureScala : language of the future
Scala : language of the future
AnsviaLab854 vues
Go Programming Language by Google par Uttam Gandhi
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by Google
Uttam Gandhi3.4K vues
Rust - Fernando Borretti par Tryolabs
Rust - Fernando BorrettiRust - Fernando Borretti
Rust - Fernando Borretti
Tryolabs 1.1K vues
Introduction to Go programming language par Slawomir Dorzak
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
Slawomir Dorzak5.7K vues
Scala at GenevaJUG by Iulian Dragos par GenevaJUG
Scala at GenevaJUG by Iulian DragosScala at GenevaJUG by Iulian Dragos
Scala at GenevaJUG by Iulian Dragos
GenevaJUG1.3K vues
Programming in scala - 1 par Mukesh Kumar
Programming in scala - 1Programming in scala - 1
Programming in scala - 1
Mukesh Kumar3.9K vues
Scala in Action - Heiko Seeburger par JAX London
Scala in Action - Heiko SeeburgerScala in Action - Heiko Seeburger
Scala in Action - Heiko Seeburger
JAX London10.8K vues
Paris stormusergroup intrudocution par Paris_Storm_UG
Paris stormusergroup intrudocutionParis stormusergroup intrudocution
Paris stormusergroup intrudocution
Paris_Storm_UG556 vues
Getting Functional with Scala par Jorge Paez
Getting Functional with ScalaGetting Functional with Scala
Getting Functional with Scala
Jorge Paez113 vues
Introduction to Spark with Scala par Himanshu Gupta
Introduction to Spark with ScalaIntroduction to Spark with Scala
Introduction to Spark with Scala
Himanshu Gupta6.7K vues

Similaire à Introduction à Scala - Michel Schinz - January 2010

Introducing Pattern Matching in Scala par
 Introducing Pattern Matching  in Scala Introducing Pattern Matching  in Scala
Introducing Pattern Matching in ScalaAyush Mishra
3.3K vues24 diapositives
Scala par
ScalaScala
ScalaZhiwen Guo
1K vues25 diapositives
(How) can we benefit from adopting scala? par
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
1.1K vues69 diapositives
scala.ppt par
scala.pptscala.ppt
scala.pptHarissh16
7 vues25 diapositives
Scala Talk at FOSDEM 2009 par
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
37.2K vues42 diapositives
C# programming par
C# programming C# programming
C# programming umesh patil
435 vues19 diapositives

Similaire à Introduction à Scala - Michel Schinz - January 2010(20)

Introducing Pattern Matching in Scala par Ayush Mishra
 Introducing Pattern Matching  in Scala Introducing Pattern Matching  in Scala
Introducing Pattern Matching in Scala
Ayush Mishra3.3K vues
(How) can we benefit from adopting scala? par Tomasz Wrobel
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel1.1K vues
Functional Programming With Scala par Knoldus Inc.
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
Knoldus Inc.802 vues
Miles Sabin Introduction To Scala For Java Developers par Skills Matter
Miles Sabin Introduction To Scala For Java DevelopersMiles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java Developers
Skills Matter1.4K vues
A Brief Introduction to Scala for Java Developers par Miles Sabin
A Brief Introduction to Scala for Java DevelopersA Brief Introduction to Scala for Java Developers
A Brief Introduction to Scala for Java Developers
Miles Sabin5.2K vues
Scala training workshop 02 par Nguyen Tuan
Scala training workshop 02Scala training workshop 02
Scala training workshop 02
Nguyen Tuan486 vues
Introduction to Functional Programming with Scala par pramode_ce
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce57.6K vues

Plus de JUG Lausanne

Introduction aux algorithmes génétiques par
Introduction aux algorithmes génétiquesIntroduction aux algorithmes génétiques
Introduction aux algorithmes génétiquesJUG Lausanne
180 vues21 diapositives
Développer un moteur d'exécution symbolique en partant de rien par
Développer un moteur d'exécution symbolique en partant de rienDévelopper un moteur d'exécution symbolique en partant de rien
Développer un moteur d'exécution symbolique en partant de rienJUG Lausanne
593 vues51 diapositives
Reverse engineering Java et contournement du mécanisme de paiement inapp Android par
Reverse engineering Java et contournement du mécanisme de paiement inapp AndroidReverse engineering Java et contournement du mécanisme de paiement inapp Android
Reverse engineering Java et contournement du mécanisme de paiement inapp AndroidJUG Lausanne
578 vues24 diapositives
Exemple d'IOT et ML avec Android, Cassandra et Spark par
Exemple d'IOT et ML avec Android, Cassandra et SparkExemple d'IOT et ML avec Android, Cassandra et Spark
Exemple d'IOT et ML avec Android, Cassandra et SparkJUG Lausanne
339 vues76 diapositives
Play! chez Zaptravel - Nicolas Martignole - December 2012 par
Play! chez Zaptravel - Nicolas Martignole - December 2012Play! chez Zaptravel - Nicolas Martignole - December 2012
Play! chez Zaptravel - Nicolas Martignole - December 2012JUG Lausanne
1.2K vues63 diapositives
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012 par
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012JUG Lausanne
882 vues51 diapositives

Plus de JUG Lausanne(20)

Introduction aux algorithmes génétiques par JUG Lausanne
Introduction aux algorithmes génétiquesIntroduction aux algorithmes génétiques
Introduction aux algorithmes génétiques
JUG Lausanne180 vues
Développer un moteur d'exécution symbolique en partant de rien par JUG Lausanne
Développer un moteur d'exécution symbolique en partant de rienDévelopper un moteur d'exécution symbolique en partant de rien
Développer un moteur d'exécution symbolique en partant de rien
JUG Lausanne593 vues
Reverse engineering Java et contournement du mécanisme de paiement inapp Android par JUG Lausanne
Reverse engineering Java et contournement du mécanisme de paiement inapp AndroidReverse engineering Java et contournement du mécanisme de paiement inapp Android
Reverse engineering Java et contournement du mécanisme de paiement inapp Android
JUG Lausanne578 vues
Exemple d'IOT et ML avec Android, Cassandra et Spark par JUG Lausanne
Exemple d'IOT et ML avec Android, Cassandra et SparkExemple d'IOT et ML avec Android, Cassandra et Spark
Exemple d'IOT et ML avec Android, Cassandra et Spark
JUG Lausanne339 vues
Play! chez Zaptravel - Nicolas Martignole - December 2012 par JUG Lausanne
Play! chez Zaptravel - Nicolas Martignole - December 2012Play! chez Zaptravel - Nicolas Martignole - December 2012
Play! chez Zaptravel - Nicolas Martignole - December 2012
JUG Lausanne1.2K vues
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012 par JUG Lausanne
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012
Playframework Realtime Web - Guillaume Bort & Sadek Drobi - December 2012
JUG Lausanne882 vues
CloudBees - Sacha Labourey - May 2011 par JUG Lausanne
CloudBees - Sacha Labourey - May 2011CloudBees - Sacha Labourey - May 2011
CloudBees - Sacha Labourey - May 2011
JUG Lausanne825 vues
Apache Camel - Stéphane Kay - April 2011 par JUG Lausanne
Apache Camel - Stéphane Kay - April 2011Apache Camel - Stéphane Kay - April 2011
Apache Camel - Stéphane Kay - April 2011
JUG Lausanne4.6K vues
Session dédiée à l'analyse de la qualité du code Java - Cyril Picat - Februar... par JUG Lausanne
Session dédiée à l'analyse de la qualité du code Java - Cyril Picat - Februar...Session dédiée à l'analyse de la qualité du code Java - Cyril Picat - Februar...
Session dédiée à l'analyse de la qualité du code Java - Cyril Picat - Februar...
JUG Lausanne980 vues
OpenDS - Ludovic Poitou - December 2010 par JUG Lausanne
OpenDS - Ludovic Poitou - December 2010OpenDS - Ludovic Poitou - December 2010
OpenDS - Ludovic Poitou - December 2010
JUG Lausanne877 vues
Spring Batch - Julien Jakubowski - November 2010 par JUG Lausanne
Spring Batch - Julien Jakubowski - November 2010Spring Batch - Julien Jakubowski - November 2010
Spring Batch - Julien Jakubowski - November 2010
JUG Lausanne1K vues
Infinispan - Galder Zamarreno - October 2010 par JUG Lausanne
Infinispan - Galder Zamarreno - October 2010Infinispan - Galder Zamarreno - October 2010
Infinispan - Galder Zamarreno - October 2010
JUG Lausanne857 vues
No Sql - Olivier Mallassi - September 2010 par JUG Lausanne
No Sql - Olivier Mallassi - September 2010No Sql - Olivier Mallassi - September 2010
No Sql - Olivier Mallassi - September 2010
JUG Lausanne965 vues
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010 par JUG Lausanne
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
JUG Lausanne1K vues
Introduction Groovy / Grails - Cyril Picat - December 2009 par JUG Lausanne
Introduction Groovy / Grails - Cyril Picat - December 2009Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009
JUG Lausanne1.3K vues
Initiation aux tests fonctionnels - Philippe Kernevez - October 2009 par JUG Lausanne
Initiation aux tests fonctionnels - Philippe Kernevez - October 2009Initiation aux tests fonctionnels - Philippe Kernevez - October 2009
Initiation aux tests fonctionnels - Philippe Kernevez - October 2009
JUG Lausanne3.2K vues
Sonar - Freddy Mallet - April 2009 par JUG Lausanne
Sonar - Freddy Mallet - April 2009Sonar - Freddy Mallet - April 2009
Sonar - Freddy Mallet - April 2009
JUG Lausanne669 vues
Maven2 - Philippe Kernevez - March 2009 par JUG Lausanne
Maven2 - Philippe Kernevez - March 2009Maven2 - Philippe Kernevez - March 2009
Maven2 - Philippe Kernevez - March 2009
JUG Lausanne492 vues
Introduction à Google Web Toolkit (GWT) - Philippe Kernevez - February 2009 par JUG Lausanne
Introduction à Google Web Toolkit (GWT) - Philippe Kernevez - February 2009Introduction à Google Web Toolkit (GWT) - Philippe Kernevez - February 2009
Introduction à Google Web Toolkit (GWT) - Philippe Kernevez - February 2009
JUG Lausanne740 vues
XML & Java - Raphaël Tagliani - March 2008 par JUG Lausanne
XML & Java - Raphaël Tagliani - March 2008XML & Java - Raphaël Tagliani - March 2008
XML & Java - Raphaël Tagliani - March 2008
JUG Lausanne705 vues

Dernier

The Coming AI Tsunami.pptx par
The Coming AI Tsunami.pptxThe Coming AI Tsunami.pptx
The Coming AI Tsunami.pptxjohnhandby
14 vues12 diapositives
Discover Aura Workshop (12.5.23).pdf par
Discover Aura Workshop (12.5.23).pdfDiscover Aura Workshop (12.5.23).pdf
Discover Aura Workshop (12.5.23).pdfNeo4j
20 vues55 diapositives
This talk was not generated with ChatGPT: how AI is changing science par
This talk was not generated with ChatGPT: how AI is changing scienceThis talk was not generated with ChatGPT: how AI is changing science
This talk was not generated with ChatGPT: how AI is changing scienceElena Simperl
34 vues13 diapositives
GDSC GLAU Info Session.pptx par
GDSC GLAU Info Session.pptxGDSC GLAU Info Session.pptx
GDSC GLAU Info Session.pptxgauriverrma4
15 vues28 diapositives
NTGapps NTG LowCode Platform par
NTGapps NTG LowCode Platform NTGapps NTG LowCode Platform
NTGapps NTG LowCode Platform Mustafa Kuğu
474 vues30 diapositives
"Node.js Development in 2024: trends and tools", Nikita Galkin par
"Node.js Development in 2024: trends and tools", Nikita Galkin "Node.js Development in 2024: trends and tools", Nikita Galkin
"Node.js Development in 2024: trends and tools", Nikita Galkin Fwdays
37 vues38 diapositives

Dernier(20)

The Coming AI Tsunami.pptx par johnhandby
The Coming AI Tsunami.pptxThe Coming AI Tsunami.pptx
The Coming AI Tsunami.pptx
johnhandby14 vues
Discover Aura Workshop (12.5.23).pdf par Neo4j
Discover Aura Workshop (12.5.23).pdfDiscover Aura Workshop (12.5.23).pdf
Discover Aura Workshop (12.5.23).pdf
Neo4j20 vues
This talk was not generated with ChatGPT: how AI is changing science par Elena Simperl
This talk was not generated with ChatGPT: how AI is changing scienceThis talk was not generated with ChatGPT: how AI is changing science
This talk was not generated with ChatGPT: how AI is changing science
Elena Simperl34 vues
NTGapps NTG LowCode Platform par Mustafa Kuğu
NTGapps NTG LowCode Platform NTGapps NTG LowCode Platform
NTGapps NTG LowCode Platform
Mustafa Kuğu474 vues
"Node.js Development in 2024: trends and tools", Nikita Galkin par Fwdays
"Node.js Development in 2024: trends and tools", Nikita Galkin "Node.js Development in 2024: trends and tools", Nikita Galkin
"Node.js Development in 2024: trends and tools", Nikita Galkin
Fwdays37 vues
Business Analyst Series 2023 - Week 4 Session 8 par DianaGray10
Business Analyst Series 2023 -  Week 4 Session 8Business Analyst Series 2023 -  Week 4 Session 8
Business Analyst Series 2023 - Week 4 Session 8
DianaGray10180 vues
Innovation & Entrepreneurship strategies in Dairy Industry par PervaizDar1
Innovation & Entrepreneurship strategies in Dairy IndustryInnovation & Entrepreneurship strategies in Dairy Industry
Innovation & Entrepreneurship strategies in Dairy Industry
PervaizDar139 vues
The Role of Patterns in the Era of Large Language Models par Yunyao Li
The Role of Patterns in the Era of Large Language ModelsThe Role of Patterns in the Era of Large Language Models
The Role of Patterns in the Era of Large Language Models
Yunyao Li104 vues
The Power of Heat Decarbonisation Plans in the Built Environment par IES VE
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built Environment
IES VE85 vues
Business Analyst Series 2023 - Week 4 Session 7 par DianaGray10
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7
DianaGray10152 vues
Future of AR - Facebook Presentation par Rob McCarty
Future of AR - Facebook PresentationFuture of AR - Facebook Presentation
Future of AR - Facebook Presentation
Rob McCarty66 vues
Webinar : Desperately Seeking Transformation - Part 2: Insights from leading... par The Digital Insurer
Webinar : Desperately Seeking Transformation - Part 2:  Insights from leading...Webinar : Desperately Seeking Transformation - Part 2:  Insights from leading...
Webinar : Desperately Seeking Transformation - Part 2: Insights from leading...
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell par Fwdays
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell
"Node.js vs workers — A comparison of two JavaScript runtimes", James M Snell
Fwdays14 vues
LLMs in Production: Tooling, Process, and Team Structure par Aggregage
LLMs in Production: Tooling, Process, and Team StructureLLMs in Production: Tooling, Process, and Team Structure
LLMs in Production: Tooling, Process, and Team Structure
Aggregage65 vues
Digital Personal Data Protection (DPDP) Practical Approach For CISOs par Priyanka Aash
Digital Personal Data Protection (DPDP) Practical Approach For CISOsDigital Personal Data Protection (DPDP) Practical Approach For CISOs
Digital Personal Data Protection (DPDP) Practical Approach For CISOs
Priyanka Aash171 vues
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or... par ShapeBlue
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
Zero to Cloud Hero: Crafting a Private Cloud from Scratch with XCP-ng, Xen Or...
ShapeBlue209 vues

Introduction à Scala - Michel Schinz - January 2010

  • 2. What is Scala? Scala is a programming language that: • coherently combines the best aspects of object-oriented and functional programming languages, • runs on the JVM and is fully interopeable with Java – a .NET version is in the works, • is statically typed and very concise, • offers a high level of abstraction and good performances.
  • 4. Rational numbers First example: model rational numbers n / d where n and d are integers, and d ≠ 0. Provide addition, multiplication and comparison of rationals.
  • 5. A class for rationals (1) class Rational(n0: Int, d0: Int) { require(d0 != 0) constructor arguments private def gcd(x: Int, y: Int): Int = if (y == 0) x else gcd(y, x % y) no return no explicit type (Int inferred) private val g = gcd(n0.abs, d0.abs) val n: Int = n0 / g public fields val d: Int = d0 / g (immutable) def this(n: Int) = this(n, 1) to be continued… auxiliary constructor
  • 6. A class for rationals (2) …continued def +(that: Rational): Rational = new Rational(this.n * that.d + that.n * this.d, public this.d * that.d) method def *(that: Rational): Rational = new Rational(this.n * that.n, this.d * that.d) override def toString: String = n +"/"+ d } parameterless method
  • 7. Using rationals scala> val r1 = new Rational(1, 3) r1: Rational = 1/3 primary constructor call inferred type scala> val r2 = new Rational(5) r2: Rational = 5/1 auxiliary constructor call scala> r1 + r2 // or: r1.+(r2) res0: Rational = 16/3 scala> res0 * r1 // or: res0.*(r1) res1: Rational = 16/9
  • 8. A companion for rationals singleton companion object for class Rational object Rational { def apply(n: Int, d: Int): Rational = new Rational(n, d) def apply(n: Int): Rational = new Rational(n) val ZERO = new Rational(0) } implicitly calls apply scala> Rational(2,5) + Rational.ZERO res1: Rational = 2/5
  • 9. Ordered objects type parameter trait Ordered[T] { def compare(that: T): Int abstract method def < (that: T): Boolean = (this compare that) < 0 def <=(that: T): Boolean = (this compare that) <= 0 def > (that: T): Boolean = (this compare that) > 0 def >=(that: T): Boolean = (this compare that) >= 0 }
  • 10. Ordered rationals class Rational(n0: Int, d0: Int) extends Ordered[Rational] { … as before provides <, <=, > and >= methods def compare(that: Rational): Int = (n * that.d) compare (that.n * d) }
  • 11. Cells Second example: model mutable cells that contain a single value of some arbitrary type. Additionally, define logging and undoable variants.
  • 12. A class for generic cells make init available as a field class Cell[T](val init: T) { private var v = init mutable field def get(): T = v def set(v1: T): Unit = { v = v1 } ≈ Java’s void override def toString: String = "Cell("+ v +")" }
  • 13. A trait for logging cells trait LoggingCell[T] extends Cell[T] { override def get(): T = { println("getting "+ this) super.get() } override def set(v1: T): Unit = { println("setting "+ this +" to "+ v1) super.set(v1) } }
  • 14. A trait for undoable cells trait UndoableCell[T] extends Cell[T] { import collection.mutable.ArrayStack private var hist = new ArrayStack[T]() override def set(v1: T): Unit = { hist.push(super.get()) super.set(v1) } def undo(): Unit = super.set(hist pop) }
  • 15. Mixin composition new Cell(0) basic integer cell new Cell(0) logging integer with LoggingCell[Int] cell new Cell(0) with LoggingCell[Int] logging, undoable with UndoableCell[Int] integer cell (undos are logged) new Cell(0) with UndoableCell[Int] with LoggingCell[Int] logging, undoable integer cell (undos are not logged)
  • 17. Optional values An optional value is either empty, or contains a single element. Example use: as a clean replacement for null. variance (here co-variant) abstract class Option[+T] { def isEmpty: Boolean def get: T bounded type parameter def getOrElse[U >: T](d: =>U): U = if (isEmpty) d else get by-name parameter …many more methods }
  • 18. Optional values (2) can be matched (see later) & compiler-provided methods case class Some[+T](x: T) extends Option[T] { def isEmpty = false def get = x } case object None subtype of all types extends Option[Nothing] { def isEmpty = true def get = throw new … }
  • 19. Using optional values compiler-provided factory method scala> val v1 = Some("something") v1: Some[String] = Some(something) compiler-provided toString method scala> val v2 = None v2: None.type = None scala> v1 getOrElse "nothing" res1: String = something scala> v2 getOrElse "nothing" res2: String = nothing
  • 20. Tuples A tuple of size n contains exactly n heterogenous elements – i.e. they can be of different types. Example use: a function that has to return n values can return them wrapped in a single tuple. case class Tuple2[+T1,+T2]( _1: T1, _2: T2) case class Tuple3[+T1,+T2,+T3]( _1: T1, _2: T2, _3: T3) etc.
  • 21. Short tuple syntax Scala offers syntactic shortcuts for tuple values: (e1, …, en) ≣ Tuplen(e1, …, en) and for tuple types: (T1, …, Tn) ≣ Tuplen[T1, …, Tn] Example: scala> val p = ("Orwell", 1984) p: (String, Int) = (Orwell,1984) scala> p._1 arguments of case classes are fields res1: String = Orwell
  • 22. (Im)mutable collections Options and tuples are immutable. Standard collections (sequences, sets, maps) are provided in mutable and immutable variants. Mutable collections are similar to the ones found in Java and other imperative languages. Immutable collections are similar to the ones found in typical functional languages.
  • 23. Immutable lists An immutable list is either empty or composed of a head element and a tail, which is another list. abstract class List[+T] { def isEmpty: Boolean def head: T def tail: List[T] def ::[U >: T](x: U): List[U] = new ::[U](x, this) …many more methods }
  • 24. Immutable lists (2) case class ::[T](val head: T, val tail: List[T]) extends List[T] { def isEmpty = false } case object Nil extends List[Nothing] { def isEmpty = true def head: Nothing = throw new … def tail: List[Nothing] = throw new … }
  • 25. Sequences, maps and sets scala> val aSeq = Seq("zero","one","two") scala> aSeq(1) res1: String = one scala> val aMap = Map("zero" -> 0, "one" -> 1, "two" -> 2) scala> aMap("one") res2: Int = 1 scala> val aSet = Set("zero","one","two") scala> aSet("one") res3: Boolean = true
  • 26. For loops For loops enable iteration over the elements of collections, using a syntax that is reminiscent of SQL queries. for (user <- users if (user.isMale && user.age > 30)) yield user.name
  • 28. Pattern matching Instances of case classes can easily be constructed: scala> Some((1,2)) res: Some[(Int,Int)] = Some((1,2)) Pattern matching makes deconstruction of case classes similarly easy.
  • 29. Integer division def divMod(n: Int, d: Int): Option[(Int,Int)] = { if (d == 0) None else { …compute quotient q and remainder r Some((q, r)) } }
  • 30. Using integer division def testDivMod(n: Int, d: Int) = divMod(n, d) match { case Some((q, r)) => println("quot: "+ q +" rem: "+ r) case None => println("<no result>") } scala> testDivMod(5, 3) quot: 1 rem: 2 scala> testDivMod(5, 0) <no result>
  • 31. Pattern matching lists Since lists are recursive, it is natural to manipulate them with recursive functions. Furthermore, since they are defined as a disjunction of two cases (non-empty / empty list), it is natural to use pattern matching to do a case analysis. Example: a function to sum a list of integers. def sum(l: List[Int]): Int = l match { case h :: t => h + sum(t) case Nil => 0 }
  • 32. Typed patterns Pattern matching can also be used to discriminate on the type of a value: supertype of all types def succAny(x: Any): Any = x match { case i: Int => i + 1 Int and Long are not case l: Long => l + 1 case classes case other => other } scala> succAny(2) res1: Any = 3 scala> succAny("two") res2: Any = two
  • 33. Exception handling Unsurprisingly, exception handling is done using pattern matching: try { val f = new FileInputStream("f.txt") println(f.read()) f.close() } catch { _ is a wildcard case _: FileNotFoundException => println("not found") case e: IOException => println("other error: " + e) }
  • 35. What is FP? The functional style of programming is one that relies on mathematical functions as the basic building block of programs. In mathematics, a function always returns the same result when applied to the same arguments. Therefore, the functional style of programming strongly discourages the use of side-effects – i.e. variables and other kinds of mutable data.
  • 36. What is a FPL? A functional programming language is one that encourages the functional style of programming by: • offering first-class functions that can be manipulated like any other value, • providing lightweight syntax to define arbitrarily-nested functions, • discouraging the use of side-effects, for example by providing libraries of immutable data-structures.
  • 37. Why is FP interesting? Side-effects complicate several classes of programs, like: • concurrent programs with shared, mutable state, • programs that need to do “time travel”, e.g. interactive programs with undo, SCMs, … • programs that need to work on a consistent state of some data, e.g. a live backup program, • etc.
  • 38. A trait for functions trait Function1[F, T] { f => def apply(x: F): T new name for this def compose[F2](g: Function1[F2, F]) : Function1[F2, T] = new Function1[F2, T] { def apply(x: F2): T = f.apply(g.apply(x)) } override def toString = "<fun>" }
  • 39. Using functions as values scala> val succ = new Fun[Int,Int] { def apply(x: Int) = x + 1 } succ: …with Function1[Int,Int] = <fun> scala> val twice = new Fun[Int,Int] { def apply(x: Int) = x + x } twice: …with Function1[Int,Int] =<fun> scala> succ.apply(6) res1: Int = 7 scala> twice.apply(5) res2: Int = 10 scala> (succ compose twice).apply(5) res3: Int = 11
  • 40. se ! Using functions as values W or ks ,b ut w ay to o ve rb o scala> val succ = new Fun[Int,Int] { def apply(x: Int) = x + 1 } succ: …with Function1[Int,Int] = <fun> scala> val twice = new Fun[Int,Int] { def apply(x: Int) = x + x } twice: …with Function1[Int,Int] =<fun> scala> succ.apply(6) res1: Int = 7 scala> twice.apply(5) res2: Int = 10 scala> (succ compose twice).apply(5) res3: Int = 11
  • 41. Functional syntactic sugar anonymous function scala> val succ = { x: Int => x + 1 } succ: (Int) => Int = <function1> a.k.a. Function1[Int, Int] scala> val twice = { x: Int => x + x } twice: (Int) => Int = <function1> scala> (succ compose twice)(5) res1: Int = 11 implicit apply
  • 42. Partial application Function values can also be created by applying existing functions or methods to a (possibly empty) subset of their arguments: scala> val succ: Int=>Int = _ + 1 succ: (Int) => Int = <function1> scala> val toStr: Any=>String = _.toString toStr: (Any) => String = <function1> scala> toStr(0123) res0: String = 83
  • 43. Collections as functions Most collections are functions: • Seq[T] has type Int=>T, • Map[K,V] has type K=>V, • Set[T] has type T=>Boolean. This explains the common notation to access their elements: it’s simply function application!
  • 44. Operating on collections Functional values are ideal to operate on collections. Examples: scala> val s = Seq(1,2,3,4,5) scala> s map (_ + 1) res1: Seq[Int] = List(2, 3, 4, 5, 6) scala> s reduceLeft (_ * _) res2: Int = 120 scala> s filter (_ % 2 == 0) res3: Seq[Int] = List(2, 4) scala> s count (_ > 3) res4: Int = 2 scala> s forall (_ < 10) res5: Boolean = true
  • 46. Solving problem 8 val n = "7316717653133062491922511967442…" val digits = s.toList map (_.asDigit) def prods(l: List[Int]): List[Int] = l match { case a :: (t@(b :: c :: d :: e :: _)) => (a * b * c * d * e) :: prods(t) case _ => List() } prods(digits) reduceLeft (_ max _)
  • 47. For loops translation The for notation is pure syntactic sugar. The example: for (user <- users if (user.isMale && user.age > 30)) yield user.name is automatically expanded to: users .filter(user => user.isMale && user.age > 30) .map(user => user.name)
  • 49. Scala implicits Scala offers two notions of implicit entities that are automatically inserted by the compiler in certain contexts: • Implicit conversions, which can be applied automatically to transform a type-incorrect expression into a type-correct one. • Implicit parameters, which can be automatically passed to a function.
  • 50. Implicit conversions An implicit conversion from Int to Rational can be added to the latter’s companion object: object Rational { …as before implicit def i2r(i: Int): Rational = Rational(i) } scala> 2 + Rational(1,3) // i2r(2) + … res2: Rational = 7/3 scala> Rational(1,3) + 3 // … + i2r(3) res3: Rational = 10/3
  • 51. “Pimp my library” Implicit conversions make it possible to “augment” existing classes by implicitly wrapping them – known as the Pimp my library pattern. This technique is heavily used in the standard library to improve anemic Java classes (e.g. String, Integer, Boolean, arrays, etc.). scala> "1337" strings are really Java strings res1: java.lang.String = 1337 implicit conversion scala> "1337".toInt res2: Int = 1337
  • 52. Implicit parameters repeated parameter def max[T](xs: T*) (implicit ord: Ordering[T]): T = xs reduceLeft ord.max implicitly Ordering.Int scala> max(4, -2, 12, 25, 7, -1, 2) res1: Int = 25 scala> max(4, -2, 12, 25, 7, -1, 2) (Ordering.Int.reverse) res2: Int = -2 scala> max(1 to 20 : _*) res3: Int = 20 pass all elements as separate arguments
  • 54. XML literals Scala supports XML literals, which are translated to instances of various classes in scala.xml. scala> val hello = <p>Hello <b>world</b></p> hello: scala.xml.Elem = <p>Hello <b>world</b></p> scala> val name = "Roger&Co." name: java.lang.String = Roger&Co. scala> val hello = arbitrary Scala expression <p>Hello <b>{ name }</b></p> hello: scala.xml.Elem = <p>Hello <b>Roger&amp;Co.</b></p>
  • 55. XPath-like queries scala> val users = <users> <user name="Roger" age="12"/> <user name="Mary" age="44"/> <user name="Jean" age="12"/> </users> scala> users "@name" res1: scala.xml.NodeSeq = RogerMaryJean scala> (users "@age") map (_.toString.toInt) reduceLeft (_ max _) res2: Int = 44
  • 56. XML pattern matching def parseRow(r: xml.Node): (String, Int) = r match { case <tr><td>{ name }</td> <td>{ age }</td></tr> => (name.text, age.text.toInt) } scala> val table = <table> <tr><td>Roger</td><td>12</td></tr> <tr><td>Mary</td><td>44</td></tr> </table> scala> (table "tr") map parseRow res1: Seq[(String, Int)] = List((Roger,12), (Mary,44))
  • 58. Properties for rationals The operations we defined on rationals should satisfy several properties: • ∀x, y ∈ Q: x + 0 = 0 + x = x • ∀x, y ∈ Q: x + (y + z) = (x + y) + z • etc. ScalaCheck makes it possible to express such properties and test them on random rationals. Extensive use of implicits keep the client code very concise.
  • 59. Properties for rationals object RatProps extends Properties("Rat") { property("+ left unit") = Prop.forAll((x: Rational) => 0 + x == x) property("+ right unit") = Prop.forAll((x: Rational) => x + 0 == x) property("+ associativity") = Prop.forAll((x: Rational, y: Rational, z: Rational) => (x + y) + z == x + (y + z)) }
  • 60. Generating rationals ScalaCheck doesn’t know how to generate arbitrary rationals, but we can easily define a generator for them: implicit def arbRat: Arbitrary[Rational] = Arbitrary { Gen.sized(sz => for (n <- Gen.choose(-sz, sz); d <- Gen.choose(-sz, sz) suchThat (_ != 0)) yield Rational(n, d)) }
  • 61. Testing rationals % + + + scala Rat.+ Rat.+ Rat.+ RatProps left unit: OK, passed 100 tests. right unit: OK, passed 100 tests. associativity: OK, passed 100 tests. When a property can be falsified (here the incorrect property ∀x ∈ Q: x = 0), the counter-example is presented: ! Rat.wrong: Falsified after 0 passed tests. > ARG_0: 1/2
  • 62. Further reading http://www.scala-lang.org/ Two books about Scala: • Programming in Scala by Odersky, Spoon & Venners • Programming Scala by Wampler & Payne One book about functional programming: • The Functional Approach to Programming by Cousineau, Mauny & Callaway