[erlang-questions] How erlang handle complicated data structure like C?

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Tue Sep 20 15:45:18 CEST 2011


On Mon, Sep 19, 2011 at 08:26, George Catalin Serbanut
<cgsmcmlxxv@REDACTED> wrote:
> Considering all variables integers, here is an example how to play with
> records:

I'll move the quotes around a bit...

> 7. How to use the test:
> receive_function(Packet) when is_my_record(Packet) == true ->
> do_something_with_my_packet;
> receive_function(Packet) when is_my_record(Packet) /= true -> I_do_not_care.

You can't do this in Erlang. Guard expressions are limited so you can
be sure they terminate.

> 6. Binary tester:
> is_my_record(Binary) ->
>     L = re:split(binary_to_list(Binary),?SEPARATOR,[{return,list}]),
>     if length(L) == 3 -> Result = lists:all(fun(E) -> TL =
> string:join(string:tokens(E,"0123456789"),""), if length(TL) == 0 -> Result
> = true; length(TL) /= 0 -> Result = false end, Result end,L),
>        length(L) /= 3 -> Result = false,
>     end,
>     Result.

This part can be done much more beautifully. length is generally a bad
idea when a match will do:

is_my_record(B) ->
  case re:split(binary_to_list(B), ?SEP, [{return, list}]) of
     [A, B, C] = L ->
       lists:all(fun(E) -> string:join(string:tokens(E,"0123456789"),
"") == [] end, L);
     _ -> false
  end.

I'd probably write (not tested, subject to infinite failure):

is_digit(C) when C >= $0 andalso C =< $9 -> true
is_digit(C) -> false.

all_digits(B) when is_binary(B) -> all_digits(binary_to_list(B)); %
Building a traverser over binaries will be faster
all_digits(L) -> lists:all(fun is_digit/1, L).

is_my_record(B) ->
  case binary:split(B, <<?SEP>>, [global]) of
    [A, B, C] = L -> lists:all(fun all_digits/1, L);
    _ -> false
  end.

all_digits/1 is inefficient. But we can write:

all_digits(F, <<>>) -> true;
all_digits(F, <<C:8/integer, R/binary>>) ->
  F(C) andalso all_digits(F, R). % I can't remember if andalso is tail
recursive. It should be. If not, replace this with a case.

This avoids the creation of lots and lots of garbage. It also avoids
the pesky re-library which is usually a bad idea :) And I believe it
is a tad more readable.

-- 
J.



More information about the erlang-questions mailing list