Module listcomp

Authors: Serge Aleynikov (saleyn(at)gmail(dot)com).

Description

Erlang map-reduce parse transform

This transform introduces two modifications of the list comprehension syntax that allow to perform a fold and mapfold on a list.

Indexed List Comprehension
This extension of a list comprehension, passes an additional argument to the left hand side of the comprehension, which is the index of the current item in the list:
   [ io:format("Rec#~w: ~p\n", [I, N]) || I, N <- L]
                                          ^^
   ```
   The index is defined by the a variable listed after the `||' operator.
   This is equivalent to the following:
   ```
   lists:mapfoldl(
     fun(N, I) ->
       io:format("Rec#~w: ~p\n", [I, N]),
       I+1
     end, 1, L)
   ```
  
   === Fold Comprehension ===
  
   To invoke the fold comprehension transform include the initial state
   assignment into a comprehension that returns a non-tuple expression:
   ```
   [S+N || S = 1, N <- L].
    ^^^    ^^^^^
In this example the S variable gets assigned the initial state 1, and the S+N expression represents the body of the fold function that is passed the iteration variable N and the state variable S:
   lists:foldl(fun(N, S) -> S+N end, 1, L).
Fold comprehension can be combined with the indexed list comprehension:
   [running_sum(I, N, S+N) || I, S=5, N <- L].
  
   running_sum(I, N, RunningSum) ->
     io:format("Rec#~w: ~p (~w)\n", [I, N, RunningSum]),
     S.
In this case the definition of the indexed fold comprehension would be transformed to:
   element(2, lists:foldl(fun(I, {N, S}) ->
     running_sum(I, N, S), {N+1, S+N} end, {1,5}, L)),

Compilation

When using this as a parse transform, include the {parse_transform,listcomp} compiler option.

For debugging the AST of the resulting transform, pass the following options to the erlc compiler:
  • -Dlistcomp_orig - print the original AST before the transform
  • -Dlistcomp_ast - print the transformed AST
  • -Dlistcomp_src - print the resulting source code after the transform
  • Function Index

    foldl/3Fold over a list by additionally passing the list's current item number to the folding fun.
    foldr/3Fold over a list by additionally passing the list's current item number to the folding fun.
    parse_transform/2parse_transform entry point.

    Function Details

    foldl/3

    foldl(Fun ::
              fun((Position :: integer(),
                   Item :: term(),
                   Acc :: term()) ->
                      NewAcc :: term()),
          Init :: term(),
          List :: list()) ->
             term()

    Fold over a list by additionally passing the list's current item number to the folding fun. This function is similar to lists:foldl/3, except that the fun takes the extra second integer argument that represents the sequential number of the item from the list.

    foldr/3

    foldr(Fun ::
              fun((Position :: integer(),
                   Item :: term(),
                   Acc :: term()) ->
                      NewAcc :: term()),
          Init :: term(),
          List :: list()) ->
             term()

    Fold over a list by additionally passing the list's current item number to the folding fun. This function is similar to lists:foldr/3, except that the fun takes the extra second integer argument that represents the sequential number of the item from the list.

    parse_transform/2

    parse_transform(AST, Options) -> any()

    parse_transform entry point