<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace">Your proposed fix may be easy and small, but it is not a fix.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Why do you suppose append/1 wasn't written *this* way?<br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">app([X|Xs], Ys) -> [X | app(Xs, Ys)];</div><div class="gmail_default" style="font-family:monospace,monospace">app([],     Ys) -> Ys.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">app([Xs|Xss]) -> app(Xs, app(Xss));</div><div class="gmail_default" style="font-family:monospace,monospace">app([])       -> [].</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">I coded this up, using app instead of append, and got this:</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">2> app:app([[],[a|b]]).<br>** exception error: no function clause matching app:app(b,[]) (app.erl, line 4)<br>     in function  app:app/2 (app.erl, line 4)<br>     in call from app:app/1 (app.erl, line 7)</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">That would seem to be what you are after, and it's *simpler* than the</div><div class="gmail_default" style="font-family:monospace,monospace">existing code.  So what is the point?</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Let L be a well formed list, and consider</div><br><div class="gmail_default" style="font-family:monospace,monospace">   append([[1],[2],...,[N],L])</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">The fact that L is a well-formed list is verified N times,</div><div class="gmail_default" style="font-family:monospace,monospace">for a total cost O(N * |L|).  But with the current definition,</div><div class="gmail_default" style="font-family:monospace,monospace">the cost is O(N), independent of |L|.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Oddly enough, there *is* a way to check that a list is well formed</div><div class="gmail_default" style="font-family:monospace,monospace">in a guard.  Let's try this.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">append([Xs]) when length(Xs) >= 0 -> Xs;</div><div class="gmail_default" style="font-family:monospace,monospace">append([Xs|Xss]) -> Xs ++ append(Xss);</div><div class="gmail_default" style="font-family:monospace,monospace">append([]) -> [].</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">This actually *would* be a "fix", and the cost would be</div><div class="gmail_default" style="font-family:monospace,monospace">O(N + |L|) instead of O(N * |L|).</div><div class="gmail_default" style="font-family:monospace,monospace">But that would make append([Xs,Ys]) inconsistent with</div><div class="gmail_default" style="font-family:monospace,monospace">Xs++Ys.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">I will say that I've been using languages in the Lisp family for</div><div class="gmail_default" style="font-family:monospace,monospace">a little over 40 years, and this has been the very *least* of my</div><div class="gmail_default" style="font-family:monospace,monospace">problems.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 16 Sep 2019 at 06:02, Karlo Kuna <<a href="mailto:kuna.prime@gmail.com">kuna.prime@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Michal, <div>i really prefer crashing than garbage in, garbage out policy. </div><div>also it would be nice if someone from OTP team confirms if stdlib has "garbage in garbage out" policy. i can certainly see benefits of it but in this case fix is easy and small.  </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Sep 15, 2019 at 7:54 PM Michał Muskała <<a href="mailto:michal@muskala.eu" target="_blank">michal@muskala.eu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



<div>
<div name="messageBodySection">
<div dir="auto">My understanding is that for most functions in the Erlang standard library, if you don't uphold the contract the documentation specifies the function can crash, but it could also return whatever - in short "garbage in, garbage out" applies.</div>
</div>
<div name="messageSignatureSection"><br>
<div dir="auto">Michał.</div>
</div>
<div name="messageReplySection">On 15 Sep 2019, 18:45 +0100, Karlo Kuna <<a href="mailto:kuna.prime@gmail.com" target="_blank">kuna.prime@gmail.com</a>>, wrote:<br>
<blockquote type="cite" class="gmail-m_6942475427312310470gmail-m_-1695047812462014610spark_quote" style="margin:5px;padding-left:10px;border-left:thin solid rgb(26,188,156)">
<div dir="ltr">
<div>Hello,<br></div>
<div><br></div>
<div>i have found surprising  behavior of function lists:append/1: </div>
<div><br></div>
<div>spec and documentation  are in a agreement that this function should accept lists of lists ( [List] ) , </div>
<div>and return list of T ( [T] ), however when we use function like: </div>
<div> </div>
<div>     lists:append([a]) %wrong input parameter </div>
<div>one gets: </div>
<div>     a  % wrong type of a return </div>
<div><br></div>
<div>implementation assumes correct type: </div>
<div><br></div>
<div>append([E]) -> E; % E is not checked for type <br>
append([H|T]) -> H ++ append(T);<br>
append([]) -> [].<br></div>
<div><br></div>
<div>simple solution could be: <br>
<br>
lists:append([E]) when is_list(E) -> E <br>
<br></div>
<div>am i missing something? </div>
<div><br></div>
</div>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br></blockquote>
</div>
</div>

</blockquote></div>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div>