Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the in keyword in OCAML

Tags:

ocaml

I am confused what the keyword in does in OCAML. When do i need to use it ? The only example I came close to understanding is :

let quit_loop = ref false in
while not !quit_loop do
  print_string "Have you had enough yet? (y/n) ";
  let str = read_line () in
  if str.[0] = 'y' then
    quit_loop := true
done;;

or

let x = 10 in
let y = 20 in
x + y ;;

what does in indicate here ?

like image 469
MistyD Avatar asked Sep 19 '15 20:09

MistyD


1 Answers

The best way to look at it is that in is not a separate keyword. Instead, there's an expression that looks like let v = expr1 in expr2. This is the way in OCaml to define a "local" variable. What it's saying is that you're going to use v as a named value in expr2, and its value when it appears in expr2 is the value of expr1.

I suspect the only reason this is confusing at all is that there's a different construct in OCaml for defining "global" variables. At the top level of a module you can say let v = expr. This defines a global name that is (in general) exported from the module.

All of the examples you give are of the first kind; that is, they're defining local variables named quit_loop, str, x, and y.

As a matter of syntax, in is mostly acting like punctuation; it allows a parser for the language to tell where expr1 stops and expr2 begins. This is especially necessary in ML languages, where putting two expressions next to each other has a specific (and very commonly used) meaning.

Update

By request, here are some examples of let ... in:

let compare_lengths a b =
    (* Here "let ... in" is used to name values used throughout
     * the computation (i.e., to make local variables).
     *)
    let alen = List.length a in
    let blen = List.length b in
    if alen < blen then -1
    else if alen > blen then 1
    else 0


let rec split list =
    (* Here "let ... in" is used to name
     * the parts of an intermediate result.
     *)
    match list with
    | [] -> ([], [])
    | (a, b) :: rest ->
        let (ra, rb) = split rest in
        (a :: ra, b :: rb)


let euclidean_distance (x1, y1) (x2, y2) =
    (* Here "let ... in" defines a nested helper function.
     *)
    let sqr f = f *. f in
    sqrt (sqr (x2 -. x1) +. sqr (y2 -. y1))
like image 108
Jeffrey Scofield Avatar answered Sep 27 '22 23:09

Jeffrey Scofield