[erlang-questions] Some functions must return values other may do so...

French, Michael michael.french@REDACTED
Sun Aug 16 09:08:56 CEST 2015


Perhaps may(...) and must(...) are just higher-order combinators that can wrap any function.

Mike

________________________________________
From: French, Michael
Sent: Saturday, August 15, 2015 9:49 PM
To: Joe Armstrong
Subject: RE: [erlang-questions] Some functions must return values other may do  so...

________________________________________
From: erlang-questions-bounces@REDACTED [erlang-questions-bounces@REDACTED] on behalf of Joe Armstrong [erlang@REDACTED]
Sent: Saturday, August 15, 2015 4:56 PM
To: Erlang
Subject: [erlang-questions] Some functions must return values other may do      so...

For a while now I've adopted a convention for naming functions
which I find rather useful, so I thought I'd discuss it here,
(it's a kind of RFC-2119 lite notation :-)

Rule1: Functions which return {ok,X} | {error,W} are called may_<name>

Rule2: Functions which return a value or raise an exception are called
must_<name>

I use a small interface library which enforced this, for example,
I have a wrapper round file:open which looks like this:

   must_open_file(File, Mode) ->
       case file:open(File, Mode) of
           {ok, X} ->
              X;
           {error, E} ->
              exit({most_open,File,in_mode,Mode,failed,E})
       end.

   may_open_file(File, Mode) ->
      file:open(File, Mode).

Using this convention

  dict:find(Key, D)  should be called may_get(Key, Dict)
  dict:fetch(Key, D) should be renames must_get(Key, Dict)

With this convention I can write code like:

   must_sequence() ->
      Handle = must_open_file("some_file_which_i_know_must_exist.txt", [read]),
      Data = must_read_file(Handle),
      must_write_file("fileout", Data).
      must_close_file(Handle).

Or, when "file" might exist, I'd write:

    test1() ->
        case may_open_file("file", [read]) of
           {ok, Handle} ->
                 ...
           {error, _} ->
                 .. do something else ...
        end.

may_<name> function are *always* called from case statements
must_<name> function are called in linear code with no case statements

I usually also wrap the top level call to a sequence of
must_* functions in a catch, something like:

     top() ->
         case (catch must_sequence()) of
             {'EXIT', What} ->
                ... do some recovery stuff ...
             Ok ->
                Ok
        end.

Code written using the must/may convention seems to be extremely easy
to read, since from the name of the function I don't have to speculate
as
to the form of the return value - I know immediately if the function
will raise and exception on error or give an ok/error return value.

Cheers

/Joe
_______________________________________________
erlang-questions mailing list
erlang-questions@REDACTED
http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list