On Fri, May 09, 2008 at 01:39:54AM +0100, Jon Harrop wrote: > Brian Hurt recently published... > > 3. Lack of multi-file modules: I have never found this to be a > problem. Nor do I find filenames implying module names to be a > problem, as many SML advocates seem to believe (yes, both of them ;-). I would add a 3a: the inability to have a "root"-level functor. As it stands, all functors are (sometimes naturally, sometimes not) embedded in a "root" module. I'm looking at you, Map.Make. You too, Set.Make. > 4. Mutable data: I believe the exact opposite. The ability to drop down to > mutable data structures for performance without leaving the language is > essential and the ability to predict memory consumption is essential, both of > which Haskell lacks. Consequently, Haskell's inability to handle mutation > efficiently and safely have doomed it to failure for practical applications. Well, in fairness, there's always the ST monad. However, the rank-2 polymorphism involved is nontrivial, and I agree with you [Jon.] > 5. Strings: pushing unicode throughout a general purpose language is a > mistake, IMHO. This is why languages like Java and C# are so slow. This is simply ridiculous. Using heavy-weight unicode-aware functions for character operations may slow down string-intensive operations in those languages, but the only alternative is to be broken. See items 3 and 4 here: http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html In both cases, we need locale-aware character processing. That means Unicode these days. Unless you code your own routines for processing every 8-bit character set out there. I don't. > 6. Shift-reduce conflicts: although there as aspects of OCaml's syntax that I > would like to tweak (e.g. adding an optional "end" after a "match" > or "function" to make them easier to nest), I am not bother about the > shift-reduce conflicts. Mainstream languages get by with far more serious > syntactic issues (like <<...>> in C++). I've been bitten by exactly these sorts of problems. Sometimes I get an obscure type error, sometimes I don't. I've just gotten used to not placing a match-like construct in the middle of a sequence expression when I can avoid it. > 8. Exceptions: I love OCaml's extremely fast exception handling (6x faster > than C++, 30x faster than Java and 600x faster than C#/F#!). I hate > the "exceptions are for exceptional circumstances" line promoted by the > advocates of any language implementation with cripplingly-slow exception > handlers. I really miss fast exception handling in F#. Brian gives an example > of exception handling with recursive IO functions failing to be tail > recursive here and advocates option types. But recursion is the wrong tool > for the job here and option types are even worse. You should use mutation > and, failing that, CPS. I suspect his reaction to exceptions comes from an unfamiliarity with their uses in Ocaml. In C++/Java land, the gospel is to only use them for exceptional circumstances. In the case of C++, this is probably because of the difficulty of writing exception-safe code: if you're going to throw an exception, your code is likely going to be broken as a result. As a result, exceptions seem to be reserved for situations where normal processing must terminate anyways. > 9. Deforestation: Brian says "Haskell has introduced a very interesting and > (to my knowledge) unique layer of optimization, called deforrestation". True, > of course, but useless theoretical piffle because we know that Haskell is > slow in practice and prohibitively difficult to optimize to-boot. Deforesting > is really easy to do by hand. Yes, its easy to do by hand. It's also time consuming. Don't you make a living off ocaml? I'm surprised you can justify using your time on such a mechanical task. Granted, deforesting something like map f . map g into map (f . g) is trivial, but we can come up with both trivial and nontrivial examples for almost anything. Cheers, Matt