Binary comprehensions

Per Gustafsson per.gustafsson@REDACTED
Mon Aug 23 14:55:29 CEST 2004


I think it would be useful to have binary/list comprehension mixes as well
for example:

[X || HalfWord:16 <- HalfWordBin>>

That would work like binary_to_list but instead of taking 8 bits per
element it would use 16, filters

<<tofloat(X):64/float|| X <- List]

I believe that both these constructions can be implemented efficiently
as well as the binary comprehensions. Particularily for the special case
when the size of the resulting binary is known at compile time. When this
is not the case a rather complex solution would probably be necessary
particularily as garbage collections might be necessary during the
construction of the binary.

The binary_to_list comprehension would probably be the easiest one to
implement. I think it might even be possible to implement it something
like this

if we have

[f(X) || X:N/integer <- Bin, filter(X)]

we could write that as:

transform(Bin, N) ->
  Size = size(Bin),
  InPos = Size*8-N,
  Rest = 0,
  transform(Bin, N, InPos, Rest, []).

transform(Bin, N, InPos, Rest, Acc) when InPos > 0 ->
  <<_:InPos, X:N, _:Rest>> = Bin,
  if
    filter(X) ->
      transform(Bin, N, InPos-N, Rest+N, [f(X)|Acc]);
    true ->
      transform(Bin, N, InPos-N, Rest+N, Acc)
  end;

transform(Bin, N, 0, Rest, Acc)  ->
  <<X:N, _:Rest>> = Bin,
  if
    filter(X) ->
      [f(X)|Acc];
    true ->
      Acc
  end;

This is reasonably efficient even though a lot of extra work is done in
each iteration to extract X. Doing something similar for the
list_to_binary comprehension would be very inefficient as it would require
us to rebuild the entire binary in each iteration.


On Thu, 12 Aug 2004, Jay Nelson wrote:

> Has anyone requested binary comprehensions?  Something like the following:
>
> {ok, FileInput} = file:read_file("example.txt"),
>
> Lowercase = << downcase(Char) || Char <- FileInput >>,
> Printables = << R || R <- Lowercase, R > 32 >>,
> HexNybbles = << integer(Byte) || Byte:4/binary <- FileInput >>,
> Inverse = << flip(Bit) || Bit:1/binary <- FileInput >>,
> ...
>
>
>
> Has the following restriction been lifted?
>
> |Size| must be an integer literal, or a previously bound variable. Note
> that the following is not allowed:
>
> foo(N, <<X:N,T/binary>>) ->
>   {X,T}.
>
>
>




More information about the erlang-questions mailing list