Primo incontro con Scala

In un post precedente ho citato Scala, un nuovo linguaggio a tipizzazione statica che cerca di fondere i paradigmi della programmazione ad oggetti e di quella funzionale.
Per illustrarne alcune caratteristiche, prenderò in prestito un esempio dal sito metodiagili.it, convertendolo da Java a Scala.
File starter/main.scala
package starterimport java.util.GregorianCalendarimport core._
//Se non leggo parametri di ingresso, estendo Application
object main extends Application {
def nov1st2009 = new GregorianCalendar(2009,11-1,1).getTime()
def nov1st2005 = new GregorianCalendar(2005,11-1,1).getTime()
def createResourceList() =
List(new Employee("Francesco", new Contract(nov1st2005)),
new Employee("Nicola", new Contract(nov1st2009)))
new Department(createResourceList()).printSlips()
}
File core/Department.scala
package coreclass Department (resources: List[Resource]) {def printSlips() =
resources.filter(resource => resource.inForce)
.foreach(resource => printSlip(resource))
def printSlip(resource: Resource) = {
println(resource.name); println(resource.salary)
}
}
File core/Resource.scala
package coreimport java.util.GregorianCalendarabstract class Resource (resourceName: String, contract: Contract) {
def salary: double //Metodo astratto
def inForce = {
def today = new GregorianCalendar(2007,12-1,1).getTime() //Esempio
contract.deadLine.after(today)
}
}
File core/Employee.scala
package coreclass Employee (name: String, contract: Contract) extends Resource (name: String, contract: Contract) {
def salary = 1024.89
}
File core/Contract.scala
package corecase class Contract(deadLineDate: java.util.Date) //Tutto qui!
Pur non entrando in tutti i dettagli dei programma, possiamo comunque fare qualche riflessione.
La sintassi base del linguaggio è molto simile a quella di Java. Non penso che un qualsiasi programmatore abbia difficoltà a capire il significato del codice.
L'integrazione degli oggetti Java all'interno di Scala è estremamente naturale. Basta una semplice direttiva di import, e le classi Java, come GregorianCalendar nel nostro esempio, sono immediatamente disponibili all'uso.
Il codice, pur essendo espressivo, è sicuramente snello. A ciò contribuiscono diversi fattori. In primo luogo l'inferenza dei tipi evita dichiarazioni superflue. Il compilatore nel nostro caso deduce che il tipo di ritorno del metodo inForce di Resource è Boolean dal valore di contract.deadLine.after(today). Vi è inoltre la possibilità di avere costruttori predefiniti ai quali possono essere passati dei parametri, che risultano visibili all'interno del codice dell'intera classe, come nel caso di
class Resource (resourceName: String, contract: Contract)
Se la classe è di tipo case, allora vengono generati automaticamente i getters dei parametri del costruttore. Per questo la classe Contract è così semplice.
Alla compattezza del programma contribuisce anche la facilità nella definizione di funzioni anonime. Quando scriviamo resources.filter(resource => resource.inForce), intendiamo passare al metodo filter della lista resources un nuovo oggetto di tipo funzione che prende in ingresso un valore di tipo Resource e restituisce il booleano ottenuto tramite l'applicazione del metodo inForce.
La presenza di metodi quali filter e foreach per la gestione di liste e collezioni (sequenze nella terminologia Scala) migliora il design del codice, senza appesantirlo con ulterioni definizioni a carico del programmatore.

Lascia un commento