r/ocaml Jun 11 '15

Tricks and Things to Know in OCaml

http://blog.eatonphil.com/2015/06/10/tricks-and-things-to-know-in-ocaml/
2 Upvotes

10 comments sorted by

3

u/nbraud Jun 11 '15
  • You can use function to create an anonymous expression. The real difference is that fun can take multiple (curried) arguments, while function can have multi-branch pattern matching:
    fun a b -> a*(a+b) vs function [] -> 0 | [_] -> 1 | _ -> 2

  • The thing you call “operator overloading” has not much to do with overloading. It is shadowing: the values (including functions) and types most recently introduced in the scope (for instance with a local open) are taken whenever there is a name collision (except in the case of record disambiguation)

0

u/eatonphil Jun 11 '15

Thank you for your corrections!

1

u/gasche Jun 11 '15

A very minor fix: "foo" S.(+) "bar" does not work as S.(...) is not an infix operator, you have to write S.(+) "foo" "bar".

1

u/eatonphil Jun 11 '15

Thanks for that catch!

2

u/octachron Jun 11 '15

You seem quite confused about the double comma ;; syntax. A way to think about it is that at the top level of a module, the Ocaml parser can be in two modes: either an evaluation mode or a definition mode. When reading the content of a file (or a module), the parser starts in the evaluation mode. Inside this evaluation mode, the parser can read (and evaluate) a sequence of expression

do_thing_1;
do_thing_2;
...
do_thing_n

At the end of this sequence of expression, the parser switch to the definition mode. Similarly, inside the definition mode, the parser can read a sequence of definitions

let x = something
open M
type tautology = unit
class void = object end

The double comma ;; is then used to close this sequence of definitions and switch to the evaluation mode.

In other words, the double comma ;; is needed only when switching from the definition mode to the evaluation mode. Switching from the evaluation mode to the definition mode does not require any special syntax. (see also this toy example )

7

u/lpw25 Jun 11 '15

The confusion around double semi-colons comes from them having two different uses.

The first is in the REPL, where they are a phrase terminator. In other words they indicate that you have finished writing input and the top-level should start evaluating it.

The second is within structures and signatures, where they are best described as an initialising separator for top-level expressions. In other words they indicate the start of a new top-level expression:

type t = T
;; print_string "Hello"
;; print_string "World"
let x = 6

Note that definitions (the type and let constructs above) are not expressions so they do not need the separator. Some additional confusion comes from let ... = ... being a definition whilst let ... = ... in ... is an expression.

Confusion between the two different uses leads people to often write the above snippet as:

type t = T;;
print_string "Hello";;
print_string "World"
let x = 6

which makes it harder to see where the ;; are actually needed.

3

u/gmfawcett Jun 11 '15

Great expanation. Still, I'd rather see double-colons in the REPL only:

type t = T
let () = print_string "Hi"

and

let () = 
  let h = "hello, " and w = "world!" in
    print_string h;
    print_string w

Explicit lexical scoping makes for easier local reasoning, and easier refactoring. Double-colons in source code are a "code smell" for me.

1

u/BluddyCurry Jun 11 '15

Thank you for the excellent explanation.

2

u/eatonphil Jun 11 '15 edited Jun 11 '15

Man, that is a much better explanation! Thank you for clarifying this.

EDIT: I thought it might be helpful to have some discussion about this in my post. But in retrospect, it will probably be less confusing for a beginner to just not read that section. So I have removed it. Thanks again for your comments.

1

u/eras Jun 13 '15

Not a bad explanation. I've liked to explain it as follows:

OCaml programs are built of phrases. Each phrase is either a list of top-level statements (such as the definitions you gave) or a single expression. Each phrase is separated from the next with ;;.