[erlang-questions] Best practice for defining functions with edoc,erlc,eunit and the dialyzer

Zoltan Lajos Kis <>
Thu Dec 3 10:55:50 CET 2009


>
> On Dec 2, 2009, at 11:31 PM, Zoltan Lajos Kis wrote:
>>>
>> One more thing that can be addressed is the order of exporting (and
>> defining) functions. My preference is to:
>> - 1, export API functions
>> - 2, export Behavior callback functions (a separate export line for
>> each behavior)
>> - 3, export internal functions. The functions that you _don't want
>> to export_, but Erlang makes you to do so in order to use them in
>> spawns, applys, etc.
>>
>
> Could I make a plea for
>   - a SINGLE export list for all "API" (horrible term) functions
>   - in alphabetic order

Sorry. Borrowed the term from the Erlang/OTP source code :)

>
>> Something like:
>>
>> %% API
>> -export([start_link/0, update/0, get/1, put/2, ...]).
>
> Something like
>
> -export([
>      get/1,
>      put/2,
>      start_link/0,
>      update/0
> ]).
>
> It's just that much easier to see what the module is all about.
> Someone using emacs can easily keep such a list in order using
> sort-lines.

I prefer to group the "API" functions based on their functionality and
order them by the order they will most probably be used.
In my config server example start_link / update will be used by the
supervisor/management hierarchy, while get and put will be used by whoever
needs something.

>
>>
>>
>> %% Behavior callbacks
>> -behaviour(gen_server).
>> -export([init/1, handle_call/3, handle_cast/2, ...]).
>
> Years ago I recommended that the syntax should be extended
> to
> 	-behaviour(Behaviour, [Callback...]).
> so that a cross-checking tool could tell that these functions
> were *intended* to be used as callbacks by that behaviour and
> weren't just accidentally adjacent.

A simple -behavior(Behavior). could be interpreted by the compiler as
exporting all of the behavior's callback functions. That would trigger a
compiler error if you forgot to implement one.

>
>>
>>
>> %% Internal functions
>> -export([spawnee/0, applyee/2, ...]).
>
> Now that we have spawn(fun () -> ... end) and F(...),
> we shouldn't need this group at all.
>

In general you can argue that all of these internal functions can be
handled as callbacks, and thus put into behaviors, and exported as such.
Nevertheless grep for "internal exports" in the Erlang/OTP source. There
is quite a lot of them.

Regards,
Zoltan.



More information about the erlang-questions mailing list