Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Has anyone used both Haskell and OCaml (or F#?)? How do they compare in practice? I've been wanting to put some time into a functional language and I've been debating between Haskell and OCaml. Because of F#, OCaml seems like it might be the more practical language (i.e. direct job opportunities). However, excluding F#, Haskell does seem to much more popular than OCaml.


Either one is great. Short of it is that OCaml and Haskell will both teach you a lot of the same things. OCaml has better modularity features (namely, genuine modules which are replicated almost nowhere else) and Haskell has better purity features (namely... purity).

It turns out that sophisticated functional programming essentially stresses that good modularity and good purity are both killer features and techniques and they should be in heavy use all of the time. In OCaml you'll have an easy time expressing the exact modularity concerns you find important, but will struggle a bit to manage purity explicitly. In Haskell you'll find it beautiful to express pure and typed-effectful computation as much as needed, but will struggle a bit with expressing modularity as you'd like.

Haskell also has the whole typeclass system which is really, really interesting and valuable for many kinds of expressiveness. It's sort of an oddball feature, but interesting to see the impact of.

Personally, I find strict purity more important than expressive modularity. But if anyone could really put them together in a way that worked it'd be great. I'm not so sure such a language exists today, though.


> Personally, I find strict purity more important than expressive modularity. But if anyone could really put them together in a way that worked it'd be great. I'm not so sure such a language exists today, though.

There is Ur, which has both ML-style modules and Haskell-style type classes. It's also pure and strict. And it has advanced type-level programming features and record types. There's a lot to like.

There are a few problems with it, though. It's mostly a one-man project. The compiler is immense, complex and almost entirely devoid of documentation (it's pretty amazing actually, like 1 comment per 1000 lines or so), so contributing is hard. It's very difficult, if not impossible, to use the language for anything but web development: there's no way that I know to execute a program directly, rather than as a sub-program of the ur/web framework. The standard library is tiny and doesn't even include `print`. But even with those warts it has enough good things about it that it's worth checking out.


Oh! I've used Ur a bit and spoken to Adam about it briefly. He gave a talk on Ur at Haskell Boston. I wasn't actually aware that it had typeclasses (though it surely has modules).

Honestly, Ur is completely ingenious but there remains an enormous challenge getting it away from being entirely Adam's project. It's completely web-only right now (although Ur is supposedly a more generalized language) as the only compiler is Ur/Web.


By the way, Adam is apparently going to be a lecturer at OPLSS this summer. That kind of event seems right up your alley; have you ever gone? Any plans to go this summer? I'm hoping to attend.


I watch all the lectures! I really really really want to go but can never afford it timewise. :(


Yeah, it has type classes, although the syntax is a little different than how Haskell does it.

Agreed to all of that. I've tried to get into it several times, but I have almost no interest in web development. I'd really like to use it just as a language. It seems like it should be possible to decouple it, but it seems like the only way that will happen is if Adam gets more people in on it. And that's not likely to happen with the scanty documentation and completely impenetrable compiler code. :(


My experience is that, Haskell syntax is a dream compared to Ocaml, with 'where' clauses, beautifully simple lambda syntax, do notation support, . and $ composition, typeclass operator overloading.

Ocaml is more practical in a hard to explain way. Much more predictable in terms of it's memory and cpu use with non-lazy default evaluation, and I found much better performing on general code.


Funny, I have the opposite experience. Where clauses force you to look down and then up again (bonus if you managed to use both let and where in the same function!). The lambda syntax is a matter of debate, writing "fun" instead of "\" doesn't bother me and is, IMHO, clearer. OCaml has an equivalent of $ with @@, but I haven't seen it used very much, since chaining functions with |> is so convenient.

OCaml does not have generic ways of doing monadic stuff (do notation or generic >>=), which means in practice that monadic code looks like "fun1 x >>= (fun r -> )" which is kind of awkward. It also doesn't have typeclasses (yet).

However, one thing you're unlikely to find in OCaml and which is unfortunately not uncommon in Haskell is functions with a long list of positional parameters (since you have named arguments) or different versions of the same function with a "_" suffix, depending on various defaults (since you have named arguments). It makes a tremendous difference of readability when dealing with complex code.

Also, interface files (.mli), while a bit of a pain to maintain at times, give a very clear idea of what interface a given module exposes.

All in all, I find OCaml code much easier to read, not to mention less "clever" than equivalent Haskell code.


> However, one thing you're unlikely to find in OCaml and which is unfortunately not uncommon in Haskell is functions with a long list of positional parameters (since you have named arguments) or different versions of the same function with a "_" suffix, depending on various defaults (since you have named arguments). It makes a tremendous difference of readability when dealing with complex code.

Can you give an example, I'm interested in seeing what you mean but having trouble figuring out what an example would look like.


I have used all three languages professionally—Haskell & some OCaml at Facebook, and some F# at Xamarin—and would recommend learning Haskell.

There’s a strong community around Haskell, with a decent library ecosystem and high-quality implementations, and learning it will make it easy to pick up F# or OCaml—the reverse is not necessarily true.

F# is a decent choice if you want to write functional code in .NET land, but Visual Studio and MonoDevelop support for F# aren’t as good as for C#.

OCaml is a good language, but I would recommend against it. Like F#, it has some syntactic and semantic conveniences that Haskell lacks. However, the community is small, there are relatively few libraries, and the runtime falls down when you need to do anything with large arrays or floating-point math.


> OCaml is a good language, but I would recommend against it. Like F#, it has some syntactic and semantic conveniences that Haskell lacks.

I haven't had a chance to use OCaml or F# yet, what syntactic and semantic conveniences are you talking about?


For example, OCaml has an object system (the “O”), polymorphic variants (somewhere between ADTs and symbols), parameterised/first-class modules, and named/optional function parameters. A lot of these things have suitable replacements in Haskell, they’re just not in the language directly. And of course, Haskell has plenty of features that OCaml and F# lack, such as pervasive purity, typeclasses, and an array of useful advanced type system features. It’s tradeoffs all the way down. :)


I used both Haskell and OCaml professionally.

OCaml's strictness makes some things easier to reason about. Haskell is a nicer language and has more momentum.


OCaml has, IMHO, strong syntactic advantages over Haskell which have a major impact on readability:

- the way you access records (which also means it's not going to clutter your namespace)

- named arguments

- default values

- not an OCaml-the-language property, but there is much less of a race in the OCaml ecosystem to write the shortest variable name possible and accumulate the most ASCII operators

Also, the great module system, with easy abstract types or "public" types with private constructors. By contrast, having to export accessors (if using a lens library) is embarrassing.


The modules are great in OCaml.

The short variable names in Haskell follow the convention that the more polymorphic your variable is, the shorter its name should be. Eg in

map f (x:xs) = f x : xs; map _ [] = []

f, x and xs are very polymorphic, so there's really no better longer name there.


First, people are not shy about using short names in general, however polymorphic the variable is.

And you could easily write:

    map func (item:items)


The point is typically something like "generic english names don't provide much benefit over conventional short names".

When I'm writing map, parametricity literally ensures that I cannot care about the element of the list. Giving their priority with any thought toward the name is actually taking the focus off the list structure where it belongs.


That's nice, but when reading non-trivial code, having "generic English names" makes the programmer's intention easier to decipher than a random sprinkling of 5 different one-letter variables - though it's fine to have ecosystem-wide conventions for the most common cases.


I would argue that in non-trivial code when variables represent meaningful concepts it is Haskell tradition to use long, descriptive variable names. Sometimes these are even longer than in other languages since that's a tool used so rarely.

The trick is that once you're exposed to short names at the right places you realize that there are relatively few times that variables are meaningful as much more than function-wiring notation. Especially in pure code!

As soon as you add in mutability this all goes out the window really fast. Subsequently, you see "meaningful" variable names all the time in IO or ST code.


    map fn (head:tail) = (fn head):(map fn tail)
    map _ [] = []


Your version, while not very different, is not easier to read than that of the parent post.

A few weeks into learning Haskell, reading x:xs will become second nature, so much so that "head" and "tail" become noise. (Also, "head" and "tail" are function names in the Prelude, but I'll assume you meant to write "hd" and "tl" or something like that).


    (Also, "head" and "tail" are function names in the Prelude, but I'll assume you meant to write "hd" and "tl" or something like that).
No, I overlooked that. Writing "hd" and "tl" would be opposite to my point! I think that "head:tail" is much more readable and much more informative than "x:xs".


Shadowing built-in names comes with it's own set of problems. (At least that's the opinion of the compiler writers that enable warnings about shadows by default.)


Actually, (some form of) default values are easy to add to Haskell. We did so at Standard Chartered.


How do they compare in practice might be too broad a question, I'm willing to bet you'd get more responses if you asked for comparisons in certain use cases.


I tend to think of OCaml as a functional C. It's strict and not purely functional. You can write for-loops and while-loops if you want (but you shouldn't) and use refs to have mutable state (but you shouldn't). It has a better module system than Haskell, but doesn't have type classes. It has functors, which are equivalent-- OCaml's functor is an operation over modules and only very loosely connected (through type theory, which isn't essential to being proficient in either language) to Haskell's Functor type class-- and better in some ways and worse in others.

Haskell is more expressive and has a much more powerful type system, but it's probably harder to reason about performance.

OCaml's biggest issue (note: I may be out of date on this, since I haven't heavily used it since the late 2000s) is the GIL. This probably limits your ability to use it for multithreaded programming, but it can compile down to extremely fast single-threaded executables.


This book actually teaches C in relationship to previous assumed knowledge of Standard ML (not quite OCaml, but close).

http://eprints.eemcs.utwente.nl/1077/02/book.pdf

I'm not sure I agree with all of the conventions, but it's interesting to see a deliberately functional approach applied to C code.


Can you compare that to Scala? Scala also has non-pure constructs built in, but most people tend to opt in to its purity. And I don't know much about OCaml, but it seems like Scala may have better type system parity with Haskell's type level features.


I'd really love to be able to think of ATS as "functional C"!

(Not that I actually do. Maybe someday).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: