3 ms·
I don’t understand why javascript developers aren’t calling for comprehensions, like python/haskell (and standard mathematical set theory notation).
by da39a3ee 5y ago
I don’t understand why javascript developers aren’t calling for comprehensions, like python/haskell (and standard mathematical set theory notation).
- JoelMcCracken 5y agoPersonally I find list compressions in Haskell overrated. I never use them.
- da39a3ee 5y agoInteresting data point, my impression was that they were used quite a bit in Haskell but I’m no expert. They are ubiquitous in Python, providing an extremely expressive means to construct lists, sets, maps, and generators. JS map and filter are exceedingly crude and unergonomic in comparison. Rust does it with a sophisticated iterator API.
- JoelMcCracken 5y agoThey seem to be used mostly in like beginner tutorials as examples of crazy cool stuff haskell can do. I actually just recently saw it in production code for the first time and was like "whaaaat is that?" It had been so long since I saw one that I didn't recognize it at first. The thing is, usually in real haskell code you aren't going to be using something that is roughly like set builder notation. Well at least, I haven't seen many scenarios where its needed. You're pulling data from someplace, manipulating it, etc, and then sending it somewhere else. That's not to say that I'm absolutely correct on this or whatever. But to me, overall I think Haskell syntax is far too complex and has too many special cases, and given list comprehensions are exactly equivalent to doing the same thing via the list monad, I'd prefer they be gone. I fear that someday we'll collectively need to replace GHC, and each and every weird edge case just means that its that much more of a giant task when that day comes.
- da39a3ee 5y ago> You're pulling data from someplace, manipulating it, etc, and then sending it somewhere else. Like this? stream = (manipulate(item) for item in producer_stream() if passes_filters(item)) consumer(stream)
- JoelMcCracken 5y agoof course, but its more normal to do: fmap manipulate $ filter passes_filters producer_stream And GHC has list fusion rules in this case (not sure if they exactly apply for list comprehensions; they probably do, but i'm not certain of that.) so IIRC the xyntax in haskell syntax your example would be smth like: [ manipulate x | passes_filters x, x <- producer_stream ] which is transformed to: do x <- producer_stream guard (passes_filters x) manipulate x Which I believe does not have the same run-time performance as my fmap/filter example; even if it does, I'm just saying I don't see it often, and its not idiomatic. Its different in python though because, well, python is more cursed.
- tome 5y agoI think you probably want `pure (manipulate x)` at the end of your do block.
- JoelMcCracken 5y agoYa could be. It depends upon the type of manipulate really. Thanks.
- da39a3ee 5y agoRight, thanks. Don't get me wrong, I like Haskell (though haven't got good at it yet; keep getting lost somewhere between fmap and applicatives/monads). However, I prefer the comprehension and `do` version over your `fmap` expression. The reason is that I think that filtering and transforming a stream is sufficiently common/important that a language should provide declarative syntax / a DSL for it. Whereas your `fmap` version makes too many implementation details explicit: all that should be needed is for the programmer to say "lazily filter and transform these values". I think it would be ideal for the programmer not to have to worry about `fmap` and `$`, and I think the expression should read more naturally than your fmap example. The Python and Haskell comprehension versions pass the "read naturally" test very well: "create a set/stream of manipulated items where the items pass the filter". The Haskell `fmap` version reads as "apply the manipulate function to a functor where, oh by the way the functor is a kind of list, and oh by the way use $ to separate arguments in this expression, but as I was saying do that but filter the list first". EDIT: I don't mean to imply that I know how Haskell should be written, I defer to you; the sophistication of Haskell's functor-related abstractions is such that I bet you're right that the special case syntax of a comprehension is kind of an annoying presence in the language (but that still leaves two ways to do it?). But, we were talking about javascript and there I think it makes a lot of sense to give the world a way to construct collections declaratively.