Repeated parameter

Similmente al meccanismo dei tre punti (...) di Java, Scala permette di indicare che l’ultimo argomento di una funzione o di un costruttore può essere ripetuto, scrivendo * dopo il tipo del parametro; ad esempio:

case class Person(name: String, isMale: Boolean, children: Person*)

Tale parametro prende il nome di repeated parameter, e permette all’utente di fornire una lista di argomenti variabile; ad esempio:

val lara = Person("Lara", false)
val bob = Person("Bob", true)
val julie = Person("Julie", false, lara, bob)

Nel codice, un repeated parameter di tipo T è accessibile come una sequenza di tipo Seq[T].

For expression

Data la lista di persone

val persons = List(lara, bob, julie)

si vuole costruire la lista di tutte le coppie di nomi (madre, figlio/a) per tutte le madri contenute in persons. Ciò può essere fatto usando i metodi all’ordine superiore di List (ovvero di Seq):

  1. si filtra la lista persons per escludere i maschi, che non possono essere madri
  2. si usa map per trasformare la sequenza di figli di una persona in una sequenza di coppie di nomi di madre e figlio/a, e ciò viene fatto per ogni persona nella lista filtrata usando flatMap, in modo da ottenere complessivamente una singola sequenza di coppie invece che una sequenza di sequenze.
persons filter (p => !p.isMale) flatMap (p =>
	p.children map (c => (p.name, c.name))
) // res0: List[(String, String)] = List((Julie,Lara), (Julie,Bob))

Quest’esempio mostra che i metodi all’ordine superiore, seppur estremamente potenti, non sempre sono semplici da scrivere o da comprendere: la sematica delle operazioni effettuate qui è un po’ nascosta dall’interazione non banale tra i metodi filter, flatMap, e map coinvolti nel presente frammento di codice.

L’uso dei metodi all’ordine superiore tende a diventare più facile con l’abitudine, ma comunque Scala fornisce dello zucchero sintattico che permette di esprimere in una forma più chiara combinazioni di map, flatMap e filter: le for expression. Una for expression ha la forma generale

$$ \texttt{for (s) yield e} $$

oppure

$$ \texttt{for \{s\} yield e} $$

dove: