OCaml by Example?

Is there an “OCaml by Example” book/tutorial somewhere?

I’m familiar with Rust/Clojure and want to learn OCaml syntax by typing lots of OCaml examples, trying to run the code, and fixing any typos.

See 99 (solved) problems. The official OCaml manual has also a lot of examples,

1 Like

There are a LOT of examples on RosettaCode:
http://rosettacode.org/wiki/Category:OCaml

1 Like

My original question was not well written.

I’m looking for the OCaml equiv of https://doc.rust-lang.org/rust-by-example/

something that intends to explain OCaml syntax / features one by one, by examples.

Maybe you’re looking for Yaron Minsky’s Real World Ocaml book?

A bit OT, but please be careful with RosettaCode. It contains plain wrong information about OCaml which hasn’t been corrected for years.

If anyone on this forum has an account there please correct it, there’s a discussion about this here (see my answer).

3 Likes

Having a cursory look at the rust book you have provided I think the closest you can get to this is John Whitington’s series of books starting with OCaml from the Very Beginning.

His books are the best ones I ever read about OCaml.

1 Like

Could you explain what is wrong there, we still get the same result with a recent version of OCaml.

My answer on stackoverflow explains what is wrong. I won’t repeat it here.

Sorry but I don’t understand your post on stackoverflow, I don’t find your explanation very clear, so maybe someone else could explain it here?

Also I’m not sure to understand is it really “plain wrong” as in “it was never true”, or do you mean it’s just “out of date”? Because there is this explanation from the ocaml mailing list:

http://caml.inria.fr/pub/ml-archives/caml-list/2008/05/9fbbd2d5896fb5a78236e2ebbe2c4c4a.en.html

So do you mean this was fixed already, and if so since which version of OCaml?

I’ve been meaning to make one for a while. Past year I wrote the first chapters as a blog post series, but then life happened™. Until life happens again in September, perhaps I can make a few more.

I’ve made an initial import to git (https://github.com/dmbaturin/ocaml-book/) and uploaded a rough, nearly unstyled build to http://ocaml-book.baturin.org/

What sets it apart from other books is that it’s under a free license (CC-BY-SA) and belongs to the community. I hope it can become a collaborative effort.

The examples are meant to be compile-ready (not being REPL-centric is one of the goals), so I think it should be easy enough to make them runnable.

3 Likes

Maybe the explanation is not clear but if would have to write it again I would write exactly the same, sorry. It’s difficult to help if you just say “I don’t find it clear”.

In any case if you understand what rosetta says you actually get in my post an executable proof that what is written on rosetta, namely:

The OCaml programmer should be aware that when multiple values are returned with a tuple, the finalisation does not handle each values independently, but handles the tuple as a whole. So all the values are only finalised when all the values are not reachable anymore.

is wrong in general and moreover (if you understand the rest of the answer) is so most of the time.

I think it’s very bad to have that kind of wrong information on a site a newcomer is likely to consult and the reason why this bit should be removed from that website altogether. It also makes the language look completely broken from a memory management perpsective which we all know on this forum is clearly not.

Was it ever true, or it has been wrong all along?

To be honest, I don’t know but I highly suspect that what I wrote in the answer has always been true (cf. also the “worrying comment” above that mentions pattern matching, not tuples in general).

It doesn’t mentions pattern matching but functions returning tuples (at least as long as what I can understand).

found this, so it seems that this problem was fixed with OCaml version 4.00.0

That’s precisely what this rosetta comment gets completely wrong. I don’t think the following pattern for any function f returning a tuple:

let x = fst (f r)

ever had a space leak in any of the ocaml versions. Yet that’s what it will lead you to believe.

git clone https://github.com/janestreet/core
cd core/
git checkout 9b123844eb5ba519be647
cd lib/
cat space_safe_tuple.mli
(** The raison d'etre for Space_safe_tuple<N> is that OCaml doesn't properly
    free variables matched in tuple patterns.  If one writes

      let (a, b) = ... in
      ... a ... b ...

    when a and b appear at most once in the subsequent expression
    then this effectively becomes

      let t = ... in
      ... (fst t) ... (snd t) ...

    Hence, references to [a] and [b] keep alive the entire tuple.  This can
    lead to surprising space leaks.

    One notable instance of this bad behaviour is when one writes:

    let _,a = ... in ...a...

    The first element of the tuple, albeit not even being named, is live in the
    subsequent expression.

    By using Space_safe_tuple<N>, one makes it clear to the user where the tuple
    selection happens, and (hopefully) causes them to think about space safety,
    and to write the following if they want to free the tuple.

      let t = ... in
      let a = Space_safe_tuple2.get1 t in
      let b = Space_safe_tuple2.get2 t in
      ... a ... b ...
*)
module T2 : sig
  type ('a, 'b) t
  val create : 'a -> 'b -> ('a, 'b) t
  external get1 : ('a, _) t -> 'a = "%field0"
  external get2 : (_, 'a) t -> 'a = "%field1"
end

module T3 : sig
  type ('a, 'b, 'c) t
  val create : 'a -> 'b -> 'c -> ('a, 'b, 'c) t
  external get1 : ('a, _, _) t -> 'a = "%field0"
  external get2 : (_, 'a, _) t -> 'a = "%field1"
  val get3 : (_, _, 'a) t -> 'a
end

For what I can understand, it actually talks about a memory leaks for functions returning a tuple, and it proposes to use equivalents of fst and snd as a fix.

Read carefully what you are quoting. It’s not the fact that you are returning tuples from functions that is problematic it’s the fact that you pattern match on them.

I’m sorry but I don’t catch.

This won’t leak the second component:

let x = fst (f r)

This might leak the second component in the scope of the let binding, i.e. until e finished executing:

let x, _ = f r in
e