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

Haskell is a language for experimenting, success is not their goal and it would remove resources to actual research.

They had promises and async/await in 1995. They're trailblazers that other languages can follow (like rust did).

I would add that, after stack, tooling is not a problem anymore. It's not as good and polished as rust's cargo but it's ahead several other languages.

Still, as a language, Haskell is not ideal for teaching and productivity.

There too many different ways of doing things (eg. strings, records); compiler errors need improvement, prelude has too many exceptions-throwing functions (eg. head); exceptions handling is not something I want in a pure language; ghc extensions change the language so much that using some extensions almost feel like having to learn another language.

On documentation, I can't say I feel the need for it, but I understand some developers may be used to program against documentation and feel lost without it.

I think that Haskell is a great language to prototype pure business logic because of the type system and focus on purity, but it has several warts, because haskellers focus more on language research than DX.

The reason I stopped using Haskell is because I was bit by exception handling (which is a feature shared by many other languages, incidentally!) and by GC spikes.

I still like Haskell, it's closest to my "ideal" language than any other, but for production Rust is more useable (albeit being a bit uglier)



> Haskell is a language for experimenting, success is not their goal and it would remove resources to actual research.

You rightfully point to Rust, which took a lot of inspiration from Haskell, but I think it's worth emphasizing just how much of the progress in programming languages in the last two decades was inspired by functional programming (many features were not invented in Haskell, but some like type inference were popularized by it).

For example: proper type inference, algebraic data types (enums in Rust) and consequently option types, pattern matching, property-based testing, immutability by default, parametric polymorphism (generics), ad-hoc polymorphism (type classes/traits/...), first class functions (very old idea but only recently common in mainstream languages), ...


The Rust docs claim most things actually came from ML and OCaml: https://doc.rust-lang.org/reference/influences.html

They only mention Haskell's type classes and type families as inspiring a Rust feature directly (traits).


It's kind of alluded to, but, while FP languages, as a broad category, were the progenitor of a lot of different PL ideas, Haskell ended up implementing many of them in a single place. It's fair to say "we were influenced by (this other language that originated an idea)", but it's also fair "and Haskell also has that feature". Do it enough times, and you start to see why the claim that Haskell is important; being a research language it's able to have all of these ideas implemented in it in pursuit of its design goals, where other FP languages pick and choose in pursuit of a different one.


I think it would be best to create a spin off of Haskell. A small subset with only the good parts of Haskell, few hand selected extensions, new prelude, with focus on performance, very easy tooling/build chain and use in production for businesses: "Production Haskell Lite".


The original rust compiler was written in ocaml


I learned type inference in Caml Light, Haskell was still Miranda back then, and I bet any language designer of all major languages has similar backgrounds in regards to ML type inference.

Even type classe ideas can be found in CLU, ML, Objective-C, before the paper that gave origin to their adoption in Haskell.


For history buffs: https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_sy... was invented in 1969 (and rediscovered my Milner in 1978).

AFAIK, that was the basis of type inference in many of the non-mainstream languages before they branched off into their own more powerful type systems.


from lisp and ML, but yes, haskell is a white-coat language.


a white-collar language


no.

white-coat as in white lab coat, i.e. a research language.


> I think that Haskell is a great language to prototype pure business logic because of the type system and focus on purity, but it has several warts, because haskellers focus more on language research than DX.

This is very true. We recently started https://github.com/digitallyinduced/haskell-ux to keep track of haskell DX improvements. Some of our suggestions are already issues on the GHC (haskell compiler) bug tracker.

Here's an example of a great UX improvement in GHC: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4711


Good to see that the article is at least underselling that people are actively working on this


Exactly. It's a research vehicle. Not everything in Haskell is useful for business or productivity.

The reason I stopped using it is because of performance. Despite having state of the art optimizations there it's still too slow for my needs and writing fast code is way to hard compared to C++ or C.

I was also quite disappointed to learn that a lot of useful concepts (Monad transformers/stacks) have a runtime performance impact when it looked to me like I was just playing with types.


> It's a research vehicle.

Well, it's also one that happens to make people lots and lots of money. Standard Chartered, for example, uses it extensively to earn lots of money. Facebook uses it for spam filtering logic. Niche, perhaps, but painting it as purely for research is just incorrect.

Yes, it's not going to be great if all you're writing is integrations with various vendors using SOAP or just legacy or odd protocols. Those have libraries or code generators on the JVM/.Net/etc. platforms... not so much in Haskell. However, this has nothing to do with the language, it's just a matter of people actually doing the work to support those things.

Everything else, though... you're golden. It has a learning curve, but there's a reason that Scala is moving ever closer to monads, adopting proper syntax for type classes, etc.


This is a good point.

The language doesn’t have to be good to make money, in fact in can be quite bad.

Oddly, while modern development embraces agility, many things often benefit from small changes, and a bad language has small change built-in.

Why? Well, if the language is bad, you have to pay your developers well to retain them, since there are few that want to program in that language. The developer comes aboard because of the money and the challenge. Once they join the company and become a developer in a bad language, there are fewer alternatives for the developer to find another job in that bad language. This means that they have to stay around and get to know that bad language better, making to even harder for the business to hire others to help or replace them. So, the development doesn’t suffer as much from team scaling problems, and change can’t happen as quickly.

This isn’t what you want for everything of course. Especially when talking with a VC about a startup.

But JS, an ok language, has gotten to a similar level of nonsense through the difficulty and complexity of its rapidly changing ecosystem and changing browsers.

And few languages have really avoided unnecessary difficulty over time in their ecosystems.


Absolutely.

I think we in the IT community should really strive to be better at nuance when discussing these things.

I mean, as much as I've seen "Haskell sucks" posts, I've also seen quite a lot of "Haskell solves all your problems!" posts. That's not how anything works in the Real World(TM) when solving concrete business problems -- whatever that business domain may be. Rather, it's trade-offs all the way down. It does get tiresome to read these re-hashes of debates which should have been over already. (EDIT: For anyone wondering, the answer is: It depends.)

I think the "tribes" blog post mentioned in https://news.ycombinator.com/item?id=25699983 is very insightful for the meta-level of this discussion.

EDIT: Final edit while I can. We see this a lot with "lol PHP" style comments... and all those achieve is a sense of elitism and making people who actually get lots of important work done in PHP feel bad. I don't want that world.


> The language doesn’t have to be good to make money, in fact in can be quite bad.

In fact, I think that there's an inverse relationship between how good a language is, and how much money has been made with it, on the condition that you have heard of it.

Why? Well if you've heard of a language, it's likely because it is a language that has proliferated through the community. The worse a language is the more it must have made people money to 'survive' and proliferate.

Think of the worst/ugliest languages you can think of (coming to my mind is Visual BASIC, C++, PHP, Javascript). These are languages that made an exceptional amount of money, and this allows them to survive despite being so bad.


Hi.

I am a professional software developer and my full time job is currently writing software in Haskell for a bank.

I also stream projects and open source work I do in Haskell once a week.

I am not a researcher. I don’t have a horse in that race. Although I am thankful for the research that is done as things like STM and type system extensions benefit my work greatly.

I really wish Haskell could shed this meme that it’s a “research,” language and that, “nobody uses it.”

I’m Nobody. I use Haskell every day. It’s a practical language for industrial strength programming in a pure functional language.


The fact that Haskell is a good industrial strength language is a byproduct of its quest for language design excellence.

Avoid success at all cost, implies an unwillingness to sacrifice on design to please corporate needs.

I don't think it's a "meme", there really is a focus on research over being production ready. Monads, Arrows, Dependent Types - Haskell is where a lot language research happens (and the language chosen by a lot of researchers).

Sure, you can ship Haskell in production if you're happy to fill in the gaps. I did some of that for a non-Haskell company and it wasn't as easy to deploy apps written in other languages and community-provided solutions for logging / monitoring were lacking.

That said, I'm always happy to hear about people using Haskell in production and wish you the best


> I would add that, after stack, tooling is not a problem anymore. It's not as good and polished as rust's cargo but it's ahead several other languages.

In a way Cabal 3 is even ahead of cargo, by being able of sharing build libraries between different projects and still having a sandbox like build for each project.

> There too many different ways of doing things (eg. strings, records), compiler errors need improvement, prelude has unsafe functions (eg. head), exceptions handling is not something I want in a pure language, ghc extensions change the language so much that using some extensions almost feel like having to learn another language.

For such a self called safe language, some things are almost comedy like, like getting exceptions for uninitialised record fields or unhandled alternatives in case expressions.

But Haskell still has a place in my heart and I‘m still following its development. But for my side projects Rust has replaced it, by being at some things even safer, but foremost safe at the places it‘s most important for me and also quite a bit more pragmatic. For me Rust combines the best parts of Haskell and C++.


> some things are almost comedy

We're trying to fix that! https://github.com/ghc-proposals/ghc-proposals/pull/351


> Haskell is a language for experimenting, success is not their goal and it would remove resources to actual research.

It's somewhat facetious motto is "Avoid success at all cost".


   Avoid $ success at all costs


I dunno why people downvote, obviously this means

    Avoid (success at all costs)


> async/await in 1995

Unix had fork and wait before 1979.

Unix shell:

  # run some commands asynchronously

  $ command1 &
  $ command2 &
  $ command3 &

  # wait for all of them

  $ wait


Multiprocessing and parallel programming is a different thing from async/await, which primarily has to do with with green threads and coroutines. You're right that the ideas go way back (hell, Knuth was writing about coroutines in TAoCP in the 70s!), but this does not qualify.


Unix was originally green threads, at least in kernel mode: it was a non-preemptable kernel running on a uniprocessor. This means that kernel code ran until hitting a voluntary context switch. User space was preemptible.

(User space being preemptible doesn't really make a semantic difference to the shell & and wait examples, unless some of the commands contain lengthy CPU-bound loops.)


> They had promises and async/await in 1995.

Really? Do you have a source on this? I was under the impression that C# was the pioneer here.


Async/await is specialised syntax for a more generic concept of monads which haskell was the language in which this was heavily researched.

Specifically continuation monad describes asynchronous computation (promises) and was one of the motivating examples In the early 90s going back all the way to Moggis original "notions of computations" paper from 1991 http://homepages.inf.ed.ac.uk/wadler/topics/monads.html

Async/await and LINQ were the brainchild of Erik Meijer. A haskell researcher.

Also see https://news.ycombinator.com/item?id=25565229 from a recent discussion here.

Specifically http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.... where Eric tells his story about bringing haskell concepts to .NET


Fwiw, c# wasn't even the first dotnet language with it. F# had async computation expressions a few years earlier.


But F# doesn't have async/await. As you write, it has "computation expressions", which are inspired by Haskell's "do-notation", but are more generalised and powerful (than both Haskell's "do-notation" or Scala's "for-comprehension", let alone async/await).

One of the things I liked best about F#.


Idk if you can strictly say that.

Haskell allows more generalized do blocks because of HKTs. I blogged about this a few years ago. https://www.sparxeng.com/blog/software/higher-kinded-fun-in-.... (Granted, I've never had a use for that beyond code golf).

And C# is nice because you can await anywhere in an expression instead of just at a "let!" declaration. This is something I do miss when using F#.

But agreed, F# is usually my language of choice.


I think the Haskell abstraction is what allows monad transformers. Saw some hacks in F# to allow similar, but you lose generic "lift", for instance.


More precisely, I was referring to monads and do-notation with that phrase.

Here are some references on when it was invented / implemented: https://www.reddit.com/r/haskell/comments/8rkrgq/when_was_do...

Also a JS gist on async/await and do-notation: https://gist.github.com/MaiaVictor/bc0c02b6d1fbc7e3dbae838fb...


promises, futures, etc... are much older - it takes 15 years for stuff pioneered in research to make it into general purpose langs :p

- https://d1wqtxts1xzle7.cloudfront.net/50657913/p260-liskov.p...

- http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.97....


Even though the concepts weren't invented for C#, you are technically correct in that C# pioneered the keywords async and await.


But since industries used Haskell, now they are concerned with backward compatibility, which AFAIK makes some parts of Haskell ugly. I wish there would be something like RHEL/Fedora model rather than letting Simon Peyton Jones being dictated by industry by ceding towards backward compatibility.


> It's not as good and polished as rust's cargo but it's ahead several other languages.

Until cargo supports sharing of binary crates it isn't as polished as I care about.

All the languages I use, except for scripting languages, support distribution of binary artifacts, including Haskell.


> prelude has unsafe functions (eg. head),

`head` is not unsafe, it is a partial function. An unsafe function can lead to u.b.; the behavior of `head` on an empty list is very much defined. Haskell is not a total language.


As an aside -- Rust's definition of "unsafe" (e.g. "can lead to u.b.") is not the only definition of unsafe one can use for a programming language, which can have different safety guarantees.

As a motivating example, in many languages converting a reference to an integer containing a memory address is unsafe (e.g. Java[1]/golang[2]/C#[3]/Haskell[4]), but this is considered safe in Rust.[5] All these languages literally use the word "unsafe" for it.

[1]: See sun.misc.Unsafe, which indirectly provides this https://stackoverflow.com/a/7060500/315936

[2]: https://golang.org/pkg/unsafe/#Pointer

[3]: pointer types are only allowed with the unsafe keyword, see: https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...

[4]: I believe this requires unsafeCoerce https://stackoverflow.com/a/18563789/315936

[5]: https://doc.rust-lang.org/reference/unsafety.html


I think in all these cases unsafe actually means 'leads to UB'.

Converting a pointer to an integer address is problematic if you have a garbage collector due to compacting. Technically it's still the dereferencing that actually causes the UB, but I don't think this is too much of a leap.

C# marking all pointers unsafe also makes sense in the same way, because "passing pointers between methods can cause undefined behavior."


I agree, I'm just pointing out that not all languages have the same safety model, even if they are similar.

Converting a pointer to an integer address and never dereferencing it (e.g. to print it) does not lead to U.B., but it does leak ASLR information. Some languages consider that safe (Rust) and others do not. I think that is in an important distinction.


It is Haskell's definition, however.

All functions that have `unsafe` as part of their name have it because they can lead to u.b. with improper use.


Is it? The definition I see in the GHC docs seems to be broader than that: https://downloads.haskell.org/ghc/latest/docs/html/users_gui...

Regardless, I agree the function under discussion though, "head", is not "unsafe" in either sense. That's why I said "as an aside".


Thanks for the correction, changed to exception-throwing - that's the behaviour I don't like


I think it's worth pointing out that your values[0] may not align with Haskell's values. That's absolutely fine, but it doesn't mean that Haskell is "bad" in some objective sense.

AFAICT, most of your 'complaints' would apply equally to, say, Java or C#.

[0] I can't recall which exact presentation it was, but Bryan Cantrill had a brilliant segment on this in one of them. Perhaps others around here can remember?


> I can't recall which exact presentation it was, but Bryan Cantrill had a brilliant segment on this in one of them. Perhaps others around here can remember?

I think that's his discussion of language values in "Rust and Other Interesting Things" at Scale By The Bay 2018. https://www.youtube.com/watch?v=2wZ1pCpJUIM

[edit: This talk is also titled "Platform values, Rust, and implications for systems software". I'm not sure which title is preferred.]


Yup, sounds about right. That was an excellent insight from him.


They didn’t argue that it was “bad in some objective sense”, they pointed out a feature in Haskell that they specifically don’t like. Unless you consider Haskell to be a perfect language, discarding an opinion that was labeled as exactly that seems silly to me. Especially with such a broad strokes “love it or leave it” reply...

Those complaints apply to those languages too, yes. What’s your point here?


I may have overreacted to the title of the blog post and carried that over to the post I replied to :). That's my bad.




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

Search: