
Introduction to OCaml - jxub
https://blog.baturin.org/introduction-to-ocaml.html
======
frisco
OCaml is a great language. We looked really seriously at using it at my
startup for some critical things a while ago, when the company was very young,
because some of the team knew it and we were inheriting a small code base in
it. Ultimately immaturity of tooling (eg ocamlp4 vs ppx) and near total lack
of library support killed it for us. (We ultimately went with C++.) Good luck
trying to use gRPC in it, for example: there are like three different
"protocol buffers" libraries that all implement different parts of it and
which are incompatible with each other. While Clojure and Scala have their
weaknesses, being on the JVM and being able to re-use all of that Java
infrastructure was such a massive advantage.

OCaml seems awesome and I wish I could use it more, but don't underestimate
how much time you'll spend fighting with opam (and a lot of things just aren't
in opam at all, or the opam version isn't compatible with your OS, but there's
an apt package for it, but oh no what is going on) and just trying to get to
talk to the rest of your stack.

~~~
nikofeyn
i am curious if you considered f#.

~~~
frisco
We didn’t. I’ve heard good things about it, but my understanding is it’s
windows/mono, and we run all Linux in production, which seems like a pain to
navigate. (F# is CLR right?) Maybe this isn’t that big of an issue in reality
but we had a reason to specifically consider OCaml, and once we passed on it,
had strong biases to otherwise avoid things considered exotic.

~~~
systems
F# runs fine on Linux, and it compatible with dotnet core, and have a very
good emacs mode

If you have more questions on F# i recommend the community forum
[http://forums.fsharp.org/](http://forums.fsharp.org/)

I am not an expert, yet, but F# is missing several of the more sophisticated
OCaml features, but on the positive side, you have the .net core ecosystem

~~~
mlevental
can you point me to a tut to get f#running on Ubuntu?

~~~
nikofeyn
[https://fsharp.org/use/linux/](https://fsharp.org/use/linux/)

------
georgewfraser
The ML family languages are _still_ so far ahead of "mainstream" languages in
many ways. The first language I ever really learned was SML, my freshman year
of college, and I swear there's still a part of me that reaches for "case",
even after 15 years and about 1m lines of Java.

I've been playing around with an implementation of the ML semantics+type
system, using the Go AST as a compilation target. Golang makes a surprisingly
great compilation target for a functional language, because Go itself doesn't
have any object-oriented baggage. I think there's real potential for a
functional companion to Go, much like F#::C# and Scala::Java.

~~~
nikofeyn
it is truly amazing to me that an ML language never made it mainstream. an
OOP-enabled ML like F# or Ocaml beats the pants off of the likes of something
like python, but here we are where python is taking over the world. and
everyone else is clinging to java and c++.

f# and ocaml aren’t even hard to learn! i mean, one can learn Standard ML in a
couple of weeks using dan grossman’s programming languages course! i
understand, f# and sml and even some scala after just some small reading. but
i took a semester long course in c++ and never understood it.

~~~
vram11
>an OOP-enabled ML like F# or Ocaml beats the pants off of the likes of
something like python

Can you explain why you think so?

~~~
nikofeyn
well python is often loved for how clean it is. however, i believe f# (or any
ml dialect) is much cleaner than python in terms of syntax. and not only is it
cleaner, it is more consistent, which is due to its ml ancestry. python is
often loved for how it allows people to express solutions to their problems.
however, f# allows much more expression that python has explicitly chosen to
disallow. for example, f# is every bit as capable if not more capable as an
oop language than python (see .net generics and ecosystem), but it also has
functional programming features. if you have never programmed in a language
with discriminated unions and pattern patching, you really should try. just
look at people implementing ideas and compilers in f#, ocaml, or sml. using
pattern matching and union types, it almost looks trivial. it looks as those
they're just writing out a description of what they're trying to solve, and
then bam, it's done. and i like f# out of these because of the .net platform
and how it has embraced its multi-paradigm nature in a very graceful way.

python is a very pedestrian language. that is probably the secret to its
popularity. it makes people who have put no study into programming languages
feel great because they're able to accomplish things quickly, at least at the
start. however, they are missing a lot, in my opinion by sticking with python.
there is nothing, from my perspective, that python has that f# doesn't or
couldn't have. and the reverse of that is explicitly not true.

ml and lisp/scheme are two of the greatest programming language approaches and
paradigms, and python chose and continues to choose to ignore both of them.

~~~
nv-vn
It's always been funny to me as a functional programmer that Python took off.
People always talk about how much quicker it is to write code in Python, and
99% of the time I find the Python code to be more complex than the
OCaml/Scheme/Haskell/Common Lisp equivalents (minus, of course, the library
support).

~~~
nikofeyn
yes, it's really sad. i feel like the ML and lisp dialects are all we ever
needed. having these two languages allows so much. they're perfect for getting
stuff done and they're perfect for creating new languages. there's no reason
why they couldn't have been used to perform the roles of things like java or
c++ or python, but yet, here we are.

~~~
pjmlp
Yeah, that is my though since I used Caml Light in the university, quite a
while ago.

Specially since adding to what you mentioned, those languages were compiled
since the early days.

It all boils down to lack of love from OS vendors.

Even nowadays, F# is still the black swan of .NET languages, with less tooling
support that C++ gets.

So I came to appreciate the small additions we get in Java, C#, C++ to get
closer to FP kind of programming than expecting a radical change.

------
stcredzero
_Do not make it REPL-centric. Real life programs are not developed in the
REPL. Include examples of complete programs._

In certain environments/languages, real programs are developed in the REPL.
Real programs, managing billion dollar portfolios, natural gas scheduling, and
the payroll of Fortune 500 companies have essentially been "developed in the
REPL."

~~~
SomeHacker44
I sort of lost interest in what else the author had to say at this early
point, despite having been interested in OCaml for many years. (Referring, for
context, to the "Do not make it REPL-centric" comment in the article.)

In Common Lisp, Clojure, Scheme/Racket and Haskell, I constantly develop with
the REPL. I also use it in other languages such as Ruby which are not
necessarily REPL-centric.

I find that I write much better (less buggy) code, faster, in a language with
great support for a REPL.

~~~
dmbaturin
I'm not against the REPL (perhaps I should even describe its usage in more
detail). In fact, I use it all the time. I'm against books like Learn You A
Haskell that leave the reader wondering how to make and distribute executable
programs. Or, worse, create an impression that it is not even possible, if the
reader is not motivated enough to read another book or blog posts.

------
kccqzy
Do not forget the Real World OCaml book! I personally found it to be very well
written.

Available both online and as a printed book published by O'Reilly:
[https://v1.realworldocaml.org/v1/en/html/index.html](https://v1.realworldocaml.org/v1/en/html/index.html)

~~~
mi_lk
You probably want to go with
[https://dev.realworldocaml.org/](https://dev.realworldocaml.org/) , which is
a in-progress rewrite of v1.

~~~
laylomo2
The v1 version has not aged well unfortunately. I _highly_ recommend just
reading the dev version.

------
therein
My compilers course in college was taught in OCaml. The first semester of the
course was spent on teaching functional programming and OCaml and the second
semester was spent on implementing a compiler that compiled a restricted
subset of OCaml.

It is a pleasure to write a tokenizer and a lexer in OCaml.

~~~
howenterprisey
Did you use parser combinators or what?

~~~
nv-vn
I assume OCamllex and OCamlyacc (or the various other alternatives like Sedlex
and Menhir). The OCaml standard distribution is very compiler-writing-
oriented, so to speak, and comes with tools for parsing out of the box. A lot
of newer projects use parser combinators, but there are far fewer examples of
how to use them (like the plZoo) and most people are already familiar with
lex/yacc, so I imagine most courses would choose to use those.

~~~
therein
Correct, good guess. :)

------
girzel
I thought this was a pretty great introduction. Part 2, in particular, finally
helped me understand function type signatures in ML languages: the fact that,
under the hood, functions only accept a single argument, and the way the type
signatures are presented are merely an aesthetic cleanup of what it actually
looks like (which would include more parentheses to indicate associativity).

One of the examples did refuse to compile for me, and I felt Part 1 was still
too light on basic syntax. I tried to do the exercise at the end of Part 1,
about prompting for, squaring, and printing an integer. This works:

    
    
      let this_integer = read_int ()
      let _ = print_int (this_integer * this_integer); print_newline ()
    

But this doesn't:

    
    
      let this_integer = read_int () in
        let _ = print_int (this_integer * this_integer); print_newline ()
    

And nothing in the tutorial explains why that should be so -- at least not
that I could find.

I've also yet to see a really good explanation of when you need to use
parentheses for grouping and when you don't -- this is the only part of the
language that really feels like a "syntax error" to me. Like, "Look, ocaml is
clean and doesn't need to use all this extraneous syntax! Except when it
does."

Anyway, good introduction.

~~~
nv-vn
So the reason for this is actually because OCaml has 2 types of expressions,
which is sort of confusing. The first is a top-level and the second is just a
normal expression. In top-level expressions, they are implicitly put into
scope. If you've seen any of the ";;" in tutorials, this indicates that you're
working in the top-level (although these are pretty much always automatically
inserted assuming you're not running a REPL). Now, if you're not in the top-
level, you need to use the `let x = ... in ...` syntax, where the `in` is
roughly analogous to a semi-colon. So the reason the first works is because
the REPL runs at the top-level, and the second would only work inside of a
function.

~~~
girzel
Okay, I think I get it... And if you're not at top-level, ie you're in a
function definition, you actually _can 't_ use "let" without an "in".

That is a little weird, but not terrible. Thanks for the explanation.

------
meritt
In addition to books/tutorials/etc, I've found reading the source to unison
[1] was a great way to see a more tangible example of using OCaml to create
software

[1]
[https://github.com/bcpierce00/unison](https://github.com/bcpierce00/unison)

------
xamlhacker
I loved OCaml as well but the lack of libraries pushed me to another ML
variant: F# on .net platform. With .net core and F# tooling around it
gradually maturing, it is a solid cross-platform functional language.

------
zumu
Awesome. I've been getting into OCaml lately, and it's great to see new
resources. This bodes well for future adoption.

For those looking for a slightly more comprehensive source, check out
[https://dev.realworldocaml.org/](https://dev.realworldocaml.org/) (no
affiliation).

------
alkonaut
What are the biggest differences between OCaml and F#? If I wanted to
learn/use an ML style language 2018, for what purposes should I use or learn
one over the other?

~~~
nv-vn
F# is very much focused on gaining real-world usage by making it compatible
with .NET. It has a lot of features that heavily target this, so for example
the object system is built to be compatible with the .NET style of
classes/objects (but sadly, they ditched the OCaml way of doing this, which
IMO is much better). This introduces many inconsistencies in the type system
and some clumsy syntax, which is pretty much a deal-breaker for me. However,
these features are very specific to more advanced parts of the language. If
FP+.NET or library support is a must for you, F# is probably the best choice
by far. Also, F# does a great job at interfacing with the GUI parts of .NET,
so if you need GUI (or Windows support) it is definitely the right choice. The
core language is still quite elegant and a joy to use.

I think if you have the choice not to use F#, though, that OCaml is generally
nicer to use. It offers a ton of features that I find myself missing in F#,
like a much more powerful module system, a more advanced approach to OOP, a
cool macro system, and so many more (polymorphic variants, better
exceptions/soon to be an effects system, ...). In general, I find the syntax
to be slightly more predictable for OCaml, but a lot of people still prefer
F#'s syntax (which is indentation-based, btw) so I wouldn't focus on that
point.

Overall, I think they fit different niches. I've had to use F# quite a few
times and it's by no means a bad language, but after using OCaml extensively I
feel disappointed by F# a little bit like how I'd feel disappointed if I had
to write a project in Java.

------
foobaw
OCaml was a required course in school for me. It was immensely useful and
allowed me to think differently about programming (I only knew Java,C,C++ at
the time).

------
gfiorav
Super late to the party but, if you love OCaml and ML languages, check out
Elixir. Runs on the Earlang machine and this inherits all its libraries. It
takes more than a page from patterns and conditional method bodies. Love it.

~~~
willtim
Like Erlang, Elixir is still a "dynamic" language with no static types, it
would have been great if it had introduced ML semantics to the Erlang/BEAM
world, but this would have been tough to retrofit.

------
nv-vn
For those considering learning OCaml, I thought I'd share my (admittedly
biased) thoughts about the language as a long-time user (well... roughly 4.5
years).

Out of all the languages I've learned, OCaml is one of the few that I would
consider to be a "sweet spot" language. A lot of people seem to have one
language that they tend to fall back to when they're not sure what else to use
because they find it most practical, whether or not they enjoy using it as a
language. Out of the languages I know, it's pretty much between Java and OCaml
for me, with OCaml being much more ergonomic. Writing OCaml code is much more
relaxing than most other languages I've encountered because everything is
quite predictable once you know the core language, but it features a multitude
of tools that you can use to approach any task (OOP, modules, functional
programming, imperative, low-level, high-level, metaprogramming, etc.). I also
think that OPAM is one of the best language package managers around (for
example, it comes with native support for having multiple copies of the OCaml
toolchain installed in parallel). Finally, Reason+BuckleScript have become
really nice and for web programming I think they offer one of the best
options.

There's still a few things that are far from perfect, though. OCaml still
lacks an equivalent to Haskell's typeclasses and that makes designing good
generic libraries a pain (it's still possible using modules+functors, but it
takes a little boilerplate because it's not implicit). As a side effect of
this, the standard library is pretty fragmented between the official one (aka
"things we used to write the compiler so you can keep them if you want"), the
Batteries library (which is essentially what the standard library would be if
the official one was "finished"), and Jane Street's Core library (which
replaces the standard library altogether). The problem is that this extends
into basically all of OCaml. For such a small language, there's little room
for all the competition and that means that a lot of libraries either don't
exist or aren't actively maintained. That said, most libraries are a breeze to
implement and for the real-world code that I do write, they are hardly a
distraction 99% of the time. The only other downside is that OPAM isn't
compatible with NPM, which means that BuckleScript (the OCaml->JS compiler)
has a totally separate ecosystem from the native compiler.

Tl;dr, if you're looking for a very general language to learn and don't care
about having to implement your own libraries, OCaml is one of the best choices
out there. If you're doing JS programming, it's worth taking a look into
ReasonML/BuckleScript.

If you're interested, feel free to ask me any questions about the
language/ecosystem/learning.

~~~
zumu
How do you feel about the progress OCaml since you started using it?

What is your general prognosis for the future?

Are you by chance getting paid to write OCaml? If so, how hard was it to find
opportunities.

~~~
nv-vn
1\. It's definitely been slower than I would have liked. A lot of developments
have been hyped up a lot, when in fact they are years away. Modular Implicits
(which approximates Haskell's type classes) and Multicore have been in the
works since only a little bit after I started using the language. At the time,
they were kind of described to me as being "right around the corner" but
failed to appear. There have certainly been lots of good additions to the
language apart from this (e.g. we got a great inliner called Flambda), but it
seems like it's still gonna be >=6 months before Multicore lands and possibly
a year or more before Modular Implicits makes its way into the mainline
compiler.

2\. I think it's kind of a bittersweet future. I think growth is decelerating
for OCaml because of ReasonML/BuckleScript making it really easy to get
started with OCaml and use web libraries. This is great because it brings
exposure to the language, but I think it's caused a number of people to switch
over from native to web, which means abandoning some of the OCaml libraries
for their web versions. OCaml has a great native backend and it's really a
shame for me to see it fade away, but I think in the long-run that's probably
going to happen. Still, I think popularity of Reason will continue to go up
and that will bring OCaml into the mainstream for hopefully long enough to
garner some attention and get people to take the native backend seriously.

3\. I'm currently working for equity at a very small startup I co-founded but
we're using ReasonML for the web side of things. Previously, I was at an
internship where I had a lot of freedom to use whatever I wanted and was paid
to write some software in OCaml. I think finding a job writing OCaml is rather
difficult, but introducing it in a job (especially for internal tools or web
development with Reason) is much, much easier. The "big" OCaml jobs seem to
all be at companies where it's really hard to find employment (Jane Street,
Facebook, Bloomberg), but occasionally you'll see some smaller ones pop up
online.

~~~
zumu
Thanks for the detailed and thoughtful answers.

I'm going to keep hacking away at OCaml, but measure my expectations a little
and perhaps start looking into Reason as well.

A couple questions wrt Reason:

Do you find it easy to switch between OCaml / Reason? I personally find the
syntax of Reason a little unnecessary.

Do you use ReactReason or some other framework -- perhaps the Elm-like 'tea'
package?

------
kasajian
where's the PDF version?

~~~
Normal_gaussian
The wonderful thing about a (relatively) plaintext site like this is you can
'print' it into whatever random format you want.

