Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EEP 78: Multi-valued comprehensions #75

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

michalmuskala
Copy link
Contributor

TL;DR: This EEP proposes enhancing the comprehension syntax to allow emitting multiple
elements in a single iteration of the comprehension loop - effectively enhancing
comprehensions to implement flatmap with a fixed number of elements, for example:

[X + 1, X + 2, ... || X <- Xs]

@elbrujohalcon
Copy link

Not as a criticism, just out of curiosity… What will these expressions evaluate to?

[ Z = binary_to_integer(X), Z || X <- [<<"1">>, <<"2">>, <<"3">>] ].
%% My guess: [1, 1, 2, 2, 3, 3].
[ hello, goodbye || true ].
%% My guess: [hello, goodbye].
#{hello => Hello = hello, Hello => goodbye} || true }.
%% My guess: #{hello => goodbye}.

Maybe you can even add some of them as tests in erlang/otp#9374

@michalmuskala
Copy link
Contributor Author

The first expression will be an error:

test.erl:6:31: variable 'Z' is unbound
%    6|   [ Z = binary_to_integer(X), Z || X <- [<<"1">>, <<"2">>, <<"3">>] ].
%     |                               ^

Similar how it would be in a plain list [X = binary_to_integer(~"1"), X].

The second will indeed yield as you expected:

3> [ hello, goodbye || true ].
[hello,goodbye]

The third will again error with Hello variable undefined:

test.erl:6:29: variable 'Hello' is unbound
%    6|   #{hello => Hello = hello, Hello => goodbye || true }.
%     |                             ^

The same would happen if you tried this with a plain map #{hello => Hello = hello, Hello => goodbye} won't compile.

In other words, similar to all "containers" expressions are evaluated "in parallel" not "in sequence" as far as variable scoping is concerned.

@Maria-12648430
Copy link
Contributor

Hm, there is an unconvenient limitation, namely that it is not possible to decide if something should be inserted once, twice, thrice etc, or not at all (yes, that can and still has to be done with filters). That is, with the proposed syntax, it is only possible to add elements a fixed number of times, which IMO puts a severe limitation on the ergonomics the extension would otherwise provide.

That said, I also find it somewhat confusing. It looks like a set of expressions where, everywhere else, the last would be the result, but here the result of each expression is inserted.

@elbrujohalcon
Copy link

That said, I also find it somewhat confusing. It looks like a set of expressions where, everywhere else, the last would be the result, but here the result of each expression is inserted.

I guess you should think of it as the list of expressions at the "head" of a cons operator…

1> [1, 2, 3 | lists:seq(4, 10)].
[1,2,3,4,5,6,7,8,9,10]

I presume that's what @michalmuskala was using as inspiration.

@Maria-12648430
Copy link
Contributor

I guess you should think of it as the list of expressions at the "head" of a cons operator…

Ok, makes sense :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants