[erlang-questions] API Design/Documentation [Was: Why isn't erlang strongly typed?]

Geoff Cant <>
Wed Oct 22 15:54:16 CEST 2008

Steve Davis <> writes:

> <snip>
> However, the fact remains that Erlang does essentially leave a library
> user in the dark at code level, since functions may return any data
> type at all depending on their arguments. When you are designing your
> pattern matches to extract/unpack/*use* return values it becomes
> onerous whenever the data type is non-trivial. Of course feeding in
> the "right" arguments bring similar issues of how to package them
> correctly. I tend to get lost quite quickly in the ream of balanced
> separators required (maybe that's just me). Yes, records do help
> here... perhaps they are the "right" answer, and should be more widely
> encouraged.

Ack - yes, inconsistent return values from (3rd party?) library
functions are annoying. This is just bad library API design and the
author would probably be happy with a comment indicating this point of
weakness (or a patch to fix it :).

It's only in the last year or so that I've come to realise how small
changes in ad-hoc datastructures (such as return values) can affect how
easy it is to program with a library. A common case of this is returning
tuples of varying arities - most often this requires the caller to have
one case or function clause per possible arity, and this is frequently

Returning records is somewhat frustrating too - this means that I as an
API client need to include your code as a build dependency so I can
-include the definition. This will recursively frustrate people that
build on top of my code as to compile theirs they now have to compile yours
and mine as well.

The obvious alternative of retuning proplists for less-commonly used
information is frustrating too as when I do need it, I have to call
functions instead of patternmatching.

e.g. Say you're writing a dns library - what whould dns:lookup(Name, Type)
        [#dns_rr{name,class,type,ttl,data},...] - now you need to
        -include() to use the code
        [{name,type,data,[{class,C},{ttl,TTL}]},...] - somewhat better
        until you want to examine the ttl of something and you need
        proplists:get_value(ttl,Info) instead of the pattern #dns_rr{ttl=TTL}.

Regarding library documentation, I applaud the Erlware call for higher
standards in 3rd party libraries and am working towards making more of
my libraries comply. (http://www.erlware.org/development/standards.html)

My own particular library rating scheme gives points for:
* Low number of non-OTP library dependencies
* Platform standard build infrastructure (make/erl -make in my case)
* Ease of scm checkout -> working library (bonus point for a distributed
  scm - if I have to tweak the code then a dvcs make my life
  easier. bonus points for hosting on github)
* OTP application packaging
* Good API
* Documented API
* Example code
* Compiler-warning free
* Xref-warning free
* Dialyzer warning free (well minimal)

As a convenience matter it'd be nice if the shell would spit out
function documentation if you try to tab complete on arguments. i.e.
1> erlang:setelement(<TAB>

setelement(Index, Tuple1, Value) -> Tuple2

Index = 1..tuple_size(Tuple1)
Tuple1 = Tuple2 = tuple()
Value = term()
1> erlang:setelement(

Geoff Cant

More information about the erlang-questions mailing list