(Digression: I did not find ânon-skippingâ to be a helpful way to describe it, because I have never thought of the existing constructions as âskippingâ. Iâm using error-on-mismatch here as being understandable in its own right without reference to what any other form of generator does.)
This is a very valid point. When I first thought about the problem, I used the term âfilteringâ, because a comprehension contains generators and filters, and the current generators also act as an implicit filter when they contain patterns. I switched to the term âskippingâ during implementation, because the compiler calls the respective clause of the generated anonymous fun the skip clause. But this name is completely internal to the compiler, so it would be easy to change to something that makes sense to users.
it has long been âintuitiveâ to me that IF you are allowed to put patterns in a generator at all, then you OBVIOUSLY want candidates that donât match those patterns to be silently passed over
For me at least this is not intuitive at all. It isnât even documented how generators with patterns treat non-matching elements. For the very least this should be documented, but I believe having a different kind of generator that errors on non-matching elements would be even better, because nobody reads the fine print in the documentation, but I hope most people at least remember what operators are in a language. And once you remember that there are two different generators, but you donât remember what the difference is, than at least the problem became a known-unknown for you, which is much better than an unknown-unknown.
But wanting more than one kind of arrow, and distinguishing between them in a way that is NOT done elsewhere in the language, no. That just makes things harder to understand.
I think that ship has long sailed, Erlang already uses ->
, <-
, =>
, <=
and :=
, not to mention <<
and >>
which also sort of look like arrows. And it doesnât make things hard to understand. If you donât like the proposed <:-
and <:=
arrows (or my original proposal of <-:-
and <=:=
, which by the way are not random character sequences, the :
was chosen to represent a match, similar to how =:=
is a test for matching vs. ==
which is not), please propose something better! But just introducing a new arrow that can be used in a specific context wonât make the language too hard to understand. Just look at how the maybe
expression introduced the ?=
operator, without exploding Erlangâs complexity.
Letâs agree that EEP 70 thinks that the problem is the way existing Erlang list comprehensions work.
EEP 70 doesnât actually change that.
Yes, it intentionally avoids messing with existing comprehensions. Adding new language elements instead of changing the semantics of existing ones gives us backward compatibility, and makes it easier to read the code (if you encounter syntax that you havenât seen before, you can go and check in the docs; if you encounter syntax that unknowingly to you changed its semantics, youâll just be very confused). Both of these are desired properties.
It doesnât change all the training material in existence, like LYSE, which points people to the current syntax.
This is not an argument against EEP 70, itâs an argument against any kind of change. Also, pretty much out of scope for an EEP.
And it doesnât make the new syntax easier to use than the old.
Unfortunately, this is true, because the new operators will be longer than the old ones. But this will be just one more entry on the long list of language elements where the thing you typically want is not the thing that is easiest to type. See ==
vs. =:=
in Erlang, or ==
vs. ===
in Javascript, or C requiring you to mark const
arguments instead of mutable ones etc.
Just how many people will find the new syntax useful enough to adopt?
Remember, it doesnât let you DO anything you couldnât do before.
It doesnât make it EASIER to do something you could do before.
It doesnât make your code FASTER.
I respectfully disagree. I just want to cite my example: writing [{User, Email} || #{user := User, email := Email} <:- all_users()]
is definitely easier and faster than typing out a lists:map/2
call with an anonymous function and whatnot. (And one may even argue that since the comprehension compiles into a fun that will only use local calls and just one call per element, it will be faster than the one local call + one qualified call per element lists:map/2
.)