[erlang-questions] Human readable errors in lists module

Hynek Vychodil vychodil.hynek@REDACTED
Wed Feb 11 09:54:51 CET 2009


Yes, I love it too. I love Erlang because enables this.

On Tue, Feb 10, 2009 at 11:02 PM, Kunthar <kunthar@REDACTED> wrote:

> I love "let it crash" way :)
>
> Simplicity is the ultimate sophistication!
> Leonardo Da Vinci, da great Italian magician
>
> Peace
> Kunth
>
>
> On Tue, Feb 10, 2009 at 11:46 PM, Joe Armstrong <erlang@REDACTED> wrote:
> > On Tue, Feb 10, 2009 at 4:22 PM, Adam Lindberg
> > <adam@REDACTED> wrote:
> >> Hi,
> >>
> >> Is there any reason that for example lists:zipwith/3 returns a function
> clause instead of a human readable error when the lists are of different
> length?
> >
> > Yes
> >
> > Everything has a cost - if we applied this principle rigidly to all
> > functions in
> > the system then every function in the entire system would be extended
> with
> > additional code. This make the code more difficult to read, and makes the
> > program larger (think cache hits).
> >
> > Suppose we have a function that maps a to 1 and b to 2, I'd write it like
> this:
> >
> > f(a) -> 1;
> > f(b) -> 2.
> >
> > should I then add an additional clause to warn for bad arguments?
> >
> > f(a) -> 1;
> > f(b) -> 2;
> > f(_) -> error('arg is not a or b').
> >
> > This adds nothing to the clarity of the code since the original expresses
> exact
> > the intention of the program *and nothing else*
> >
> > Programs that are cluttered with additional error messages are difficult
> to read
> > (which increases the chances of an error) an less efficient
> > (everything has a cost)
> >
> >> It might seem obvious at first but the reason I'm asking is because a
> colleague of >mine just spent a long time debugging code with used
> list:zipwith/3 and it threw >this error. What he did at first was to check
> that all arguments to lists:zipwith/3
> >> > was not zero (this is what the function clause error indicated).
> >
> > *everybody* spends a long time figuring out what when wrong the first
> time
> > they get an error of a particular type - then they learn - when you've
> seen
> > these errors a few times you'll find that you can find the error very
> quickly
> >
> > The fact that erlang crashes at the first error and prints something
> really
> > aids debugging ...
> >>
> >> lists:zipwith/3 could have been implemented as below (or something
> similar):
> >>
> >> zipwith(F, [X | Xs], [Y | Ys]) -> [F(X, Y) | zipwith(F, Xs, Ys)];
> >> zipwith(F, [], []) when is_function(F, 2) -> [].
> >> zipwith(F, [], Ys) -> error(lists_of_different_length). %% Just a
> proposal, insert
> >> zipwith(F, Xs, []) -> error(lists_of_different_length). %% preferred
> error mechanism here.
> >>
> >> The function clause, noting the arguments as [#Fun..., [], [5,6,7,...]],
> is kind of misleading since it happens inside the lists:zipwith/3 function.
> >>
> >> I can see the purists' argument here "that it is really a function
> clause" but I also see the pragmatist argument "that it is much easier to
> debug."
> >
> > Nw let's look at the error message - here's an experiment
> >
> > 1> lists:zipwith(fun(X,Y) -> X + Y end, [1,2,3],[4,5]).
> > ** exception error: no function clause matching
> >                    lists:zipwith(#Fun<erl_eval.12.113037538>,[3],[])
> >     in function  lists:zipwith/3
> >
> > To the experienced eye the error is clear
> >
> > zipwith(Fun, [3], []) doesn't match any of the clauses defining zipwith
> >
> > Show me the code Luke ... (just run less on
> > /usr/local/lib/erlang/stdlib ... ish)
> >
> > zipwith(F, [X | Xs], [Y | Ys]) -> [F(X, Y) | zipwith(F, Xs, Ys)];
> > zipwith(F, [], []) when is_function(F, 2) -> [].
> >
> > This is two lines of code.
> >
> > So zipwith(Fun, [3], []) doesn't match one of these two lines of code ...
> >
> > this is actually *shorter* than the documentation (a lot shorter)
> >
> > what does the documentation say?
> >
> >  zipwith(Combine, List1, List2) -> List3
> >       Types  Combine = fun(X, Y) -> T
> >       List1 = [X]
> >       List2 = [Y]
> >       List3 = [T]
> >       X = Y = T = term()
> >      Combine the elements of two lists of equal length into one list.
> >
> **************
> > What I have noticed teaching Erlang is that beginners make almost exactly
> > the same mistakes as experienced users - the difference is in the time
> > it takes them to debug an error.
> >
> > The first time is *always* slow - then you learn.
> >
> > (this is universally true - while I can fix erlang programs pretty
> quickly
> > I can stare at simple javascript errors for ages before twigging what
> > went wrong)
> >
> > But there's a more subtle problem.
> >
> > Let's try your suggestion. (I put your zipwith in a module test4)
> >
> > try4:zipwith(fun(X,Y) -> X + Y end, [1,2,3],[4,5]).
> > ** exception error: lists_of_different_length
> >     in function  try4:zipwith/3
> >     in call from try4:zipwith/3
> >
> > It works - great - we think ... but what about this?
> >
> > try4:zipwith(fun(X,Y) -> X + Y end, {1,2},[4,5]).
> > ** exception error: no function clause matching
> >                    try4:zipwith(#Fun<erl_eval.12.113037538>,{1,2},[4,5])
> >
> > Now what? Opps the guards were wrong - need to add a few
> > when is_list(..) guards. Or do we want an error message that says
> > error,arg1 should not be a tuple ....
> >
> > There are a very large number of ways we can supply incorrect arguments
> > and we can't program all of them.
> >
> > So what do we do - we only write patterns that match the desired cases
> > *and nothing else* - this is part of the erlang "let it crash"
> philosophy.
> >
> > In erlang we don't do defensive programming - (or rather we do do it
> using
> > patterns)
> >
> > Best
> >
> > /Joe Armstrong
> >
> >
> >> Cheers,
> >> Adam
> >> _______________________________________________
> >> erlang-questions mailing list
> >> erlang-questions@REDACTED
> >> http://www.erlang.org/mailman/listinfo/erlang-questions
> >>
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-questions@REDACTED
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



-- 
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill your
boss.  Be a data hero!
Try Good Data now for free: www.gooddata.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090211/1f4e18ef/attachment.htm>


More information about the erlang-questions mailing list