Aspe2Avanza5deiLinguaggidi Programmazione h;p://www.scala-lang.org/ M.Odersky,L.Spoon,B.Venners comunitàmolto dinamica: ProgramminginScala Ar5maed. even$,formazione, blog,social h;p://www.meetup.c om/it/Scala-by-the-Lag go n Scala:dadoveviene? 1996-1999 : Pizza 1998 – 2000: GJ, Java generics, javac ( “make Java better” ) inizia il distacco dai linguaggi staticamente tipati 2003 – 2006: The Scala “Experiment” 2006 – 2009: An industrial strength programming language ( “make a better Java” ) codice conciso sintassi , aspetti di base, librerie FP Java C # Java8 3.0 X10 closurese ML Haskell Scala comprehensions Uniform object model Ruby Smalltalk Uniform access principle FP+OOP OCaml, OHaskell PLT-Scheme Erlang Eiffel costrutti di concorrenza Scala:cos’è? • Un linguaggio staticamente tipato – ma con una sintassi leggera Scala:siusa? • Gira su Java Virtual Machine: Scala copila in bytecode • È completamente interoperabile con Java… • Integra la programmazione funzionale e object-oriented – un modello ad oggetti uniforme – funzioni higher-order e pattern matching – nuovi modi di comporre e astrarre espressioni • È un linguaggio scalabile: – con gli stessi costrutti si scrivono agevolmente piccoli script e grandi programmi – è facile creare domain-specific languages molto ricchi (es. Attori) • Supporto efficace alla programmazione concorrente: – futures e actors sono strumenti potenti per organizzare sistemi concorrenti ad un alto livello di astrazione Completainteroperabilita’conJava Author.scala Java’sComparable<T> interface class Author(val firstName: String, val lastName: String) extends Comparable[Author] { override def compareTo(that: Author) = { val lastNameComp = this.lastName compareTo that.lastName if (lastNameComp != 0) lastNameComp else this.firstName compareTo that.firstName } } object Author { def loadAuthFromFile(file: java.io.File): List[Author] = ... } Completainteroperabilita’conJava App.java convertsfromScalacollec5ons toJavacollec5ons import static scala.collection.JavaConversions.asJavaCollection; public class App { public List<Author> loadAuthFromFile(File file) { return new ArrayList<Author>( asJavaCollection(Author.loadAuthFromFile(file))); } public void sortAuth(List<Author> ats){Collections.sort(ats);} public void displaySortedAuthors(File file) { List<Author> authors = loadAuthFromFile(file); sortAuth(authors); for (Author a : authors) { System.out.println(a.lastName() + ", " + a.firstName()); } }} Scala:siusa? Scala:siusa? • Gira su Java Virtual Machine: Scala copila in bytecode • È completamente interoperabile con Java… • C’è un compilatore per .NET – .NET ha un type system molto diverso e supporta gia’ linguaggi con ingredienti funzionali: C#, F# – Dotty, the next generation Scala compiler – Scala native: compila Scala code in LLVM per native execution • IDE: SBT (Simple Build Tool), plugin per IntelliJ, NetBeans, Eclipse • REPL (Read-Eval-Print-Loop) Scalatomeetthedemandingreal-5me contentsearching,indexingorupda5ng. Scala:chilousa? Usingactorstheywereabletoreducethesearchindexbuild5me from20hourstojustone. Requestpa;erns,hesays,arehardtopredictso THEABILITYTOEASILYSCALETHESERVICESWASESSENTIAL. Scala-basedtechnologies: • Akka(Actors), • ApacheSpark(Clustercompu5ngandDataanalysis), • ApacheKaSa,Flink(streamprocessing) • Scala.js(integra5onwithJavaScript,compilesScala codetoJavaScript) • ScalaonAndroid • … Scalavieneado;ato perchésidimostra ada4o allaprogrammazioneconcorrente manellinguaggiononcisono(nonpiù!) primi$vediconcorrenza! Perché? Iservizinelback-enderanoscri2inRuby, poisonomigra5inScala Ilmodelloada7orihapermessodiscalareil concurrentmessagequeuesystem adungrannumerodiuten9 1) Supporta bene la programmazione funzionale… – funzioni higher order, pattern matching, dati immutabili PerchélaFPècrucialeperla programmazioneconcorrente? • La concorrenza è difficile, molto difficile – Data races, deadlocks, side effects in memoria,… • Motivo: interleaving non-deterministico dei thread – Interleaving diversi hanno effetti diversi sullo quelle stato della con valore modificabile!! memoria condivisa Eliminando variabili condivise eliminiamo concurrency hazards Scalavieneado;ato perchésidimostra ada4o allaprogrammazioneconcorrente Perché? 1) Supporta bene la programmazione funzionale… 2) la fa interagire in modo efficace con la programmazione OO :Future[T] val x = future { someExpensiveComputation() } val y = future { someOtherExpensiveComputation() } val z = for (a <- x; b <- y) yield a*b for (c <- z) println("Result: " + c) println("Meanwhile, the main thread goes on!") someExpensiveComp a*b someOtherExpensiveComp print(“Result”+c) print(“Meanwhile...”) Parallel Graph Processing, Parallel Collections, Parallel DSLs Esempidicodice :T Actors Si possono definire DSLs per la concorrenza e il parallelismo: L’unico modo efficace di lavorare con strutture dati immutabili è la programmazione funzionale Futures Futures 1) Hello, World! codice conciso, chiaro, elegante HelloWorld class HelloWorld { public static void main(String[] args){ System.out.println(“Hello, World!”); } } HelloWorld class HelloWorld { public static void main(String[] args){ System.out.println(“Hello, World!”); } } Singletonobject:classeconunasolaistanza println(“Hello, World!”) Scalainterpreter: • unashellinteraCvachevalutaespressioni(integratainIDE) unoscriptterminaconun’espressione-risultato • interpretagliscript:sequenzadiistruzionidentrounfilehello.scala un’applicazioneèuninsiemedidefinizioni cheeseguoconilcomando>scala hello.scala object HelloWorld { def main(args: Array[String]){ println(“Hello World!”) } } Trait:interfacciaconunmetodomain object HelloWorld extends Application { println(“Hello World!”) Codicedel } costru;oredidefault println(“Hello, World!”) unoscriptterminaconun’espressione-risultato un’applicazioneèuninsiemedidefinizioni Array[T]èuna object HelloWorld { classegenerica def main(args: Array[String]){ println(“Hello World!”) } No5podiritorno:Unit No; } • Sicompilailfilecon> scalac Hello.scala • Vieneprodo;oHello.classchecon5enestandardJavabytecode • Sieseguecon> scala HelloWorld Esempidicodice 1) Hello, World! 2) Definire una classe molto semplice codice conciso, chiaro, elegante Unaclasse public class Person { public final String name; public int age; Person(String name, int age) { this.name = name; this.age = age; } } variabili:valoppurevar? • Due tipi di variabili: val msg = “Hello world” immutable variable non può essere modificata mutable variable var i=0 • i parametri dei metodi/funzioni sono vals – i valori dei parametri non cambiano, per costruzione! – i parametri sono passati per valore, come in Java class Person( val name: String, var age: Int) {} Immutablevalue read-onlyvariable val b = new Person(“Pippo”,10) println(b.age) Esempidicodice 1) Hello, World! 2) Definire una classe molto semplice 3) Dato un elenco di Persone, produrre un elenco di maggiorenni ed un elenco di minorenni codice conciso, chiaro, elegante nalS FuncEo tyle Ogni volta che si può, meglio usare vals, è più facile ragionare su ciò che si è scritto! importjava.util.ArrayList; ... Person[]people=...; Lista implementata con un resizable array Person[]minors; Person[]adults; ArrayList<Person>minorsList=newArrayList<Person>(); ArrayList<Person>adultsList=newArrayList<Person>(); for(inti=0;i<people.length;i++) if(people[i].age<18)minorsList.add(people[i]); elseadultsList.add(people[i]); minors=minorsList.toArray(people); adults=adultsList.toArray(people); Restituisce un array del tipo del parametro val people: Array[Person] = ... val (minors, adults) = people partition (_.age < 18) val people: Array[Person] val (minors, adults) = people partition (_.age < 18) val people: Array[Person] val (minors, adults) = people partition (_.age < 18) È un metodo della classe Array[T] def partition(p: T=>Boolean):(Array[T], Array[T]) È un metodo della classe Array[T] def partition (p: T=>Boolean) : (Array[T], Array[T]) È un valore funzione, Scorre gli elementi dell’array this e restituisce una coppia di array i9pisono inferi9! Invocato con notazione infissa def fun(x){ retrun x.age < 18 } à la Ruby e Haskell un anonymous function literal x => x.age < 18 val people: Array[Person] val (minors, adults) = people partition (_.age < 18) x => x.age < 18 È un pattern matching! importjava.util.ArrayList; ... Lista implementata con un resizable array Person[]people; Person[]minors; Person[]adults; ArrayList<Person>minorsList=newArrayList<Person>(); ArrayList<Person>adultsList=newArrayList<Person>(); for(inti=0;i<people.length;i++) È un metodo della classe Array[T] def partition(p: T=>Boolean):(Array[T], Array[T]) if(people[i].age<18)minorsList.add(people[i]); elseadultsList.add(people[i]); minors=minorsList.toArray(people); adults=adultsList.toArray(people); scala> val prova = Array (1,2,3,4) prova: Array[Int]=Array(1,2,3,4) scala> val (x,y)=prova partition (_<2) x: Array[Int] = Array(1) y: Array[Int] = Array(2,3,4) i9pisono inferi9! Restituisce un array del tipo del parametro val people: Array[Person] val (minors, adults) = people partition (_.age < 18)