What is the error in the following OCaml Snippet? - functional-programming

Code:
let ab = let a = 'a' in let b = 'B' in (Char.lowercase b) in a :: [b];;
I am learning the let keyword. I want the expression to evaluate to the list of characters ['a', 'b'] but instead I keep getting the error
Error: Unbound value a
I don't know why this is happening. As far as I understand, I can keep using let inside let to create new bindings and I have used let to bind a to 'a' in the beginning itself and hence it should have a valid value in the inner scope as well right?
I know that I can simply do b = 'b' instead of b = 'B' in (Char.lowercase b) but I am experimenting with what I can do and what I cannot do and to me this should also work.

You have too many in keywords. The topmost let shouldn't have a corresponding in.
let ab =
let a = 'a' in
let b = 'B' in
(Char.lowercase b) in
a :: [b];;
Re-write it like this:
let ab =
let a = 'a' in
let b = 'B' in
a :: [Char.lowercase b];;
In fact, since the let b expression doesn't refer to a, you can write it like this:
let ab =
let a = 'a'
and b = 'B' in
a :: [Char.lowercase b];;

Based on discussion in comments, I would also suggest, if you want an expression:
let ab =
let a = 'a' in
let b = 'B' in
a::[Char.lowercase b]
in
(* The rest of your code. *)
The problem is that your expression was this:
let ab =
let a = 'a' in
let b = 'B' in
Char.lowercase b (* Result: ab gets bound to 'b'. *)
in
a :: [b] (* a and b aren't visible out here! *)
I also recommend indenting in a style similar to this one, to help you see such things clearly. OCaml programmers usually break lines before let. If you have let p = e in e' and e or e' don't fit on one line, indent the e, but not the e'. That way, you can quickly see which further expressions the bindings of p are visible in, and see that any bindings made in e are not visible in e'.

Related

F# (F sharp) unzip function explained

I'm taking a university course in functional programming, using F#, and I keep getting confused about the logical flow of the following program. Would anyone care to explain?
let rec unzip = function
| [] -> ([],[])
| (x,y)::rest ->
let (xs,ys) = unzip rest
(x::xs,y:ys);;
So this program is supposed to take a list of pairs, and output a pair of lists.
[(1,'a');(2,'b')] -> ([1;2],['a','b'])
It seems to me, like the base case where the argument (list) is empty, the format of the output is given, but I don't understand how the third and fourth line is evaluated.
let (xs,ys) = unzip rest
(x::xs,y:ys);;
Firstly, this is a recursive function - the rec keyword is a giveawy :).
These can be quite hard to get you head around, but are quite common in functional programming.
I'll assume you are OK with most of the pattern matching going on, and that you are aware of the function keyword shorthand.
let rec unzip = function
| [] -> ([],[])
| (x,y)::rest ->
let (xs,ys) = unzip rest
(x::xs,y:ys);;
You seem quite happy with:
| [] -> ([],[])
Given an empty list, return a tuple with 2 empty lists. This isn't just a guard clause, it will be used later to stop the recursive program running forever.
The next bit...
| (x,y)::rest ->
Takes the first element (head) of the list and splits it off from the tail. It also deconstructs the head element which is a tuple into 2 values x and y.
The could be written out long hand as:
| head::rest ->
let x,y = head
Now is the fun part where it calls itself:
let (xs,ys) = unzip rest
(x::xs,y:ys);;
It might help to walk though an example an look at what goes on at each step:
unzip [(1,'a');(2,'b');(3,'c')]
x = 1
y = 'a'
rest = [(2,'b'); (3,'c')]
unzip rest
x = 2
y = 'b'
rest = [(3,'c')]
unzip rest
x = 3
y = 'c'
rest = []
unzip rest
return [],[]
xs = []
ys = []
return [x:xs],[y:ys] # 3:[] = [3], 'c':[] = ['c']
xs = [3]
ys = ['b']
return [x:xs],[y:ys] # 2:[3] = [2,3], 'b':['c'] = ['b', 'c']
xs = [2,3]
ys = ['b','c']
return [x:xs],[y:ys] # 1:[2;3] = [1,2,3], ['a']:['b';'c'] = ['a', 'b', 'c']
done

Swapping Variables by pattern matching?

Assume you have 2 Integer Variables a and b
How would you swap them only if a > b by using a match expression?
If a <= b do not swap the ints.
In an imperative language:
if (a > b){
int temp=a;
a=b;
b=temp;
}
Doing the same in ocaml seems surprisingly hard.
I tried
let swap a b =
match a,b with
| a,b when a > b -> b,a
| a,b when a <= b -> a,b
I am trying to do this because in the following function call, I want to make sure that x is the bigger of the two variables.
One easy way :
let swap a b =
if (a>b) then (b,a)
else (a,b)
But this is not equivalent to the C code, your C code is swapping the value of the variable - this is how imperative language are doing.
In Ocaml, there is no side-effect (except if you use reference to some int). This swap function will return a tuple whose members are always ordered (the first member will be always smaller than the second order).
Without state, you cannot "swap" the values of the variables since the variables are immutable. Your best bet is to use a tuple and introduce new variables in the scope. Example:
let diff a b =
let (min, max) = if a <= b then (a, b) else (b, a)
in max - min
You can of course use the same identifiers and shadow the original variables:
let diff a b =
let (a, b) = if a <= b then (a, b) else (b, a)
in b - a
It doesn't really help with readability though.
Just for reference, if you'd like to swap the values in two refs, it would look like the following:
let swap a_ref b_ref =
let a, b = !a_ref, !b_ref in
a_ref := b;
b_ref := a
;;
which has the type val swap : 'a ref -> 'a ref -> unit.

Ocaml pattern matching for "square" tuple?

In attempting to learn Ocaml and functional languages in general, I have been looking into pattern matching. I was reading this documentation, and decided to try the following exercise for myself:
Make an expression that evaluates to true when an integer 4-tuple is input such that each element in the 4-tuple is equal.
(4, 4, 4, 4) -> true
(4, 2, 4, 4) -> false
I find that doing pattern matching for the specificity of the value of the elements to not be obvious. This is the code I wrote.
let sqr x = match x with
(a, a, a, a) -> true
| (_, _, _, _) -> false ;;
Of course, this code throws the following error:
Error: Variable a is bound several times in this matching
How else can I not only enforce that x is a 4-tuple, but also of strictly integers that are equal?
(Also, of course a "square" tuple should not allow non-positive integers, but I'm more concerned with the aforementioned problem as of now).
`
As you found out, unlike some other languages' pattern-matching systems, you can't do this in OCaml. What you can do is match each element of the tuple separately while using guards to only succeed if some property (like equivalence) holds across them:
let sqr x =
match x with
| (a, b, c, d) when a = b && b = c && c = d -> `Equal
| (a, b, c, d) when (a < b && b < c && c < d)
|| (a > b && b > c && c > d) -> `Ordered
| _ -> `Boring
You have many ways to do pattern-matching, pattern matching is not only when using the match keyword
let fourtuple_equals (a,b,c,d) = List.for_all ((=) a) [b;c;d]
val fourtuple_equals : 'a * 'a * 'a * 'a -> bool = <fun>
Here you have a pattern matching directly in the parameter in order to access your four elements tuple.
In this example I use a list to have a more concise code, but is not the more efficient.

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

Scope/order of evaluation of nested `let .. in ..` in OCaml

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.

Resources