scopeocamllet

let in and the use of ; vs ;;


I have this chunk of code below. I'm a bit confused as to how the let in syntax should work. I was under the assumption that the let in let you use that variable in the scope of in. Although, I don't understand how I am able to access the table variable here without being inside the in block. Am I going about this whole block of code the wrong way? I'm just trying to get a hang of the let in and when to the ; vs the ;;.

let first_nonrepeating lst =
    let store tbl value =
        if Hashtbl.mem tbl value then
            let seen_count = Hashtbl.find tbl value
            in Hashtbl.replace tbl value (seen_count+1)
        else
            Hashtbl.add tbl value 1 in
    let table = Hashtbl.create 100 in
    let store_table = store table in
    List.iter store_table lst;

    let rec findOne lstX =
        match lstX with
        | [] -> -10000
        | h :: t -> if Hashtbl.find table h = 1 then
                        h
                    else
                        findOne t in
    findOne lst;;

If I slap another in after the iter then it throws a syntax error. I was expecting this to work because that List.iter is required to be able to use the table. Somehow, I'm able to use the table outside of the scope of those in blocks by using a ;. How does this work? The above code compiles, I'm just a bit lost as to how to use the ; versus an in.


Solution

  • The ; token sequences multiple expressions to form a single expression. Everything other than the last excursion is expected (but not required) to be of type unit and the computer will warm you if they aren't.

    You can achieve a similar effect with the following, though this will not compile say all if expr1 and expr2 are not of type unit.

    let () = expr1 in
    let () = expr2 in
    expr2
    

    Compared with:

    expr1;
    expr2;
    expr3
    

    The ;; token tells the toplevel it has reached the end of an expression. This is never necessary in a full, properly formed OCaml program.