They 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.
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.
Right, 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.
This is all just my POV too. I'm sure there are people out there who use list comprehensions all day every day. I just haven't seen them.
I tend to vastly prefer a small, beautiful, principled, "growable" language over one that has many builtin forms. e.g. Scheme. Because, as I said, each of these features just makes it harder for other implementations.
FWIW I also don't think it made sense for JS to get a pipeline operator; only reaosn I like those is when a language supports user-defined operators. But, anyway.
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.