Why did you learn OCaml?

I’ve come back to it, after years of fooling around with Haskell; getting along better with the syntax this time, I just put “begin/end” around every match/function. Why? It’s practical. Not just in its ability to address problems via whatever the most suitable paradigm (I’m even using objects), there’s also the mundane considerations of being able to deploy it on a wide variety of platforms, and standard libraries that continue to work across major versions.

1 Like

Dabbled in Haskell for about 6 years. Then one day I decided I wanted to understand what an “impure” Haskell looked like. Needless to say, what I found was a criminally under-appreciated language with a funny syntax but extremely sensible and practical trade-offs in its design and community.

2 Likes

Shortest version: Type inference + versatility.

Short version: I have always liked static typing but the switch from Swift/Flow (for JS) to OCaml felt like a bigger leap forward then my previous switch going from Objective-C to Swift. I am also a big believer in having few languages organisation-wise and OCaml is extremely good at many things.

5 Likes

That’s a fun story. I’ve severely crippled my hand, so that I left one-handed for about half a year and was unable to code in C++ as it requires too much typing. Therefore I had to find a more concise language in which I could be as productive as in C++ but using only one hand.

Putting fun aside. OCaml is a fast, both in runtime and development time, programming language that facilitates functional style of programming without hampering other styles. It has type-inference so it is concise and at the same time is statically typed. Its powerful module system enables collaborative development of large projects and scales as the project grows. It is a very simple language with clear semantics which is very easy to learn and to teach. It has a strong foundation in mathematics and logic so it doesn’t give you any nasty surprises. At the same time, it is a programming language built by practical people for the use in the real world.

13 Likes

Indeed. This has also been my observation. Ocaml is my first and only full stack language so far.

We had to pick a primary programming language for our lab in 2013.

I wanted to use a statically-typed functional programming language because I find those language features facilitate safety and concision.

I had written some Scala in the past and was weary of the JVM ecosystem with Oracle as the steward, the instability of the language across minor versions, and Scala’s lack of explicit nulls, among other things.

I looked at F#, but this was pre-Satya Microsoft, so I was quite wary of Microsoft as a steward for the CLR; F# was also missing functors and the handling of nulls was clumsy.

I spent a lot of time with Haskell thanks to Real World Haskell, possibly the best programming book I have read. However, when I talked with organizations using Haskell, I found two issues that caused me to put Haskell aside: first, the proliferation of pragmas across libraries and organizations means everyone is writing a different dialect of Haskell, an issue to which I am particularly sensitive having worked with large C++ codebases in the past; second, I saw a presentation at CUFP 2013 about how Haskell’s lazy evaluation made it very hard to identify thunk-driven memory leaks for long-lived Haskell servers. I also found that the library ecosystem in Haskell was not as rich for systems and data-intensive programming. And as someone with a mathematics degree who is quite comfortable with category theory, it’s hard to stomach the condescension of many in the Haskell community who believe their language to be mandated by the mathematical gods.

Finally, I ended up with OCaml. I find OCaml to be the most readable major programming language. The module system really helps, as does the language’s opposition to operator overloading. Relative to Haskell, I value strict evaluation by default, and I find the compiler extension ecosystem built around camlp4 and now ppx to be saner than Haskell’s pragmas (though obviously they’re not directly comparable). My lab was located in NYC, so I figured there would be some OCaml-capable programmers who didn’t want to work in finance. I also thought we’d need to build embedded domain-specific languages, for which OCaml has many facilities, including MetaOCaml’s staged metaprogramming, which intrigued me even if I didn’t totally understand it.

Ultimately I found it hard to get our lab to adopt OCaml for most work, unfortunately. There are many ergonomic issues with the OCaml Platform, perhaps best exemplified by the “Essential Packages” table on that website (all “TBD”!). The standard library is quite bad, and libraries don’t always use the same alternatives to the standard library; the library ecosystem for common tasks in data science is quite thin; compiler error messages were opaque, and very common for new OCaml users; opam had a weird dependency on a external solver at the time that required the end user to do work to get good package manager performance; dune did not exist then so the build ecosystem was fragmented and poorly documented; and long-promised upgrades to the core language and runtime like multicore and modular implicits never landed.

7 Likes

Is Oracle really the Stewart of the JVM? Seems like the JVM has a lot of serious stakeholders.

Unless things have changed severely, the licensing agreement under which Oracle (previously SUN) licenses the Java APIs and libraries [note carefully I didn’t write JVM – more on that later] pretty much guarantees them control. It’s true that there are “expert groups” with representation from industry partners (and even academic ones) but at the end of the day, Oracle gets the final say. And of course, they take ownership of any code and redistribute it. Since I worked inside the JVM and also in major commercial products on-top, i experienced this personally.

A little more about the Java APIs and libraries. It would be infeasible to clean-room re-implement (hence, unencumbered by licenses) these (though IBM did it for quite a while in the J9 project), and the nature of how any useful add-on library gets incorporated into the “Java Standard” pretty much guarantees that it gets harder with time to re-implement. But even if you did a clean-room re-implementation, if you want to be compatible with the “Standard”, you need to adhere to the APIs, and that (again) forces you pretty much hew to Oracle’s line.

But none of that addresses the JVM itself: that is, “Java minus the standard libraries”. There are at least two JVMs out there today that adhere to the standard: the Solaris JVM from Oracle, and the J9 JVM from IBM. AFAIK neither is the actual source for the commercial JVMs these companies ship, and the code is strictly and strongly controlled by the companies that created it. Outside groups basically have no input into this process, except for submitting code with beseeching prayers.

So yeah, more-or-less, Oracle is the steward/owner of Java (JVM and standard libraries) and the “Java Standard”.

2 Likes

Thanks for all the info. I’ve never worked with any Java-related technologies as a developer. I thought it must have been, uh, “more open” because otherwise it seems nuts that so many major companies would be so deeply reliant on Java, but I really don’t know anything about it, apparently.

Oh ha. It’s actually the opposite. Major companies bought into Java -because- it was run and managed top-down by a single organization. After all, what commercial software companies (like all companies) care about, is “a single throat to choke” (when something goes wrong). [1]

And of course, for SUN (and later ORCL) Java was a source of revenue – they weren’t about to relinquish control of that cash cow (from licenses). As “top-down driven” as the Ocaml development appears, it is still light-years more open than anything in the Java world. Anything.

[1] Nevermind that more things go wrong with commercial software than with OSS. Remember that Linux really started to catch on commercially when companies like Redhat offered support contracts, yes?

3 Likes

Since I wish to write plugins for BAP, I’ve taken up OCaml. I’m only new to the language, am working through a few textbooks and have also done the recent FUN-MOOC course. I have to think more about what I’m doing when writing OCaml code, as compared with C or Python, but it somehow seems more satisfying when your recursion gives the result you want, rather like finding the right fitting cogs for a clockwork mechanism. Onward and upward.

3 Likes

What drew me to OCaml is in some respects more superficial than some folks’ reasons, but still valid, imo.

I love FP, and had been thoroughly enjoying Clojure (still do), after getting back into programming with Perl and then Common Lisp after a multi-year hiatus. I don’t mind piles of parentheses, but writing a lot of math without infix operators is annoying. (There is an infix library or two, but they are nonstandard and have their own oddities.)

At the same time, I was feeling the pull of the benefits of type safety (notwithstanding that I still like the flexibility of dynamic typing–there are advantages to each), and feeling like trying something new. But I have a horror of Java type annotations. OMG! I had a job writing Java a long time ago, write and I enjoyed it at the time, I write some Java now when I have to, but who would want to write the same type over and over again in a line of code when it’s obvious what the types should be. (Why should I have to perform mental type inference and tell the compiler about it?) So I wanted a language with solid type inference.

I remembered liking Haskell syntax from playing with it years ago, but having to jump through monads for a simple thing like printing a value is, to me, silly, and it reflects something else, which is the total fastidiousness about types that is built into Haskell. Every time I’d read a blog post about Haskell, there’d be two or three screens of type definitions before you’d actually see code that did anything. I’m a more informal kind of guy, I guess. (Remember, I like Clojure.) This might seem like a silly reason to reject Haskell, but I was using heuristics to evaluate a language in which to invest my limited time, and to evaluate norms in the community from which I would learn. I might have misjudged Haskell, but I’m not sorry I chose OCaml. I decided I preferred a language with type inference but that’s open to including fully imperative code when that’s better.

OCaml was the obvious choice in the end. I still had Développement d’applications avec Objective Caml from years ago, which I’d read but didn’t actually do much with. I got RWO too. I actually looked at F#, briefly, but wasn’t keen on mixing in C# syntax constantly, and I really liked the idea of compiling down to machine code. Also, the Clojure community is very, very friendly and helpful, but it’s very business oriented, and for a while it was hard to get people interested in things that an academic like me cares about. The F# community seemed similarly business-oriented, and obviously Windows oriented. OCaml’s academic roots and unix-orientation made it more attractive. I spent time learning SML years ago, and it would have been a natural choice for me, but it’s gotten to be more of a historical language.

With OCaml I get type safety without type annotations, infix math, a community I like, and fast code. I usually don’t write mli files (like Clojure, remember?), but when I do, that’s still better than Java. I came along right at the time that the core of Owl had been mostly implemented, and at the time I wanted to do some modeling using matrices, so it fit perfectly.

5 Likes

I was a quantitative biology PhD student who did not know any compiled low-level programming language. I wanted to be able to write efficient simulation code, but the little C/C++ I had been in contact with seemed idiosyncratic and requiring so much work to do anything. Java seemed like a sea of boilerplate code.
A (french :wink: ) post-doc in the lab introduced me to OCaml. I immediately liked the no-nonsense, nicely structured feel of it. For me the promise was: almost as concise as Mathematica, almost as accessible as Python, and almost as fast as C. In hindsight I think the last statement doesn’t quite hold true, but it’s good enough for my purposes.
Learning OCaml has definitely paid off in terms of programming skills in general. That said, I hesitate to recommend OCaml for scientific work to others, because the library landscape is a indeed quite thin. It seems that most researchers, who don’t write long-lived production code anyway, would not see a productivity benefit overall.

5 Likes

I started learning OCaml in 2005 because I was “forced to”. At that time I was “hired” (somewhat…) by a startup based in Milan. There OCaml and in general functional programming was mandatory. “Ok, let’s learn Yet Another Awesome Language”.

That adventure ended up very bad, with a failure and lawyers involved, I have only bad memories.

But in that year I fell in love with the language: coming from the defense industry (inside the Tythoon Program), with a strong personal and professional background in C/C++, Java and Ada95 (another language I fell in love with) I was searching for something more “light”, so I started writing code in Lua and Python. It was a pleasure but the performances were not satisfactory.

OCaml was love at first sight! A strongly and statically typed language with the terse syntax of Python or Lua.

Two things captured my imagination as a new comer: first of all the type inference, which I considered something marvelous at that time. Second a relatively stupid feature: the “non exhaustive pattern matching” warning.

Today we mostly use OCaml in system programming, enjoying stability, performances and the elegance of a pragmatic functional language.

5 Likes

Owl is adding a lot, but there’s a lot to catch up to e.g. with Python.

3 Likes

Owl is heroically trying to provide a whole ecosystem of scientific libraries. That may seem hopeless, but if integration with tensorflow/etc can get to a point where numerical tasks are seamless to program in OCaml and run at no speed penalty compared to the state of the art, Owl may become the ‘best choice’ for some use cases. That could help it gain a critical mass.

5 Likes

I have learned OCaml because that was the language of choice of the chair that was doing “Introduction to Computer Science II” at my university (it regularly switches chair so it is a toss up whether you get to use SML, OCaml or Haskell, depending on chair preferences). Of course, in these types of courses you don’t learn very much outside the superficial parts of the language like a bit of syntax, a bit of recursion, stuff like that. But you get at least a bit of familiarity, so further learning is less of a daunting task.

Before that I have learned Java but greatly preferred Python since all the verbosity of Java didn’t seem to have an advantage. I also looked at Haskell, but in these days (some time between 2003 and 2008, mind you) the materials were pretty bad and Haskell seemed somewhat inaccessible. In 2008 I got on the Clojure train and it was quite nice, because I could switch from my non-idiomatic Scheme-inspired Python code to Clojure where functional constructs were actually idiomatic.

In university I ended up using OCaml for my bachelors and masters thesis, which were nice, but OPAM was just getting started so the ecosystem was pretty distributed and using other peoples code was painful. Meanwhile in Clojure everything was fine and dandy, so after graduating I was working in a Clojure company.

It was fun but the years of OCaml have made me see all kinds of issues in Clojure that you wouldn’t have with OCaml. You never need to debug why something suddenly is nil since in OCaml you always know what data comes in and what comes out. So when that job ended, I started using OCaml full time and have been ever since.

3 Likes

*cough*
(try Julia)

1 Like

To be honest, Julia suffers the similar problem (at least with many libraries I tried) - they have a better selection of libraries, but the features in them are quite scarce. I root for that language and think it is so far the best choice for the science (especially with the Rust instead of C/C++/Fortran for the low-level/computing libraries like NumPy/BLAS/LAPACK).

1 Like

Not to derail my own thread too much, but we got PyCall.jl and RCall.jl to fill in the gaps.

Regarding that, while I would definitely agree that Rust is an improvement over other languages in the same domain (how could any language that steals so heavily from OCaml be bad?), but I don’t really think Julia needs Rust extensions to be fast. Someone is working on an experimental BLAS library in pure Julia that already beats OpenBLAS on some benchmarks. Julia’s lack-luster support for AOT makes a non-starter in some domains, but once the JIT has done its work, execution speed of well-optimized Julia is comparable to any other high-performance language out there. The main benefit of Rust in this case would be that it has a safer type system.