Why should I use OCaml?

I’m a developer looking for a new language to learn. I mostly used mainstream languages to work but never actually felt “happy” why them. Some are really productive and error-prone like Ruby, others performant but bureaucratic like Go.
I’m yet to find something that could be fast, secure, and productive. I think Rust was the closest that I got, but still way too low level for day to day work like web development.

I’m trying to learn Scala and it’s hell. The mix between Java and Scala is so bad, same for Clojure. Elixir is kind of going well, to be honest, it’s a really nice language, slow, but nice, and the BEAM is simply amazing. But the lack of types is a deal breaker.

One thing that I found through this quest is how good OCaml is, all the time I see people recommending the langauge, saying that it’s fast and productive and this raised some questions in my head.

  • If OCaml is so fantastic, why it’s not more used?
  • Most of what I’m doing is web development. Is OCaml suitable for the task?
  • Does OCaml has the same problem as Scala? Being OOP and FP at the same time it’s the jack of all trades master of none. In the company that I’m working at the moment, we have hundreds of Scala projects, all different. Some functional, some mixed, some imperative, some throwing exceptions, some with options, it’s simply a hell. To learn Scala looks like I need to learn 10 languages.
  • What’s the difference between OCaml and Reason, ReScript, Buckescript, and so on?

So that’s it, I’m really looking into giving OCaml a try if it fit my needs. I really hope that OCaml, with its flaws like every other language, would make me a better programmer while delivering fast code and being productive.

5 Likes

Yes, this is common. I have been around multiple large Scala codebases. The one thing that I find impressive about Scala is how fast the FP corner has accelerated towards Haskell. You can almost write Haskell in Scala now, but then I wonder why those programmers don’t just be honest with their management and ask for permission to use Haskell directly.

3 Likes

OCaml is a language that promotes developer productivity. It’s:

  • Statically typed with an excellent implementation of ML type system
  • Inherits features of Pascal and Modula-2 module system with fast incremental compiles
  • Very pragmatic, doesn’t insist on functional purity like other languages. You can smash together stuff to get the job done and refactor later because of the type system
  • Makes some really solid tradeoffs from an engineering point of view, e.g. has very good single-threaded performance and encourages parallelization via multiple processes (but this will change in the near future with Multicore OCaml)

To answer your specific questions:

  • Why are really good languages like OCaml and Erlang/Elixir not more used? I think it’s clear that popularity doesn’t have anything to do with quality. It’s a lot to do with luck and timing.
  • (Assuming by ‘web development’ you mean web server backends) Yes, OCaml has some good options for web development, from complete fullstack solutions like Ocsigen/Eliom to smaller more focused frameworks like Opium (and even my own framework, ReWeb)
  • OCaml code tends to be uniformly functional-style; it’s rare to come across significant use of object-oriented style
  • ‘OCaml’ is the original syntax and compiler; Reason is an alternative JavaScript-like syntax and toolkit for OCaml; ReScript is a TypeScript-like syntax and compiler (fork of OCaml) that specializes in outputting high-quality JavaScript; BuckleScript is the old name of ReScript.
12 Likes

Hi!

I’ve been using OCaml for a while and I definitely feel that it is a “fast, secure, and productive” language. If Rust was your closest language, I think you’ll find something that you’ll like in OCaml.

I’ll try my best to answer some of your questions, but some of the more experienced people here might have a better perspective.

If OCaml is so fantastic, why it’s not more used?

I think the popularity of a programming language is largely circumstantial. Some languages are popular now because they were the best choice 20 years ago and now there are millions of lines of code that have to be maintained. Some languages are popular because they found a niche and built a community around it.

My personal opinion is that OCaml is “better” as a language than others, but being a better language doesn’t necessarily guarantee users. Even for something like a programming language, there’s a lot of marketing (word-of-mouth or otherwise) that has to happen to maximize popularity.

I would also say that there’s a catch-22 around OCaml’s popularity: some new users don’t want to use it because its library ecosystem is (relatively) small, but there can’t be a larger library ecosystem unless there are more users to write the libraries. That being said, you might find that OCaml is already sufficient for your needs.

Most of what I’m doing is web development. Is OCaml suitable for the task?

I’m no web developer, but I’ve found OCaml to be suitable for targeting JS with Js_of_ocaml. There are libraries like opium and eliom that should be helpful.

Does OCaml has the same problem as Scala?

I don’t think so. OCaml does have OOP features, but they are used infrequently. A functional style is greatly preferred by most libraries and developers. All functions are curried by default and the “pipeline” |> operator makes it easy to write readable function chaining. OCaml does have exceptions, but like objects, they tend to be used infrequently and functions that can raise exceptions are typically marked clearly.

OCaml doesn’t have typeclasses like Haskell/Rust or implicits like Scala, but it has an incredibly powerful module system that is as expressible. Modules in OCaml are my favorite part of the language and they seem to be unrivaled by other languages.

What’s the difference between OCaml and Reason, ReScript, Buckescript, and so on?

  • OCaml is the language and compiler (to native or bytecode).

  • Js_of_ocaml is an OCaml-to-JS compiler that works in the OCaml ecosystem of libraries. You can use the latest version of the OCaml language with most OCaml libraries. It should be easy to share code between native and JS projects.

  • Reason is an alternative syntax for OCaml that looks more like JS. It has the same type system as OCaml and can be used in the same ways (native, JS). With the release of ReScript, I am personally not very confident in its future.

  • Bucklescript is (was) an OCaml-to-JS compiler that integrates closer with the NPM/JS ecosystem. It is an older fork of the OCaml compiler and I don’t think it can use OCaml libraries very easily.

  • ReScript is two things:

    1. A new alternative syntax that looks similar to Reason with more changes. It supports less OCaml language features and can only be used when compiling to JS.
    2. A rebranding of the Bucklescript compiler. It can compile from ReScript syntax. OCaml and Reason syntax are also supported (for now) but they are referred to as “old(er) syntax” and it is clear the focus is on Rescript syntax. Like Bucklescript, it is still on an older OCaml compiler version.

I realize these different technologies can get confusing. My choice is to stick to the original OCaml language and use Js_of_ocaml if I need to target JS. I’ve been very happy so far.

15 Likes

Thoses kinds of posts are rather difficult to anwer, because they refer to subjectives arguments and the ones we can answer are not the one you are sensitive.

First, if you are looking for a new language to learn, just try :slight_smile: Do not be confused by the “objective” label in the language name, the objects in OCaml are not commonly used, and are very differents from the ones in Java for example (inheritance does not implies subtyping — if you don’t understand what this mean, you’ll learn the hard way)

The module system is powerfull enough for not requiring any other construction for all the common usages (and combined with a powerfull type system, you can use OCaml for years without using the object side at all).

For the web side, it is not clear if you are requesting information on the server-side or client-side. Targetting javascript is easy thanks to js_of_ocaml, (be sure to understand what a phantom type is before reading the api), and there are many wrappers which allow to target web with a simpler API or to design FRP style applications :

In a general way, I’ll say that OCaml is very fair, you just have to write down what you want, without any excessive anotations. I stay focus on what I have in my mind, and the language let me express very concisely what I want. As an example, it is for me unbearable to write something like ArrayList<String> my_array = new ArrayList<String>(); where I have the feeling to stutter on my keyboard.

And last, the community is very small, and very warm, but the answers from this post will speak from thelseves !

3 Likes

fully agreeing with what @mnxn said, I find OCaml appealing, because

  • compact and comprehensible code as typical for functional languages,
  • static linking possibility, create self-contained binaries that run with no dependencies and survive OS updates well,
  • runtime performance so as you can target tiny machines like raspberry-pi zero,
  • no GAFAM inside, i.e. not controlled by a monopolist but rooted in educational background.

The last point may be the weakest, because of the worrying github dependency (now the M of GAFAM) of the ecosystem.

3 Likes

I think it should also be said that web development in OCaml is not as mature as in other, larger communities. There are interesting tools on both the backend and the frontend, and people have built amazing things on top of them, but it will still be harder to find documentation, protocol-support libraries etc. than for more “web mainstream” languages like Javascript (or Python, Ruby on the backend). This is a cost that should be taken into account when making migration decisions.

11 Likes

I looked into the same languages with the exception of Scala in the context of web development before landing at OCaml.

As @gasche pointed out, the web dev story is not that mature, maybe even the least mature of all the languages you listed. That fact that we can not piggyback on an existing ecosystem has also its upsides. Libraries tend to be idiomatic FP and you won’t have to deal with OOP poking through.

After going through the quite steep learning curve (the small web dev ecosystem and community don’t make it easier), OCaml is a quite nice language for that task in my opinion.

My idea of usage for OCaml would be full-stack development.

It’s possible to use exclusively the javascript environment using the Js_of_ocaml? I got a little scared when I saw the number of libraries available for OCaml, for sure I’ll step into the problem of not having a library that I need. Being able to simply call any javascript lib would be awesome (server-side and front end).

I would lose the Ocaml static compilation and speed, but at least I would have the tools I need to perform my tasks.

1 Like

Yes you can directly use any JavaScript library out there. Js_of_ocaml provides an FFI to JavaScript. You can read about it here.

I don’t find that FFI and the typing of JavaScript into OCaml object types to be very ergonomic in practice. A simpler scheme is to model JavaScript objects as abstract datatypes. The brr project which provides bindings to browser APIs exposes an alternative FFI that supports this scheme, see this manual.

The gen_js_api promotes a similar FFI approach but automatically generates binding code from annotated .mli interfaces which are preprocessed by ppx. Personally I prefer to work directly with OCaml code than having to understand a new language (the annotations) and its translation to OCaml code; it’s also more flexible when you get into odd JavaScript API corners.

In theory the three bindings strategies should be interoperable but in practice they are currently not because of a small detail, see this issue.

2 Likes

If you want to do backend JS in an OCaml-like language, you should probably look at ReScript (which despite somewhat confusing branding changes, you can use OCaml syntax for). I don’t think anyone is doing backend Js_of_ocaml. But you should definitely try real backend OCaml too! They can sometimes be a little hard to find, but I think there are libraries available for most common webdev things now.

2 Likes

I am curious about your experience in Scala. I’m evaluating Scala for a project mainly due to Akka. There is a lot of love and hate for Scala across the web. What do you think about Scala? Have you used it extensively?

Now that you use OCaml, do you still prefer Scala? Scala 3 is supposed to be a huge improvement over Scala 2 – do you agree? Are the compilation times improved?

My personal impression of Scala is currently not positive though I’m willing to use the language because of Akka. A distillation of your experience will be valuable – thanks!

2 Likes

Good ecosystem with many libs, good dev tools, excellent debugging experience.

Scala 3 is an improvement over Scala 2 and def worth a try.

3 Likes

Thanks @Ulugbek – What about the language itself? Do you personally like it? Is the compilation speed improved in Scala 3 or more or less the same? Any other insight on Scala 3 useful…

I haven’t used scala 3.

For scala 2, the syntax is a little verbose and awkward, as you try to implement more functional idioms, but the functional libraries have clever ways to work around the awkwardness. If you want to use it as “better java”, I think it is great for that purpose. It is much less verbose than java.

I liked the ecosystem. As other people have mentioned about f# and other vm languages, the downside of using the java (or c#, in f#'s case) libraries is that you get dragged into this OO world. The amount of effort to write a clean wrapper over these libraries is probably equal to the effort of implementing the same library from scratch in scala / Haskell / OCaml, so then you start to question the value of having access to the java libraries. It is a huge relief to be able to use a java library when you are in a rush, and to know that the java library will be feature complete and maintained possibly by a company or a dedicated maintainer.

The type system is large and overly complex, because the language tries to support too many paradigms. People seem to adopt scala over Haskell because it is more approachable, but I think someone can master the Haskell type system faster than the Scala type system.

I agree with the critique of Scala which points out how much energy someone spends fighting over scala style/paradigm use within a team, and how much easier life is in golang, where there is little room to debate style/paradigm (I have never used golang professionally). The perfect use for Scala is if you have an architect who knows Haskell or Scala well, and a team of engineers who know java well. Then you can gradually on board the java developers to FP paradigms, without hurting their productivity in the short term. After a year or so, you can go all in on cats or zio, all within the same language.

My favorite thing about the Scala community is that it attracts architects with deep expertise in building highly available systems, high throughput systems, and scalable systems. I also see less NIH syndrome in Scala shops. The Scala shops usually want to use the best tools and libraries that they can find, rather than use tools implemented exclusively in Scala. If I wanted to find people who knew how to use Kafka, Cockroachdb, or some other best of breed tool, I would put Scala in my job advertisement. I think it attracts this crowd because of two factors: people aren’t drawn to it because of some deep passion for the language like a Haskell enthusiast might be, and the success of akka and marketing towards Java devs means it caught the attention of people who have been building complex distributed systems in Java for many years.

My general preferences are: 1. Haskell, 2. OCaml, 3. golang, but in reality, I want to work on compute intense systems dealing with bioinformatics, geospatial systems, and operations research problems, so I will work in whatever language that the most interesting startup in one of those domains is using. In 2021, it feels like the jvm is just an awkward historical leftover that makes containerizing more complex, so I try to avoid scala and clojure when possible.


Why are you considering akka? Are you trying to build something like a ticketing system or game world, where the state needs to stay in memory and can’t wait for fetches and writes to a persistence system? If so, I would probably attempt zio or haskell with a distributed cache, rather than akka.

2 Likes

Thank you for the considered and detailed response. I appreciate your insights.

One issue with integrating Scala with Java libraries is the awkward issue of Null in Java. The presence of Null in the Java ecosystem is a huge negative in general – looking from the outside. I wonder if it was a practical concern when you programmed in Scala 2 though.

Regarding akka, my use case is for a system that involves a lot of messages. I personally rule out Haskell because these messages must have a tight spread of latencies and Haskell due to its lazy/somewhat unpredictable runtime tends to be all over the place. OCaml BTW is excellent here – though the language is less expressive and the ecosystem not as rich as Haskell, the runtime is totally rock solid.

I was further piqued by your by personal ranking of Haskell ahead of OCaml. I’ve personally written about this but in brief while I continue to find Haskell extremely impressive I’m not to sure about its runtime. You spent so much of time writing type heavy code (to get good safety) but then your code has a space leak and you need to track it down. That does not seem like a good tradeoff for me – gaining significant safety due to types but then promptly throwing all those safety guarantees away due to laziness (because it can cause space leaks).

Anyways I’ll stop now. Thanks again for your insights.

1 Like

I used this sometimes - Try. Generally, this is part of the “effort to write a proper wrapper” that I was mentioning. You have to wrap each java method with transformations like this.

1 Like