<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Texto sin formato Car";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.5pt;
        font-family:Consolas;}
span.TextosinformatoCar
        {mso-style-name:"Texto sin formato Car";
        mso-style-priority:99;
        mso-style-link:"Texto sin formato";
        font-family:Consolas;}
span.EstiloCorreo19
        {mso-style-type:personal-compose;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:70.85pt 3.0cm 70.85pt 3.0cm;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=ES link=blue vlink=purple>

<div class=Section1>

<p class=MsoPlainText><span lang=EN-US>Hi Joe, hi every one,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>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.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>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:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @doc <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% This is a function that does nice
stuffs<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% NOTE: this does nice,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% 
     almost always... <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @end<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>-spec my_function(Name, Opts) -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    {ok, Result} |
{error, Reason} when<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Name :: atom(),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Opts :: [{OptionName
:: atom(), OptionValue :: any()}, ...],<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Result :: any(),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Reason :: term().<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>my_function(Name, Opts) -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   %% maybe some comments<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   ... maybe some nice code
;).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Or<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% ...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @exception<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%   may throw an exception if
...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>-spec my_function(Name, Opts) -> Result
when ...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Since specs where introduced Erlang
definitely got elegancy.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoNormal><span lang=EN-US style='font-size:10.5pt;font-family:Consolas'>I
almost always do that, no matter which function is or that it does if it is
private I just use @private edoc tag.<o:p></o:p></span></p>

<p class=MsoNormal><span lang=EN-US style='font-size:10.5pt;font-family:Consolas'><o:p> </o:p></span></p>

<p class=MsoNormal><span lang=EN-US style='font-size:10.5pt;font-family:Consolas'>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.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Maybe adding all this to Joe's
convention will look even better.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>i.e.:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @doc <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% This is a function that does nice stuffs<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% NOTE: this does nice,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% 
     almost always... <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @end<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>-spec may_open(Name, Opts) -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    {ok, Result} |
{error, Reason} when<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Name :: atom(),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Opts :: [{OptionName
:: atom(), OptionValue :: any()}, ...],<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Result :: any(),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Reason :: term().<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>may_open(Name, Opts) -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   %% maybe some comments<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   ... maybe some nice code
;).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>With must:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @doc <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% This is a function that does nice stuffs<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% NOTE: this does nice,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%        
almost always... <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @end<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%% @exception<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%    will throw an error
if ...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>%%
-------------------------------------------------<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>-spec must_open(Name, Opts) -> Result
when<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Name :: atom(),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Opts :: [{OptionName
:: atom(), OptionValue :: any()}, ...],<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    Result :: any().<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>must_open(Name, Opts) -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   %% maybe some comments<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   ... maybe some nice code
;).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>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 ;).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>So Why cannot Erlang have its nice IDE
of its own? Always using tiny and uncomfortable IDEs like vim, or emacs, etc,
etc.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>My intention is not to critique
anything, rather than that, I am just expressing my self.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>I will like to post thoughts since time
to time in this email list if you are so kind to let me.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>  <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Cheers,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Ivan (son of Gilberio).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US> <o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText>-----Mensaje original-----<br>
De: erlang-questions-bounces@erlang.org
[mailto:erlang-questions-bounces@erlang.org] En nombre de Joe Armstrong<br>
Enviado el: sábado, 15 de agosto de 2015 10:57<br>
Para: Erlang<br>
Asunto: [erlang-questions] Some functions must return values other may do so...<o:p></o:p></p>

<p class=MsoPlainText><o:p> </o:p></p>

<p class=MsoPlainText><span lang=EN-US>For a while now I've adopted a
convention for naming functions<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>which I find rather useful, so I thought
I'd discuss it here,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>(it's a kind of RFC-2119 lite notation
:-)<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Rule1: Functions which return {ok,X} |
{error,W} are called may_<name><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Rule2: Functions which return a value or
raise an exception are called<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>must_<name><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>I use a small interface library which
enforced this, for example,<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>I have a wrapper round file:open which
looks like this:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   must_open_file(File, Mode)
-><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>      
case file:open(File, Mode) of<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>          
{ok, X} -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>             
X;<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>          
{error, E} -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>             
exit({most_open,File,in_mode,Mode,failed,E})<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>      
end.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   may_open_file(File, Mode)
-><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>     
file:open(File, Mode).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Using this convention<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>  dict:find(Key, D)  should be
called may_get(Key, Dict)<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>  dict:fetch(Key, D) should be
renames must_get(Key, Dict)<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>With this convention I can write code
like:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>   must_sequence() -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>      Handle =
must_open_file("some_file_which_i_know_must_exist.txt", [read]),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>      Data =
must_read_file(Handle),<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>     
must_write_file("fileout", Data).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>     
must_close_file(Handle).<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Or, when "file" might exist,
I'd write:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>    test1() -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>       
case may_open_file("file", [read]) of<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>          
{ok, Handle} -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>                
...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>          
{error, _} -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>                
.. do something else ...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>       
end.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>may_<name> function are *always*
called from case statements<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>must_<name> function are called in
linear code with no case statements<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>I usually also wrap the top level call
to a sequence of<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>must_* functions in a catch, something
like:<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>     top() -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>        
case (catch must_sequence()) of<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>            
{'EXIT', What} -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>               
... do some recovery stuff ...<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>            
Ok -><o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>               
Ok<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>       
end.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Code written using the must/may
convention seems to be extremely easy<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>to read, since from the name of the
function I don't have to speculate<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>as<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>to the form of the return value - I know
immediately if the function<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>will raise and exception on error or
give an ok/error return value.<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>Cheers<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>/Joe<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>_______________________________________________<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>erlang-questions mailing list<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>erlang-questions@erlang.org<o:p></o:p></span></p>

<p class=MsoPlainText><span lang=EN-US>http://erlang.org/mailman/listinfo/erlang-questions<o:p></o:p></span></p>

</div>

</body>

</html>