Skip to content

Commit

Permalink
add example and fix typo
Browse files Browse the repository at this point in the history
  • Loading branch information
lucioleKi committed Oct 10, 2024
1 parent 71cf040 commit 93182c6
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions eeps/eep-0073.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ resulting list has length 4 when the two input lists both have length 2.
In contrast, parallel list comprehension (also known as zip comprehension)
evaluates qualifiers (a generalization of lists) in parallel. Qualifiers are
first "zipped" together, and then evaluated. Many functional languages
([Haskell][2], [Racket][3], etc.) and non-functional languages (Python etc.) support
this variation. Suppose the two lists in the example above are evaluated as
a zip comprehension, the result would be `[{1,3}, {2,4}]`.
([Haskell][2], [Racket][3], etc.) and non-functional languages (Python etc.)
support this variation. Suppose the two lists in the example above are
evaluated as a zip comprehension, the result would be `[{1,3}, {2,4}]`.

Zip comprehensions allow the user to conveniently iterate over several lists
at once. Without it, the standard way to accomplish the same task in Erlang
Expand All @@ -54,11 +54,33 @@ can be mixed freely with all existing generators and filters. Zip comprehension
then becomes a special case of comprehension where only zip generators are
used.

In summary, zip generator removes the user's need to call the zip function
and allows for any number of lists to be zipped at once. It can be used in
list, binary, and map comprehensions, and mixed freely with all existing
generators and filters. Internally, the compiler does not create any
intermediate data structure, therefore also removing the need of deforestation.
Within the OTP codebase, there are many uses of `lists:zip` within comprehensions.
All of them can be simplified by zip generators using `&&` syntax. For example,
The `yecc.erl` in parsetools contains the following comprehension (external
function calls and irrelevant fields redacted for readability):

PartDataL = [#part_data{name = Nm, eq_state = Eqs, actions = P, states = S}
|| {{Nm,P}, {Nm,S}, {Nm,EqS}} <-
lists:zip3(PartNameL, PartInStates, PartStates)].

When using zip generators, the comprehension is rewritten to:

PartDataL = [#part_data{name = Nm, eq_state = Eqs, actions = P, states = S}
|| {Nm,P} <- PartNameL && {Nm,S} <- PartInStates && {Nm,EqS} <- PartStates].

By using zip generators, the compiler avoids the need to build the intermediate
list of tuples. Variable bindings and pattern matching within a zip generator
works as expected, as `Nm` is supposed to bind to the same value in `{Nm,P}`
and `{Nm,S}`. If the binding fails, then one element from each of the 3
generators is skipped. (If a strict generator is used, then the comprehension
fails with exception `badmatch`, as specified in EEP-70.)

In summary, zip generators remove the user's need to call the zip function
within comprehensions and allows for any number of lists to be zipped at once.
It can be used in list, binary, and map comprehensions, and mixed freely with
all existing generators and filters. Internally, the compiler does not create
any intermediate data structure, therefore also removing the need of
deforestation.

Specification
========================
Expand Down

0 comments on commit 93182c6

Please sign in to comment.