Como dijo Gabe , F # usos interactivos sombra de los valores cuando se introduce una función con un nombre que ya existe (para más información sobre el sombreado, véase por ejemplo this SO question). Esto significa que el F # compilador ve algo como esto cuando se ejecuta el código:
> let [email protected] x = x + 2;;
> let [email protected] x = [email protected] x;;
> [email protected] 10;;
val it : int = 12
> let [email protected] x = x + 3;;
> [email protected] 10;;
val it : int = 12
F # utiliza algún nombre revuelto (como @) que no se puede utilizar directamente para distinguir entre las versiones del valor. Por otro lado, el comportamiento de Clojure puede ser mejor entendido como un gran diccionario de funciones. Usando pseudo-sintaxis, algo como esto:
> symbols[f] = fun x -> x + 2;;
> symbols[g] = fun x -> symbols[f] x;;
> symbols[g] 10;;
val it : int = 12
> symbols[f] = fun x -> x + 3;;
> symbols[g] 10;;
val it : int = 13
Esto debería hacer la distinción bastante clara.
Como nota al margen, hay un posible problema con el enfoque Clojure (al menos para un lenguaje como F #). Puede declarar una función de algún tipo, usarla y luego, el siguiente comando puede cambiar el tipo de la función. Si F # usó el enfoque de Clojure, ¿cómo debería funcionar el siguiente ejemplo?
> let f a b = a + b;;
> let g x = f x x;;
> let f() = printf "f!";;
> g 0;;
La función g
utiliza f
como si tuviera dos parámetros de tipo int
, pero la línea thrid cambia el tipo de la función. Esto hace que el enfoque de Clojure sea un poco complicado para los lenguajes verificados por tipo.
¿Quieres decir con sombreado que una variable en un ámbito inferior con 'sombras' del mismo nombre los de mayor ¿alcances? En el interactivo F #, ¿debemos leer las declaraciones de let sucesivas como ámbitos anidados? Eso lo explicaría! En el caso de Clojure, aquí no se trata de una cuestión de alcance, sino realmente de cambiar el enlace de raíz de var f (los vars son mutables). –
@Michiel - Sí, eso es exactamente correcto. Usando la sintaxis no liviana para F #, tu ejemplo sería 'let f = ... in (let g = ... in (g 10; let f = ... in g 10))', donde la creación de nuevos ámbitos es un poco más evidente. – kvb