Perché la parola chiave rec è necessaria in F #?


28

In F # è necessario utilizzare la recparola chiave. In Haskell non è necessario dire esplicitamente se una determinata funzione è ricorsiva o meno.

Dato il ruolo della ricorsione nella programmazione funzionale, il design di F # mi sembra piuttosto strano. È una buona decisione di progettazione del linguaggio o esiste solo per motivi storici o a causa di un vincolo di implementazione?

Risposte:


16

C'è una differenza intrinseca nella semantica di Haskell e F #. In Haskell, una chiamata di funzione non esegue alcun calcolo reale, ma alloca un oggetto heap noto come "thunk". È perfettamente accettabile che un thunk abbia un collegamento a se stesso o ad un altro thunk. Tuttavia, in F #, una chiamata di funzione è una chiamata effettiva, che rende espressioni come let x = 1 : 2 : x in xnon valide, poiché xdeve essere costruita prima che 1 : 2 : xvenga costruita. Tuttavia, è ancora una definizione più o meno ragionevole per l'elenco infinito, dovrebbe esistere un modo per definirlo. Ecco le radici per rec. Se vuoi di più, cerca e leggi la semantica operativa per SML e Haskell: è diversa.


2
AFAIK, Haskell non ha intenzionalmente una semantica operativa.
dan_waterworth,

@dan_waterworth è impossibile compilare senza la semantica operativa definita.
permeakra,

8
Il linguaggio Haskell non definisce una semantica operativa, ma fornisce invece una semantica denotazionale. Quando si costruisce un compilatore, una semantica operativa viene definita in modo implicito, ma ciò non significa che faccia parte dello standard del linguaggio Haskell.
dan_waterworth,

6
@dan_waterworth In pratica, esiste solo una implementazione e uno standard del linguaggio Haskell: ghc, oltre a un solo standard F #: l'implementazione di Microsoft. Quindi teoricamente potresti avere ragione, ma la pratica è una bestia completamente diversa.
permeakra,

19

A questa domanda è stata data una risposta su SO , e include un forte background storico sul perché si usa "rec".

Ecco la citazione importante per i posteri:

Le funzioni non sono ricorsive per impostazione predefinita nella famiglia di lingue CAML francese (incluso OCaml). Questa scelta semplifica il superamento delle definizioni di funzioni (e variabili) usando let in quelle lingue perché è possibile fare riferimento alla definizione precedente all'interno del corpo di una nuova definizione. F # ha ereditato questa sintassi da OCaml.


12

Un ricorsivo letdefinisce una semantica significativamente più complicata di una normale. Pertanto, per motivi di semplicità e design del linguaggio pulito, c'è una buona ragione per avere entrambi, esattamente come avere separati let, let*e letrecnello Schema.

Semplice let x = y in zè equivalente a ((fun x -> z) y). Una let ricorsiva è molto più complicata e può comportare l'uso di un combinatore a punto fisso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.