
OCaml for the Masses (2011) - alanfranz
https://queue.acm.org/detail.cfm?id=2038036
======
jasim
I for one can't wait for Typed FP to become mainstream as soon as possible. I
think the prevalence of scripting languages in large systems today is a quirk
of history.

In early 2000s, as the web was growing to be an application delivery platform,
the only practical statically typed language was Java. It didn't have generics
or lambdas at the time, and was infested with the sprawl of J2EE. Choosing
Ruby/Python over Java was at the time an act of rebellion and a show of
technical superiority. To quote pg: "if they wanted Perl or Python
programmers, that would be a bit frightening-- that's starting to sound like a
company where the technical side, at least, is run by real hackers."

The static type system in Java is object-oriented: the only way to create a
type is to create a class. I believe it was limited in abstraction power and
everyone attributed it to the rigidity of static types. Java has come a long
way since, but the sense that dynamic typing is superior to static types
lingers.

But OCaml's static types are a completely different kind of type. There is a
kind of "procedural" static typing in Go, C, and to some extent C++ where
primitives are typed and you can construct structs and unions without much
ceremony. Then there is object-oriented static typing in Java and C#, which
traces its origin back to Simula through C++ where types and classes are the
same. Then you have functional static types where types are just and only
about data. Almost all Typed FP languages use a form of Hindley-Milner
inference, support algebraic data types and pattern matching, have generics
(they were invented by Milner for ML in 1973), and allows for code
organization and encapsulation through modules and opaque types.

Algebraic data types alone is a tool for thought like no other. You'll start
reifying concepts that would've otherwise gone implicit in your codebase
thanks to ADT. The languages are solid, ecosystems are vibrant but small and
that can only be fixed with more people. Come on in, the water is fine!

~~~
weberc2
I agree with the points in your post and I also want a mainstream typed FP
(something with a clear happy path so I don’t need to guess about what prelude
or string types or standard library or etc to use). The biggest impediment I
see is that these language communities are more concerned about the abstract
mathematical properties of the language and things like tooling get neglected.

I would love to see a typed FP equivalent to Go—everything is super
simple/small learning curve (I should be able to meaningfully contribute to a
project after a day or so), the standard library is decent, package management
just works, no guessing about what test lib to use, everything compiles to a
single static binary by default (dead simple deployments), no-fuss
documentation generation, great concurrency/parallelism story, straightforward
profiling and optimizations (e.g., if my program is slow because I’m
allocating too much in the hot path I can trivially preallocate), etc. These
are the things that matter for real world projects—mathematically elegant type
systems really are just gravy, which is why Go has been able to be so
successful in spite of its flat-footed type system.^1

^1: if you go over to r/programming, no one can figure this out because
everyone believes you can’t ship Software in a language without monads or
generics, so Go’s popularity must be due to Google marketing.

~~~
_hardwaregeek
I'd say Rust is the closest thing. Cargo is fantastic, super ergonomic and
with an excellent package ecosystem. Rust doesn't have the pretense of purity
or immutability, but honestly, you can very easily write pure functional Rust
(and it'll save you a lot of pain with lifetimes). Performance is excellent,
of course.

~~~
weberc2
I agree that Rust is the exception--it has a fantastic tooling story, but it's
actually the _language_ that holds it back for the sorts of applications I
tend to write. The performance and even correctness benefits it affords me
over Go are just too small for the cognitive burden it imposes (and yes much
of the gap closes with time--I've been kicking the tires on and off for 5
years now--but every year the returns diminish and it's looking like the gap
will remain significant). Hopefully I'll be proven wrong in the next few
years.

~~~
Ar-Curunir
Would you mind elaborating on the cognitive burden you find Rust imposes?

I find that after roughly two years of writing Rust, I can architect and re-
architect big projects fairly clearly, and the type system gives me strong
reassurances that refactors haven't screwed things up.

Not to mention the advantage of even simple things like enums, which most
languages (including Go) tend to lack.

~~~
weberc2
> Would you mind elaborating on the cognitive burden you find Rust imposes?

Millions of little decisions with respect to which lifetimes to use, which
types to use, which type of pointer to use, whether to pass by ref or by copy,
and so on.

> I find that after roughly two years of writing Rust, I can architect and re-
> architect big projects fairly clearly, and the type system gives me strong
> reassurances that refactors haven't screwed things up.

> Not to mention the advantage of even simple things like enums, which most
> languages (including Go) tend to lack.

I don't doubt it. I think these are really cool properties of Rust. They just
don't pay for the cognitive burden, since the applications I write aren't
critical systems (I can afford _some_ unsafety, but I can't afford to slow my
development process).

To put it differently, if I write in Go, I can quickly ship a feature with a
high degree of confidence that it's overwhelmingly correct, and the few errors
that do slip into production can be quickly fixed because I can iterate so
quickly. If I write in Go, I will eventually ship a feature with a very high
degree of confidence that it's overwhelmingly correct, but even if I find zero
bugs in production, the time spent shipping the first iteration in Rust is
much larger than the time it would spend me to ship _and_ iterate on bugfixes
in Go. I'm sure the extent to which this is true shrinks as I get more
experience with Rust, but there's a law of diminishing returns at play, and no
indication that the gap will ever vanish entirely.

~~~
Ar-Curunir
What kind of code have you been writing? For most Rust code that I write and
read, I find almost no lifetime annotations are needed.

------
yminsky
Hey, author of the linked post here.

A few thoughts, since some things have changed since that post was written:

First, the tooling limitations that I mentioned in the article have gotten a
lot better. In particular:

Merlin now provides IDE-like functionality for your editor of choice
(including code, vim, and emacs).

Also, Dune is an excellent build system for OCaml that does an enormous amount
to simplify the build process, and tie a bunch of different tools in the
ecosystem together. One great thing about Dune is it does a lot to unify the
experience we've long had inside of Jane Street with the open-source OCaml
experience. It's really a big upgrade.

We've also made some progress on debugging tools, like the spacetime
allocation profiler. There's also active work on making GDB/LLDB debugging in
OCaml really first class.

Also, OCaml has had some major industrial uptake. Notably, Facebook has
several major projects built in OCaml (Hack, Flow, Infer) as well as their own
syntactic-skin-plus-tooling on top of OCaml, in the form of Reason. Reason has
gotten a lot of traction in the webdev world, which is awesome. Bloomberg, and
Docker are some other big names that have real dependencies on OCaml, along
with some more names you probably don't know like Ahrefs, LexiFi, and SimCorp.

People sometimes feel like Jane Street is the only real user of OCaml, so they
imagine that Jane Street's needs are the ones that drive the language
priorities. So, the thinking goes, if you're not a trading firm, you should
look elsewhere. But this is the wrong picture. First, there are other serious
users, as discussed above. Besides, the community doesn't just roll over and
do what we say. If you don't believe it, go and see how often our PRs to OCaml
get rejected.

And even our interests in the language have grown beyond what you might
imagine a trading firm would care about. We use OCaml for building traditional
UNIX system software, like MTAs, for designing hardware (via HardCaml), and
for building dynamic browser-based applications (via Incr_dom).

For sure, there are still challenges of being a minority language (and there's
still no multicore GC, despite some exciting progress). But I believe OCaml is
a yet better choice than it was in 2011 when I wrote the article.

~~~
yminsky
And, shameless plug, if you're interested in seeing what it's like using a
functional language at scale for solving real problems, well, you can apply...

[https://www.janestreet.com/programming/](https://www.janestreet.com/programming/)

~~~
krupan
You mentioned HardCaml in your other post, but I don't see any hardware
positions on the website. Are you guys really doing hardware too?

~~~
yminsky
Right now, we're looking to hire an FPGA engineer in London. Our hardware team
is still small, but I expect we'll be doing more hiring as time goes on.

[https://www.janestreet.com/join-jane-
street/apply/ldn/full-t...](https://www.janestreet.com/join-jane-
street/apply/ldn/full-time/fpga-engineer/)

------
rkangel
If people want to move towards functional programming, I would recommend
Elixir as the first step.

There is a fantastic web framework called Phoenix built in Elixir. This
provides a way that you can immediately build something useful, and it teaches
you how to use Elixir well: the documentation is good, the generated code that
you start working with is a great example of how to use the language properly,
and when you start understanding the design of the framework it's a great
example of functional systems design (e.g. the Plug.Conn structure that gets
passed around).

Not having to deal with a full ML (or Haskell) like type system takes away a
large barrier to entry, but you still have to change your mindset about how
you implement things. And then the dialyzer is there, when you later want to
start using gradual typing.

~~~
progman
If you want to teach FP you should use the very first and most simple FP
languages --- Lisp and Scheme. Despite their extreme simplicity, they provide
an extremely expressive power (through their macros) which is still unmatched
in most other languages.

~~~
baby
These languages are horrible, filled with parenthesis and not fun. I had to
learn these in school, like many other people, and I stayed away from FP
languages for a long time because of that (like most people).

Try to learn Erlang or Ocaml, it's fun.

------
raphinou
I'm currently looking for the language and framework to use for a project, and
I'd like to go with a functional language.

I really, _really_ want to do my next project in Ocaml, but... I find the
ecosystem seriously lacking. You find Ocaml libs for a lot of needs, but a lot
of those a unmaintained and have their last commit a couple of years ago. I'm
afraid that choosing Ocaml would mean spending quite some time on libraries I
need, and less on the app I want to develop.

There's F# and the SAFE stack, but I don't feel home there. A lot of docs/libs
still are (or have quirks due to having been) Windows specific, and joining
the most popular f# community communication channels requires you to join the
F# Software Foundation....

Then there's Scala, with functional programming and access to Java's
ecosystem. But I prefer the ML style of Ocaml and F#.

~~~
nestorD
My ML of choice is F#, I came from OCaml because I wanted better tools,
librairies and an improved syntax.

The only place where I suffer from windows only librairies is UI and graphics
in general (I don't do web developement so I cannot comment on that) otherwise
developement on linux feels good (first via mono and now dotnet core).

Without the heaviness of dotnet (and, in particular, its project files), it
would be perfect.

~~~
raphinou
As you have experience in both, are there Ocaml things you really miss in F#?
How long are you developing in F# (and which type of apps if I may ask)?

~~~
nestorD
I have been using F# for data science, developing algorithms (where ML truly
shines) and most of my scripting needs for 3 years now (it is not my main
language as, these days, I need to instrument some C++).

As remify said F# came from Ocaml : it lacks modules, GADT and other thing but
you can easily translate most Ocaml to F#. For me the syntax was a net win.

The thing I miss is the Graphics module of Ocaml's std. I used to build quick
visualizations with it and I have not found a good F# equivalent that would
run flawlessly on Linux (the relevant section of mono's std was very buggy the
last time I tried using it).

~~~
hardlianotion
But now there is no need to rely on Mono, right? Now that Microsoft has
released dot net for other OS.

~~~
nestorD
When the first version of dotnet core went out, parts of it such as
system.drawing were just empty shells. Nowadays dotnet core is all you need
(happily F# seems to be developed first and foremost by the community and not
by Microsoft).

------
prossercj
> _Sometimes, the elegant implementation is a function. Not a method. Not a
> class. Not a framework. Just a function._ \- John Carmack

This mirrors a discussion I've had with my boss a number of times. Most of our
products are written in C++, and we complain about how often developers
(usually coming from Java) think that everything needs to be inside a class
hierarchy. The procedural parts are still there for a reason: the CPU is
procedural. A procedure or function is a closer mapping to what the CPU is
actually going to do when the code runs.

On the other hand, I've never done serious work with a pure functional
language like OCaml. I would welcome the chance, though I wonder if one finds
the same kind of dogmatism as in the OOP world...("it _must_ be a pure
function!")

~~~
hajile
Haskell is dogmatic. Everything _must_ be lazy. Everything _must_ be
immutable. Everything _must_ be pure.

Ocaml (and SML) aren't particularly dogmatic. They are both eager, so
reasoning about performance is much easier. Most things are immutable by
default, but you can make mutable data structures in both. Rather than
insisting on pure functions, SML and Ocaml allow side effects in functions and
have the `unit` type for functions without a return.

The type system is actually strong (eg, no implicit casts) and null exceptions
simply do not exist. Multi-threading is the big weakness. Ocaml has been
promising support for at least a decade without mainline support. Likewise,
most SML variants don't have support (though PolyML does along with a couple
others).

~~~
elbear
The first one, about everything having to be lazy, isn't true. You can define
strict data types or functions. The other two are though.

~~~
sudomakeup
You can still have mutable references and impure functions in Haskell, but its
not like "path of least resistance" of other languages. The IO type marks
impure functions

Also one can use STRef if they want to have a pure function that is internally
implemented with mutable values - that is all the side effects are self
contained.

[http://gamasutra.com/view/news/169296/Indepth_Functional_pro...](http://gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php)

"a function can still be pure even if it calls impure functions, as long as
the side effects don't escape the outer function"

------
zengid
I'm personally having a lot of fun learning Rust, which seems to have been
largely inspired by OCaml. Algebraic data types and pattern matching are a
revelation!

~~~
aldanor
Fun fact: Rust compiler was initially written in OCaml.

------
christophilus
I would love to see something more like SML, with OCaml compile times, and a
Go-like standard library. If that could be accomplished, I think we would see
statically typed functional programming go mainstream.

------
adultSwim
Python makes it easy to start a program. OCaml is easy to finish one.

------
lovebes
ReasonML is going to bring Ocaml to the masses. Massively popular React apps
can be created from ReasonML. Ocaml + syntactic sugar = ReasonML.

------
tybit
The masses won’t be coming to ocaml unless it comes to them. ReasonML seems
like a much more likely approach to succeed to me.

~~~
lmm
What seems to be working is Rust.

~~~
leppr
Rust is a very different beast when it comes to development speed. When
compromises must be made, its design decisions always favor runtime speed over
developer friendliness. That results in rather unwieldy APIs compared to the
alternatives in dynamic languages.

As a replacement for C/C++ this makes perfect sense, as a replacement of
JS/Ruby/OCaml, not so much.

~~~
fnord123
OCaml belongs with C++ and Rust for compile times...

~~~
LeonidasXIV
How so? OCaml complies way faster and you don't actually need to compile it.
You can sort of use it as scripting language without any compile step to begin
with.

------
remify
Great writing.

By the way, How is it that HN readers always heavily promote OCaml related
threads ?

~~~
DanielBMarkham
The nice thing about OCaml (and its MS cousin F#) is that it's a hybrid
language. Know FP? Fine, you can code that way. Know OO? Fine, you can code
that way. It meets you where you are.

~~~
int_19h
I would even argue that for OO, OCaml is a better object-oriented language
than most dedicated OO languages. It nicely decouples classes from types, for
example, so that the subclass diagram needs not correspond to the subtyping
diagram (i.e. you can reuse code via inheritance without following LSP
subtyping rules, but the type system will still prevent any unsafe use of such
hierarchies).

------
ynniv
I want to spend more time in OCaml, but without threads it's a tough sell.
Modern performance requires parallelism with shared memory, and the current
mainline solutions don't offer that.

Where threads aren't part of the equation, OCaml has become suddenly popular.
That's telling.

~~~
jasim
[https://pl-rants.net/posts/go-and-ocaml-scalability/](https://pl-
rants.net/posts/go-and-ocaml-scalability/) has an interesting take where they
found multi-process OCaml performing better than goroutines. I don't know how
to interpret those measurements correctly, so any help there would be
appreciated.

~~~
ynniv
This experiment has "embarrassingly parallel" data, ie there is little to no
benefit to sharing data between computations. It's not surprising that
multiprocess does well on this, but this is not common in most real world
applications. Imagine a simple chat server, where every request needs to read
and write shared state. Even when the application doesn't seem to have shared
state, any in-memory caching requires it.

~~~
anentropic
"most real world applications" is a meaningless phrase, I doubt anyone can
quantify "real world applications" one way or the other

also the result is still interesting, why wouldn't goroutines scale just as
well, but apparently didn't?

~~~
ynniv
That's fair, but perhaps I can rephrase it to say that embarrassingly parallel
applications are a well known edge case and not the norm.

------
donpdonp
Elm is the langauge that showed me a functional language can be amazing. It
clicked in my head like no other language. I did a substantial web app in it,
and came to appreciate it more and more. I only wish it were available as a
general purpose language. I used to call elm a gateway-drug to ocaml but I
have a hard time swallowing a lot of ocaml syntax. Reason seems to be a good
way around that. I'm also keeping an eye on the Grain language.

------
twoquestions
Is F# still being used/developed, or has MS started to leave it out to dry?

------
revskill
The problem with Reason is non-automatic understanding 3rd party Javascript
codebase. It's the pain to implement correct type to use in Reason program
with existing JS codebase.

------
justaaron
is there any NON-garbage-collected functional programming language? Something
suitable for real-time or deterministic timing usage?

~~~
manu3000
[http://intuitionistic.org/](http://intuitionistic.org/) ... seems barely
alive

------
thibran
These kind of blog posts are one of the reasons why I love the internet, and
why Hacker News is such a great place.

------
devit
It seems like Rust would have been an even better choice, had it been
available at the time they chose OCaml.

~~~
progman
Rust may be a very good choice for systems programming. However, safety
criticial software can also be written in other languages which don't need a
borrow checker -- Ada and SPARK for instance, or even in C with verificatino
tools (FramaC etc.). Most developers also don't need Rust's "feature" of not
having a garbage collector since they are not involved in systems programming.
As for me, what makes OCaml attractive is its functional nature combined with
a very practical imperative syntax. There is no steep learning curve like in
Rust, and OCaml's compilation speed is staggering.

------
G4BB3R
I am still waiting a friendly backend language similar to Elm. OCaml is hard
and lost timing.

~~~
eterps
You might find this interesting:
[https://wende.github.io/elchemy/](https://wende.github.io/elchemy/)

IMO OCaml is not any harder than Elm.

------
fileoffset
OCaml is not for the masses, it never has been

