OCaml for the Masses (2011)
queue.acm.org
queue.acm.org
I highly recommend you give it a try. By the way, although we hear about OCaml less often than other languages, it is still used in many well known places such as Facebook (for pfff and Hack), Microsoft (SLAM, a verification tool for drivers), and Airbus (they use the ASTRÉE static verification tool which is written in OCaml).
Microsoft's F# language is essentially a .NET version of OCaml.
Oh, how I wish there was a JVM variant of F# (no, Scala does not count).
https://github.com/penberg/fjord
It doesn't seem to be in active development, though.
A few F# features depend on CLR features that JVM does not offer, like value types and reified generics.
This will probably change with the planned changes for Java 9+, but until then not everything can be efficiently supported.
You know what's the defining property of OCaml's OO/module systems?
That nobody actually uses it.
Compared to that, Scala tries to make all parts of the language work in an orthogonal and consistent fashion.
In OCaml, one part of the language is crippled intentionally, due to what seems to be ideological reasons.
Apart from that, I'm unsure how OCaml counts as "functional". It doesn't even have typeclasses, let alone higher-kinded types.
Erm, what? Functional languages are those which implement as much as possible using functions, rather than adding language primitives (eg. if/then/else, looping, mutable state, etc.). If anything, typeclasses make a language less functional, since they're a language primitive which could be implemented with functions instead (by passing records explicitly).
Lambda Calculus doesn't have typeclasses or higher-kinded types, does that mean it doesn't count as "functional"? Hell, even Joy is a purely-functional language and it can't even call functions!
Type systems are a completely orthogonal concept to functional style; they're a way of embedding a formal logic into a programming language. It just-so-happens that many logics make heavy use of implication (a -> b), and that corresponds to functions. It's possible to give a rich type system to, for example, Prolog or assembly, but the logical operators would be quite unfamiliar.
"Functional" means many things to many people, but it's the term a lot of people use when talking about the recent rise of languages like Haskell, Scala, F# and OCaml - much of which rise is, IMO, attributable to their type systems. Whatever "it" is that these languages have (and sure, it might be more accurate to talk about "languages providing ADTs and controlled sequencing of effects" or some such), I think it's fair to say that OCaml/F# have less of it in this area, because their type systems don't allow you to express higher-kinded types.
F# may have its advantages, but you're definitely missing out on some of the "functional language renaissance" - because whatever the terminology, at least some of that renaissance is about the value of powerful type systems.
These are new languages in the functional paradigm but functional programming isn't itself a new concept, and strong static typing has never been a prerequisite in order to be "functional". The first functional language, Lisp, was dynamic, and to this day no commonly used Lisp has been statically typed out-of-the-box. Erlang and the array languages (APL, J, etc.) are other examples of dynamically typed functional languages.
You can say that functional languages are more likely to have strong type systems than other languages, but it's totally disingenuous to claim that languages are somehow "less functional" because they lack typeclasses and higher-kinded types.
The K language, which presumably incorporates parts of Scheme, is a notable exception to this.
Like the original FP/FL languages, J supports function-level programming via its tacit programming features (note that function-level programming is not the same as functional programming).
As I said, it's unclear to me what the difference is, but that's what I based my previous comment on.
Something is going on in the languages I mentioned - and from my perspective, distinctly isn't going on with any Lisp (including Dylan or Clojure), isn't going on with the array languages, and mostly isn't going on with Erlang. So it's not a functional language thing by your definition of a functional language
Whatever that something is, it involves powerful type systems
F# and OCaml therefore have less of it than Haskell and Scala (though more of it than languages outside those four list).
Um, no. Lisp and Erlang are still functional. They have always been and will always be functional. The definition of that word has not changed. You seem to want to redefine "functional" to make Haskell the end-all and be-all of functional languages, but that's just not how it works.
Semantic arguments are tiresome, and I wish more people would focus on the content of the discussion, instead of arguing about how it might better have been conveyed. Sometimes people misunderstand the commonly accepted meanings of terms, and it's worth correcting them. But if people start arguing about terminology, then it's better to just define terms and move on, since there's clearly not a consensus worth teaching anyone.
I'm not exactly sure what you're thinking of here, but if you try to turn a typeclass into a dictionary of its methods, you'll need a dictionary for each instantiation of type variables in the typeclass. And then it still won't be as type-safe as Haskell, because nothing stops a programmer from swapping in random dictionaries. This is the flaw in the Scala implementation of type-classes.
Wrong, wrong, wrong, wrong, wrong. I wonder where this myth comes from ...
"Since you can pass any dictionary anywhere to any implicit you can't rely on the canonicity of anything. If you make a Map or Set using an ordering, you can't be sure you'll get the same ordering back when you come to do a lookup later. This means you can't safely do hedge unions/merges in their containers. It also means that much of scalaz is lying to itself and hoping you'll pass back the same dictionary every time."
You get the same issue with Ocaml's implementation of polymorphic tree-based maps, where you lose type-safety. This is why you don't want to pass dictionaries for this stuff, but instead want to use modules and functors, which allow you to emulate existential types, higher-order kinding and higher-rank polymorphism.
That's one thing that cannot be claimed for Scala, at last. No matter what concept it is or whether it fits anywhere, it goes in.
It's what is called language design.
That's absurd, and you know it.
On the other hand, OCaml is able to express typeclasses with it's module system.
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.
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.
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)
And an April Fools joke -- http://gallium.inria.fr/blog/ocaml-5/
So I end up mostly reading the book as a means to update the knowledge I had from the Caml Light days and differences to F#.
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.
http://hackage.haskell.org/packages/search?terms=prelude
See the classy prelude github page: https://github.com/snoyberg/classy-prelude
And the latest blog post about classy-prelude: http://www.yesodweb.com/blog/2013/01/so-many-preludes
It looks like iHaskell actually depends on classy-prelude: http://hackage.haskell.org/package/ihaskell
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
parse :: Parser a -> String -> ParseResult a
with
parse :: Parser a -> String -> [`Error String | `Result a]
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.
utop # printf "%d\n" "foo!";; Error: This expression has type string but an expression was expected of type int
versus what happens in Haskell:
λ printf "%d\n" "foo" * Exception: printf: bad formatting char 'd'
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.
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.)
http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-ret...
Probably the biggest problem on Windows is that OPAM, the package manager, doesn't work there. That will come eventually, though.
Wodi [1] is a reasonable choice until OPAM starts supporting Windows. It includes many of the interesting/useful libraries (including, importantly, batteries [2] and core [3])
[1] http://wodi.forge.ocamlcore.org/ [2] http://batteries.forge.ocamlcore.org/ [3] https://github.com/janestreet/core_kernel
Any ETA on it? If I knew about it before buying the book, I would not have done it.
The book is great, but as it is I have better luck with F# at work.
(Personally, I don't really think it's worth it--many libraries that need to get stuff done in Java end up using JNA anyway, negating this supposed advantage. But it's certainly much better about it than ostensibly cross-platform languages like Ruby are).
Shameless plug: there's also a newish O'Reilly book, Real World OCaml http://realworldocaml.org, which I think is a big help in learning the language.
Oh, and there's OCaml Labs, a new lab at Cambridge University that's dedicated to improving the language.
And of course the compiler is constantly making progress. The upcoming 4.02 release is a pretty fun one, which I documented here: https://blogs.janestreet.com/ocaml-4-02-everything-else/ And before that, changes like GADTs and first-class modules landed, which have been quite useful extensions.
Really, it's a very active and fun community these days. The language is getting better quite quickly, but mostly in conservative and tasteful ways. The people in charge of the core language have been doing a great job, and the community infrastructure (things like OPAM) have been making big strides as well.
I've tried it a few times through the years. Most recently I grabbed a kindle version of "real world ocaml" a couple months ago, and started to work through it. The fact there's a recent book in English made it easier to get into than the previous times I've looked at it, and a good sign of progress, IMO.
Unfortunately, after a couple weeks a new version of ocaml came out, and some packaged from opam were updated, and something about it broke everything for me and stopped me in my tracks. I'm pretty sure it's a problem waiting for changes to trickle through to osx, but I don't really know. I spun up a linux vm, and everything worked great, so it seems osx specific.
- OPAM was already mentioned.
- The OCaml to JS compiler has matured and gained a lot of use. Interestingly, I suspect that it can also be used to achieve different types of parallelism than the types that the stock OCaml compilers provide. https://github.com/ocsigen/js_of_ocaml
- Merlin is also a fantastic autocompletion plugin for Vim/Emacs. https://github.com/the-lambda-church/merlin
VimBox (shameless plug) uses Merlin and is configured to provide "intellisense" style completion (as you type) like Visual Studio. https://github.com/jordwalke/VimBox
- utop is perhaps the best top level REPL that I've ever seen. https://github.com/diml/utop (edit: Regarding utop: Normally I dread using a REPL for a statically typed language, but utop actually makes the top level fun and interactive. I actually look forward to using it!)
The interop with .net libs is helpful too - but i've found that if there's anything that's really hurting F#, it's all the OOP tacked onto it to make the .net interop work. Decent tradeoff if you ask me, but it's cringeworthy to see people using F# like an oop language when the oop only appears to be there for the interop magic to work.
One big point I would give to F# is tooling. Having a real IDE for OCaml would be nice. When I was writing OCaml I used Emacs with ocamlspotter.
The other big F# feature is library support. OCaml has pretty good libraries but F# can leverage the whole .NET framework. This would be noticeable in areas like GUIs.
I imagine that not using Microsoft F# would negate the benefits of F# over OCaml.
To be honest, go with either. For most people the benefits come from the simple/common/old features. Once you get used to dealing with the compiler, you'll likely fall in love with ML.
There is work going on at OCaml Labs on a parallel runtime. I suspect it will be useful, but in the end, message passing is I think a better idiom than shared memory threads for parallel programming. When the true parallel runtime lands, I'm not sure that we'll actually use it much for running truly parallel threads.
Don't get me wrong: OTP by all accounts has richer support for this kind of stuff. I think OCaml is a better language for many purposes, but OTP is a great runtime and set of libraries whose equal is not yet found in any other language as far as I can tell.
It really depends on the problem you are working with. You wouldn't want to make a high-performance HTTP server this way. Especially if you get to copy 2MB of POST data every time.
Here is Minsky's Planet's project, by the way: http://planets.homedns.org/
Although I didn't run off and learn OCaml at the time it did spark my interest in functional programming - eventually picking up Scala and Erlang.