Live data from Hacker News

How it feels to join an all-Haskell startup

wagonhq.com

41–50 of 59 posts

Re: How it feels to join an all-Haskell startup

#41
Habitually rewriting things in applicative and/or pointfree is a sure sign of a junior Haskell dev. One who has never had to maintain someone else's code.

There are cases where it helps (e.g. structured parsing), but all too often this is simply obfuscation. Even if motivation is good -- learning new structures -- you still have to focus on cost/benefit of each change in structure.

Keep it simple, folks.

Re: How it feels to join an all-Haskell startup

#42
post #17

Earlier quoted context omitted.

It's somewhat debatable whether the refactor is an improvement, but there is at least one good argument that it is, and (in my opinion) only a much poorer argument that it makes things less clear. If the applicative code is better, it's because applicatives are strictly less powerful than monads, in the sense that everything you can do with applicatives you can also do with monads, but not vice-versa. Many Haskellers…

> at this point Which is a huge problem. Optimizing around the current fashion is generally a mistake. As for the rest: the argument seems to come down to "there are no junior developers in Haskell, because if you don't understand the deep and dark abstractions you're really hardly better than a barbarian anyway." This translates to: Haskell is doomed as a production language in the real world beyond a few niche/feti…

> > at this point

> Which is a huge problem. Optimizing around the current fashion is generally a mistake.

I think this invokes the invention vs. discovery debate. There are many "design patterns" in Haskell, some of which might be regarded as clever inventions (for example conduits and pipes), in which case I agree that there's an element of "fashion" involved, which leads to incompatibilities and churn.

However, Monad and Applicative are clear examples of discoveries. Even if we try to write code without them, the pattern will still be lurking in there somewhere. Applicative is basically a "static" data-flow graph; ie. the graph is fixed, data flows through. Monad is a "dynamic" graph; parts of the graph can be generated from the data. These patterns will still be present, even if we use a completely different language.

Re: How it feels to join an all-Haskell startup

#43
post #41

Habitually rewriting things in applicative and/or pointfree is a sure sign of a junior Haskell dev. One who has never had to maintain someone else's code. There are cases where it helps (e.g. structured parsing), but all too often this is simply obfuscation. Even if motivation is good -- learning new structures -- you still have to focus on cost/benefit of each change in structure. Keep it simple, folks.

I'm generally in favour of introducing applicatives, but I don't think the code in the article is a good example:

    (bid, now)  randomIO
         getCurrentTime
The applicative code could be considered better, since it avoids one-shot variables. However, that's not the biggest smell with this code. To me, the problems are:

- Constructing-then-destructing a pair; is it really necessary?

- Use of `$`; is there a way to avoid having to alter the precedence?

- Combining two seemingly unrelated actions into one; `randomIO` should be completely uncorrelated to the current time, so why put them in the same action?

- Potential laziness issues; it looks like we're using the `(bid, now)` combination to ensure the two IO actions are executed together, but will they be? WHNF will give us `(_ , _)`; if we force `bid`, will `now` also be forced?

Not saying I have answers to these, but I would say those are more "smelly" than the do-notation with a return

Re: How it feels to join an all-Haskell startup

#44
post #23

How was that snippet an improvement to your coding style? The original was extremely clear, and now someone who reads your code has to understand what (,) and do. IMO this tendency for code golf one-upmanship is a huge detractor for anyone wanting to learn the language.

This to me is the biggest barrier to reading anyone else's Haskell code. It seems like it's always full of unfamiliar, ungooglable infix operators.

That is one point of having code reviews, to get everyone in a team or an organization to write (mostly) the same type of code.

Re: How it feels to join an all-Haskell startup

#46
post #37

Earlier quoted context omitted.

I feel that it's important to have code that is immediately readable and understandable, without requiring much context. Smalltalkers had it right: > If a system is to serve the creative spirit, it must be entirely comprehensible to a single individual. Imagine you're reading a musical score. Suddenly there's an unfamiliar symbol. Oh right, you need to turn to page 5 to figure out how it's defined. Oh no, it's define…

Sheet music is positively packed with unfamiliar, unpronouncable, ungoogleable squiggles. Imagin you're reading a musical score, with no fancy symbols, just a waveform of the sound you should produce. What could be simpler, you say?

[deleted]

Re: How it feels to join an all-Haskell startup

#47
post #23

How was that snippet an improvement to your coding style? The original was extremely clear, and now someone who reads your code has to understand what (,) and do. IMO this tendency for code golf one-upmanship is a huge detractor for anyone wanting to learn the language.

This to me is the biggest barrier to reading anyone else's Haskell code. It seems like it's always full of unfamiliar, ungooglable infix operators.

One of our Haskellers once tried to explain the bizarre internal consistency of the many Haskell's lens operators. It's basically just trolling in API form:

https://hackage.haskell.org/package/lens-3.8.5/docs/Control-...

Re: How it feels to join an all-Haskell startup

#48
post #41

Habitually rewriting things in applicative and/or pointfree is a sure sign of a junior Haskell dev. One who has never had to maintain someone else's code. There are cases where it helps (e.g. structured parsing), but all too often this is simply obfuscation. Even if motivation is good -- learning new structures -- you still have to focus on cost/benefit of each change in structure. Keep it simple, folks.

I'm generally in favour of introducing applicatives, but I don't think the code in the article is a good example: (bid, now) randomIO getCurrentTime The applicative code could be considered better, since it avoids one-shot variables. However, that's not the biggest smell with this code. To me, the problems are: - Constructing-then-destructing a pair; is it really necessary? - Use of `$`; is there a way to avoid havin…

Code review 4 lines: hundreds of comments

Code review 1000 lines: "Looks fine"

Re: How it feels to join an all-Haskell startup

#49
post #48

Earlier quoted context omitted.

I'm generally in favour of introducing applicatives, but I don't think the code in the article is a good example: (bid, now) randomIO getCurrentTime The applicative code could be considered better, since it avoids one-shot variables. However, that's not the biggest smell with this code. To me, the problems are: - Constructing-then-destructing a pair; is it really necessary? - Use of `$`; is there a way to avoid havin…

Code review 4 lines: hundreds of comments Code review 1000 lines: "Looks fine"

Well, my main comment is that the most pungent smells in this code depend on its context and what it's trying to achieve. If I encountered it, I would immediately look at the surrounding context and usage to see if it's a reasonable approach to the problem.

Without that context, all that can be done are superficial changes like monad/applicative; which in this case are very minor. In other words, the original code wasn't a bad approach to the problem; but is it solving the right problem?

Re: How it feels to join an all-Haskell startup

#50
post #10

How was that snippet an improvement to your coding style? The original was extremely clear, and now someone who reads your code has to understand what (,) and do. IMO this tendency for code golf one-upmanship is a huge detractor for anyone wanting to learn the language.

I was about to try to talk about the genuine elegance of Applicatives—and I'm more than happy to defend them in general—but then, yeah. In this instance, I'm not sure I'd be able to argue that the change was such a good choice. liftIO (liftA2 (,) randomIO getCurrentTime) Eh, I'm not sure I could defend it. I'd honestly probably actually do bid

It's worth noting that there's a small potential performance penalty to this if it's being called all the time and it's being lifted through a large transformer stack.
Post reply on HN