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

28

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

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

    
pregunta Simon 28.08.2012 - 12:11

3 respuestas

16

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

    
respondido por el permeakra 28.08.2012 - 12:41
19

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

Aquí está la cita importante para la posteridad:

  

Las funciones no son recursivas de forma predeterminada en la familia de idiomas CAML de Francia (incluido OCaml). Esta opción hace que sea más fácil reemplazar las definiciones de funciones (y variables) utilizando la opción de dejar en esos idiomas porque puede consultar la definición anterior dentro del cuerpo de una nueva definición. F # heredó esta sintaxis de OCaml.

    
respondido por el Chris Pitman 28.08.2012 - 16:01
12

Un let recursivo define una semántica mucho más complicada que la normal. Por lo tanto, por motivos de simplicidad y diseño de lenguaje limpio, hay una buena razón para tener ambos, al igual que tener let , let* y letrec separados en el Esquema.

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

    
respondido por el SK-logic 28.08.2012 - 12:23

Lea otras preguntas en las etiquetas