<div dir="ltr">We use function <div><br></div><div><div>ok2def( { ok, X } ) -> X;</div><div>ok2def( { error, E } ) -> throw( E ).</div></div><div><br></div><div>then <span style="font-size:12.8000001907349px">must_open_file becomes:</span></div><div><br></div><div><span style="font-size:12.8000001907349px">must_open_file(File, Mode) -></span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">       ok2def( file:open(File, Mode) ).</span><br></div><div><br></div><div>I hope you'll enjoy this shortcut (although thrown error is not so specific as in your's implementation).</div><div><br></div><div>Cheers,</div><div>Vojta</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">2015-08-15 16:56 GMT+02:00 Joe Armstrong <span dir="ltr"><<a href="mailto:erlang@gmail.com" target="_blank">erlang@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">For a while now I've adopted a convention for naming functions<br>
which I find rather useful, so I thought I'd discuss it here,<br>
(it's a kind of RFC-2119 lite notation :-)<br>
<br>
Rule1: Functions which return {ok,X} | {error,W} are called may_<name><br>
<br>
Rule2: Functions which return a value or raise an exception are called<br>
must_<name><br>
<br>
I use a small interface library which enforced this, for example,<br>
I have a wrapper round file:open which looks like this:<br>
<br>
   must_open_file(File, Mode) -><br>
       case file:open(File, Mode) of<br>
           {ok, X} -><br>
              X;<br>
           {error, E} -><br>
              exit({most_open,File,in_mode,Mode,failed,E})<br>
       end.<br>
<br>
   may_open_file(File, Mode) -><br>
      file:open(File, Mode).<br>
<br>
Using this convention<br>
<br>
  dict:find(Key, D)  should be called may_get(Key, Dict)<br>
  dict:fetch(Key, D) should be renames must_get(Key, Dict)<br>
<br>
With this convention I can write code like:<br>
<br>
   must_sequence() -><br>
      Handle = must_open_file("some_file_which_i_know_must_exist.txt", [read]),<br>
      Data = must_read_file(Handle),<br>
      must_write_file("fileout", Data).<br>
      must_close_file(Handle).<br>
<br>
Or, when "file" might exist, I'd write:<br>
<br>
    test1() -><br>
        case may_open_file("file", [read]) of<br>
           {ok, Handle} -><br>
                 ...<br>
           {error, _} -><br>
                 .. do something else ...<br>
        end.<br>
<br>
may_<name> function are *always* called from case statements<br>
must_<name> function are called in linear code with no case statements<br>
<br>
I usually also wrap the top level call to a sequence of<br>
must_* functions in a catch, something like:<br>
<br>
     top() -><br>
         case (catch must_sequence()) of<br>
             {'EXIT', What} -><br>
                ... do some recovery stuff ...<br>
             Ok -><br>
                Ok<br>
        end.<br>
<br>
Code written using the must/may convention seems to be extremely easy<br>
to read, since from the name of the function I don't have to speculate<br>
as<br>
to the form of the return value - I know immediately if the function<br>
will raise and exception on error or give an ok/error return value.<br>
<br>
Cheers<br>
<br>
/Joe<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div><br></div></div>