Ответ 1
Как сказал gabe, F # interactive использует затенение значений при вводе функции с уже существующим именем (для получения дополнительной информации о теневом изображении см., например, этот вопрос SO). Это означает, что компилятор F # видит что-то вроде этого при запуске вашего кода:
> 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 # использует некоторое искаженное имя (например, @), которое вы не можете использовать напрямую, чтобы различать версии значения. С другой стороны, поведение Clojure, вероятно, лучше всего понимается как большой словарь функций. Использование псевдосинтаксиса, что-то вроде этого:
> 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
Это должно сделать различие совершенно ясным.
В качестве побочной заметки существует одна возможная проблема с подходом Clojure (по крайней мере, для языка, такого как F #). Вы можете объявить функцию некоторого типа, использовать ее, а затем следующую команду можно изменить тип функции. Если F # использовал подход Clojure, как должен работать следующий пример?
> let f a b = a + b;;
> let g x = f x x;;
> let f () = printf "f!";;
> g 0;;
Функция g
использует f
, как если бы она имела два параметра типа int
, но строка thrid меняет тип функции. Это делает подход Clojure немного сложным для языков с проверкой типов.