This EEP adds assignments to comprehension qualifier lists, providing a convenient and readable alternative to other syntactical tricks.
It would often be useful to be able to easily bind variables in the qualifier sequence of a comprehension, for example:
[Z || X <- Ls,
{foo, Y} = g(X),
Z <- f(Y, h(Y))].
using plain Pattern = ...,
entries between qualifiers.
You can do this today by writing a singleton generator:
[Z || X <- Ls,
{foo, Y} <- [g(X)], % produce single element
Z <- f(Y, h(Y))].
but this has some drawbacks:
Another trick is to piggy-back on a boolean test, using export of bindings from within a subexpression to propagate to the subsequent qualifiers:
[Z || X <- Ls,
is_tuple(Y = g(X)),
Z <- f(Y, h(element(2,Y)))].
which is very much not a recommended style in Erlang, making it hard to see where the bindings come from. It also relies on having a suitable test as part of the qualifiers for the value you want to bind. If you don’t, it is possible to invent a dummy always-true test:
[Z || X <- Ls,
foobar =/= (Y = g(X)),
Z <- f(Y, h(Y))].
Such tricks are very bad for readability and maintenance of the code, making the logic hard to follow.
It is in fact already allowed syntactically to have a Pattern = ...
match expression in the qualifiers. This however gets interpreted as
any other expression - thus expected to produce a boolean value - and
if false
, the current element will be skipped.
Hence, any qualifier following after a match Var = Expr
will only be
executed if Var
has the value true
. We can therefore expect that
no such uses exist in practice, because Var
would be fully
redundant. (The OTP code base has been checked and does not contain
any.) To avoid incompatibilities with any possible existing code that
relies on the current behaviour, the new semantics can be implemented
as an optional feature at first, and an error be reported for such
assignments when the feature flag is not enabled.
The main change needed is then for the compiler to detect a match
expression Pattern = Expr
in the qualifier list, and treat it as a
strict singleton generator Pattern <-:- [Expr]
.
A reference implementation exists in the
lc-match-operator
branch of the author’s GitHub account, together with a
GitHub pull request to the Erlang/OTP repository.
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.