La valutazione delle espressioni in Scala è basata sul modello di sostituzione (substitution model), nel quale i nomi sono rimpiazzati dalle loro definizioni. Tramite una sequenza di passi, la valutazione riduce un’espressione a un valore, che è un termine che non richiede ulteriori valutazioni. Un singolo passo di valutazione può essere chiamato valutazione, riduzione o rewriting.
Il modello di sostituzione è formalizzato dal $\lambda$-calcolo, un modello computazionale. Turing completo (cioè di potenza equivalente alle macchine di Turing) che è stato introdotto da Alonzo Church nel 1936, e costituisce il fondamento teorico dei linguaggi funzionali.
Questo modello di valutazione può essere applicato quando le espressioni non hanno effetti collaterali, perchè non è in grado di descrivere gli aspetti mutable di un linguaggio, ad esempio la valutazione dell’espressione x++
di un linguaggio come C o Java.
Una sequenza di passi di valutazione è significativa se termina, altrimenti non potrebbe mai produrre un valore, ma solo “dare problemi”. Allora, è naturale chiedersi se sia sempre possibile ridurre un’espressione a un valore in un numero finito di passi.
La risposta è negativa: considerando ad esempio la seguente funzione ricorsiva loop
,
def loop(): Int = loop()
si ha che la valutazione dell’espressione loop()
non termina, perchè ogni volta l’uso della funzione viene sostituito con il corpo della funzione, ma questo è ancora esattamente un uso della stessa funzione:
$$ \texttt{loop()} \rarr \texttt{loop()} \rarr \texttt{loop()}\rarr \dots $$
Nel modello di sostituzione esistono due diverse strategie di valutazione delle funzioni:
Si può dimostrare che entrambe le strategie riducono un’espressione al medesimo valore se:
Ciascuna di queste strategie ha un vantaggio: