Scope/order of evaluation of nested `let .. in ..` in OCaml - functional-programming

I have a little problems here that I don't 100% understand:
let x = 1 in let x = x+2 in let x = x+3 in x
I know the result of this expression is 6, but just want to make sure the order of calculating this expression; which part is calculated first?

You asked about the order of the evaluation in the expression let x=1 in let x=x+2 in .... The order is "left-to-right"! When you have a chain of let a=b in let c=d in ..., the order of evaluation is always left-to-right.
However, in your example there is a confusing part: you used the same variable name, x, in every let construct. This is confusing because you then see things like let x=x+1, and this looks like you are "redefining" x or "changing the value of x". But no "changing" of "x" actually happens here in OCAML! What happens here, as already pointed out above, is that a new variable is introduced every time, so your example is entirely equivalent to
let x = 1 in let y = x+2 in let z = y+3 in z;;
Note that here the order of evaluation is also left-to-right. (It is always left-to-right in every chain of let constructs.) In your original question, you chose to call all these new variables "x" rather than x, y, and z. This is confusing to most people. It is better to avoid this kind of coding style.
But how do we check that we renamed the variables correctly? Why "let x=1 in let y=x+2" and not "let x=1 in let x=y+2"? This x=x+2 business is quite confusing! Well, there is another way of understanding the evaluation of let x=aaa in bbb. The construct
let x=aaa in bbb
can be always replaced by the following closure applied to aaa,
(fun x -> bbb) aaa
Once you rewrite it in this way, you can easily see two things: First, OCAML will not evaluate "bbb" inside the closure until "aaa" is evaluated. (For this reason, the evaluation of let x=aaa in bbb proceeds by first evaluating aaa and then bbb, that is, "left-to-right".) Second, the variable "x" is confined to the body of the closure and so "x" cannot be visible inside the expression "aaa". For this reason, if "aaa" contains a variable called "x", it must be already defined with some value before, and it has nothing to do with the "x" inside the closure. For reasons of clarity, it would be better to call this variable by a different name.
In your example:
let x=1 in let x=x+2 in let x=x+3 in x
is rewritten as
(fun x -> let x=x+2 in let x=x+3 in x) 1
Then the inner let constructs are also rewritten:
(fun x -> (fun x -> let x=x+3 in x) x+2 ) 1
(fun x -> (fun x -> (fun x-> x) x+3) x+2 ) 1
Now let us rename the arguments of functions inside each function, which we can always do without changing the meaning of the code:
(fun x -> (fun y -> (fun z -> z) y+3) x+2 ) 1
This is the same as
let x=1 in let y=x+2 in let z=y+3 in z
In this way, you can verify that you have renamed the variables correctly.

Imagine parens:
let x = 1 in (let x = (x+2) in (let x = (x+3) in x))
Then substitute (x=1) where x it's not covered by another declaration of x and eliminate outermost let:
let x = (1+2) in (let x = (x+3) in x)
Evaluate:
let x = 3 in (let x = (x+3) in x)
Substitute:
let x = (3+3) in x
Evaluate:
let x = 6 in x
Substitute:
6

(This is a little long for a comment, so here's a smallish extra answer.)
As Chuck points out, there is no closure involved in this expression. The only complexity at all is due to the scoping rules. OCaml scoping rules are the usual ones, i.e., names refer to the nearest (innermost) definition. In the expression:
let v = e1 in e2
The variable v isn't visible (i.e., cannot be named) in e1. If (by chance) a variable of that name appears in e1, it must refer to some outer definition of (a different) v. But the new v can (of course) be named in e2. So your expression is equivalent to the following:
let x = 1 in let y = x+2 in let z = y+3 in z
It seems to me this is clearer, but it has exactly the same meaning.

Related

smlnj - Function That Adds Even and Odd Elements In An Int List

I am fairly new to functional programming and I do not understand my error here. I am trying to make a function that takes an integer list and returns both the sum of the even elements and the sum of the odd elements. The error I am getting is in line 1, and it states: "Error: right-hand-side of clause doesn't agree with function result type [overload conflict] ...". I don't understand the error, and I would appreciate any help in understanding my error.
fun add(nil) = 0
| add([x]) = x
| add(x :: xs) =
let
val evenList = xs;
val oddList = x :: xs
in
(hd evenList + add(tl(tl(evenList))), hd oddList + add(tl(tl(oddList))))
end;
The reason for the type error is that the function should return a pair, but your base cases don't.
I suspect you got to that code by thinking about skipping every other element, dividing the list by skipping.
There's a different way to approach this.
Consider the list [a,b,c,d].
Counting from 1, the elements are numbered
1 2 3 4
a b c d
Now consider the positions in the tail of the list.
They are
1 2 3
b c d
That is, odd positions in the tail are even positions in the entire list, and even positions in the tail are odd in the entire list.
This means that if we recursively compute "odds and evens" in the tail, we will get the sums from the tail, where its "odds" is our "evens", and if we add our head to the tail's "evens", we will get the "odds" we want.
All we need now is a good base case – and the sums of an empty list must be (0, 0).
Something like this:
fun add [] = (0,0)
| add (x::xs) = case add xs of
(odds, evens) => (x + evens, odds)
or, you can deconstruct the recursive result with a let-binding instead of case:
fun add [] = (0,0)
| add (x::xs) = let val (odds, evens) = add xs
in
(x + evens, odds)
end

F# Recursive Objects

I'm new to F#, and functional languages. So this might be stupid question, or duplicated with this Recursive objects in F#?, but I don't know.
Here is a simple Fibonacci function:
let rec fib n =
match n with
| 0 -> 1
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
Its signature is int -> int.
It can be rewritten as:
let rec fib =
fun n ->
match n with
| 0 -> 1
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
Its signature is (int -> int) (in Visual Studio for Mac).
So what's the difference with the previous one?
If I add one more line like this:
let rec fib =
printfn "fib" // <-- this line
fun n ->
match n with
| 0 -> 1
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
The IDE gives me a warning:
warning FS0040: This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.
How does this line affect the initialization?
What does "recursive object" mean? I can't find it in the documentation.
Update
Thanks for your replies, really nice explanation.
After reading your answers, I have some ideas about the Recursive Object.
First, I made a mistake about the signature. The first two code snippets above have a same signature, int -> int; but the last has signature (int -> int) (note: the signatures have different representation in vscode with Ionide extension).
I think the difference between the two signatures is, the first one means it's just a function, the other one means it's a reference to a function, that is, an object.
And every let rec something with no parameter-list is an object rather than a function, see the function definition, while the second snippet is an exception, possibly optimized by the compiler to a function.
One example:
let rec x = (fun () -> x + 1)() // same warning, says `x` is an recursive object
The only one reason I can think of is the compiler is not smart enough, it throws an warning just because it's a recursive object, like the warning indicates,
This is because you are defining one or more recursive objects, rather than recursive functions
even though this pattern would never have any problem.
let rec fib =
// do something here, if fib invoked here directly, it's definitely an error, not warning.
fun n ->
match n with
| 0 -> 1
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
What do you think about this?
"Recursive objects" are just like recursive functions, except they are, well, objects. Not functions.
A recursive function is a function that references itself, e.g.:
let rec f x = f (x-1) + 1
A recursive object is similar, in that it references itself, except it's not a function, e.g.:
let rec x = x + 1
The above will actually not compile. The F# compiler is able to correctly determine the problem and issue an error: The value 'x' will be evaluated as part of its own definition. Clearly, such definition is nonsensical: in order to calculate x, you need to already know x. Does not compute.
But let's see if we can be more clever. How about if I close x in a lambda expression?
let rec x = (fun() -> x + 1) ()
Here, I wrap the x in a function, and immediately call that function. This compiles, but with a warning - the same warning that you're getting, something about "checking for initialization-soundness at runtime".
So let's go to runtime:
> let rec x = (fun() -> x + 1) ()
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
Not surprisingly, we get an error: turns out, in this definition, you still need to know x in order to calculate x - same as with let rec x = x + 1.
But if this is the case, why does it compile at all? Well, it just so happens that, in general, it is impossible to strictly prove that x will or will not access itself during initialization. The compiler is just smart enough to notice that it might happen (and this is why it issues the warning), but not smart enough to prove that it will definitely happen.
So in cases like this, in addition to issuing a warning, the compiler will install a runtime guard, which will check whether x has already been initialized when it's being accessed. The compiled code with such guard might look something like this:
let mutable x_initialized = false
let rec x =
let x_temp =
(fun() ->
if not x_initialized then failwith "Not good!"
else x + 1
) ()
x_initialized <- true
x_temp
(the actual compiled code looks differently of course; use ILSpy to look if you're curious)
In certain special cases, the compiler can prove one way or another. In other cases it can't, so it installs runtime protection:
// Definitely bad => compile-time error
let rec x = x + 1
// Definitely good => no errors, no warnings
let rec x = fun() -> x() + 1
// Might be bad => compile-time warning + runtime guard
let rec x = (fun() -> x+1) ()
// Also might be bad: no way to tell what the `printfn` call will do
let rec x =
printfn "a"
fun() -> x() + 1
There's a major difference between the last two versions. Notice adding a printfn call to the first version generates no warning, and "fib" will be printed each time the function recurses:
let rec fib n =
printfn "fib"
match n with
| 0 -> 1
| 1 -> 1
| _ -> fib (n - 1) + fib (n - 2)
> fib 10;;
fib
fib
fib
...
val it : int = 89
The printfn call is part of the recursive function's body. But the 3rd/final version only prints "fib" once when the function is defined then never again.
What's the difference? In the 3rd version you're not defining just a recursive function, because there are other expressions creating a closure over the lambda, resulting in a recursive object. Consider this version:
let rec fib3 =
let x = 1
let y = 2
fun n ->
match n with
| 0 -> x
| 1 -> x
| _ -> fib3 (n - x) + fib3 (n - y)
fib3 is not a plain recursive function; there's a closure over the function capturing x and y (and same for the printfn version, although it's just a side-effect). This closure is the "recursive object" referred to in the warning. x and y will not be redefined in each recursion; they're part of the root-level closure/recursive object.
From the linked question/answer:
because [the compiler] cannot guarantee that the reference won't be accessed before it is initialized
Although it doesn't apply in your particular example, it's impossible for the compiler to know whether you're doing something harmless, or potentially referencing/invoking the lambda in fib3 definition before fib3 has a value/has been initialized. Here's another good answer explaining the same.

Limitations of let rec in OCaml

I'm studying OCaml these days and came across this:
OCaml has limits on what it can put on the righthand side of a let rec. Like this one
let memo_rec f_norec =
let rec f = memoize (fun x -> f_norec f x) in
f;;
Error: This kind of expression is not allowed as right-hand side of `let rec'
in which, the memoize is a function that take a function and turns it into a memorized version with Hashtable. It's apparent that OCaml has some restriction on the use of constructs at the right-hand side of 'let rec', but I don't really get it, could anyone explain a bit more on this?
The kind of expressions that are allowed to be bound by let rec are described in section 8.1 of the manual. Specifically, function applications involving the let rec defined names are not allowed.
A rough summary (taken from that very link):
Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.
You can use tying-the-knot techniques to define memoizing fixpoints. See for example those two equivalent definitions:
let fix_memo f =
let rec g = {contents = fixpoint}
and fixpoint x = f !g x in
g := memoize !g;
!g
let fix_memo f =
let g = ref (fun _ -> assert false) in
g := memoize (fun x -> f !g x);
!g
Or using lazy as reminded by Alain:
let fix_memo f =
let rec fix = lazy (memoize (fun x -> f (Lazy.force fix) x)) in
Lazy.force fix

Recursive anonymous functions in SML

Is it possible to write recursive anonymous functions in SML? I know I could just use the fun syntax, but I'm curious.
I have written, as an example of what I want:
val fact =
fn n => case n of
0 => 1
| x => x * fact (n - 1)
The anonymous function aren't really anonymous anymore when you bind it to a
variable. And since val rec is just the derived form of fun with no
difference other than appearance, you could just as well have written it using
the fun syntax. Also you can do pattern matching in fn expressions as well
as in case, as cases are derived from fn.
So in all its simpleness you could have written your function as
val rec fact = fn 0 => 1
| x => x * fact (x - 1)
but this is the exact same as the below more readable (in my oppinion)
fun fact 0 = 1
| fact x = x * fact (x - 1)
As far as I think, there is only one reason to use write your code using the
long val rec, and that is because you can easier annotate your code with
comments and forced types. For examples if you have seen Haskell code before and
like the way they type annotate their functions, you could write it something
like this
val rec fact : int -> int =
fn 0 => 1
| x => x * fact (x - 1)
As templatetypedef mentioned, it is possible to do it using a fixed-point
combinator. Such a combinator might look like
fun Y f =
let
exception BlackHole
val r = ref (fn _ => raise BlackHole)
fun a x = !r x
fun ta f = (r := f ; f)
in
ta (f a)
end
And you could then calculate fact 5 with the below code, which uses anonymous
functions to express the faculty function and then binds the result of the
computation to res.
val res =
Y (fn fact =>
fn 0 => 1
| n => n * fact (n - 1)
)
5
The fixed-point code and example computation are courtesy of Morten Brøns-Pedersen.
Updated response to George Kangas' answer:
In languages I know, a recursive function will always get bound to a
name. The convenient and conventional way is provided by keywords like
"define", or "let", or "letrec",...
Trivially true by definition. If the function (recursive or not) wasn't bound to a name it would be anonymous.
The unconventional, more anonymous looking, way is by lambda binding.
I don't see what unconventional there is about anonymous functions, they are used all the time in SML, infact in any functional language. Its even starting to show up in more and more imperative languages as well.
Jesper Reenberg's answer shows lambda binding; the "anonymous"
function gets bound to the names "f" and "fact" by lambdas (called
"fn" in SML).
The anonymous function is in fact anonymous (not "anonymous" -- no quotes), and yes of course it will get bound in the scope of what ever function it is passed onto as an argument. In any other cases the language would be totally useless. The exact same thing happens when calling map (fn x => x) [.....], in this case the anonymous identity function, is still in fact anonymous.
The "normal" definition of an anonymous function (at least according to wikipedia), saying that it must not be bound to an identifier, is a bit weak and ought to include the implicit statement "in the current environment".
This is in fact true for my example, as seen by running it in mlton with the -show-basis argument on an file containing only fun Y ... and the val res ..
val Y: (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b
val res: int32
From this it is seen that none of the anonymous functions are bound in the environment.
A shorter "lambdanonymous" alternative, which requires OCaml launched
by "ocaml -rectypes":
(fun f n -> f f n)
(fun f n -> if n = 0 then 1 else n * (f f (n - 1))
7;; Which produces 7! = 5040.
It seems that you have completely misunderstood the idea of the original question:
Is it possible to write recursive anonymous functions in SML?
And the simple answer is yes. The complex answer is (among others?) an example of this done using a fix point combinator, not a "lambdanonymous" (what ever that is supposed to mean) example done in another language using features not even remotely possible in SML.
All you have to do is put rec after val, as in
val rec fact =
fn n => case n of
0 => 1
| x => x * fact (n - 1)
Wikipedia describes this near the top of the first section.
let fun fact 0 = 1
| fact x = x * fact (x - 1)
in
fact
end
This is a recursive anonymous function. The name 'fact' is only used internally.
Some languages (such as Coq) use 'fix' as the primitive for recursive functions, while some languages (such as SML) use recursive-let as the primitive. These two primitives can encode each other:
fix f => e
:= let rec f = e in f end
let rec f = e ... in ... end
:= let f = fix f => e ... in ... end
In languages I know, a recursive function will always get bound to a name. The convenient and conventional way is provided by keywords like "define", or "let", or "letrec",...
The unconventional, more anonymous looking, way is by lambda binding. Jesper Reenberg's answer shows lambda binding; the "anonymous" function gets bound to the names "f" and "fact" by lambdas (called "fn" in SML).
A shorter "lambdanonymous" alternative, which requires OCaml launched by "ocaml -rectypes":
(fun f n -> f f n)
(fun f n -> if n = 0 then 1 else n * (f f (n - 1))
7;;
Which produces 7! = 5040.

map function if a predicate holds

I feel like this should be fairly obvious, or easy, but I just can't get it. What I want to do is apply a function to a list (using map) but only if a condition is held. Imagine you only wanted to divide the numbers which were even:
map (`div` 2) (even) [1,2,3,4]
And that would give out [1,1,3,2] since only the even numbers would have the function applied to them. Obviously this doesn't work, but is there a way to make this work without having to write a separate function that you can give to map? filter is almost there, except I also want to keep the elements which the condition doesn't hold for, and just not apply the function to them.
If you don't want to define separate function, then use lambda.
map (\x -> if (even x) then (x `div` 2) else x) [1,2,3,4]
Or instead of a map, list comprehension, bit more readable I think.
[if (even x) then (x `div` 2) else x | x <- [1,2,3,4]]
mapIf p f = map (\x -> if p x then f x else x)
In addition to the answer of PiotrLegnica: Often, it's easier to read if you declare a helper function instead of using a lambda. Consider this:
map helper [1..4] where
helper x | even x = x `div` 2
| otherwise = x
([1..4] is sugar for [1,2,3,4])
If you want to remove all the other elements instead, consider using filter. filter removes all elements that don't satisfy the predicate:
filter even [1..4] -> [2,4]
So you can build a pipe of mapand filter than or use list-comprehension instead:
map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]
Choose whatever you like best.
Make your own helper function maker:
ifP pred f x =
if pred x then f x
else x
custom_f = ifP even f
map custom_f [..]
(caveat: I don't have access to a compiler right now. I guess this works OK...)
I like the other, more general solutions, but in your very special case you can get away with
map (\x -> x `div` (2 - x `mod` 2)) [1..4]
Mostly a rip off of existing answers, but according to my biased definition of "readable" (I like guards more than ifs, and where more than let):
mapIf p f = map f'
where f' x | p x = f x | otherwise = x
ghci says it probably works
ghci> let mapIf p f = map f' where f' x | p x = f x | otherwise = x
ghci> mapIf even (+1) [1..10]
[1,3,3,5,5,7,7,9,9,11]

Resources