我想知道F#如何实现let rec
,我无法找到答案。作为前言,我将介绍Scheme如何实现letrec
:
let
只是用于定义lambda并应用它的语法糖: (let ((x 1)) (+ x 2))
转换为
((lambda (x) (+ x 2)) 1)
(在每种情况下,表达式都计算为3
)。
letrec
也是语法糖,但#f
作为初始参数传递给lambda的参数,set!
表达式在letrec
体之前注入,就像在这个转变中: (letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f)
。
考虑到F#没有与Scheme set!
相同的运算符,它如何实现let rec
?它是否将函数的参数声明为mutable
,然后在函数体中将它们变异?
答案 0 :(得分:3)
在F#中,let rec
允许在绑定之前从函数内引用绑定。 let rec
本身没有实现,因为它只是一个编译器提示。
在这个人为的例子中,
let rec even =
function 0 -> true | 1 -> false | x -> odd (x - 1)
and odd =
function 0 -> false | 1 -> true | x -> even (x - 1)
编译后的IL非常不合理地转换为:
public static bool even(int _arg1)
{
switch (_arg1)
{
case 0:
return true;
case 1:
return false;
default:
return odd(_arg1 - 1);
}
}
public static bool odd(int _arg2)
{
switch (_arg2)
{
case 0:
return false;
case 1:
return true;
default:
return even(_arg2 - 1);
}
}
所有函数定义都静态编译为IL。 F#最终是一种在CLR上运行的语言。 没有元编程。