F#如何实现let rec?

时间:2016-12-18 14:12:37

标签: recursion parameters f# scheme

我想知道F#如何实现let rec,我无法找到答案。作为前言,我将介绍Scheme如何实现letrec

  1. 在Scheme中,let只是用于定义lambda并应用它的语法糖:
  2. (let ((x 1)) (+ x 2))

    转换为

    ((lambda (x) (+ x 2)) 1)

    (在每种情况下,表达式都计算为3)。

    1. letrec也是语法糖,但#f作为初始参数传递给lambda的参数,set!表达式在letrec体之前注入,就像在这个转变中:
    2. (letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f)

      考虑到F#没有与Scheme set!相同的运算符,它如何实现let rec?它是否将函数的参数声明为mutable,然后在函数体中将它们变异?

1 个答案:

答案 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上运行的语言。 没有元编程。