Ask Hackers: Opinions on OCaml?
I've been looking into OCaml a bit, and it looks interesting. Here are two articles, one on either side of the debate (sorry haven't figured out embedded links):
Stevey on OCaml (pros) - http://steve.yegge.googlepages.com/ocaml
Steingold on Ocaml (cons) - http://www.podval.org/~sds/ocaml-sucks.html
Anyone here an OCaml hacker?
41 comments
[ 3.6 ms ] story [ 78.6 ms ] threadI think OCaml would be a big win if you have your software designed all up front, and need to verify that it works correctly, e.g., avionics software. Unfortunately, avionics software development seems to be moving toward C/C++...
http://www.astree.ens.fr/
"In Nov. 2003, ASTRÉE was able to prove completely automatically the absence of any RTE in the primary flight control software of the Airbus A340 fly-by-wire system, a program of 132,000 lines of C. [...] From Jan. 2004 on, ASTRÉE was extended to analyze the electric flight control codes then in development and test for the A380 series."
Powerful templates plus multiple inheritance give you a very impressive weapon to play with. C# and Java don't even come close.
And please... 99% of software on Windows, Mac OS X and Linux are built using the same stuff: C/C++/ObjectiveC.
C# and VB run an awful lot of Windows software, too.
But in general (at least from what I've observed on Hacker News), OCaml gets less love than Haskell. Actually, I don't ever remember OCaml getting love here.
This pdf is a report from the Commercial Users of Functional Programming workshop last year. There are some good stories about OCaml, Scheme, and Haskell. 20 pages but well written, reads quickly.
http://cufp.galois.com/CUFP-2007-Report.pdf
Take a look at a specialized reddit I created for OCaml discussion: http://reddit.com/r/ocaml
I left it behind because it was easier to learn than Haskell. I use these languages (Ocaml, Haskell, Erlang, Scheme) because they're mind-expanding. For practical programs, I'd rather use something practical, like Python. Haskell was more mind-expanding than Ocaml, and so was better for the task at hand.
I think that is cool, because in my mind functional and imperative programming each have their distinct niche's of effectiveness. However, I have zero significant projects under my belt in any functional language, so I'm not necessarily one to talk.
Update
This is a counter (on slashdot w/ discussion) to the speed claim: http://developers.slashdot.org/article.pl?sid=05/03/14/22582...
Having said that, it was remarkably civil!
What it's great for is anything that involves the manipulation of lists or trees - one of my projects in OCaml was a simple computer algebra system, and OCaml was great for that. I had previously written a super-simple interpreter for a made-up programming language in Java, and in comparison OCaml is way more expressive for that type of project. I also wrote a fractal renderer in OCaml and found the expresivity helpful, although the library support was not great so I ended up writing my own bitmap library. It's also nice to be able to break out of the purely-functional paradigm, because there are times when a problem is better suited for imperative programming.
Another project I did in OCaml was a web proxy, and it turned out to not be a great idea. The libraries were confusing and in the end I wished I used python.
So it really comes down to the project. OCaml is very cool conceptually, and it is great for certain tasks, and not so great for others. (For what it's worth, I've only been using OCaml intermittently for about a year, so I am no expert.)
Ultimately, I think both OCaml and Haskell have a much nicer feel than Blub, but when I need to get something done, I reach for Common Lisp before anything else.
I've found the code is easy to change. Type inference lets me swap out datatypes without changing any code. If i need to add or remove arguments, the compiler tells me everything i need to update.
I've run into two situations where i don't know what to do next. Both times, I've been able to figure out what i need, without figuring out exactly how to do it. That gave me enough of an edge to write a quickcheck test or two. Then i fooled around with various implementations until i found something that met quickcheck's requirements.
It's been very nice.
That said, i've picked up haskell 4 or 5 times, worked on something for 1-3 months, become frustrated, and quit. I feel like i'm finally proficient enough to actually solve problems.
I don't know if it's worth it. I've come to appreciate all the compiler can tell me. In CL, you can use very abstract data structure access like elt. + is overloaded to work on everything. Haskell gives typeclasses. Haskell macros are disgusting, where lisp macros are very pretty. Since haskell is lazy, a lot of the control flow macros aren't as useful.
I like haskell. I'd like it to be my default language. Lisp lets me make lisp look like they way i think, so i can write big fancy programs. Haskell frees me up from thinking about the rest of the program so i can write nice modules.
http://www.storytotell.org/articles/2006/11/22/the-quicksort...
If your problem can be presented as advanced data structures, it's really the right tool for the job. Unless if your problem is purely functional, then maybe in Haskell would do better, but we're talking about a pretty narrow niche.
When you design an application, you can generally shift complexity from the algorithm to the structuring of data, and vice versa. It's better to put complexity into data, as they're easier to debug, and that's even much truer in OCaml.
There's one very cool feature in Haskell that ought to make it into OCaml, though: classes (which are almost unrelated to the homonym OO concept).
I don't know why OCaml gets so little attention (and such bitter hatred from a few people), but maybe it's because its merits are mundane: it focuses on doing things right, rather than superficial coolness (Python) or lofty idealism (Haskell, Scheme). The result is a language that's very nice to use.
It's nice when the philosophers come down to rescue us from our cave.
Having said that, there are a lot of constraints around real world use. Libraries, the ability to collaborate with other (blub) programmers, etc. I've used it exactly once in anger -- not on a learning/hobby project -- and although it was a resounding success, I had to go out of my way a bit even then to bring O'Caml to bear.
I'd highly recommend it if you're out to learn, and particularly so if you've never used a modern statically typed functional language before. It also makes sense to deliberately choose learning projects that play to the languages' strengths. I myself set out writing a L-System interpreter & functional image composer, which is good for learning because you can see your bugs...
As long as languages can do that, I don't see what the big deal library support is. Maybe it's just the extra tedium or something.
I'm thinking of making my next project straight html with Javascript hitting an OCaml server(s) on the backend using JSON. I believe if done correctly you should be able to do all sorts of cool stuff, like continuations across the http barrier. I don't know if any of you have looked at the F# web toolkit (open source I believe), but it allows using OCaml in one script file and tagging your methods to either run on the server or client or both places at once. So you have one module file that exists anywhere you like it to -- very cool stuff indeed.
So count me in!
Anyone know what he's referring to?
There are now at least two solutions to obtain speedups on multi-core and multi-processor machines plus scalability by allowing seamless distributed processing: the JoCaml extension, which integrates the join calculus (http://jocaml.inria.fr/), and coThreads (http://cothreads.sourceforge.net/), which comprises shared-memory (with extensions like STM) and message passing while keeping backwards-compatibility with the original Threads library.
http://steve.yegge.googlepages.com/when-polymorphism-fails
Note that like many of the alleged deficiencies of OCaml, this was a compromise for performance.
There are a several hackish polymorphic print implementations, but the best solution so far seems to be the "deriving" camlp4 extension (http://code.google.com/p/deriving/wiki/Introduction). This looks pretty good:
It's a loyal language because it doesn't bite you in the ass when you don't expect it. It's practical because there's a decent number of (high-quality, in general) libraries available, there are several concessions to serviceability in the language (mainly the ability to combine imperative and functional styles) and the implementation is solid and stable.
I haven't experienced the problems with the type system I've seen some people complain about. On the contrary, I've found it to be immensely helpful both when exploring new ground and when refactoring code. Deliberately breaking the code by changing a type or a function and letting the compiler guide you is a joy. In addition to other well-known benefits (Caml riders often feel that "it works as soon as it types" for a reason...) I won't repeat here, the type system (in particular the module system) sometimes makes me realize that I'm following the wrong track (I've learned to love functors after the early troubles).
Another thing I appreciate very much is the excellent performance and its predictability (other people might not care about this). The compiler doesn't (nor needs to) do deep magic the way GHC does to yield good results, so you can easily predict the performance (speed & memory usage) of your code --- and improve it when needed. Joel Raymond tells how this feels perfectly: "I would describe working with OCaml to guiding a scalpel: you move it and things happen. Right now, right here, in real-time. Compilation time is almost unnoticeable, the tool is powerful but reasonably simple. I have no problem expressing the most complex things and moving the project forward at a fast clip. I'm enjoying myself tremendously at the same time!" (Joel has switched to Erlang^H ^H^Hfactor^H^H^H K since he wrote that, though).
Expanding a bit on the Objective Caml toolset, I haven't really used ocamldebug (even though it knows some fine tricks like allowing you to go back in time...), but I often use the profiler and I've come to love camlp4, a tool that allows you to extend OCaml's grammar (I'll just say that it's very powerful, this post is already getting too long). I use the REPL mainly to explore libraries (just do "include Themodule" to see all its types & functions) or to check the type of a function (the type almost always tells you all you need to know without reading the documentation). I don't find it worse than irb --- but I rarely code inside the REPL anyway.
Now for the cons... as much as I like the language, some things could be improved:
* the standard library is a bit meager. Several third-party libs to complement/extend it exist, but there's still work left (there's some activity in the works to create a Community Distribution with richer libs).
* sometimes you feel some kind of ad-hoc polymorphism would be nice
* I've also wished a few times that the compiler were a bit smarter (inlining in higher-order functions, other classical optimizations)
* the community is very quiet: the code-to-blogging/discussion ratio is much higher than in other communities. INRIA isn't very talkative regarding its future plans for the language, and the ML has seen moderate activity historically (it's been revitalized as of late after the first OCaml Meeting)
Yes, that's what I meant (you change the grammar, resulting in new syntax).
Some examples of what you can do with camlp4:
http://martin.jambon.free.fr/pa_memo.ml allows to define memoized functions very conveniently:
Automatic generation of* typed JSON marshallers (http://martin.jambon.free.fr/json-static.html)
* serialization with S-expressions (http://www.janestcapital.com/ocaml/)* pretty-printing, type-safe marshalling with structure-sharing, dynamic typing, equality... (http://code.google.com/p/deriving/)
* list comprehensions, heredocs, string interpolation, lazy pattern matching, "do syntax" for monads (very much like Haskell's)...
Here's some OCaml code that relies on a rather large syntax extension of mine which allows you to generate (or verify) SQL schemas automatically and build composable queries using a typed relational algebra (the type system ensures that all queries are valid; if you change the schema and break some queries, the compiler will tell you what's wrong --- broken queries just don't compile):
You can read more about this extension at http://eigenclass.org/hiki/typed-relational-algebra-in-OCaml[pdf] http://cufp.galois.com/slides/2006/YaronMinsky.pdf
Unison is a file-synchronization tool for Unix and Windows. It allows two replicas of a collection of files and directories to be stored on different hosts (or different disks on the same host), modified separately, and then brought up to date by propagating the changes in each replica to the other.
It's also listed as one of the OCaml "success stories" here: http://caml.inria.fr/about/successes.en.html
Subversion access details here: http://www.seas.upenn.edu/~bcpierce/unison/svn-instructions....
The author has several papers on it and data synchronization in general here: http://www.cis.upenn.edu/~bcpierce/papers/index.shtml#Synchr...