top | item 17735560

Introduction to OCaml

229 points| jxub | 7 years ago |blog.baturin.org | reply

72 comments

order
[+] frisco|7 years ago|reply
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|7 years ago|reply
i am curious if you considered f#.
[+] dmbaturin|7 years ago|reply
I haven't used gRPC as such, but for protobuf specifically, ocaml-protoc works well for me.
[+] georgewfraser|7 years ago|reply
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|7 years ago|reply
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.

[+] jnbiche|7 years ago|reply
> I've been playing around with an implementation of the ML semantics+type system

Sounds cool. Is it open source? I've attempted to write some ML interpreters and compilers, but I've always hit a brick while when I try to move from a basic "mini-ML" type of language -- which is relatively straight forward -- to one including pattern matching.

[+] kornish|7 years ago|reply
Totally agree, and would love to see something with Go interop gain serious adoption. Thought it might have been Oden [1] for a while, but the project seems to have petered out.

[1]: http://oden-lang.github.io/

[+] stcredzero|7 years ago|reply
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."

[+] shafte|7 years ago|reply
A REPL is an incredibly useful tool for all sorts of development, "real" or not. But I share the author's frustration with intros to functional programming that take advantage of a REPL to provide small, context-less examples. It makes it hard to see how I could use the language in for a complex project with significant side effects (e.g. file/network IO).

Real World Haskell[1] is a great example of an introduction that provides small examples AND situates them in the context of programs that I could see myself actually using.

[1] http://book.realworldhaskell.org/read/

[+] dan-robertson|7 years ago|reply
Ocaml is not one of those environments. The repl is of limited value in ocaml as the language is not dynamic enough to use it. Much of the language is built on its module system and the repl requires one to write an entire module and (it’s signature) at once. This makes the repl very much inferior to compiled ocaml.

The article suggests that the repl is of use for finding the type of things. This is only half true. Consider the following:

  type 'a my_extra_args = foo -> bar -> 'a
  val some_fn : (int -> unit) my_extra_args
Now suppose you want to know the type of the function so you ask at the repl:

  utop> some_fn;;
  val - : (int -> unit) my_extra_args
And now if you want to know how to call this function you need to try to guess arguments until a type error expands the type.

Alternatively you could use compiled ocaml, write your programs in a sensible editor and then query the type using Merlin (a program to provide ide-like features to editors for ocaml)

On the other hand, I would expect a Common Lisp tutorial to talk about the repl as real world programs are written with the repl (but also in files)

[+] SomeHacker44|7 years ago|reply
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.

[+] tlrobinson|7 years ago|reply
And... Hacker News. I can't find it now, but I'm pretty sure pg talked about how Hacker News was, at least initially, REPL-centric (not in those words)

EDIT: http://pchristensen.com/blog/articles/are-you-this-agile-pau...

> This is a step beyond that. I'm not even doing releases; I've been pasting the changes into the running server's repl.

https://news.ycombinator.com/item?id=99586

Obviously it's a bit extreme to be hacking on the production site with no version control etc, but HN was a lot smaller back then.

[+] systems|7 years ago|reply
How does that really work?

Because at the end of the day, to build your program, you need to have code in a source file of disk Code in the REPL is not persistent

So unless the language come with some sort of repl server, which persist code on a server, and the program instantiate themselves from the server (something i have never seen and i doubt that this is what you meant)

I am guessing you actually mean, that development was REPL supported, and that you used the repl to test your code, and help you design your code

And I see no problem in that, but still you need a solid traditional cycle around that to actually build, deploy and distribute your code ... right

[+] jorge-fundido|7 years ago|reply
I interpreted that as not making his "intro to ocaml" REPL-centric, so that things like the build tooling gets covered.
[+] devmunchies|7 years ago|reply
but this article is about learning, not the day-to-day development in OCaml. I agree it is good to learn how to structure, compile, and run code without a REPL. ie. learning how to import files and all that.
[+] Scarbutt|7 years ago|reply
I read that as do not make your program depend on REPL features.
[+] therein|7 years ago|reply
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|7 years ago|reply
Did you use parser combinators or what?
[+] girzel|7 years ago|reply
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|7 years ago|reply
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.
[+] dmbaturin|7 years ago|reply
This would work:

   let _ = 
     let this_integer = read_int () in
     print_int (this_integer * this_integer); print_newline ()
I agree part 1 should explain more of the basic syntax. The whole thing is a work in progress so I keep improving it as I get feedback.
[+] meritt|7 years ago|reply
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

[+] xamlhacker|7 years ago|reply
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|7 years ago|reply
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/ (no affiliation).

[+] alkonaut|7 years ago|reply
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|7 years ago|reply
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|7 years ago|reply
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|7 years ago|reply
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|7 years ago|reply
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|7 years ago|reply
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|7 years ago|reply
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.

[+] SniperOwl|7 years ago|reply

[deleted]

[+] gaius|7 years ago|reply
more like introduction to getting a job at Jane Street

I interviewed at Jane Street years ago, back when I was quite active in the OCaml community, got to the on-site rounds but didn't get an offer (a lucky escape it turns out, tho' I was pretty disappointed at the time). Anyway - OCaml wasn't even mentioned during their process. I think they just assume they'll have to teach it anyway.

[+] kasajian|7 years ago|reply
where's the PDF version?
[+] Normal_gaussian|7 years ago|reply
The wonderful thing about a (relatively) plaintext site like this is you can 'print' it into whatever random format you want.
[+] dmbaturin|7 years ago|reply
It will appear when (and I hope it's when rather than if) I complete the series. Then I'll typeset it properly and release the source under CC-BY-SA or another free license and make PDFs from it.