First of, the course was called "Operating Systems", and I was expecting subsetting like the Tannenbaum, explaining the theory and practice behind kernels. The course actually was about Unix system programming, and solely about that. At least the page is properly named.
Second, I think OCaml is an amazing language, but frankly it's a terrible choice for this course. One needs the right tool for the right job. No particular " insight " is gained as the page alleges, beyond the insight that, gee, C would probably be a better lanhuage to interface with the system it was designed for!
Our project consisted in implementing the "ls" command in OCaml, which meant mostly covering all the corner cases brought by different flags. It wasn't interesting, it didn't teach valuable skills.
Functional programming languages shine when they deal with complex, recursive data structures, not for simple tasks which are primarily IO and need to handle many cases.
While I obviously can't comment on the details of the course you took a decade ago, I do have to disagree vehemently with this. OCaml is close to as ideal a systems programming language as I've ever used since:
- it has a simple, stable and predictable runtime with strict evaluation semantics, so you can identify what statements allocate memory by inspecting code.
- the compilation to native code is fast and Unix-like, with standard object files generated that can be linked to and from C programs easily.
- the memory representation of values is uniform and native code debugging with gdb/lldb works great, thanks to the DWARF symbols emitted.
- OCaml's basic language features such as algebraic data types and exhaustive pattern matching are fantastic for both building low-level programs, and refactoring them in the future as they inevitably get more complex.
> not for simple tasks which are primarily IO and need to handle many cases.
And this is exactly where libraries like Async or Lwt are so useful, since you can juggle millions of concurrent threads and still do high-level programming without getting lost in the noise. Error monads, failure monitors, function wrappers to ensure resources get freed, can all be built directly within the language itself using the usual ML abstractions, and the compiled code is still lightweight and natively compiled.
For those interested in reading more about the runtime system in OCaml, the entire third part of Real World OCaml is dedicated to this topic: https://realworldocaml.org/v1/en/html/pt03.html
Besides being able to get a simple backtrace, I've always had nothing but headaches trying to print out variables. It's not tightly integrated with gdb, so the default "p my_ocaml_var" of course doesn't work and info locals rarely if ever works. Only time the debugging is good is when you get to the C code underlying the system calls.
I would love for this not to be the case, but I'm not sure if anyone is working on making OCaml better to debug in gdb.
This is primarily what I use functional languages for so far, so naturally I disagree. As long as their aren't stringent performance requirements (though functional languages like Ocaml and Haskell are pretty fast) I find functional languages to be a generally better fit.
Also parsing and string handling in C is worlds more difficult than something like Parsec using parser combinators.
I think most of the advantages of FP languages (as they exist today) become disadvantages as your data structures get more and more complex. Efficient mutability becomes necessary. Pattern matching breaks down as (G)ADTs can no longer encode useful invariants. Referential transparency becomes useless once you realize you want explicit sharing. Laziness and space leaks become a huge PITA. The RTS and the mandatory GC start getting in your way as it gets harder and harder to eek out performance from your code. etc etc..
You seem to be describing Haskell with that rather overgeneral (and incorrect) statement above. OCaml supports mutation and explicit sharing just fine, and is strict by default. As for the rest, as you get closer to needing manual resource control, it just gracefully devolves.
If your purpose is to learn how to program in a functional style, then either language is fine. Other than that, the main difference between the two is purity/effects, lazy/strict, and type-classes/modules in Haskell and OCaml. That all changes the specifics of the code being written quite dramatically.