Scala: come recuperare la programmazione funzionale e perché
1. Scala: come recuperare la
programmazione funzionale e
perché
Edmondo Porcu
Università di Cagliari, 10/05/2013
4. Agenda
1. Introduzione - 10 minuti
2. Scala tutorial e demo – 40 minuti
3. Suggerimenti per gli interessati – 10 minuti
4. Extra: uno sguardo al mercato del lavoro per
gli interessati: NoSQL, Hadoop, FP
7. L’espressività di un linguaggio
* http://en.wikipedia.org/wiki/Halstead_complexity_measures
- Un concetto molto discusso
- Definizione da Wikipedia
(http://en.wikipedia.org/wiki/Expressive_power):
- Ampiezza delle idee che si possono esprimere tramite un
linguaggio
- In pratica, quando si parla di linguaggi di programmazione, molto
spesso ci si riferisce a «practical expressivity» => brevità e
leggibilità
Definizione più semplice ed intuitiva:
la difficoltà nell’esprimere un concetto in un certo linguaggio
8. Halstead complexity measure (1977)
* http://en.wikipedia.org/wiki/Halstead_complexity_measures
N(bugs) proporzionale a N(righe di codice)
Un linguaggio più espressivo è sempre degno di
interesse
9. Un possibile confronto
Utilizzando LOC/commit su 7,5 milion progetti/mese open source
- 52 linguaggi differenti, ma i risultati hanno senso?
- I linguaggi ad alto livello sono più espressivi (Python [#27] , Ruby[#34]) dei linguaggi a basso
livello ( C[#50], C++ [#45], Java[#44] )
- I linguaggi funzionali sono i più espressivi: Haskell [#10], Erlang[#22], F#
[#21], Clojure[#7], Scala[#18]
14. La storia di
• Nel 1999 Odersky divenne professore all’Ecole Polytechnique Federale de
Lausanne, concentrando la sua ricerca sul miglioramento di linguaggi FP e OO
• Progetto Scala inizia nel 2001, prima versione rilasciata nel 2003
• Prima versione del compilatore scritto in Java
• Nella versione 2.0.0 il compilatore era già scritto in Scala
• Attuale versione 2.10.1 (Marzo 2013)
• Dal 2011, Odersky diventa Chairman di una società dedicata
a fornire supporto commerciale per Scala: Typesafe
• Ottiene oltre 20$ m di finanziamento. Headquarters nella
Silicon Valley
15. Martin Odersky
• Autore di un linguaggio funzionale chiamato Pizza, nel
1995, che compilava in java bytecode
• Pizza divenne quello che oggi sono i Java generics
• Nel 1997 su richiesta della Sun Microsystems Odersky si
occupa del compilatore Java 1.1
• Odersky fu responsabile di Javac dalla versione Java 1.1
all’1.4
16. InfoQ survey
What is the next language on the JVM?
• 27 Nov 2012
• Scala il più votato
http://www.infoq.com/research/next-jvm-
language?utm_source=infoqEmail&utm_medium=WeeklyNL_ResearchCont
ent&utm_campaign=050713news
18. James Gosling
Rod Johnson
Inventore del Java
Inventore del framework di maggior successo per Java
(Spring framework)
«Se oggi dovessi scegliere un altro
linguaggio al di fuori del Java, sarebbe
Scala»
«Vorrei un linguaggio con cui fare delle cose
interessanti in maniera semplice, non un
linguaggio per fare solo delle cose semplici»
«Oramai programmo solo in Scala»
Martin Odersky
19. Perchè Scala?
La scalabilità della programmazione funzionale
Senza rinunciare alla programmazione ad oggetti
Sulla JVM (Interoperabile con Java)
Con strumenti di sviluppo maturi (Eclipse)
Migliorato e progettato da un’università
20. Perchè Scala?
• OP + FP sulla JVM
• Strongly typed
• Type inference
• Parametri di default & optional types
• Lambda functions
• Collezioni funzionali
• Interfacce (traits) con metodi concreti
• Covariance/contravariance/invariance
• Tipi astratti
• Pattern matching
• Implicits
• Parallelismo
21. Una storia già vista?
• Spring Framework 2.0 Dependency Injection fu così di
successo da diventare parte di JEE5
• Idem per Hibernate, le cui idee sono diventate parti dello
standard JPA
• Le idee di Scala saranno integrate dal Java?
– Type inference parziale in Java 7
– Java8 conterrà Lambda expressions ed un miglior supporto per
parallelismo...
– http://openjdk.java.net/projects/jdk8/features
– Java 9 puramente OO ( non ci saranno più i tipi primitivi )
• JDK 8 previsto non prima di Settembre 2013 !
23. • Shell interattiva
• Con il vostro classpath
• Per prototipare/testare
READ PRINT EVAL LOOP
24. INDOVINA CHI?
Joshua Bloch
Ex Chief Java Architect di
Google
Autore di Effective Java
(arrivato alla seconda
versione)
L’unica guida a scrivere
un buon Java
25. public class Person {
private String lastName;
private String firstName;
public Person() {
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
In Java...
26. Una parola sull’immutabilità
- 13esimo suggerimento nel libro Item 13 of
Effective Java, 2° edition, la bibbia del Java
“Immutable objects have a very compelling list of
positive qualities. Without question, they are among
the simplest and most robust kinds of classes you can
possibly build. When you create immutable
classes, entire categories of problems simply
disappear”
- In realtà, già nel 2003 Brian Goletz lo suggeriva:
http://www.ibm.com/developerworks/java/library/j-
jtp02183/index.html
27. La nostra persona in bello stile
public class Person {
public final String lastName;
public final String firstName;
public final DateTime dateOfBirth;
public Person(String lastName, String firstName, DateTime dateOfBirth) {
this.lastName = lastName;
this.firstName = firstName;
this.dateOfBirth = dateOfBirth;
}
}
28. public Person() {
}
public Person(String lastName){
this.lastName=lastName;
}
public Person(String firstName){
this.firstName=firstName;
}
In Java...
29. Construttori multipli
• Fonte di errore
• Quale dei 18 construttori bisogna usare nelle
classi derivate?
• Come gestire gli errori di inizializzazione ?
• Joshua Bloch: preferite factory methods/builder
(Item 1: Static Factory Method)
30. Factory methods !
• Proprietà immutabili => unico costruttore
con tutti i parametri
• Si può renderlo privato, obbligando a
passare per factory methods
• Gestione delle eccezioni semplice e pulita!
31. V1 factory methods
private Person(String lastName, String firstName, DateTime dateOfBirth) {
this.lastName = lastName;
this.firstName = firstName;
this.dateOfBirth = dateOfBirth;
}
public static Person newPerson(String lastName, String firstName, DateTime dateOfBirth) {
return new Person(lastName,firstName,dateOfBirth);
}
public static Person justBorn(String lastName, String firstName) {
return new Person(lastName,firstName,DateTime.now());
}
32. V2 factory methods
public static Person newPerson(String lastName, String firstName, DateTime dateOfBirth)
throws IllegalArgumentException{
if(lastName==null)
throw new IllegalArgumentException("Invalid person data", new
NullPointerException("LastName can't be null"));
if(firstName==null)
throw new IllegalArgumentException("Invalid person data", new
NullPointerException("FirstName can't be null"));
if(dateOfBirth==null)
throw new IllegalArgumentException("Invalid person data", new
NullPointerException("DateOfBirth can't be null"));
return new Person(lastName,firstName,dateOfBirth);
}
Joshua Bloch: Throw exceptions appropriate to
the abstraction (Item 61).
33. In Scala
• L’immutabilità è incoraggiata tramite una keyword: val
• Un solo costruttore per classe è possibile, tutti gli altri sono obbligati
a chiamarlo
• Esistono parametri con valori di default
– Molte volte i construttori multipli sono stati creati per questo motivo
• I singleton sono implementati tramite “object”, quidi non esistono
metodi statici.
• In un solo file sorgente si possono definire più classi/object
• Un object con lo stesso nome della classe si chiama ”companion
object” ha i suoi stessi access rights
34. In Scala
class ScalaPerson private(val lastName:String, val firstName:String, val dateOfBirth:DateTime) {
}
object ScalaPerson {
def apply(lastName:String, firstName:String, dateOfBirth:DateTime = DateTime.now()) = new
ScalaPerson(lastName,firstName,dateOfBirth)
}
Construttore privato
Companion object
Proprietà immutabile e argomento del
costruttore
Valore di default
PS: non scrivete codice così. Fate un test sui parametri e ritornate
Either[IllegalArgumentException,ScalaPerson]. O meglio ancora
Validation[IllegalArgumentException, ScalaPerson]
35. Case classes
• Classi con solo proprietà immutabili
• Keyword case
• Hashcode and equals generati
automaticamente
– Item 11 di Effective Java
• Inheritance deprecated!
– Difficile non rompere il contratto se si eredità
delle classi
36. Funzioni: oggetti in Scala
scala> val a: Int => Int = i => i * 2
a: Int => Int = <function1>
scala> val a: Function1[Int,Int] = i => i * 2
a: Int => Int = <function1>
37. Collezioni funzionali
• Mutabili ed immutabili
– Classi differenti che implementano una parte di
tratti in comune
– Mai più l’orrore di Java.util.List (Optional add )
• Un punto di forza di Scala:
– filter
– map
– flatMap
– partition
– groupBy
– 115 funzioni disponibili su List
38. Trait: interfacce estese
• Le interfacce si chiamano trait
• Non solo metodi astratti , ma anche metodi concreti
• Niente più gerarchia:
– MyInterface
– MyAbstractClass (implementazione standard di
MyInterface)
– MyClass1
• Permettono il “cake pattern” : costruire oggetti
complessi “mixando” più traits
39. Covarianza/Controvarianza/Invarianza
- A[B] è covariante in B se, per C<B A[C]
< A[B] (in Scala si esprime con il +)
- A[B] è controvariante in B se, per C>B
A[C] < A[B] (in scala si esprime con il -)
- Invarianza: A[B] < A[C] B=C
40. In Java:
public static void main(String []args) throws Exception{
Person persons[] = new Person[2];
Object[] personsAsObject = persons;
personsAsObject[0] = new Cat();
}
Neanche un warning!!
Exception in thread "main" java.lang.ArrayStoreException: Cat
at Person.main(Person.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j
ava:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Covarianza/Controvarianza/Invarianza
41. In Scala:
def main(args:Array[String]) {
val array = Array.empty[Person]
val castedArray:Array[Object] = array
}
error: type mismatch;
found : Array[Person]
required: Array[Object]
Note: Person <: Object, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ <:
Object`. (SLS 3.2.10)
val castedArray:Array[Object] = array
Covarianza/Controvarianza/Invarianza
42. • Correttamente implementata nelle
collection (ex. List[+A] )
• E nelle FunctionN. Quiz: Perchè?
Covarianza/Controvarianza/Invarianza
trait Function1[-T1, +R] extends AnyRef {
def apply(v1: T1): R
}
43. Pattern matching
• Uno switch sophisticato, compreso sulla classe dell’oggetto
• Esempio: Option[T] può essere Some o None.
– Obbliga a gestire il caso in cui un valore non sia specificato, usatelo
senza pietà!
def printMark(mark:Option[String]) = {
val result = mark match {
case Some(value) => "You obtained " + value
case None => "You failed the exam"
}
println(result)
}
44. Implicits
• Metodi, argomenti o oggettin automaticamente
risolti dal compilatore.
• Utilissimi per:
– Automaticamente convertire da A a B
– Implementare DSL
– Ad-Hoc polymorphism
• Esempi:
– Semigroup typeclass
– Specs2 testing
– Future tasks scheduling
45. Parallelismo
• Tre astrazioni chiave:
– Parallel collection
– Futures
• Estendono e migliorano i java.util.concurrent.Future
• Molto più flessibili
– Actors
• Paradigma di calcolo parallelo basato su message-passing
• Scalabile su un numero elevato di processori e/o server
46. E i lati negativi?
• Più difficile da imparare
• Type system complesso
– Turing complete
– Ho fatto crushare il compilatore diverse volte
• Non vorrete più tornare indietro!
48. Come continuare...
• Scala-lang website
• Functional programming principles in Scala – Corso gratuito online
• Twitter Scala school
• Scala wiki at Stackoverflow:
• Scala for Java Refugees
• Libri:
– Tantissimi, nell’ordine suggerisco:
• Scala for the impatient
• Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine
• Programming in Scala, 2° edition
• Functional programming in Scala (attualmente solo in Early Access Program)
49. Come continuare (2) – Il sottoscritto
• Training seguiti:
– Advanced Scala by Typesafe
– Typeful Scala: Exploit the power of types
• 4 libri letti su Scala
• Scala silver badge @ Stackoverflow
• Membro attivo delle più importanti mailing list
• Seguitemi su twitter @edmondo1984
• Ma seguite soprattutto i guru: Viktor Klang, Miles Sabin, Eric
Torreborre, Jonas Boner, Martin Odersky, Daniel
Sobral, Heiko Seeberger, Tony Morris, Paul Philips
52. Play! Framework
• LinkedIn è basato su Play!, così come il
sito di the Guardian
• Ruby on Rails con un linguaggio
funzionale
• Probabilmente il web framework più
moderno in circolazione
54. Uno sguardo al mondo del lavoro
- Capirlo richiede sforzo (arghhhh!)
- Uno sforzo che dovrete fare per tutta la
vostra carriera
- Siete tra i meglio posizionati al mondo per
trovare lavoro nella società del futuro
56. Non sempre va così bene...
Alcune tecnologie non superanno la fase di early
adopting”: c’è un baratro, in inglese “chasm”
http://en.wikipedia.org/wiki/Crossing_the_Chasm (Geoffrey Moore)
57. Capite quali tecnologie salteranno il
baratro
Imparate a padroneggiarle prima
degli altri
Vendetevi, siete richiesti!
58. Seguite le scelte degli altri in ritardo (late
adopters)
Sarete in competizione con chi ha
sistematicamente più esperienza di voi nelle
tecnologie richieste
Sarete solo della manodopera qualificata
59. Come si fa?
• Interessarsi a chi usa la tecnologia, come
e perchè
• Leggere, leggere, leggere e poi leggere
• Su riviste non tecniche, ma “business”
60. Esempi di letture utili
• McKinsey, Deloitte, Accenture, tutte le
società di consulenza
– Pubblicazioni trimestrali disponibili
gratuitamente online
• ITBusinessEdge
• Giornali economici in generale
61. Trend #1: NoSQL
• Basi di dati non relazionali = NO JOIN
• Varie tipologie:
– Key/Value (Amazon SimpleDB)
– Column Oriented (Cassandra)
– Document oriented (MongoDB)
– Graph oriented (Neo4J)
• Scalabilità orizzontale e high-availability
– Il design è stato fatto pensando che il modo naturale di
utilizzare il database sia per cluster
– I.e. Oramai un solo nodo non è sufficiente a contenere tutti
i dati
62. Trend #1: NOSQL
DB Offerte su
Indeed.com
MongoDB 2812
Cassandra 1728
Neo4J 103
CouchDB 382
Dati estratti il
4 maggio
2013
63. Trend #2: Data scientist
• Sapere utilizzare tecnologie adatte a processare parallelamente una
grande quantità di dati
• Alcune università iniziano ad offrire master in “Data scientist” o
perlomeno corsi
– http://analytics.ncsu.edu/?page_id=1799
– https://www.coursera.org/course/datasci
• Secondo McKinsey,da qua al 2018 mancheranno sul mercato del
lavoro 190.000 data scientist!
– Pensate quanto varranno quelli che ci saranno
• Hadoop è la regina delle tecnologie:
– MapReduce paper presentato da Jeff Dean di Google nel 2004
http://static.usenix.org/event/osdi04/tech/full_papers/dean/dean.pdf
– Hadoop è l’implementazione di maggior successo
64. Esempi...
Keyword Fonte Offerte di lavoro
Data Scientist Indeed.com 88777
Hadoop Indeed.com 5898
Data Scientist Careers.stackoverflow.com 412
Hadoop Careers.stackoverflow.com 60
65. Trend #3: FP
IBM DeveloperWorks:
Functional thinking: Why functional programming is
on the rise
Date: 29 Jan 2013
Summary: Java™ developers should learn functional
paradigms now, even if they have no immediate plans to
move to a functional language such as Scala or Clojure.
Over time, all mainstream languages will become more
functional; Neal Ford explores the reasons why in this
installment.
66. FP job offer on LinkedIn
Java/Scala Web Developer
Shazam Entertainment - London, United Kingdom
(London, Regno Unito)
Extract from LinkedIn post offer:
-The willingness to learn Functional Programming paradigms (even better
if you already enjoy FP).
-You should love both working in teams – even when you produce
individual works, it will be as part of the larger Shazam team.
-A good understanding of MVC architecture, how this applies to the
web, as well as experience implementing websites using any of the
current frameworks in the Java and Scala ecosphere (though experience
with Play! Framework is a bonus).
- The ability to pick up additional tasks outside of the core skill sets of
Java and Scala in order to meet the teams commitments (we love flexible
people who like learning).