I agree with the illegal guard. The reason I put it that way was to cover two cases: receive internally or via TCP connection. Your observation is correct that such a guard doesn't work. Its sole purpose was to see the condition. I missed your point first time and I apologize.<br>
<br>About the length, it depends what you prefer: slower code, but smaller, or bigger code, but faster (I usually prefer to work with vectors even if they are more memory consumers, but I can insert very fast search algorithms and that is important for me at large lists). Maybe it's my style, but I start all the time with implementing the skeleton, after that I expand it and in the end I do optimizations. I think it's easy to guess why, so, not entering details. Nevertheless, this is about styles of implementing things.<br>
<br>Cheers,<br>CGS<br><br><br><br><br><br><div class="gmail_quote">On Tue, Sep 20, 2011 at 5:00 PM, Jesper Louis Andersen <span dir="ltr"><<a href="mailto:jesper.louis.andersen@gmail.com">jesper.louis.andersen@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">On Tue, Sep 20, 2011 at 16:13, CGS <<a href="mailto:cgsmcmlxxv@gmail.com">cgsmcmlxxv@gmail.com</a>> wrote:<br>
> Hi Jesper,<br>
><br>
> Can you explain why length is a bad idea? I do not deny that matching left<br>
> and right expressions is also a solution, but I see no difference. So,<br>
> please, if you know a bug about length, I am interested in knowing about.<br>
<br>
</div>length/1 is not wrong, but note that it has to traverse all of the<br>
list to come up with its answer. In our case, the list is fairly small<br>
(length/1 returns 3), so this may not matter. But for a large list,<br>
the call to length is going to be rather expensive. Contrast this with<br>
a match on the structure which is either [] or [_|_]. This match can<br>
be done simply by examining the head of the list. We don't have to<br>
traverse the list fully to get the answer.<br>
<br>
In general, a good idea is to prefer matching over calling length/1 if<br>
you are in doubt. It usually translates to simpler code. Another<br>
worthy point is that matching on lists avoids "Boolean blindness",<br>
which often follows due to a matching on == 3 or similar. Boolean<br>
Blindness is a rather deep concept, but it is worth understanding.<br>
See,<br>
<br>
<a href="http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/" target="_blank">http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/</a><br>
<br>
The exposition could be written in a more approachable way I think,<br>
but I have not gotten around to doing it yet :P<br>
<br>
In a certain sense, length/1 tells us _too much_. It yields a number,<br>
namely the length of the list. But we are only interested in two<br>
limited cases, namely sizes 0 and 3. That is, length/1 can be seen as<br>
being too powerful for our cause.<br>
<br>
That is, there is nothing wrong with using length/1 here. You should<br>
just know the implications of doing so for other code pieces.<br>
<div class="im"><br>
>> 7. How to use the test:<br>
>> receive_function(Packet) when is_my_record(Packet) == true -><br>
>> do_something_with_my_packet;<br>
>> receive_function(Packet) when is_my_record(Packet) /= true -><br>
>> I_do_not_care.<br>
><br>
> You can't do this in Erlang. Guard expressions are limited so you can<br>
> be sure they terminate.<br>
> -------------------<br>
><br>
> Please, take a better look and you will notice I haven't used guarded<br>
> function for recursion, but for condition. What you said is okay for<br>
> recursion.<br>
<br>
</div>The problem is shown in the following silly module:<br>
<br>
----<br>
-module(f).<br>
<br>
-compile(export_all).<br>
<br>
my_own_guard(B) when is_binary(B) -> binary;<br>
my_own_guard(S) when is_list(S) -> list.<br>
<br>
f(X) when my_own_guard(X) == binary -><br>
binary_to_list(X);<br>
f(X) when my_own_guard(X) == list -><br>
X.<br>
<br>
---<br>
<br>
When we try to compile this in the Erlang shell, it fails:<br>
<br>
Eshell V5.8.5 (abort with ^G)<br>
1> c(f).<br>
./f.erl:8: call to local/imported function my_own_guard/1 is illegal in guard<br>
./f.erl:10: call to local/imported function my_own_guard/1 is illegal in guard<br>
error<br>
2><br>
<br>
The relevant part in the reference manual is the part about "Guard Sequences",<br>
<br>
<a href="http://www.erlang.org/doc/reference_manual/expressions.html#id78951" target="_blank">http://www.erlang.org/doc/reference_manual/expressions.html#id78951</a><br>
<br>
which states exactly what subset of all expressions that are valid as<br>
a Guard. In particular we are only allowed to call functions in Tables<br>
7.4 and 7.5 and f:my_own_guard/1 is not in that table which is why the<br>
above compilation fail.<br>
<br>
It is worth it to contrast this behavior with Haskell, where arbitrary<br>
guard sequences *are* allowed and Haskell is lazy. Or Coq, where are<br>
functions are total, including recursive functions. In these cases,<br>
termination is less of a problem.<br>
<div class="im"><br>
> In addition, I didn't say that was the best way to do it, but just an<br>
> example. Jovi needed an example and I gave. I am sorry if my code offended<br>
> you so much to call it "garbage". Feel free to propose the best working idea<br>
> for this case.<br>
<br>
</div>Written code is never garbage if it is correct and solves the problem<br>
in an adequate way. Even if it contains minor errors which are not<br>
deep design errors, it isn't a problem - because those are quickly<br>
fixed. To me, that the code is there has a value in its own. This is<br>
mere "golfing" in the sense of producing simpler and smaller code. My<br>
goal was not to show the code to be bad, but rather to show an<br>
alternative way of implementing a solution which I do think is a bit<br>
more idiomatic and functional.<br>
<br>
Why? Because I think it is better you see more styles and then form an<br>
opinion of your own about what style you prefer when writing programs.<br>
In any event, consistency tends to win over smug code :) Your style<br>
may be easier to comprehend for a person who is more accustomed to an<br>
imperative code writing style. My style is, perhaps, easier for one<br>
with an ML or Haskell background.<br>
<font color="#888888"><br>
--<br>
J.<br>
</font></blockquote></div><br>