Attualmente sto leggendo "Tipi e linguaggi di programmazione" di Benjamin C. Pierce. Prima di entrare veramente nella teoria dei tipi, spiega il calcolo lambda e le strategie di valutazione.
Sono un po 'confuso dalla spiegazione di chiama per nome vs chiama per valore in questo contesto.
Le due strategie sono spiegate nel modo seguente:
chiama per nome
Come ordine normale in quanto sceglie prima il redex più a sinistra, più esterno, ma più restrittivo non consentendo riduzioni all'interno delle astrazioni. Un esempio:
id (id (λz. id z))
→ id (λz. id z)
→ λz. id z
chiama per valore
Solo i redex più esterni vengono ridotti e un redex viene ridotto solo quando il suo lato destro è già stato ridotto a un valore, un termine che è terminato nell'elaborazione e non può essere ulteriormente ridotto. Un esempio:
id (id (λz. id z))
→ id (λz. id z)
→ λz. id z
(identical to the call by name evaluation)
Ok, finora tutto bene. Ma questo è seguito dal seguente paragrafo:
The call-by-value strategy is strict, in the sense that the arguments to functions are always evaluated, whether or not they are used by the body of the function. In contrast, non-strict (or lazy) strategies such as call-by-name and call-by-need evaluate only the arguments that are actually used.
So che cosa significa call-by-value e call-by-name praticamente, dall'aver usato (tra gli altri) C e Haskell, ma non riesco a capire perché la strategia di valutazione spiegata sopra porti a questo nel calcolo lambda. Si tratta di una regola aggiuntiva che accompagna sempre call-by-value o se segue la strategia di riduzione sopra descritta?
Specialmente dal momento che i passaggi di riduzione negli esempi sono identici, non riesco a vedere la differenza tra le due strategie e mi piacerebbe se qualcuno potesse aiutarmi a ottenere qualche intuito.