As a haskeller, I've heard some disconcerting things about OCaml.
Namely, the standard lib is more or less made just to be able to compile itself, and that the standard lib is not pure, which makes developers go to alternate implementations to do the job in a way that is expected.
Please do correct me if what I've heard is wrong.
My only indirect experience with OCaml is the Opa language compiler--so all I've seen is that it is a language favored for implementing languages.
The stdlib that ships with the compiler is indeed minimal, though it is used for things other than the compiler. It can be used for other projects, but you probably want something more full-featured. Core, and the more minimal and portable Core_kernel (https://github.com/janestreet/core_kernel) is a full-featured alternative that is growing in popularity, and is what the book I worked on (Real World OCaml, http://realworldocaml.org) is based on.
OCaml (and most of both the stdlib and Core) default to immutable data structures, but OCaml has good support for programming imperatively, to its credit, in my view.
FWIW: Core doesn't work with Windows (the Real World OCaml book does state this upfront) so you need either an OSX or Linux machine to work with Core, and so you can't work through the book with a Windows machine. Something to be aware of.
For what it's worth, the world has changed since then: Core_kernel (which is the highly portable bits of Core, which is most of it) works on Windows just fine. Indeed, WODI, which is the best windows package manager for OCaml right now, ships with it.
Hi, Yaron! I was recently looking into using Core for one of my projects, but have so far failed to find any good, clear, complete documentation or how-to guide. Is there anything like that available online? I guess I could read the Real World OCaml book to learn parts of it, but I already know OCaml...
I've heard that Jane Street uses their own extensions to the language. Also, how does one deal with the development of OCaml being largely done in French?
Jane Street makes use of OCaml's built-in metaprogramming facility, camlp4. While these are in some sense "our own extensions", they're wholly shareable without using a hacked version of the compiler, and just because we build our code using these syntax extensions, doesn't mean that users of our libraries need to do the same. You can use Core_kernel, for example, without using our syntax extensions.
The French thing is a non-issue. The compiler is written and documented in English, and all the main contributors are fluent English speakers, and the mailing lists are almost entirely in English.
> Also, how does one deal with the development of OCaml being largely done in French?
OCaml is developed by french people, I've never heard of it being done in french (aside from interpersonal banter I guess). The french version of the official site doesn't even work correctly (when you click on the "manual" link you get the english manual)
I think, you are misinformed. While the standard library is not huge, it is quite ok. Then, OCaml is steadily gaining strength with Opam and Jane Street's libraries, which become de-facto standard.
Personally, I see OCaml as C++ done right (minus pointers), if you need pointers, use Rust.
The default string type is terrible, the default file input output introduces space leaks and has terrible performance. The default numerical hierachy, (Num a) in particular, is nothing mathematicians tend to study (it would be much more sensible to define Ring a, for example). It overemphasizes lists and instead of attempting to define polymorphic functions that give access to a wide range of containers, pollutes the global name space with list specific functions, even though lists are rarely the right choice.
There are several alternative Prelude implementations, but as far as I am aware none of them address all of these issues. Since most of the other libraries depend on the default Prelude, especially the type class hierarchy it establishes, the none breaking changes they could make are very limited. For a discussion of one of those proposals see http://www.yesodweb.com/blog/2012/08/classy-prelude-good-bad....
Things could be worse, take Scala for example.
There are lots of high quality libraries, but no major effort to replace the Prelude's privileged position in the language. So it it kind of a minefield to find the correct module/function for your needs.
Haskell Platform is a great standard set of imports, but it is only for the commonest libs, beyond that you have again the problem of sorting out excellent libs from some student's throwaway homework project with the same name.
Thanks for this comment. I always wondered if I was the only one who felt that way, or if I was just missing the point when I found these things weird.
Another Haskeller here. I strongly recommend you take a second look at OCaml. I think it has some fantastic features that Haskell doesn't:
Modules. They are great for solving major code organisation problems and I really hope Haskell will get a module system soon ("Backpack" paper). Type classes are great for things like Monad and Num since you are likely to use many different Monads or Nums in the same chunk of code. But consider what happens if you want to support both ByteString and Text in your library (let's say a parser library). You may end up with a type class constraint like ListLike and your code will be littered with 'ListLike .. =>'. But when you're parsing some data later on it will be either ByteString or Text. So I'd fix my choice of ListLike at module instantiation time and make the constraint go away. If I need both (e.g. I'm reading some data from a socket and some of it is Text and some of it is ByteString) then I'm just going to instantiate two modules, one for each. To me this is a much cleaner solution.
Named/optional function parameters. They solve a bunch of minor but incredibly annoying problems. A simple example: for (aka flip map); It is not in Prelude and whenever it comes up there are plenty of people who are opposed for one reason or another. In OCaml (Core library) it doesn't matter because map takes the function by named parameter so List.map ~f:(fun x -> x + 1) [1;2;3] works fine and so does List.map [1;2;3] (fun x -> moderately long, perhaps few lines long function). Both cases are important for readability. Another example: in Haskell I've been working with APIs where functions have 20+ positional parameters (yeah, it's terrible design but that's out of my hands). If they were named and some of them optional (most of them really are optional) then the code would be a fraction of what it is.
OCaml is quick to compile. I've been looking at Eliom web framework recently and rebuilding a website takes seconds; compare that to yesod which takes forever and spins all the cores on my laptop which eats my battery in no time.
OCaml code tends to be quite straightforward: from my experience it is longer than Haskell equivalent, uses less abstractions but at the same time it is conceptually simple.
Typed printf. (yeah, there are 'solutions' in Haskell but it's a typed printf out of the box!)
Polymorphic variants. Can be used to bring information to the level of types. Compare
Also see OCaml's tyxml package which provides typed html5. Yeah, the types look rather crazy in some places but that's a small price to pay for rooting out invalid HTML.
This does make me want to take a look OCaml seriously.
I'd mostly use it in a web server context. Though I have no clue where to really get started in that.
Yesod actually was one of the reasons that pushed me to learning Haskell (though I arguably never got much done in Yesod since it felt like its pragmatisms didn't match up with mine.)
OCaml has compiler level support for format strings. "%d" and friends get parsed into a GADT at compile time and printf "%d" has type int -> unit
In Haskell PrintfType => type-class magic is used to make printf accept a variable number of arguments. However, the types of those arguments are not checked against the format string (since the format string is just a string). Hence the error happens at runtime and Haskell's printf is effectively untyped.
It is not very hard to implement printf that takes a GADT and and has a proper type (e.g. Int -> String) and there are libraries that do something along these lines (see formatting library on Hackage; there's also a template-haskell based solution that uses a quasi-quoter [fmt|%d\n|]). But I do prefer the elegance of c-style format strings.
Besides OCaml has this out of the box and in standard library while Haskell printf is dangerous and should be avoided. Even C++ is better -- I've seen compilers/linters throwing warnings at me when arguments didn't match the format string. Printing to stdout/stderr shouldn't be hard and shouldn't be something one needs third-party libraries to do nicely. Hence I've put it on the list.
Namely, the standard lib is more or less made just to be able to compile itself, and that the standard lib is not pure, which makes developers go to alternate implementations to do the job in a way that is expected.
Please do correct me if what I've heard is wrong.
My only indirect experience with OCaml is the Opa language compiler--so all I've seen is that it is a language favored for implementing languages.