
The Four Flaws of Haskell - kccqzy
http://neilmitchell.blogspot.com/2016/08/the-four-flaws-of-haskell.html
======
rtpg
One flaw I'd point out after working with Purescript a lot is that Haskell's
"IO " is very large, to the point of not meaning anything.

printing to screen? IO

network connections? IO

launching the nukes? IO

You get this weird effect of having pure code, then _all_ your effectful code
inhabiting the same types. Though this helps make you write more pure code,
when you do write effectful code, it's not nearly as safe as one might want.

Purescript's effects is a nicer granular mechanism.

~~~
hota_mazi
It's almost as if programs are useless if they don't perform some IO and
therefore, trying to encode this kind of side effects in the type system is
theoretically interesting but practically inconvenient.

~~~
chriswarbo
> It's almost as if programs are useless if they don't perform some IO

You seem to have missed the point. At the moment, a CLI calculator has type
"IO ()", a filesystem scanner has type "IO ()", an FTP library has type "IO
()", a random password generator has type "IO ()", etc.

It's very convenient that GHC points out when I try to, for example, perform
arithmetic on lists, or insert unsanitised strings into templates. It would
also be convenient if it points out when my CLI calculator is trying to
perform network requests, when my filesystem scanner is trying to generate
random numbers, when my random password generator is scanning the filesystem,
etc.

~~~
platz
In trying to advocate for fine-grained effect systems, i hope Haskell isn't
presented as 'unsafe' according to an extremely high standard usually reserved
for theorem proving languages. Pure functional programming is fighting an even
more basic battle that side-effects should even be separated at all. I feel
presenting Haskell's IO as unsafe throws out the baby along with the
bathwater. Others have not reached the peaks you look down on.

~~~
hnbroseph
are you saying they should check their haskell safety privilege? :^)

------
ioseph
Readability : although I'm not proficient in Haskell it seems to lend itself
towards perl-like clever one liners.

~~~
Ericson2314
The article is about things that impact professionals (thought they also
beginners). For better or worse, experienced Haskell users can read the one
liners just fine.

~~~
b34r
Sure, but you've also nuked a developer's ability to easily onboard and
understand the codebase with "clever" one liners. Good, maintainable code
tends to trend toward lower cognitive load more often than compact solutions.

~~~
nilkn
I'm generally of this opinion, but with Haskell I think more often than not
the "clever" one liners are actually not clever -- they're just completely
standard usages of fundamental language constructs, and they only appear
clever to people who haven't used the language.

It's very common to see newcomers or people who've never used Haskell at all
mention <$> and friends in this regard. Then someone will say that if you just
used do notation explicitly it'd be a lot clearer. And then someone will point
out that do notation might _look_ familiar, but semantically it can be
spectacularly different from what one might expect from truly imperative
languages (e.g., when using the nondeterminism of the list monad). So by
encouraging overuse of do notation, you're making the code feel familiar, but
you're not actually making it more understandable; if anything, you're making
it _harder_ to understand, because you're making it look like something that
it's not.

Additionally, while do notation is very generic and broadly powerful, <$> does
exactly one thing: it applies a function to a wrapped value, producing a new
wrapped value. Once you've used Haskell a fair bit, you very strongly
internalize this and tend to immediately understand code involving <$>. If all
this code were expanded out to use do notation, you'd have to spend a lot of
extra timing reading through the do notation to realize that, oh, this is just
a re-implementation of fmap, over and over again.

~~~
blowski
Is that then a limitation of the language? I've only briefly toyed with
Haskell (and most of the time I use PHP, so my opinion is almost moot). But
from what you've written, it sounds like it's hard to write Haskell that's
expressive for novices and experts at the same time.

~~~
catnaroek
> Is that then a limitation of the language?

How exactly is it a limitation that the language has greater expressive power
than most?

Haskell does have serious limitations: laziness is a horrible default,
modularity is a joke, reasoning about performance is very difficult, and the
correctness of most basic abstractions is conditional on the user never ever
using a partial function, not even accidentally - or else hilarity ensues.

But functors, applicatives and monads are godsend.

------
karma_vaccum123
Best rant I have read in years:

[https://www.reddit.com/r/haskell/comments/4sihcv/haskell_the...](https://www.reddit.com/r/haskell/comments/4sihcv/haskell_the_bad_parts/d5a7344)

------
cies
PureScript is a language that compiles to JS which is heavily inspired by
Haskell, yet fixes some of it's "flaws".

Namely it (1) has better record syntax, (2) is employs strict-evaluation
instead of lazy-evaluation by default, (3) has a better class hierarchy for
"numbers", (4) has a better class hierarchy for control classes[1] (like
Monad, Applicative, Functor, etc.). There are more, but to me they are the
main improvements.

Compared to Haskell, PureScript fixes some of the "flaws". These flaws are
mostly different from the flaws mentioned in the article. Maybe one day
PureScript can be compiled to native ...<searching internet>... which is
already being worked on[2].

[1] [https://github.com/purescript/purescript-
prelude/tree/master...](https://github.com/purescript/purescript-
prelude/tree/master/src/Control)

[2] [https://github.com/andyarvanitis/purescript-
native](https://github.com/andyarvanitis/purescript-native)

~~~
DanWaterworth
If you'd like strictness by default, there's a pragma for that
[https://ghc.haskell.org/trac/ghc/wiki/StrictPragma](https://ghc.haskell.org/trac/ghc/wiki/StrictPragma)

~~~
taylorfausak
This is another flaw that PureScript fixes: No language pragmas.

~~~
DanWaterworth
I don't think this is a flaw, in fact I think it neatly solves the problem of
how to extend the language without committing to a design too eagerly and
provides a platform for experimentation.

There are pragmas that GHC implements that are now widely held to be
problematic, but we wouldn't know this without an implementation, and using
pragmas, we are realistically able to deprecate and remove these extensions.

~~~
taylorfausak
Very few extensions have been deprecated:
[http://hackage.haskell.org/package/Cabal-1.24.0.0/docs/src/L...](http://hackage.haskell.org/package/Cabal-1.24.0.0/docs/src/Language.Haskell.Extension.html#deprecatedExtensions)

Convenient, widely-used extensions that have been around for a long time
aren't yet part of the language standard:
[https://prime.haskell.org/ticket/67](https://prime.haskell.org/ticket/67)

~~~
DanWaterworth
That's not anywhere near a complete list of deprecated extensions and there
are others that have been completely removed from the language [1]. It's
unfortunate that ScopedTypeVariables hasn't been standardised, but there
hasn't been a new standard since 2010, so it's not hugely surprising.

[https://ghc.haskell.org/trac/ghc/wiki/LanguagePragmaHistory](https://ghc.haskell.org/trac/ghc/wiki/LanguagePragmaHistory)

~~~
taylorfausak
Thanks for that link! I haven't seen that wiki page before. Even so, only 4
extensions have been removed. I know others are de facto deprecated, like
Rank2Types.

I picked scoped type variables as an example because it's been in GHC since
version 6.4. That was released in March 2005, so it had plenty of time to make
it into the Haskell2010 language standard.

~~~
DanWaterworth
I'd expect either Rank2Types or RankNTypes to be included in Haskell', you may
be thinking of ImpredicativeTypes.

Wow, I did not realize ScopedTypeVariables had been around for so long.

~~~
taylorfausak
Sorry, I meant that you pretty much always want RankNTypes instead of
Rank2Types. My fault for not specifying.

------
Ericson2314
Tools and ecosystem coherence, basically. We have infrastructure technical
debt and...factions.

------
avindroth
I hear NixOS (linux distro based on functional principles) solves the package
management problem for Haskell.

* [https://ocharles.org.uk/blog/posts/2014-02-04-how-i-develop-...](https://ocharles.org.uk/blog/posts/2014-02-04-how-i-develop-with-nixos.html)

* [https://www.reddit.com/r/haskell/comments/1vghgw/nixos_a_gnu...](https://www.reddit.com/r/haskell/comments/1vghgw/nixos_a_gnulinux_distribution_based_on_purely)

* [https://nixos.org/~eelco/pubs/nixos-jfp-final.pdf](https://nixos.org/~eelco/pubs/nixos-jfp-final.pdf)

* [http://fuuzetsu.co.uk/blog/posts/2014-06-28-My-experience-wi...](http://fuuzetsu.co.uk/blog/posts/2014-06-28-My-experience-with-NixOS.html)

~~~
exDM69
FYI, it's possible to use Nix package manager outside of NixOS. I'm not quite
convinced that some of the choices the NixOS distro has made are good (or to
my liking) but the package manager seems much better thought out.

I was able to quickly install Nix on a not quite up-to-date Linux distro to
get my hands on specific versions of some programs that are too big to
conveniently build from source.

I'm not sure it solves the package management problem for Haskell completely,
but it should help managing GHC versions and external dependencies (ie. native
libs required by Haskell libs), which cabal/stack aren't great with.

Note: I was a bit disappointed that installing Nix required root access to
create /nix store. I would have liked to put it in my home directory instead.

~~~
vertex-four
Unfortunately, because Nix derivations embed full paths to all their
dependencies, moving /nix elsewhere means you don't get access to the binary
cache and wind up having to build everything from source. If you're happy with
that, you can compile Nix manually to put the store in your home directory:
[https://nixos.org/wiki/How_to_install_nix_in_home_%28on_anot...](https://nixos.org/wiki/How_to_install_nix_in_home_%28on_another_distribution%29#Manual_Installation)

------
SeanDav
I often wonder what is it that keeps Haskell out of the mainstream as a
development language. There seems to have been enormous popular support for
Haskell by experts over quite some time, yet relatively newer languages like
Golang are coming along and eating Haskell's lunch.

~~~
RubyPinch
Probably the whole needing to learn an entire part of English that many didn't
even know existed before.

A language really shouldn't require its language-specific glossary to be
mandatory reading, just to understand anyone speaking about it. I could just
learn any other language in half the time!

from the above comments

> "I have this pure function that I want to apply to the inner value of my
> functor"

pure function I know well enough, that is the same for any language, functors
though... is that a function object that can be applied to something? then why
does it already have a value?

I can take terminologies from C, to python, or C#, and feel a-okay, but
haskell kinda feels like it went and shut it self away from the world, and its
terminology developed differently due to that, I guess.

~~~
14113
Haskell terminology is based on the mathematical underpinnings of its type
system. It's due to this that those unfamiliar with the maths often have
trouble at first grokking the terminology. It's not that Haskell shut itself
off, it just draws it's vocabulary from a different source than the other
languages.

~~~
RubyPinch
I am aware it didn't invent the words, it was more of a "feels like"
statement, as opposed to literal

------
spriggan3
The overuse of weird operators is just a deal breaker for me. Haskell ideas
are good. But I prefer explicit keywords rather than -> <$> and co everywhere.
for instance, pattern matching that looks like switch statements would be more
readable than lines of |

~~~
icen
You can just write something like

    
    
        foo x = case x of
                  pattern1 -> ...

------
hota_mazi
I would add pragmas.

People like to say there is just one implementation of Haskell and it's ghc,
but there's actually n different ones, with n being the number of combinations
of pragmas that exist.

Each combination you use in your source is a different version of Haskell.

~~~
harpocrates
While I see how this at first appears to be a problem (when I started with
Haskell I sure thought of it as one), it turns out that language-pragma filled
code can be mixed with vanilla code too without problem. The pragmas usually
just expose more of the inner representation of GHC (I'm thinking things like
FlexibleInstances, TypeApplication, RankNTypes and not the pathologically
broken and perhaps logically unsound ImpredicativeTypes). So it really is just
GHC you are shipping (and not GHC + which extensions are enabled).

------
hellofunk
Regarding space leaks, the recent GHC version now allows an entire module to
be strict, not lazy. Would this prevent space leaks (and perhaps other
performance-sensitive problems)?

------
drivebyops
atom (ghcmod + the various haskell pluings) is good enough for me honestly

sublimehaskell (hsdev, etc.) was good as well

