Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Desugared form of "let in"

What do the let (x = 0) in x * x translate to? A function (fun x -> x * x) 0) ? - This would make sense, as let bindings are expressions - and expressions must return values (just like functions).

Example:

let result1 = 
    (fun n1 -> (fun n2 -> 
    (fun n3 -> n1 + n2 + n3 ) 3) 2) 1

let result2 = 
    let n1 = 1 in
    let n2 = 2 in
    let n3 = 3 in
    n1 + n2 + n3

let result3 = 
    let n1 = 1
    let n2 = 2
    let n3 = 3
    n1 + n2 + n3

Am I right to assume that result3 is a sugared form of result2, and result2 a sugared form of result1?

Short: Do let in bindings translate to functions?

like image 825
ebb Avatar asked Dec 05 '22 05:12

ebb


2 Answers

You can almost see let x = e1 in e2 as a syntactic sugar for (fun x -> e2) e1.

At the basic level, the two expressions mean the same thing - the compiler will probably compile them differently (depending on optimization levels and how it inlines things), but you could often use the second notation instead of the first one.

The one case where they differ is that ML-languages (including F#) only generalize function types written explicitly using the let keyword. This means that if you use fun, the language won't treat it as a generic function. If you want a generic function, you have to use let (and this is not just a compiler artifact, this is actually part of the language).

For example, the following uses let and it works:

let id = (fun x -> x) in ignore(id 1); ignore(id "A")

But the following does not work, because id is not a generic function:

(fun id -> ignore(id 1); ignore(id "A")) (fun x -> x)
like image 159
Tomas Petricek Avatar answered Jan 11 '23 07:01

Tomas Petricek


The plain old let is just the lightweight syntax form of the verbose let … in.

From MSDN: Verbose Syntax (F#):

nested let bindings:

Lightweight syntax:

let f x =
    let a = 1
    let b = 2
    x + a + b

Verbose syntax:

let f x =
    let a = 1 in
    let b = 2 in
    x + a + b

The let bindings within these function don't translate to functions themselves, however. Both of these translate to identical CIL code:

f:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldc.i4.1    
IL_0003:  add         
IL_0004:  ldc.i4.2    
IL_0005:  add         
IL_0006:  ret 

Note that the only function here is the outer function f. The variables a and b are evaluated as constants within the scope of f.

like image 41
p.s.w.g Avatar answered Jan 11 '23 07:01

p.s.w.g