Functions in F # .. why it does not compile

I wrote two versions of the code. The first works as expected, and prints "Hello." the second gives me an error that "the block after this let is not completed"

1st version

#light let samplefn() = let z = 2 let z = z * 2 printfn "hi" samplefn() 

Second version

 #light let samplefn() = let z = 2 let z = z * 2 samplefn() 

The only difference is that printfn is missing in the second version. I am using Visual Studio 2010 as my IDE. I am very new to F #, but this error seems very strange to me. I probably miss a very important concept. Please explain.

Edit: Also, if I do this outside the function, I get an error even with the first version of the code.

 #light let z = 2 let z = z * 2 printfn "Error: Duplicate definition of value z" 
0
source share
3 answers

A let , which is not at the top level (for example, your indentation), should have a statement (actually an expression, like pst notes), called a "body" after assignment. In the first example, the body is printfn "hi" , and the second example has no body. This is what the compiler is complaining about.

Note that in function definitions, internal let expressions actually create nested areas. That is, let z = z * 2 actually creates a new value called z and associates with it the value of the external z times 2, and then uses it in the body of let (which is printfn in this case). Nested let will always have a body. This is an attachment that seems to duplicate the definition.

Since the external let does not require a body, the compiler thinks that you are trying to override z in the same area as the error. You can use parentheses to tell the compiler how to correctly interpret the last example:

 let z = 2 (let z = z * 2 printfn "z = %d" z) printfn "z = %d" z 

The above text will print

  z = 4
 z = 2 
+4
source

let binds the value to the label, but otherwise does nothing else. Your function contains two bindings, but does not use them, so you get an error message.

To think of it differently, all functions in F # need a return value, which is the value of the last expression executed in your function. let has no return value, so your function is not valid. To fix this, you can add a return value, for example:

 let samplefn() = let z = 2 let z = z * 2 () 

which defines a function that does absolutely nothing (returns unit ). Perhaps the best example is:

 let samplefn() = let z = 2 let z = z * 2 z 

which will return 4 (binding value for label z ).

+7
source

I think it is useful to understand the syntax without light. Let me translate:

1st version (let it bind expressions)

 let samplefn() = let z = 2 in let z = z * 2 in printfn "hi";; samplefn();; 

It is important to understand that all let bindings at the top level are actually an expression of the form let <variable> = <expression1> in <expression2> , where <variable> bound to the result <expression1> in the new area <expression2> , and <expression2> is the return value of the entire expression. The light syntax makes you believe that such let bindings are variable assignments / operators, when in fact it is true that almost everything in F # is an expression.

Perhaps the following illustrates this more clearly:

 let a = (let b = 3 in b + 2) //a is 5 

Second version (top level bindings)

 let z = 2;; let z = z * 2;; printfn "Error: Duplicate definition of value z";; 

Top-level let-bindings end with ;; , indicating the completion of what can be considered a statement. The upper level represents a single area, and here we get an error for trying to bind z twice to the same area. Whereas, using the let bindings expression form in Example 1, we bind z again for each sub-area in the expression chain. Note that we could do something like this at the top level:

 let z = (let z = 2 in z * 2);; 
+5
source

All Articles