¿Por qué se necesita la palabra clave rec en F #?

28

En F # es necesario usar la recpalabra clave. En Haskell no hay necesidad de decir explícitamente si una función dada es recursiva o no.

Dado el papel de la recursividad en la programación funcional, el diseño de F # me parece bastante extraño. ¿Es una buena decisión de diseño del lenguaje o solo existe por razones históricas o por una restricción de implementación?

Simon Bergot
fuente

Respuestas:

16

Hay una diferencia inherente en la semántica de Haskell y F #. En Haskell, una llamada a función no realiza ningún cálculo real, sino que asigna un objeto de montón conocido como 'thunk'. Está perfectamente bien que un thunk tenga un enlace consigo mismo u otro thunk. Sin embargo, en F #, una llamada de función es una llamada real, haciendo expresiones como let x = 1 : 2 : x in xinválidas, ya que requiere xser construida antes de 1 : 2 : xser construida. Sin embargo, todavía es una definición más o menos razonable para la lista infinita, debería existir alguna forma de definirla. Aquí yace raíces para rec. Si desea más, busque y lea la semántica operativa para SML y Haskell: es diferente.

permeakra
fuente
2
AFAIK, Haskell a propósito no tiene una semántica operativa.
dan_waterworth
@dan_waterworth es imposible compilar sin una semántica operativa definida.
permeakra
8
El lenguaje Haskell no define una semántica operativa, sino que proporciona una semántica denotacional. Cuando construye un compilador, una semántica operativa se define implícitamente, pero esto no significa que sea parte del estándar de lenguaje Haskell.
dan_waterworth
66
@dan_waterworth En la práctica, solo hay una implementación y estándar del lenguaje Haskell: ghc, así como solo hay un estándar F #: la implementación de Microsoft. Entonces, en teoría, puede que tengas razón, pero la práctica es una bestia completamente diferente.
permeakra
19

Esta pregunta ha sido respondida en SO e incluye algunos antecedentes históricos sólidos de por qué se usa "rec".

Aquí está la cita importante para la posteridad:

Las funciones no son recursivas por defecto en la familia francesa de idiomas CAML (incluido OCaml). Esta opción facilita reemplazar las definiciones de funciones (y variables) usando let en esos idiomas porque puede hacer referencia a la definición anterior dentro del cuerpo de una nueva definición. F # heredó esta sintaxis de OCaml.

Chris Pitman
fuente
12

Un recursivo letdefine una semántica significativamente más complicada que una normal. Por lo tanto, en aras de la simplicidad y el diseño de lenguaje limpio, hay una buena razón para tener ambos, lo mismo que tener separados let, let*y letrecen Scheme.

Simple let x = y in zes equivalente a ((fun x -> z) y). Un let recursivo es mucho más complicado y puede implicar el uso de un combinador de punto fijo.

SK-logic
fuente