5

I am wondering how F# implements let rec, and I couldn't find an answer. As a preface, I'll address how Scheme implements letrec:

  1. In Scheme, let is just syntactics sugar for a definition of a lambda and applying it:

(let ((x 1)) (+ x 2))

is transformed to

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

(in each case the expression is evaluated to 3).

  1. letrec is also syntactic sugar, but #f is passed as initial argument to the lambda's parameters, and set! expressions are injected before the letrec body, like in this transformation:

(letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f).

Considering that F# doesn't have an equivalent operator to Scheme's set!, how does it implement let rec? Does it declare the function's parameters as mutable, and then mutate them in the function's body?

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
asafc
  • 357
  • 3
  • 21
  • 7
    You're assuming same (or similar) underlying machinery, which isn't the case. F# works on CLR, which has different machinery. In particular, all functions are defined before execution begins. And yes, F# does have an equivalent of `set!`. – Fyodor Soikin Dec 18 '16 at 14:25
  • 1
    @FyodorSoikin, in what way are the functions defined before execution? What is being defined? – asafc Dec 18 '16 at 20:34
  • 1
    Function name, parameters, result type, and code body is defined. All of this is defined during compilation, waaay before execution starts. – Fyodor Soikin Dec 18 '16 at 21:40
  • @FyodorSoikin, what is F#'s equivalent of `set!`? – asafc Dec 19 '16 at 08:41
  • I don't know Scheme, can you provide a reference with more details on this. I am considering answering this question, but want more touch points than what you have provided. – Guy Coder Dec 19 '16 at 12:33
  • 1
    Of interest: [Fixed point combinators in lambda calculus](https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed_point_combinators_in_lambda_calculus) – Guy Coder Dec 19 '16 at 12:41
  • 1
    Of interest: [What is a y-combinator?](http://stackoverflow.com/questions/93526/what-is-a-y-combinator) – Guy Coder Dec 19 '16 at 13:26
  • 1
    Of interest: [Fixed-point combinators in JavaScript: Memoizing recursive functions](http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/) – Guy Coder Dec 19 '16 at 13:28
  • 1
    Of interest: [The Y Combinator](http://mvanier.livejournal.com/2897.html) - Uses Scheme as the example language. – Guy Coder Dec 19 '16 at 13:35
  • 1
    Of interest: [Understanding, at last, the Y Combinator - a programmer-friendly perspective](http://hisham.hm/2011/04/04/understanding-at-last-the-y-combinator-a-programmer-friendly-perspective/) – Guy Coder Dec 19 '16 at 13:36
  • 1
    The equivalent of `set!` in F# is the destructive update operator: `let mutable x = 0; x <- 5` Here are some examples: https://www.tutorialspoint.com/fsharp/fsharp_mutable_data.htm – Fyodor Soikin Dec 19 '16 at 13:52
  • Are you trying to understand the concepts for recursive functions, or how a recursive function's parameters are created and used with F#? If you are just interested in how the recursive function's parameters are created and used then I think you are missing the bigger and more helpful concept of what is a recursive function and why do most functional languages require the `rec` keyword and what are the origins of `rec` – Guy Coder Dec 19 '16 at 14:09
  • Of interest: [THAT ABOUT WRAPS IT UP Using FIX to Handle Errors Without Exceptions, and Other Programming Tricks](http://www.lfcs.inf.ed.ac.uk/reports/97/ECS-LFCS-97-375/ECS-LFCS-97-375.pdf) More for my personal use, but still useful for others. – Guy Coder Dec 19 '16 at 14:18
  • Of interest: [(Y Y) Works!](https://xivilization.net/~marek/binaries/Y.pdf) Gives a practical example of inventing the Y combinator. – Guy Coder Dec 19 '16 at 14:57
  • Of interest: [Foundations of Functional Programming](http://www.cl.cam.ac.uk/~lp15/papers/Notes/Founds-FP.pdf) - Only if you like theory. Does a nice job of building up Lambda Calculus to functional programming including the Y Combinator. – Guy Coder Dec 19 '16 at 15:04
  • Of interest: [AN INTRODUCTION TO FUNCTIONAL PROGRAMMING THROUGH LAMBDA CALCULUS](https://cs.fit.edu/~ryan/library/functional_programming/gjm.lambook88.pdf) - Buy the book if you use it a lot. This is one of my favorites and an easier read than `Foundations of Functional Programming` – Guy Coder Dec 19 '16 at 15:06
  • AFAIK, the Scheme standard(s) don't require any particular implementation of either `let` or `letrec`. There are macro implementations, but those are just suggestions. – molbdnilo Dec 20 '16 at 15:35
  • in Scheme, it is not `#f` but a special `#` that must be used initially, so that any attempt at getting its *value* before it is set, is an error. – Will Ness Dec 25 '16 at 10:58

1 Answers1

4

In F#, let rec allows a reference to the binding from within the function before it has been bound. let rec doesn't have an implementation per se, because it is merely a compiler hint.

In this contrived example,

let rec even =
    function 0 -> true  | 1 -> false | x -> odd (x - 1)
and odd =
    function 0 -> false | 1 -> true  | x -> even (x - 1)

the compiled IL very unglamorously translates to:

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);
    }
}

All function definitions are statically compiled to IL. F# ultimately is a language which runs on the CLR. There is no meta-programming.

Asti
  • 12,447
  • 29
  • 38
  • 1
    "*There is no meta-programming.*" Not in this case, but F# does have metaprogramming despite being [CLI](http://www.ecma-international.org/publications/standards/Ecma-335.htm)-based (the CLR is an implementation, not a specification). – ildjarn Dec 18 '16 at 19:28
  • @ildjarn F# does have some forms of meta-programming, but I meant that it is quite unlike the kind found in scheme or lisp. – Asti Dec 18 '16 at 19:40