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

CGS <>
Tue Sep 20 16:13:14 CEST 2011


Hi Jesper,

Can you explain why length is a bad idea? I do not deny that matching left
and right expressions is also a solution, but I see no difference. So,
please, if you know a bug about length, I am interested in knowing about.

-------------------
> 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.
-------------------

Please, take a better look and you will notice I haven't used guarded
function for recursion, but for condition. What you said is okay for
recursion.

In addition, I didn't say that was the best way to do it, but just an
example. Jovi needed an example and I gave. I am sorry if my code offended
you so much to call it "garbage". Feel free to propose the best working idea
for this case.

Cheers,
CGS




On Tue, Sep 20, 2011 at 3:45 PM, Jesper Louis Andersen <
> wrote:

> On Mon, Sep 19, 2011 at 08:26, George Catalin Serbanut
> <> 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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110920/65185529/attachment.html>


More information about the erlang-questions mailing list