List/binary comprehensions

List/binary comprehensions are supported as macros. The syntax for list comprehensions is:

(lc (qual  ...) expr ... )

where the final expr is used to generate the elements of the list.

An alias is provided such that the following is also valid:

(list-comp (qual  ...) expr ... )

The syntax for binary comprehensions is:

(bc (qual  ...) expr ... )

where the final expr is a bitseg expr and is used to generate the elements of the binary.

An alias is provided such that the following is also valid:

(binary-comp (qual  ...) expr ... )

The supported qualifiers, in both list/binary comprehensions are:

Form Notes
(<- pat {{guard}} list-expr) Extract elements from a list expression
(<= bin-pat {{guard}} binary-expr) Extract elements from a binary/bits expression
(?= pat {{guard}} expr) Match test and bind variables in pat
expr Normal boolean test

Some examples:

(lc ((<- v (when (> v 5)) l1)
     (== (rem v 2) 0))
  v)

That returns a list of all the even elements of the list l1 which are greater than 5.

(bc ((<= (f float (size 32)) b1)  ; No wrapping, only bitseg needed
     (> f 10.0))
  (io:fwrite "~p\n" (list f))
  (f float (size 64)))            ; No wrapping, only bitseg needed

That returns a binary of floats of size 64 of floats which are larger than 10.0 from the binary b1 and of size 32. The returned numbers are first printed.

NOTE: A word of warning when using guards when extracting elements from a binary. When a match/guard fails for a binary no more attempts will be made to extract data from the binary. This means that even if a value could be extracted from the binary, if the guard fails, this value will be lost and extraction will cease. This is NOT the same as having following boolean test which may remove an element but will not stop extraction. Using a guard is probably not what you want!

Normal vanilla Erlang does the same thing but does not allow guards.