Banach Tarski
Banach Tarski

Reputation: 1829

What is the error in the following OCaml Snippet?

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.

Upvotes: 0

Views: 89

Answers (2)

antron
antron

Reputation: 3847

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'.

Upvotes: 2

RichN
RichN

Reputation: 372

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];;

Upvotes: 2

Related Questions