[erlang-questions] Orthogonality and Principle of least surprise Was: chained functions

Bengt Kleberg bengt.kleberg@REDACTED
Wed Feb 1 09:14:37 CET 2012


Greetings,

This is perhaps totally wrong but in my mind allowing
F = module:fun,
F().

would also mean that this is good:
F = module:fun(,
F).

Ie, "F = module:fun" is text/syntax, not semantic.


bengt

On Wed, 2012-02-01 at 09:05 +0100, Jakob Praher wrote:
> Hi Erlangers,
> 
> I think people should pay attention to issues faced by experienced newcomers in exercising Erlang programming. Matz from Ruby calls a ver important design principle, the principle of least surprise. 
> 
> No matter that the following may be a syntactic surface issue, but designating function objects is neither orthogonal nor does follow the expectations of the programmer. Therefore it also makes understanding code harder.
> 
> if I can write:
>      module:fun().
> I should be also able to write
>      F = module:fun, F().
> and not having to write
>      F = fun module:fun/0, F().
> .
> 
> I am happy to learn why module:fun is not an expression.
> 
> Best,
> Jakob
> 
> 
> Am Dienstag, 31. Januar 2012 14:07 CET, "Jakob Praher" <jakob@REDACTED> schrieb: 
>  
> >  
> > As I tried out the code below I learned that tuples of module and function atoms evalute to functions, not atoms by themselves.
> > If one can apply arguments to a tuple, why not to an atom if this would be denote a function in the current environment? 
> > 
> > {R, V} = apply_each([{m1,z},{m2,y},{m3,x}], Arg).
> > if R = ok -> ...
> > 
> > Thanks,
> > Jakob
> > 
> > 
> > Am Mittwoch, 25. Januar 2012 14:29 CET, "Jakob Praher" <jakob@REDACTED> schrieb: 
> >  
> > > 
> > > One could also compose a sequence of functions much like in combinator parsing, and fail at the first event returning the error status, otherwise continue to call apply the functions to the result.
> > > 
> > > apply_each([F|FS],X) -> 
> > >       {S, V} = F(X), 
> > >       if S = error  -> 
> > >             {S, V}
> > >          S = ok -> 
> > >             apply_each(FS, V);
> > >       end
> > >       .
> > > 
> > > {R, V} = apply_each([z,y,x], Arg).
> > > if R = ok -> ...
> > > 
> > > I have not much practice in Erlang (though I have some practice in Prolog), so this might not be 100 % correct.
> > > 
> > > Cheers,
> > > Jakob
> > > 
> > > Am Mittwoch, 25. Januar 2012 13:16 CET, Joe Armstrong <erlang@REDACTED> schrieb: 
> > >  
> > > > I think you are asking the wrong question. If a function returns
> > > > {ok,Val} | {error,Reason}
> > > > then I think to myself "the caller of this function expects things to
> > > > go wrong and is
> > > > committed to handling *both* return values.
> > > > 
> > > > So they would *never* write w(x(y(z(....))) because this does not cater for both
> > > > return values.
> > > > 
> > > > With the "let it crash" philosophy one would make w,x,y, .. return a
> > > > value OR call exit(...).
> > > > With this convention things do nest in the "happy" case without using
> > > > a staircase.
> > > > 
> > > > At the top level try or catch is used to catch the error.
> > > > 
> > > > Alternatively you could say
> > > > 
> > > >   ok({ok,X}) -> X;
> > > >   ok{error,E}) -> exit(E).
> > > > 
> > > > and then
> > > > 
> > > >    w(ok(x(ok(y(ok(z(X))))))
> > > > 
> > > > Not pretty but it does the job
> > > > 
> > > > /Joe
> > > > 
> > > > 
> > > > On Tue, Jan 24, 2012 at 8:31 PM, Reynaldo Baquerizo
> > > > <reynaldomic@REDACTED> wrote:
> > > > >
> > > > > A friend of mine asked:
> > > > >
> > > > > ##
> > > > > If you have functions that return {ok, Result} | {error, Reason}
> > > > > how do you chained them? So that you have:
> > > > >
> > > > > w(x(y(z(...))))
> > > > >
> > > > > without building a staircasing. Something that would be done in Haskell
> > > > > with monads.
> > > > > ##
> > > > >
> > > > > I would probably go for:
> > > > >
> > > > > x({ok, Value}) ->
> > > > >  NewValue = <do something with Value>,
> > > > >  {ok, NewValue};
> > > > > x({error, Reason}) ->
> > > > >  {error, Reason}.
> > > > >
> > > > > in each function
> > > > >
> > > > > which brings me other question, when do you tag return values?
> > > > >
> > > > > I tend to only use tagged return values with impure functions, were an
> > > > > error is more likely due to side effects.
> > > > >
> > > > > --
> > > > > Reynaldo
> > > > > _______________________________________________
> > > > > erlang-questions mailing list
> > > > > erlang-questions@REDACTED
> > > > > http://erlang.org/mailman/listinfo/erlang-questions
> > > > _______________________________________________
> > > > erlang-questions mailing list
> > > > erlang-questions@REDACTED
> > > > http://erlang.org/mailman/listinfo/erlang-questions
> > >  
> > >  
> > >  
> > >  
> > > 
> > > _______________________________________________
> > > erlang-questions mailing list
> > > erlang-questions@REDACTED
> > > http://erlang.org/mailman/listinfo/erlang-questions
> >  
> >  
> >  
> >  
> > 
>  
> 
> 
> 
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list