Edoc thoughts

Richard Carlsson richardc@REDACTED
Fri Oct 3 14:49:51 CEST 2003


Hello, Sean. I'd like to start by saying that I've been working on a
new release of edoc, with major internal restructuring and many
improvements, and I hope to release it in a not too distant future.
(I know I've been saying this for a while now...)


On Fri, 3 Oct 2003, Sean Hinde wrote:

> First efforts using edoc are quite promising, but have generated a
> couple of small troubles  within:
>
> 1. I would like to do something like:
>
> @spec read_customer(Msisdn::string(), Operator::atom()) ->
> 	{ok, Number::string(), Services::services()} | not_likely
>
> But edoc doesn't seem to like the notation Number::string() in a
> result. I am forced to have one or the other - Number or string(). Is
> there some strong reason for this and is it easy to change?


It's part of the design. The right-hand side (following the '->')
already _is_ a type expression, and allowing "local type constraints"
such as 'Number::string()' in your example would make it possible
to actually come up with an inconsistent declaration, where you also
claim that the _type_variable_ 'Number' also stands for e.g.
'integer()'.

To clarify this:

- The things to the left of the '::' are the _parameter_names_, which
you use for talking about the parameters (instead of having to say "the
second parameter", you can just say "Operator").

- The things to the right of the '::', and the thing that follows the
'->' are _types_. In addition, you can list further local definitions.
Your example can be written:

 % @spec read_customer(Msisdn::string(), Operator::atom()) ->
 %         {ok, Number, Services} | not_likely
 %       Number = string()
 %       Services = services()

(which actually makes it easier to see the format of the returned
values). You could also lift out all types, like this:

 % @spec read_customer(Msisdn::Msisdn, Operator::Operator) ->
 %           {ok, Number, Services} | not_likely
 %       Msisdn = string()
 %       Operator = atom()
 %       Number = string()
 %       Services = services()

(note the difference between the lhs parameter name Msisdn, and the
rhs type variable Msisdn). However, since this is a common idiom,
we allow the following as short-hand:

 % @spec read_customer(Msisdn, Operator) ->
 %           {ok, Number, Services} | not_likely
 %       Msisdn = string()
 %       Operator = atom()
 %       Number = string()
 %       Services = services()

meaning that the parameter called Msisdn has type Msisdn, and the
parameter called Operator has type Operator. (The same name is simply
being used in two distinct name spaces, but it is practical to let the
context decide which one you mean.)

Whether or not to use '::' to specify directly for a parameter what type
it has, or to put it in a separate definition, is just a question of
which version becomes more readable. When parameters are few, the '::'
works fine, but with many parameters it can get messy.



> 2. It would be nice to have a global @type area, as well as local
> @types which appear together with the @spec for the function.


Semi-local types, just used in one or a few related functions, can be
defined using the above notation, as in:

 % @spec foo(Input::thingy()) -> thingy()
 %         thingy() = string() | atom()
 ...
 % @spec bar(X::thingy()) -> {ok, thingy()} | error

and they will be listed where they are defined. The type name is still
global for the module, though. (This only works for alias types. Really
abstract types have to be defined using the @type tag.)

If the type is only used in a single function (but in several places),
it is better to just use a type variable (these are local for the
function), instead of the "datatype()" named-type notation, as in:

 % @spec foo(Input::Thing) -> Thing
 %         Thing = string() | atom()



> 3. This last could probably be an exercise for the reader (or writer?)
> but an edoc:directory(string()) or even
> edoc:application(Otp_app::atom()) mechanism to do all files and
> generate an overview page would be the icing on the cake for this
> excellent time saver.

I'm working on it. :-)

	/Richard


Richard Carlsson (richardc@REDACTED)   (This space intentionally left blank.)
E-mail: Richard.Carlsson@REDACTED	WWW: http://user.it.uu.se/~richardc/
 "Having users is like optimization: the wise course is to delay it."
   -- Paul Graham



More information about the erlang-questions mailing list