restarting the discussion
Jan Skibinski
jans@numeric-quest.com
Thu, 8 Feb 2001 18:35:25 -0500 (EST)
Oops, I mistakenly responded to a private copy of Henrik's
message and erased the public one. Resending to the
list. Sorry Henrik, but you started all of this. :-)
---------- Forwarded message ----------
Date: Thu, 8 Feb 2001 18:10:26 -0500 (EST)
From: Jan Skibinski <jans@numeric-quest.com>
To: Henrik Nilsson <nilsson@cs.yale.edu>
Subject: Re: restarting the discussion
On Thu, 8 Feb 2001, Henrik Nilsson wrote:
> Jan, one question: what do you do/intend to do with *re*exported
> entities?
>
> As explained in my previous mail, I think external documentation
> should include everything a module exports, including the related
> documentation, regardless of where the various entities were
> originally defined.
I agree. This is what is called a "flat interface" in Eiffel,
which can be selectively made a bit bigger or a bit smaller.
They have a "mother of all classes" called ANY (if I remember
it correctly) which just brings too much noise in sometimes.
So they turn if off.
Something similar to our Prelude.
But I am not ready for this yet.
> I have to say that this already looks like a quite useful tool,
> and it does show that one can go a long way with very lightweight
> conventions. A few points, tough.
>
> I'd again like to take the opportunity to push for the idea of also
> defining and intermediate format. The documentation samples Jan
> have presented are all very good examples of the kind of documentation
> renderings one might want. But on the other hand, I don't think
> they cover the entire spectrum of reasonable presentations.
> (I believe I have some support from at least Jan on this one.)
Definitely.
> This brings me my main concern: is the *style* of conventions
> Jan proposes (not necessarily exactly those conventions he currently
> use) flexible enough to:
>
> 1. support other reasonable renderings,
> 2. avoid creating a feeling among users that the conventions are
> "dictatorial" ;-)
>
> Regarding 2, I'm not entirely serious: by necessity, the conventions
> must be fairly strict. But after browsing through the Eiffel
> documentation Jan sent a pointer too, I personally felt that the
> required conventions were a bit too much. Now, I certainly do not
> wish to start a discussion about the Eiffel conventions. I'm just
> mildly concerned that too strict requirements might get in the way
> of getting wide acceptance for a standard. But maybe this is a
> non-issue.
The style I've shown is just a recommendation, not necesserily
a requirement. You can write what you wish - a parser would
not care less. I just found this kind of style tremendously
readable. So take the "dictatorial" back, will you? :-)
> Regarding 1, below are a few examples of things that I think are
> reasonable.
>
> Please keep in mind that I too favour a fairly lightweight
> convention, but I am willing to allow a little extra noise for the
> sake of flexibility. To be concrete, I like the convention 'xxx'
> to mark a piece of code (such as a variable name) in running text
> which Jan proposes, I think one or two more such conventions
> would be useful (e.g. _xxx_ for emphasis). On the other hand,
> I don't necessarily see anything wrong with HDoc/JavaDoc-style tags
> for marking large things: the extra piece of information provided
> could be quite valuable.
This markup is invented for better readability but
it would not be absolutely required. A properly structured
comment should stand on its own legs - without any help
from formatting. As an example - any of the following
excerpts will do the same job:
1-- ...from 'module'
2-- ...from module 'm'
3-- ...from module m
Versions 1 and 2 are just easier to read when rendered.
Now to your challenges:
> -----------------------------------------------------------------------
> Example 1.
>
> I sometimes write functions which take tuples among their arguments
> and/or return tuples, and I sometimes find it useful to document
> each field separately.
>
> Returning a tuple immediately implies that it might be difficult
> to start each documentation block with a sentence that describes
> what the function returns (which seems to be your convention)?
We have a beautiful keyword "where", which is perfect
for such occassions. But I do not claim that writing
good comments is an easy task. It is often a challenge.
But think about it a bit.. Java style is just an easy
way out: one writes the comments automaticaly, without
even thinking about the future users. In contrary,
when one has to structure the comment in most readable
way one often finds a flow in ones solution.
This is what happens to me sometimes...
I am not up to your challenge in your example 1, since
I do not fully understand its functionality. However,
it could start the comment with something like this:
-- Five-tuple (#1, #2, #3, #4, #5) of "whatever is
-- your indented meaning of this tuple" ... blah
-- where
-- #1 - list of new top-level definitions
[.. this and similar version example #1 cut out ..]
> ------------------------------------------------------------------------
> Example 2:
>
> The lambda lifter in the previous example illustrates another problem:
> how to deal with moands? NS happens to be a monad, so it is not
> really correct to claim that the function "returns a five tuple".
>
> In Armin's HDoc, there is a separte tag for marking monadic
> return values. (But I think they still renders as "Returns ..."?)
>
> In your case you seem to adopt the convention that functions
> with return type (IO a) should be described in imperative terms.
> This makes sense for IO and many other monads, but not necessarily for
> all monads.
>
> Do we need more structure here, or are monads just such a general
> concept that there is not much one can do about it?
Good point. Who said that the allmighty "documentation
commitee" is a bunch of lazy guys doing nothing? :-)
> ------------------------------------------------------------------------
> Example 3:
>
> This is really a variation on 2. Consider combinator libraries.
> Sometimes it makes sense to adopt special commenting conventions.
I agree here.
> Again, the Fudget GUI combinator library can serve as a useful example.
>
> The central abstraction in the Fudget GUI is the Fudget, which can
> be understood as a component with one user-visible input and one
> user-visible output. Such a component may or may not have a graphical
> rendering in the form of some GUI widget. Each fudget also has an
> invisible, low-level input/output pair which connects it to the outside
> world. An example could be a text input field. On the input it
> would accept strings which are shown as default values to the user.
> On the output, a user-entered string would appear as soon as the
> user presses return.
>
> The documentation for a function like
>
> foo :: a -> b -> F c d
>
> where (F c d) is a fudget with input of type d(!) and output of type c,
> would be something along the following lines:
>
> DESCRIPTION
> A foo fudget is a button that ...
> INPUT: True or False to switch the button on or off under
> program control.
> OUTPUT: True when the button is on, False when the button is off.
> ARGUMENTS:
> xxx :: a, ...
> yyy :: b, ...
>
> The point here is that describing foo as a function returning a Fudget
> isn't very helpful. Instead special conventions approporiate for
> the domainin question were adopted.
Even if I agree that special conventions must be adopted
sometimes, I could still attempt to raise to your challenge
here :-)
foo :: a -> b -> F c d
foo xxx yyy
-- Button fudget (obtained as a result of unknown
-- to me foo operation on arguments 'xxx' and 'yyy'),
-- whose i/o are:
-- input - a program controlled boolean
-- output - True if button is on (false otherwise, which is
obvious and redundant)
--
Assumption here is that user already knows all about
the operational model Fudgets use. The low level
documentation should not even attempt to solve ontological
problems. If you write a vehicle user manual you may
- at one point - safely assume that user knows what a clutch
is. It's good if a single function is as self-contained
as possible. Think for example about reading it in Haskell
Module Browser. But sometimes nothing one can do without
referring to a bit broader concept, such as a module
or a library of modules.
>
> I'm currently involved in the development of a framework for
> domain-specific languages called FRP (Functional Reactive Programming).
> One of its incarnations is as a combinator library. A central
> abstraction is (Behavior a b) which represents a "transformer" of
> signals of type a to signals of type b. I.e. there are some similarities
> to a fudget (F b a). Again, when we document a behaviour, it would be
> nice tobe able to talk about its inputs and outputs (which furthermore
> often happen to carry elements of tuple types).
>
> So, can we find conventions which are flexible enough to support
> documentation of this type of code?
I still believe we can. I went through the Hawk exercises
once to document them in this style and I was quite happy
with the results. But I do not see anything wrong with
customary styles for special cases - providing that user
is given a chance to grab the top ideas first.
>
> BTW, the Fudget library manual is available on line. It might be worth
> checking it out. For example:
>
> http://www.cs.chalmers.se/Cs/Research/Functional/Fudgets/Manual/current/small.html
>
> A concrete example illustrating the points above is:
>
> http://www.cs.chalmers.se/Cs/Research/Functional/Fudgets/Manual/current/toggleButtonF.html
I am familiar with the concepts but I never looked at Fudgets
from documentation point of view.
> -----------------------------------------------------------------------
> Example 4
>
> Well, not an example actually, more of a "laundry list". I touched
> on most of thses in my previous mail:
>
> * A possibility to include pictures does not seem entirely unreasonable.
As an extra, why not?
> * A convenient way of including a piece of code, e.g. a useage example.
> <code> </code> tags?
> * Explicit cross references Cf. the man-page "see also" style. Quite
> useful to be able to refer the reader to closely related functions
> in a large library, for instance.
> * Hints for generating indices at various level of detail
> (beginner's index, programmer's index, ...)
Many of the cross references, indices, etc. can be
captured from the module structure itself.
If I capture all structures of interacting modules,
as Extractor intends to do, then I could
- in principle - generate a lot of references, couldn't I?
But yes, there are always special cases to consider..
Regards,
Jan