[erlang-questions] Improve $handle_undefined_function

Loïc Hoguin essen@REDACTED
Tue Jan 22 13:34:06 CET 2013


I don't think they can appear as exported, due to error_handler's use of 
function_exported to know if it's defined. The attribute can be named 
something like -undef-export([]) though, to make it clearer. Note that 
the feature is only applicable when the function is called through 
M:F(...), not local calls, because the module wouldn't compile.

On 01/22/2013 01:30 PM, Vlad Dumitrescu wrote:
> Ok, I see. I had lost track of who suggested the example originally.
>
> I suppose that the functions listed in -attr() would have to be included
> in an -export() too if they are to be public?
>
> regards,
> Vlad
>
>
> On Tue, Jan 22, 2013 at 1:25 PM, Loïc Hoguin <essen@REDACTED
> <mailto:essen@REDACTED>> wrote:
>
>     On 01/22/2013 01:10 PM, Vlad Dumitrescu wrote:
>
>         On Tue, Jan 22, 2013 at 1:02 PM, Loïc Hoguin <essen@REDACTED
>         <mailto:essen@REDACTED>
>         <mailto:essen@REDACTED <mailto:essen@REDACTED>>> wrote:
>
>              On 01/22/2013 12:57 PM, Vlad Dumitrescu wrote:
>
>                  Hi,
>
>                  On Tue, Jan 22, 2013 at 12:10 PM, Loïc Hoguin
>                  <essen@REDACTED <mailto:essen@REDACTED>
>         <mailto:essen@REDACTED <mailto:essen@REDACTED>>
>                  <mailto:essen@REDACTED <mailto:essen@REDACTED>
>         <mailto:essen@REDACTED <mailto:essen@REDACTED>>>> wrote:
>
>                       On 01/22/2013 07:34 AM, Björn Gustavsson wrote:
>
>                           Why not use the existing -export() attribute
>         and write like
>
>                           this:
>
>                           -export([monitor/2,demonitor/______1]).
>
>
>
>                           monitor(process, Pid) ->
>                                do_something.
>
>                           demonitor(Pid) ->
>                                do_something_else().
>
>                           So what would be the advantage of your version?
>
>
>                       It still allows Evan Miller to write this:
>
>                       -attr([first_name/1, last_name/1, ...]).
>
>                       $handle_undefined_function(F, [Model]) ->
>                            {_, Value} = lists:keyfind(F, 1, Model),
>                            Value.
>
>
>                  I'm sorry, but I don't think you are answering Björn's
>         question. For
>                  this particular case, why not write regular Erlang like
>
>                  first_name(Model) -> get(first_name, Model).
>                  last_name(Model) -> get(last_name, Model).
>                  get(F, [Model]) ->
>                        {_, Value} = lists:keyfind(F, 1, Model),
>                        Value.
>                  which is much clearer to understand. One argument might
>         be that
>                  there is
>                  some duplication, but I think that it could be handled
>         with much
>                  more
>                  elegance if we had abstract patterns implemented.
>
>                  Do you have a more relevant example where using
>                  $handle_undefined_function gives significant advantage?
>
>
>              That's a question about $handle_undefined_function in
>         general, not
>              about this specific implementation proposal. Björn is the
>         one who
>              wrote the current implementation that's now in master, I
>         don't have
>              to tell him what can be done with it, he knows. I do have
>         to tell
>              him how implementing it this way improves the usage,
>         though. Which
>              is the sole reason of this thread.
>
>
>         Maybe I'm confused, but your answer would make 100% sense if Björn's
>         question would have been
>
>         "
>             Why not use the existing -export() attribute and write like
>         this:
>                   -export([monitor/2,demonitor/__1]).
>         $handle_undefined_function(____monitor, [process, Pid]) ->
>                       do_something();
>                   $handle_undefined_function(____demonitor, Pid) ->
>
>                       do_something_else().
>         "
>
>         My question is a follow-up on his own formulation, where your
>         suggestion
>         is compared with an implementation not using
>         $handle_undefined_function
>         at all.
>
>
>     And I answered it based on known potential uses. The snippet you
>     quote was made to demonstrate the flaws in the current
>     implementation, not to demonstrate an interesting use of the
>     feature. It can be demonstrated using Evan's example too, for example:
>
>     $handle_undefined_function(F, [Model]) when is_list(Model) ->
>
>          {_, Value} = lists:keyfind(F, 1, Model),
>          Value;
>
>     $handle_undefined_function(F, Args) ->
>          error_handler:raise_undef___exception(?MODULE, F, Args).
>
>     This would be an incorrect implementation of Evan's use for it, and
>     nothing about it says "It's obvious!". And yet it's still wrong.
>     Correct implementation would be:
>
>     $handle_undefined_function(F, [Model]) when is_list(Model) ->
>
>          {_, Value} = lists:keyfind(F, 1, Model),
>          Value;
>     $handle_undefined_function(F, Args) ->
>          case lists:member({F, length(Args)},
>                  [{first_name, 1}, {last_name, 1}, ...]) of
>              true -> erlang:error(badarg);
>              false -> error_handler:raise_undef___exception(?MODULE, F,
>     Args)
>          end.
>
>     With my proposal he can write:
>
>     -attr([first_name/1, last_name/1]).
>
>     $handle_undefined_function(F, [Model]) when is_list(Model) ->
>
>          {_, Value} = lists:keyfind(F, 1, Model),
>          Value.
>
>     This makes error_handler properly handle undef errors, reduces the
>     code needed to use the feature, allow tools to behave nicely when
>     using the feature, etc.
>
>     As for why Evan would use $handle_undefined_function instead of
>     creating many functions, that's for him to decide. But both
>     implementations of $handle_undefined_function allow all known uses
>     of the feature, yet only one gets error handling and tools support
>     straight.
>
>
>     --
>     Loïc Hoguin
>     Erlang Cowboy
>     Nine Nines
>     http://ninenines.eu
>
>


-- 
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu



More information about the erlang-questions mailing list