A Haskell Documentation Standard

Jan Skibinski jans@numeric-quest.com
Wed, 31 Jan 2001 05:00:59 -0500 (EST)


On Wed, 31 Jan 2001, Simon Marlow wrote:

> Sorry for not being clear about this.  You're right in that trying to
> understand arbitrary comments in Haskell source isn't workable.  The
> documentation annotations must be in a special format that the
> documentation tool can understand.
> 
> eg.  HDoc's {--- .. -} style comments.  I had in mind using Haskell's
> pragma convention, like this:
> 
> {-# DOC f
>     <desc><id>f</id> turns people into frogs</desc>
>     <arg><id>x</id> A <type>Person</type></arg>
>     <ret>A <type>Frog</type></ret>
> #-}
> f :: Person -> Frog
> f x = ...

	Machine-wise, this is an excellent format, because it
	not only signifies that this comment is important
	(as HDoc does by using triple dashes) but also associates
	the comment with the specific entity (as I was discussing
	it in the previous post). Easy to parse, no ambiguities.

	Human-wise, this is a terrible thing. I would never
	like to read sources written this way, nor to produce
	them by hand this way.

> The markup format for the documentation is of course up for discussion.
> XML seems plausible but verbose.

	Now take a look at this disciplined ascii version:

	f :: Person -> Frog
	f x
	    -- A frog made from a person 'x'
	    = .....
	   (Note the I always specify the result by placing
	    it up front of the sentence. No need for <ret>,
	    no need for types to be told twice.) 

	or at a more complex example to make even a stronger point:

	f :: Person -> Frog -> Bool
	f person y 
	    -- True if a 'person' can be turned
	    -- to a frog
	    -- where
	    --    y is a frog
	    --
	    = ....

	I am sure there is nothing in your XML version that I
	did not explain in plain English of my versions - unless you
	want to cross-reference all the frogs, persons and
	booleans (which would not make any sense to me).
	
	But the the major difference between the two is such
	that I can still read the source files with ease.
	
	This is similar to the Eiffel style of documentation:
	you extract the signature, the left hand side
	of function definition and the comments. You place
	them in your interface (which can be pretty printed
	in any format) in exactly this order - from most
	general info to the most detailed explanation. Comments
	can refer to arguments by their names for clarity.
	And a function comment clearly becomes a part of a
	function definition.

	This positional method has few drawbacks however. First,
	this specific order cannot be applied to functions
	with multiple equations (the order: "signature, comment,
	equations" looks better in such cases), although it is
	still fine with guards.
	Secondly, this could open a can of protests about the order
	requirements. Thirdly, it requires a lot of self discipline.
	However, the final result definitely exceeds other styles
	-- readability-wise.

	But I am not trying to promote this style, I am just
	pointing out some more readable alternatives to your original
	version. For example, this would do equally well:

	f :: Person -> Frog
	f x
	{-# Doc f
	    -- Frog from person 'x'
	-#}
	    = .....

	and could be pretty printed, with pragmas removed. But
	--as a developer -- I would still hate reading and writing
	those pragma tokens, especially the complex thingies
	-- as pointed by Armin in another post  .... unless I
	would never see them anytime during the development
	cycle.
	
	In theory it is possible to have both worlds with the
	help of tools: you write a single function in plain English,
	annotate it (or not - depending on the tool), and it
	comes back again, but prettified. So if we want both
	worlds then we better provide good tools and then
	convince the community that this is the way to work
	with Haskell.
	 
> If I understand correctly, I think you were proposing a two stage
> process to get the documentation (similar to the Eiffel approach?):

	No, the numbered list in my previous post did not represent
	any order of steps, but some options I was musing about.

	Jan