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

Gilberio Carmenates Garcia co7eb@REDACTED
Sat Aug 15 19:52:19 CEST 2015


Hi Joe, hi every one,

 

I would like to ask a little question, I like Erlang a lot, I must always
say that, it is inevitable and that is why I suffer, because there is not
Erlang Specific IDE. I am currently using IntelliJ IDEA with an erlang
plugin and that is the best thing I ever seem.

 

I am just a young cuban man of 31 years old who does not have any relevant
employment, but I like Erlang and like to write its code like this:

 

%% -------------------------------------------------

%% @doc 

%% This is a function that does nice stuffs

%% NOTE: this does nice,

%%       almost always... 

%% @end

%% -------------------------------------------------

-spec my_function(Name, Opts) ->

    {ok, Result} | {error, Reason} when

    Name :: atom(),

    Opts :: [{OptionName :: atom(), OptionValue :: any()}, ...],

    Result :: any(),

    Reason :: term().

my_function(Name, Opts) ->

   %% maybe some comments

   ... maybe some nice code ;).

 

Or

 

%% ...

%% @exception

%%   may throw an exception if ...

%% -------------------------------------------------

-spec my_function(Name, Opts) -> Result when ...

 

Since specs where introduced Erlang definitely got elegancy.

 

I almost always do that, no matter which function is or that it does if it
is private I just use @private edoc tag.

 

That makes code good looking in a nice IDE. And more when I can go over a
function with the mouse and see its spec and edoc.

 

Maybe adding all this to Joe's convention will look even better.

 

i.e.:

 

%% -------------------------------------------------

%% @doc 

%% This is a function that does nice stuffs

%% NOTE: this does nice,

%%       almost always... 

%% @end

%% -------------------------------------------------

-spec may_open(Name, Opts) ->

    {ok, Result} | {error, Reason} when

    Name :: atom(),

    Opts :: [{OptionName :: atom(), OptionValue :: any()}, ...],

    Result :: any(),

    Reason :: term().

may_open(Name, Opts) ->

   %% maybe some comments

   ... maybe some nice code ;).

 

With must:

 

%% -------------------------------------------------

%% @doc 

%% This is a function that does nice stuffs

%% NOTE: this does nice,

%%         almost always... 

%% @end

%% @exception

%%    will throw an error if ...

%% -------------------------------------------------

-spec must_open(Name, Opts) -> Result when

    Name :: atom(),

    Opts :: [{OptionName :: atom(), OptionValue :: any()}, ...],

    Result :: any().

must_open(Name, Opts) ->

   %% maybe some comments

   ... maybe some nice code ;).

 

Then when you get a lot of functions and you see @exception tag is in edoc
and the name of the function is called must_<name> that seems like a perfect
match to me, it will definitely become beautiful ;).

 

So Why cannot Erlang have its nice IDE of its own? Always using tiny and
uncomfortable IDEs like vim, or emacs, etc, etc.

 

My intention is not to critique anything, rather than that, I am just
expressing my self.

 

I will like to post thoughts since time to time in this email list if you
are so kind to let me.

  

Cheers,

Ivan (son of Gilberio).

 

 

-----Mensaje original-----
De: erlang-questions-bounces@REDACTED
[mailto:erlang-questions-bounces@REDACTED] En nombre de Joe Armstrong
Enviado el: sábado, 15 de agosto de 2015 10:57
Para: Erlang
Asunto: [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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150815/3fe62637/attachment.htm>


More information about the erlang-questions mailing list