Hacker News new | ask | show | jobs
by crote 38 days ago
The main issue I kept running into with Haskell is that the machinery feels haphazardly implemented.

Sure, the concept of a monoid makes sense, but (at least a few years ago) why isn't a Haskell monoid defined as an extension of a semigroup? And even these days: where's magma?

What makes monads special enough to warrant its own first-class syntax and dozens of predefined instances, while dealing with a Sum or Product monoid feels like an afterthought?

If functors are as basic and fundamental as they seem, why do they get an awkward "fmap" - with most standard types re-exporting it as plain "map"?

Programming in Haskell felt like I was dealing with a random collection of category theory concepts thrown together in a weekend, rather than a mature and well-designed programming language. I have no doubt that there's some very solid reasoning behind it all, but the Haskell documentation does an awful job answering the questions you stated. And let's not even mention giving them programmer-friendly names rather than something a German mathematician chose 150 years ago...

3 comments

Sometimes you go back and reinvent the stack (breaking everyone's code) and other times you introduce things non-breakingly.

> why isn't a Haskell monoid defined as an extension of a semigroup

  class Semigroup a => Monoid a where 
  [https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html]
> If functors are as basic and fundamental as they seem, why do they get an awkward "fmap" - with most standard types re-exporting it as plain "map"?

map was in the original 1990 Haskell spec [https://www.altocumulus.org/haskell-report-1.0.pdf]. Functors & fmap came later. I guess they went with a non-breaking feature introduction.

Other times they do a breaking change. Monads didn't used to need to be Applicative Functors. Now they do. [https://wiki.haskell.org/Functor-Applicative-Monad_Proposal]

Anyway, it could be worse. You could be working in a language that can't even express the functor/map interface.

> class Semigroup a => Monoid

Yes, hence the "at least a few years ago". But perhaps I'm misremembering and confusing it with applicative functors, it has been a few years.

> I guess they went with a non-breaking feature introduction.

Sure, but functors aren't exactly novel, are they? Although it has contributed a lot to programming language design in general, Haskell didn't exactly invent the concept of a generic "map". So why wasn't it there in the first place, and why was it - despite its obvious prominence - not deemed important enough for a (what seems to be tiny) breaking change?

> Anyway, it could be worse. You could be working in a language that can't even express the functor/map interface.

Are those still around? I thought even Go eventually started supporting generics?

"Generics" doesn't cut it. Most languages just can't functor.

Go - no. https://www.reddit.com/r/golang/comments/v1ljep/monads_and_p...

Swift - no. https://forums.swift.org/t/higher-kinded-types-monads-functo...

Rust - no. https://www.reddit.com/r/rust/comments/152bgj0/current_state...

"Awkward fmap" and "random collection of category theory concepts thrown together in a weekend" is great compared to the alternatives.

There's a language that is Haskell-inspired but more mathematically correct (not by much mind you), and it's called Purescript. And of course it has the whole zoo of algebra in its stdlib. It also has a lot of interest type-level stuff including my all-time favorite, row types to represent things like Javascript objects that can have an unbounded number of fields (Typescript tries to approximate this but is less powerful).

The best decision ever Purescript made was to not make the language lazy by default. Laziness is still there if you want to opt in, but laziness by default is the mother of all leaks.

I looked into Purescript for a frontend project, but it seemed to be a bit lacking in ecosystem at the time, so (despite its very limited type system) I went for Elm instead, in the hope that it'd grow into a more mature language. Quite a mistake that was...
Has the ecosystem or language actually limited the elm project or are you just speaking in terms of how “offbeat” the choice is now?
> thrown together in a weekend, rather than a mature

The fact that it wasn't thrown together in a weekend is the reason why we have both map and fmap, and why monoid wasn't originally an extension of semigroup (it is now). Haskell started out without that, then later added fmap and semigroup.

In any case, those are not real concerns when programming with Haskell. The actual concerns are more like "why do I have to wait for all this lens dependency stuff to compile just to fetch an url" or "why does the language server need so much ram"

> In any case, those are not real concerns when programming with Haskell.

They were my concerns when learning Haskell - and I was following graduate-level courses at a university which contributes rather heavily to the Haskell ecosystem. They might not apply to you, but that doesn't mean they aren't real.

My limit was seeing a HTTP server being praised over and over again for it's wonderful type-safe API, trying to use it, and a few weeks in discovering that a very basic HTTP feature was considered an "open research question" and "would probably require a full redesign". Having poor compile time and consuming a crazy amount of memory was indeed also quite an annoyance. Having an entire ecosystem seemingly more concerned about writing theses about type theory than with building usable libraries? That was a dealbreaker.

Haskell is a great tool for programming language research, and I can't wait to see what kind of crazy things they'll end up doing with dependent typing. Unfortunately in my experience this also seems to make it into a rather poor choice for actual programming in a non-research environment.

I don't hate or dislike Haskell. If anything, I'm disappointed in it. I really want to love it and use it for everything, but it's just... not there yet.