Functions
9 min · OCaml
Package code under a name so you can reuse it.
Enemy 1 of 5
Type inference for functions
In OCaml, defining a function uses exactly the same `let` keyword you already know from binding plain values — a function is simply a value bound to a name, the same way a number or string is; it just happens to be a value you can call with arguments. `let double n = n * 2` binds the name `double` to a function that takes one parameter, `n`, and evaluates to `n * 2`.
You never need to write `return` — the value the function's body evaluates to *is* automatically the function's result. For a one-line function like `double`, the body is just the expression after `=`; for longer functions, the body can be a sequence of expressions (often using `let ... in ...` to introduce intermediate values), and the final expression's value is what gets returned.
Notice `double` has no type annotations anywhere, yet OCaml infers a precise type for it: `int -> int`, meaning "takes an int, returns an int." It works this out purely from how `n` is used inside the body (multiplying by an int implies `n` is an int). This is the same Hindley-Milner inference from the Variables lesson, now extended to functions — one of OCaml's most distinctive strengths, since it lets you write fully type-safe code with almost no type-annotation overhead.
Calling a function needs no parentheses or commas around the arguments the way many languages require — you just write the function name followed by its argument, separated by a space: `double 5`, not `double(5)`. Parentheses are only needed to group a more complex argument expression, as in `print_int (double 5)`.
Loading editor...