
OCamlers' critiques of Haskell - a0
https://www.reddit.com/r/ocaml/comments/3ifwe9/what_are_ocamlers_critiques_of_haskell/
======
conistonwater
From the top comment:

> _Yoneda-crazy: I know Haskell, I know some category theory, but I am highly
> sceptical that teaching the Yoneda Lemma to C++ programmers is actually
> useful in any way._

This is infuriatingly true. Everything you do in Haskell you can understand in
terms of what code gets executed where and how. This is just as true of
Haskell as it is of any other high-level language.

Indeed, you can take an arbitrary Haskell program, and rewrite it in C with
the same semantics, and all you'll learn is how GHC's runtime is implemented
and how it executes your program. For a small concise program, this actually
makes for a nice exercise. I don't know why, but people sometimes seem to
think the runtime is "magic".

~~~
kzhahou
Personally I find category theory to be a red herring when it comes to Haskell
and really programming. I feel that people learn a bit of CT, then quote it
endlessly as a sort of elevation of programming from lowly code-slinging to a
high mathematical pursuit. Except CT doesn't really provide all that much
insight. At least not unless you're knee-deep in advanced type theory. But who
has _really_ read Benjamin Pierce's books (as beautiful as they are), or the
original Hindley texts?

A side comment, this one's more about CT itself, is that the standard texts
don't seem to really have many results. Not compared to, say, any undergrad
book on algebra or number theory, where cool theorems come at you every few
pages to twist up your brain. Category Theory always felt almost _mechanical_
to me. Lots of definitions and rules for assembling diagrams and such, but
then what. Just the Yoneda Lemma and that's it? If anyone can point me to the
fun CT theorems, I'd love to hear about them.

~~~
nabla9
>CT itself, is that the standard texts don't seem to really have many results.

Oh man. If you like math, CT gives nice mathematical definitions for stuff. I
would love to use my algebra skills to do general programming like I can use
my linear algebra knowledge in numerical programming.

I'm making bold claim that I hope someone can debunk with awesome
counterexamples:

"CT HAS ZERO APPLICABILITY IN PROGRAMMING"

Using CT to Linear algebra analogy: CT in programming is like learning
definitions of vector spaces, subspaces, span, and basis and stopping there.
No CT equivalent for solving linear systems, linear transformations, least-
squares or eigenvalues. Just because you have rooted programming in cool
algebraic notation does not mean anything in itself.

~~~
pron
This is a kind of marketing trick Haskell has pulled, which some people fall
for (regardless of the merits of the language), namely that Haskell is somehow
more "mathematical" than other languages. The truth is that Haskell -- like
all programming language -- has made a _design choice_ , which was to bake in
correctness proofs _based on the Curry-Howard correspondence_ into the
language. This means that instead of bringing the math to your program like
other verification methods do[1], it takes you to the math, requiring your
participation. Haskell just _feels_ more mathy because C-H puts the math in
your face.

Another trick Haskell uses is preferring abstractions that are based on
concepts from CT[2], and validating the utility of those abstractions on their
"rigorous mathematical foundations". This is again just another case of taking
you to the math rather than the other way around. Programming languages are
first and foremost human languages, meant to be written and read by humans. As
such, their power is drawn from a single source: their interaction with human
cognition. Whether an abstraction is "mathematical" (whatever that means) has
absolutely no relevance to its power, which comes from cognition (and
psychology in general) rather than math. All this "in your face" math does is
make the machine's job of verifying your software easier.

A Haskeller tried convincing me that such a language is a good fit for human
programmers, too, because all it is is a subset of more traditional, impure
languages. But the notion of subset => simpler is a mathematical notion with
no relevance to cognition. If humans operated in this way, natural languages
would have been much more mathematically simpler, too.

[1]: See KeY: [http://www.key-project.org/](http://www.key-project.org/)

[2]: To be fair, I'm not sure that Haskell, given its original design
philosophy, has much choice in the matter.

~~~
johncolanduoni
> validating the utility of those abstractions on their "rigorous mathematical
> foundations"

Some Haskell users may think this, but I think the usefulness of the
foundations is not derived from rigor. Instead, it is derived from the wealth
of knowledge we have about mathematical structures which makes them easier to
reason about. So by linking the programming structures you are using (e.g.
monads) with associated mathematical structures (also called monads[1]), all
of the mathematical knowledge surrounding that structure suddenly becomes
available. This is rather like how doing numerical calculations with matrices
benefits from the wealth of knowledge about linear algebra.

Another "mathy" aspect that Haskell and similar languages have is that they
like to start with a few fundamental constructs and build everything else
within that system. This is more a design philosophy than anything, but I
think it does have its advantages in that it results in better composablility,
since everything "comes from the same place".

As far as the relationship to cognition, I think Haskell will be better in
this regard if you are mathematically minded, because you will understand
programming constructs from their mathematical roots. For example, I had an
easy time picking up monads because I knew the category theory version. It
could be argued that once a person learns these concepts they are given a
better means of reasoning about programs than other languages, but I suspect
that largely depends on one's intellectual leanings.

[1]:
[https://en.wikipedia.org/wiki/Monad_(category_theory)](https://en.wikipedia.org/wiki/Monad_\(category_theory\))

~~~
pron
> which makes them easier to reason about

Easier to reason about by whom? Most programming models have their own calculi
which are exploited by their respective verification tools. They don't,
however, expose that to the developer.

> I think Haskell will be better in this regard if you are mathematically
> minded

I think that Haskell is better if you are mathematically minded _and_
interested in thinking (a lot!) about abstractions. I like to keep my
abstractions cognitively simple (primitive, even), and my algorithms
sophisticated and powerful. I'd rather the people writing the verifier put
their mathematical leanings to use on the relevant calculus, while I use mine
on the algorithmic domain I'm working in.

Just like I don't require the developer using my database to be familiar with
data structures and concurrency, I don't want those interested in formal
verification requiring me to change my programming style to make their job
easier. In fact, their job is quite the opposite: provide verification tools
that are useful for the programming languages that make for a good cognitive
fit, rather than design languages that make verification easier with the
(possibly misplaced) hope that by some unexplained coincidence, a language
designed to make a machine's reasoning easier would also do the same for a
human.

Software verification is a fascinating algorithmic topic. Language design is a
fascinating UI endeavour tasked -- like all UI -- with coming up with great
cognitive abstractions. The two should, of course, cross-pollinate one
another, but shouldn't become the same. Language designers should spend their
time thinking how humans think about computation and how they interact with
computers, not how to make programming models fit certain branches of math.

~~~
d4rkph1b3r
>I like to keep my abstractions cognitively simple (primitive, even), and my
algorithms sophisticated and powerful.

This is extremely poor programming practice. Let me guess, you're a solo
developer and/or working on a tiny team.

~~~
pron
At the moment I have a small team, but before that I was CTO of a large team
working on real time (soft and hard) defense systems.

------
jordwalke
I am an unashamed OCaml fan, but I think my previously stated analogy is
suitable:

"FP communities: like debating which brand of natural spring water to give
millions of thirsty people in the desert"

[https://twitter.com/jordwalke/status/566719390272335872](https://twitter.com/jordwalke/status/566719390272335872)

Note that I do genuinely appreciate the discussion, while finding the overall
scene humorous.

~~~
bunderbunder
That's a really magical analogy right there. Though I'd take it a step further
and say nowadays even stumping for an FP language smacks of the same sort of
thing.

Case in point: I've probably done more to evangelize functional programming by
just demonstrating to colleagues that they too can write their own higher-
order functions - just like LINQ! - in C# than an army of Haskellers could
accomplish in a lifetime of hurling jargon from category theory. My thought
is, if FP is really so great then I should be able to _show_ people by writing
some functional code and then having someone else come along later and go,
"Hey, that's great!" When I find I can't do that then that's a signal that
it's time to double-check the ingredients of my fruit-flavored beverage.

Yeah, that does mean I have to accept that Racket will forever be a hobby
language for me. My boring sellout Herman Miller-cradled enterprise developer
butt is comfortable with that.

~~~
the_af
> _My thought is, if FP is really so great then I should be able to show
> people by writing some functional code and then having someone else come
> along later and go, "Hey, that's great!" When I find I can't do that then
> that's a signal that it's time to double-check the ingredients of my fruit-
> flavored beverage._

I don't know about that. Sometimes people must make the effort to move beyond
their comfort zones in order to find tools that are (potentially) more useful.
You cannot expect every improvement to be self-evident with minimal effort.
There are significant rewards in "making the jump", so to speak.

~~~
bunderbunder
I'd submit that if I can't find a spot where my favorite trick solves a
problem in a way that I can easily demonstrate is better than the existing
alternatives, then my favorite trick is a solution in search of a problem.

~~~
the_af
I agree with everything you say except for the "easily" part. Sometimes you
have to make a cognitive effort; said effort is by definition harder than not
making the effort. But the payoff may be worthwhile!

I don't subscribe to the notion that for something to be worthwhile, it must
be readily apparent and "easy" to understand. Especially in the context of FP,
where most programmers -- but this is changing, thankfully! -- are
traditionally trained in imperative languages, which means for them learning
the FP "purist" mindset implies a significant effort.

My grandmother (R.I.P.) could never learn how to use an ATM. For her, using
one was daunting and too much of an effort. It terrified her that she might
make a mistake and push the wrong button. Back when she was young, ATMs didn't
exist and she didn't need them. Her solution in modern days was to ask a
helpful relative to use the ATM for her. Does this mean these hellish machines
are "a solution in search of a problem"?

------
more_original
One technical reason that makes me prefer OCaml to Haskell is Haskell's weak
module system. I think there should be a good way to parameterize one module
over another module (interface) and to use different instantiations of the
module in the same program. I think people do such things using type classes
and typing constraints. But I found this being awkward, because the compiler
needs to be able to resolve the constraints automatically and there are issues
with overlapping instances and the like.

To quote Bob Harper: _As a consequence, using type classes is, in Greg
Morrisett’s term, like steering the Queen Mary: you have to get this hulking
mass pointed in the right direction so that the inference mechanism resolves
things the way you want it to._
[[https://existentialtype.wordpress.com/2011/04/16/modules-
mat...](https://existentialtype.wordpress.com/2011/04/16/modules-matter-most)]
(I think this applies most of all if one is using type classes to emulate a
module system. For other purposes, type classes are quite nice.)

Maybe Backpack will solve these issues. [[http://plv.mpi-
sws.org/backpack/](http://plv.mpi-sws.org/backpack/)]

------
yohoho22
The OP on reddit lists several earlier "What are Haskellers' critiques of <X
functionalish language>" threads.

Here's another recent one going in the opposite direction, like this one, but
asking Clojure fans about Haskell:
[https://www.reddit.com/r/Clojure/comments/3h4qdk/what_are_cl...](https://www.reddit.com/r/Clojure/comments/3h4qdk/what_are_clojurians_critiques_of_haskell/)

A lot of the Clojure programmers seemed to focus on things, like records, that
often bug Haskellers, too.

------
bliti
I've toyed with Haskell before (enjoy toying with languages in my spare time).
Its a nice language, that has a good community. But for some reason I could
not see myself using it as one of my main goto (no pun intended) languages.
Not due to any technical reason. Mostly because there is no easy introduction
into it. No small projects to undertake showing what practical uses it might
have. No twitter clone using SQLite (laugh all you want, this type of tutorial
project helps understand how the language should be used and showcases
libraries). Its just seems purely about doing math with it. But Im probably
wrong. Last time I looked into it was about a year ago. I'll gladly look again
if anyone can comment about it.

~~~
Chlorus
Have you checked out Real World Haskell by Bryan Sullivan? It's different than
most Haskell resources I've found in that it introduces you to monads & IO
fairly quickly, so you're not trapped with toy math problems. That was an
issue I had with Learn You a Haskell for Great Good - finding the sum of all
odd squares that are smaller than 10,000 is good and all, but not exactly a
programming problem I have often...

~~~
radmuzom
Note that the book is a bit dated, though most chapters are still "valid". See
this question from Stackoverflow [1] - Which parts of Real World Haskell are
now obsolete or considered bad practice?

[1] [http://stackoverflow.com/questions/23727768/which-parts-
of-r...](http://stackoverflow.com/questions/23727768/which-parts-of-real-
world-haskell-are-now-obsolete-or-considered-bad-practice?rq=1)

~~~
bliti
Any alternatives available?

~~~
radmuzom
This looks good but I have not personally tried the courses mentioned at the
top of the article -
[https://github.com/bitemyapp/learnhaskell](https://github.com/bitemyapp/learnhaskell)

------
edgyswingset
Although this isn't OCAML, one thing I ended up missing when writing Haskell
was F#'s Active Patterns.

~~~
porges
These exist in Haskell as "Pattern Synonyms". Here's a partial translation of
some of the F# examples on MSDN to Haskell;

    
    
      {-# LANGUAGE PatternSynonyms, ViewPatterns #-}
    
      pattern Even <- ((`mod` 2) -> 0)
      pattern Odd <- ((`mod` 2) -> 1)
    
      testNumber x = show x ++
          case x of
              Even -> " is even"
              Odd -> " is odd"
    
    
      data Color = Color { r :: Int, g :: Int, b :: Int }
    
      pattern RGB r g b = Color r g b
      -- NB: this is bidirectional automatically
    
      printRGB :: Color -> IO ()
      printRGB (RGB r g b) = print $ "Red: " ++ show r ++ " Green: " ++ show g ++ " Blue: " ++ show b
    
      -- pretend we have functions to and from RGB and HSV representation
    
      toHSV :: Color -> (Int, Int, Int)
      toHSV = undefined -- implement this yourself!
    
      fromHSV :: Int -> Int -> Int -> Color
      fromHSV = undefined
    
      pattern HSV h' s' v' <- (toHSV -> (h', s', v'))
          -- here we explicitly provide an inversion
          where HSV = fromHSV
    
      printHSV :: Color -> IO ()
      printHSV (HSV h s v) = print $ "Hue: " ++ show h ++ " Saturation: " ++ show s ++ " Value: " ++ show v
    
      -- demonstrating being able to use pattern
      -- to construct a value
      addHue :: Int -> Color -> Color
      addHue n (HSV h s v) = HSV (h + n) s v

------
bbcbasic
> When I met a Haskeller at the pub after a mini-conference and I mentioned
> that I didn't like Haskell he began frothing at the mouth and punching the
> table. When we got up to leave he refused to shake my hand.

This is just gold!

All the Haskellers I have met seem to be quite normal, helpful. Maybe this guy
rubs them up the wrong way.

~~~
yokohummer7
That's not my experience. Most Haskellers are indeed good people, but quite a
few "vocal" ones are extremely arrogant and intellectually dishonest. Let me
give some examples that I've met recently:

\- A Haskeller once said Haskell is just as easy as Go to learn. I mean, yeah,
many moderately complex languages might be as complex as Haskell, but
seriously, Go? It is designed to be as simple as possible. Hell, it even
doesn't have generics, which is considered pretty essential in nowadays'
statically typed languages. And this claim isn't an outcome of ignorance. He
is the author of a very popular Haskell learning material.

\- Another said: "Steep learning curve is an interesting expression, because
what it actually means is that one is learning quickly." Ok, that's not my
interpretation of "steep learning curve" of Haskell.

\- "The average Java programmers are worse than the average Haskell
programmers" thing. This sentiment even existed in one of the "how to spread
Haskell to the industry" presentation. I'm pretty sure if Haskell does be
accepted by the industry, it will have the exactly same dumb programmers using
it. So, what's the point?

You must be lucky if you haven't met any of them in the Haskell community.
Actually, their reputation outside of the community is quite terrible. This
must be resolved if Haskell wants to succeed. (And yeah, please stop saying
"avoid success at all cost". I know it can be interpreted as "avoid $ success
at all cost", just stop it.)

~~~
mightybyte
> You must be lucky if you haven't met any of them in the Haskell community.
> Actually, their reputation outside of the community is quite terrible.

I think this is quite relevant.

[https://gist.github.com/quchen/5280339](https://gist.github.com/quchen/5280339)

All communities of significant size will have good and bad apples. The Haskell
community is no exception. But in my experience most of the community are
fantastically patient and helpful people.

~~~
bunderbunder
This may indeed be true, but Haskell has nonetheless developed a reputation,
and it's not a reputation that it shares with just any other community. The
only comparison I can think of is Lisp in the '90s and early 2000's.

My suspicion is this: There are lots of ways to make people feel inferior, or
at least make them feel like you think they're superior. Most of them are ones
that people probably don't do on purpose. But when you do it, the person you
do it to is going to think you're a smug jerk nonetheless. There are also a
lot of people who are supremely self-confident and therefore largely immune to
being made to feel inferior. Many of them have been like this all their lives,
and are therefore oblivious to this social subtlety.

One easy social gaffe that doesn't get discussed much is having no sense of
humility about your language's obtuse syntax. Yes, I know, it's a familiarity
issue, all languages have obtuse syntax, etc. etc. Doesn't matter. What
matters is, if your language's syntax is different enough from Java's or
Pascal's then it's going to be widely perceived as being obtuse. And
responding to that with anything along the lines of, "Huh, makes perfect sense
to me," risks coming across as a smug jerk.

Using the M-word is another famously risky behavior. Ironically, at least in
my experience using it is also actively harmful to any attempts to explain the
underlying concept, because at this point that word is @$#@ _loaded_. You can
take someone who is already implicitly comfortable with the concept and uses
them all the time in practice, and reduce them to a confused heap just by
mentioning the M-word. And at that point, any attempt to pursue your goals
will also risk coming across as a smug jerk. No, trying to address this issue
head-on by writing blog posts with titles like "You already understand. . ."
does not help. It just makes you come across as a _condescending_ smug jerk.

