Live data from Hacker News

Pain Points of Haskell

dixonary.co.uk

251–260 of 322 posts

Re: Pain Points of Haskell

#251

Earlier quoted context omitted.

The exact quote and source (powerpoint slides) are in this HN comment: https://news.ycombinator.com/item?id=1924061 . See also the insightful comment of plinkplonk on that thread.

That's the "Wearing the Hair Shirt" talk, for those that are familiar. " Purity is more important than, and quite independent of, laziness " The next ML will be pure, with effects only via monads. The next Haskell will be strict, but still pure. " Still unclear exactly how to add laziness to a strict language. For example, do we want a type distinction between (say) a lazy Int and a strict Int? " From plinkplonk: " I…

> The next ML will be pure, with effects only via monads

Which has already been proven wrong, by the way, by F#, which appeared in 2005 ("Wearing the hair shirt" was from 2003), so I think the comment is not to be taken too literally.

https://www.microsoft.com/en-us/research/publication/wearing...

Re: Pain Points of Haskell

#252

As a guy who casually (definitely not in-depth) reviewed working with Haskell about 2 years ago I'd say the most relatable part of the article to me is: complexity in tooling and unnecessary tension when working with libraries. Also the String situation (several types of them). A lot of the other points could be addressed but the community's seeming unwillingness to tackle everyday productivity sends to me the messag…

> complexity in tooling and unnecessary tension when working with libraries

Yep. I’m currently feeling this. I’m thankful I’m not a complete beginner and thankful for the Haskellers that blog their opinionated experiences. But this is such a roundabout way of learning.

It’s also almost unfair to compare things to Rust’s Cargo (and Elixir’s Mix). They set the bar pretty high IMO.

Haskell would be more widely used if the ecosystem was more cohesive (perhaps a bit more centralized).

I’ve been enjoying Haskell enough that I’d like to help improve things.

Re: Pain Points of Haskell

#253

Earlier quoted context omitted.

The reply by louthy is great, but it doesn't answer your first question: > What is referential transparency? A function reference that can be replaced at all call sites in a program with its body with all of the references to its arguments replaced with references to the call site arguments without the observable behavior of the program changing is referentially transparent. In practice, it means that you can safely…

Monad is really just "flatMap"? Is this basically it then: interface Monad { flatMap: (arg: Some ) => Maybe } let userAges: Monad.flatMap = flatMap (users, user => user.age)

Yep. You got it. Monads are compared with value equality, not reference equality below. The flatMap behavior has to obey some laws:

The Associative Law states that flatMapping two functions in sequential order is the same as flatMapping over a composition of those two functions:

Monad(fa).flatMap(f).flatMap(g) valueEquals Monad(fa).flatMap(g(f))

It also has a method called return/point/pure that comes from the inherited Applicative interface:

   interface Applicative> {
     pure: (arg: A): F
   }
That return/pure/point followed by flatMap has to obey the Left Identity law in a monad for it to be a valid monad:

  Monad(fa).pure(x).flatMap(f) valueEquals f(x)
The Right Identity law states that if we have a Monadic value and flatMap over the point/pure/return method we get a new monad that has value equal to the original monad:

m = Monad(fa) Monad(fa).flatMap( (v) => Monad(fa).pure(v)) valueEquals m

Those are your unit tests that you have to perform on your monad instances. If they pass, your implementation is correct, and you can rely upon it.

These laws are so that the monad interface can be composed/extended correctly with other referentially transparent interfaces, like Functor -provides map, the map must be associative, like flatMap); Apply extends Functor - provides ap, or applyParallel that allows parallel mapping over collections that can be safely parallelized. ap has to be consistent with flatMap when an implementation has a monad instance -- that is if you map over a list in parallel, the list you get out should be the same as if you flatMapped over that same list using the same function, but wrapping List() around the result, which is sequential; Applicative extends Apply - provides pure/point/return, which just constructs instances that are Applicatives from a given value; Semigroup - provides combine/concat/++, allowing two items of the same type to be combined into a new value of that type; There may be many instances for a type of semigroup (Boolean has && and || for example); Monoid extends Semigroup - provides empty, which is a value for a type when combined with another value for that type results in the other value (0 in integer addition, for example, an empty list in list concatenation, for another); traverse - provides sequence, which flips the types of wrapped values (Maybe> becomes List> when sequence is called), traverse,F, A, B>(ga: G)(f: A => F): F> -- used to define sequence, foldRight, foldMap, foldLeft, etc; And ApplicativeError - provides raiseError, A,ERRORTYPE>(t: ERRORTYPE): F and handleError, A>(fa: F)(f: ERRORTYPE => A) and catchNonFatal, ERRORTYPE, A>(f: () => A):F -- obviously these only work if your type has two members, one for success, and one for failure.

Re: Pain Points of Haskell

#254
post #244

Earlier quoted context omitted.

> finally integrate it in the ide that you are currently using. I am using IntelliJ IDE with the Haskell plugin and apparently I am out of luck because it is not listed. Well, is it an IDE that supports LSP? If so, it should just work. If not, then ghcide won't work with it. Providing a language server is the whole point of what it does!

There is a LSP plugin for IntelliJ but it is not very stable. But that was not my point: maybe I'm spoiled because I'm coming from the JVM universe, but I don't agree that ghcide installation is easy. For me, "easy" means running an installer or invoking homebrew, and continue being productive.

Yes, fair enough. There's a lot of scope for making it easier :)

Re: Pain Points of Haskell

#255
post #236

Earlier quoted context omitted.

Sure, but those that are willing to because they're sufficiently excited about the language means you can have a higher confidence in your hires, since they, A. Know what Haskell is, B. Want to learn it, C. Are willing to take a pay cut to be able to get paid to learn/use it. Very high signal to noise I'd wager. If you're a Java shop, you better be paying higher than market rate if you want to be able to attract good…

Well yeah, it seems you're reiterating that it's great for employers, not for employees. I don't disagree. Of course if Haskell somehow takes off and all the FANG companies want to hire as many Haskell engineers as they can, then the situation would probably reverse.

I'm more calling out that it's mutually beneficial; the employees choosing that tradeoff are still choosing that tradeoff. The other tradeoff, work for a higher compensated position in a language that they hate, isn't objectively "better", just different.

Re: Pain Points of Haskell

#256

As a guy who casually (definitely not in-depth) reviewed working with Haskell about 2 years ago I'd say the most relatable part of the article to me is: complexity in tooling and unnecessary tension when working with libraries. Also the String situation (several types of them). A lot of the other points could be addressed but the community's seeming unwillingness to tackle everyday productivity sends to me the messag…

> complexity in tooling and unnecessary tension when working with libraries Yep. I’m currently feeling this. I’m thankful I’m not a complete beginner and thankful for the Haskellers that blog their opinionated experiences. But this is such a roundabout way of learning. It’s also almost unfair to compare things to Rust’s Cargo (and Elixir’s Mix). They set the bar pretty high IMO. Haskell would be more widely used if t…

> Haskell would be more widely used if the ecosystem was more cohesive (perhaps a bit more centralized).

> I’ve been enjoying Haskell enough that I’d like to help improve things.

I am hatching an idea along these lines. How do I get in touch with you? Alternatively can email me at the address here if you like: http://web.jaguarpaw.co.uk/~tom/contact/

Re: Pain Points of Haskell

#257

Earlier quoted context omitted.

> I personally don't understand the hangup on the existence of an IDE. I don't understand the lack of a hangup. It's obvious from using an IDE to going back to a text editor. It hurts adoption, it hurts beginners, it hurts the ecosystem...ie disparate tools grouped with known interactions are not necessary to fully understand when creating a program, leave those details in the IDE as a simplified interaction (eg chec…

My point is there's no "lack" of tooling. Nowadays, the Haskell IDE engine is good enough for general use. It's pretty trivial to plug into every general-purpose editor. More and more beginners nowadays do not want to install a whole new IDE. They don't want to have to configure it, learn it, and understand all of its nuances and foibles. They prefer using their existing setup (VSCode, Atom, vim, emacs, etc.) with a…

There are a lot of tools, but last time I looked, they weren't particularly integrated, which is the point of an IDE. It doesn't have to be a haskell specific IDE, but there doesn't seem to be an intellij/pycharm/VS-for-some-languages equivalent experience anywhere to be found for haskell.

Re: Pain Points of Haskell

#258

Earlier quoted context omitted.

I fully grok monads. I’ve done enough reading and usage of them to understand them. They are not a useful abstraction for programming. They’re mathematically correct, but that’s not the same as what an industrial engineer needs. The big warning sign is monad transformers. Alone, monads are totally fine, but the issue is that you rarely want one . So you end up with this unwieldy tower of transformers that would make…

I firmly believe that monads (and monad transformers) are exactly what an industrial engineer needs, for the following important reason. A monad describes its scope in such a way that writing code outside of its scope is a compile time error. If your code needs certain capabilities, it must invoke the computational context of those capabilities (which is usually a monad in Haskell). If it doesn't, then the context ca…

I’ve been thinking recently about how monads in functional programming are analogous in some sense to inheritance in class-based object oriented programming. Each abstracts a useful pattern and lets the programmer write a certain type of code quite elegantly. Each is also profoundly limited by being based on a single type(class), i.e., the monadic structure or the base class/interface.

If you want to use multiple instances of the same pattern in the same place, you have to start making design choices about how to relate them. For example, you might nest monad transformers in a certain order. You might define a class hierarchy.

Sometimes the correct design will be dictated by the context. However, sometimes it won’t, and then you’ll have to make what is essentially an arbitrary decision at the time, yet one that may be expensive to change or adapt to if it turns out to be inconvenient later.

And finally, as long as everything stays nice and “linear” nothing too bad seems to happen, but in realistic programs you might end up needing to combine multiple monadic effects or wanting your class to inherit from multiple base hierarchies. That is often when awkward edge cases start creeping into the design. Suddenly, instead of the elegant patterns from the glossy brochure, you start seeing ugly and brittle warts like explicit casts to resolve ambiguities in which virtual method should be called or manual lifting through multiple layers of monadic effects.

In each case, the response has been to move away from the original patterns towards something more flexible where the compromises are not as deep. In OOP, composition tends to be favoured over inheritance these days. In languages like Haskell, there is a lot of interest in effect systems that could offer a less rigid way to combine monadic effects than monad transformer stacks.

Re: Pain Points of Haskell

#259
post #123

Earlier quoted context omitted.

for some reason you specifically ignore that it's not a complexity on top, but rather a trade-in.

That's irrelevant. OP simply said that lazy evaluation makes it harder to reason about time and space complexity. Everyone agrees with this, for goodness sake - even SPJ himself.

It is definitely not harder to reason about time. I don’t think you will find many haskellers agreeing with this.

Re: Pain Points of Haskell

#260

Earlier quoted context omitted.

The -XStrict language extension is a lifesaver here, for when you want a language like Haskell but without lazy evaluation.

Pretty much every time I turn -XStrict on for some module I'm trying to optimize, performance gets worse. Laziness gets a lot of flak for being hard to reason about. I disagree - it's just different. But I never hear anyone acknowledge that laziness can bring compositional performance benefits no other language can sniff.

That’s because full laziness is actually an optimization strategy that Haskell uses to make programs faster.

You are completely right about laziness being a big plus for composing functions.

Post reply on HN