The Many Humps of Ocaml, Part 1
DRAFT: I’m still learning Ocaml myself, so some of what I say here may be plain wrong or misguided. I’m relying on those more experienced with Ocaml to correct my mistakes! If you have plenty of Ocaml experience, please correct my mistakes. By all means, be brutal!
Welcome to the very first part of my (hopefully enlightening) series of tutorials on the Ocaml programming language! In this tutorial we’ll be learning the Ocaml flavour of everybody’s favourite program: Hello World.
Since those interested in Ocaml will likely be coming from such a background, please note that this tutorial is written under the assumption that readers will have experience with other, imperative languages such as Java or C++. Now, on with the code:
let main () =
print_endline "Hello, World!" ;;
main () ;;
Save this file as tmhoo01.ml. You can run this program from the command-line using the following:
$ ocaml tmhoo01.ml
Or compile it to native code:
$ ocamlopt -o tmhoo01 tmhoo01.ml
Predictably, running this program displays “Hello, World!” in the console window. It’s not the output we’re interested in, however: it’s Ocaml’s weird ass syntax! Let’s take this line by line:
let main () =
This declares a function called “main”. let is an Ocaml keyword which defines named expressions (sometimes called let-bindings). In this case, the name of our expression/let-binding is “main”.
main takes a single parameter: the parentheses () represent what is known as the “unit value”. It is the only possible value for the unit type, and has a similar use and meaning to what void has in C/C++. In this case, it means the function main accepts no other parameters. This is necessary because Ocaml functions must always be applied to one or more parameters: thus, when we have no parameters to pass we must resort to using (). If we do not accept this unit parameter at a minimum, the expression in main is evaluated at the next double semi-colon ;;. This is not our intention.
print_endline "Hello, World!" ;;
The print_endline call does as you would expect. Similar to System.out.println or printf. print_endline returns the unit value. Implicitly, our main function has a unit type. This distinction may not completely make sense just yet, but the importance of this will make sense later once we start doing more work with different types.
The ;; keyword is used to separate multiple top-level constructs (e.g. let-bindings and class definitions). Later, you will use ; to separate expressions within other constructs.
main () ;;
As you would expect, this calls our main function.
So that’s our first Ocaml program dissected. Thanks for reading! If you have any questions or comments, please post them here: I’ll surely be revising this article based on your recommendations.
UPDATE 1: Correction to the descriptions of ; and ;;. Thanks Paul!
UPDATE 2: Removed my haughty claim that Ocaml references are more like C++ pointers than Java references. Cheers Chris!
UPDATE 3: Tried to otherwise simplify the tutorial. Less “blah blah blah”!
UPDATE 4: Remove introduction to references all together. Several people felt it was out of place to introduce a concept like references in the first tutorial. I happen to agree. ![]()
[...] UPDATE: Part 1 [...]
Please, change the color of the code.
Your grey is too light to be readable.
That’s the first time I see someone using main() in an OCaml program : interesting….
Thanks Olivier, shall do.
The code samples are still to light to read, imho.
Is that a little easier to read?
Minor quibble: “;;” isn’t an operator. In fact, all it is is a terminator that’s necessary when using OCaml interactively, to let it know when you’re done. You might also wish to point out that “;” in OCaml isn’t a terminator; it’s just a separator. It takes a little getting used to, but eventually most OCaml programmers find themselves just not using either (except interactively) very much.
But as I said, minor stuff. Thanks for the first in the series–I look forward to other entries in the future!
I gotta say I think you’re mistaken in saying that OCaml references are more like C++ pointers than Java. The similarity with C++ pointers goes no deeper than syntax — the fact that dereferencing is a stand-alone operator rather than part of the ‘.’ and ‘[]‘ syntax. OCaml’s references don’t share many characteristics with either C++ or Java’s pointers, but they are certainly closer to Java than C++.
Paul: Noted! I’ll update the tutorial tonight.
Chris: I’m going to do some further research into OCaml references and get back to you. From what I’ve seen so far they have more in common with C++ pointers than Java. Of course, that’s not to say they’re the *same* as C++ pointers (e.g. from my understanding you can’t increment OCaml references). Obviously I’m the newbie here, this has just been my experience so far. If you can offer me any such examples where OCaml references are similar to those in Java, or where OCaml references deviate entirely from either language it’d be much appreciated.
Thanks very much for your input guys
Great intro!
Two little tips :
First, in OCaml, the “;;” are not necessary, second, you should(nt use calls as “main ();;” in the middle of nowhere.
I’d say your hello world should be written this way :
let _ =
print_endline “Hello World!”
If you really wan’t a wrapper around that print_endline, you could use :
let main () = print_endline “Hello World!”
let _ = main ()
Adrien
Thanks Adrien! Just before I update the tutorial though, I’d like to get my terminology right: would it be fair to say that
let _ = main () ;;
simply discards the unit value returned by evaluating main () ?
That’s it :
“Now we have an unusual let-binding. let _ = expression means “calculate the value of the expression (with all the side-effects that may entail), but throw away the result”.”
source : http://www.ocaml-tutorial.org/the_structure_of_ocaml_programs
Just wanted to say cool blog
cool blog !!
there you go i said it
You’re learning OCaml and you seem to be a fan of SDL. (I saw your Ruby/SDL article.)
So maybe my article about OCaml+SDL is interesting for you:
http://wiki.njh.eu/OCaml_and_SDL
Nice tutorial. I look forward to seeing more. I agree that there is a general lack of ocaml tutorials around, although ocaml-tutorial.org is good.
I was a bit confused by the _ until this morning, when I realized it was more powerful than I thought. For example, you can automatically discard any argument of a function like this:
# let a b _ = b + 1;;
val a : int -> ‘a -> int =
# a 8 “carrot”;;
- : int = 9
In this case it was useless, but it could come in handy when you need to pass a function with a certain signature but you don’t want all the arguments.
Or you can use it when assigning values from a tuple:
let (client_sock, _) = accept listen_sock in…
In this case, accept returned a tuple and I only wanted the first value.
[...] Many Humps of Ocaml, PreludeThe Many Humps of Ocaml, Part 1The Many Humps of Ocaml, Part 2 This entry is part 3 of 3 in the series, TMHOO. Welcome to part [...]