<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>