Discussion:
How to write documentation comments for procedures?
Zelphir Kaltstahl
2018-08-05 13:27:33 UTC
Permalink
Hello Guile user list members,

How do you write documentation strings for procedures? What are the
conventions for describing arguments?

Since only the last expression is returned from a procedure, one can use
normal strings as a first thing in a procedure as follows:

(define (proc a b c)
  "comment here"
  (+ a b c))

However, when I have a longer explanation for a procedure, longer than a
single line of certain length, then the line will softly wrap in editors
and the explanation will continue on the next line at the beginning
usually. Also it will be a very long line, longer than most conventions
for line lengths. For example:

(define (proc a b c)
  "comment here comment here comment here comment here comment here
comment here comment here comment here comment here comment here comment
here comment here comment here ..."
  (+ a b c))

So I could make it multiple strings instead:

(define (proc a b c)
  "comment here comment here comment here"
  "comment here comment here comment here"
  "comment here comment here comment here"
  "comment here comment here ..."
  (+ a b c))

Would that work for tools, which look at code and produce documentation
websites though? Would they be aware of multiple strings being the doc
comment?

I could also go for normal comments using ;; or even #||# regions, but
the same questions arises again: What would tools make of this? Would
they recognize it as doc comments?

How do you handle this? And what tools are there to generate
documentation websites or PDF or things like that?

Regards,

Zelphir
t***@tuxteam.de
2018-08-05 16:22:49 UTC
Permalink
Post by Zelphir Kaltstahl
Hello Guile user list members,
How do you write documentation strings for procedures? What are the
conventions for describing arguments?
Since only the last expression is returned from a procedure, one can use
(define (proc a b c)
  "comment here"
  (+ a b c))
However, when I have a longer explanation for a procedure, longer than a
single line of certain length, then the line will softly wrap in editors
and the explanation will continue on the next line at the beginning
usually. Also it will be a very long line, longer than most conventions
(define (proc a b c)
  "comment here comment here comment here comment here comment here
comment here comment here comment here comment here comment here comment
here comment here comment here ..."
  (+ a b c))
Looking at the existing sources in Guile, this seems to be the
convention (it coincides with the way it's done in other
Lisps). I'd think this is OK.
Post by Zelphir Kaltstahl
(define (proc a b c)
  "comment here comment here comment here"
  "comment here comment here comment here"
  "comment here comment here comment here"
  "comment here comment here ..."
  (+ a b c))
Would that work for tools, which look at code and produce documentation
websites though? Would they be aware of multiple strings being the doc
comment?
I'd expect the parser to "get this wrong". The first string would be
seen as the doc string, I'd expect the others to form part of the
procedure body.

The tools would be in the same position, I guess.

Let's give it a try (my interspersed comments prefixed with ';;'):

***@trotzki:~$ guile
GNU Guile 2.0.13

;; [...]

scheme@(guile-user)> (define (foo x y)
... "A simple function"
... "with a funny docstring"
... "which is actually three"
... (+ x y))

;; OK, can define...

scheme@(guile-user)> (foo 3 4)
$1 = 7

;; and works! (but see below)

scheme@(guile-user)> (procedure-documentation foo)
$2 = "A simple function"

;; alas, the "docstring" is just the first one...

Now why does the function "work"? Actually, the expressions
in the function body are wrapped in a "progn", meaning that
they are evaluated in order, and only the last expression's
value is is the function's value. So (conceptually, unless
the optimizer notices), foo first evaluates "with a funny docstring",
which evaluates to itself, throws the result away, then goes
on... you guess the rest.
Post by Zelphir Kaltstahl
I could also go for normal comments using ;; or even #||# regions, but
the same questions arises again: What would tools make of this? Would
they recognize it as doc comments?
Comments are quite different beasts from docstrings. The docstring
gets attached to the function object (so a function without source,
which you build "on the fly" at runtime) can have a docstring.

Source comments are attached to the source.
Post by Zelphir Kaltstahl
How do you handle this? And what tools are there to generate
documentation websites or PDF or things like that?
This is bigger fish. I'll defer to smarter people here :-)

Cheers
- -- tomás
Arun Isaac
2018-08-06 09:26:24 UTC
Permalink
Post by Zelphir Kaltstahl
However, when I have a longer explanation for a procedure, longer than a
single line of certain length, then the line will softly wrap in editors
and the explanation will continue on the next line at the beginning
usually.
In emacs, I find `fill-paragraph' (default keybinding of M-q) to be very
useful for wrapping long lines.
Zelphir Kaltstahl
2018-08-06 22:58:08 UTC
Permalink
Ha, I did not know that one. It still makes the second and later lines
not indented though (starting at position 0, while the first line is
indented, not starting at 0). Anyway, knowing this shortcut would have
saved me soooo much time in many cases … Thanks.
Post by Arun Isaac
Post by Zelphir Kaltstahl
However, when I have a longer explanation for a procedure, longer than a
single line of certain length, then the line will softly wrap in editors
and the explanation will continue on the next line at the beginning
usually.
In emacs, I find `fill-paragraph' (default keybinding of M-q) to be very
useful for wrapping long lines.
Arun Isaac
2018-08-07 05:58:03 UTC
Permalink
It still makes the second and later lines not indented though
(starting at position 0, while the first line is indented, not
starting at 0).
Looking at the guile source code, the lack of indentation in the second
and later lines seems to be the convention. So, I don't think this is a
problem. Something like the following is fine.

(define (foo arg)
"This is the first line.
This is the second line."
#t)
Arne Babenhauserheide
2018-08-21 21:41:09 UTC
Permalink
Post by Arun Isaac
It still makes the second and later lines not indented though
(starting at position 0, while the first line is indented, not
starting at 0).
Looking at the guile source code, the lack of indentation in the second
and later lines seems to be the convention. So, I don't think this is a
problem. Something like the following is fine.
(define (foo arg)
"This is the first line.
This is the second line."
#t)
This is what I do, too.

Note also that you can add *data* to the procedure, too, by adding a
literal array after the docstring. I use that for the equivalent of
Python doctests, but without the brittleness of writing stringly code:

(define (example)
"Testing doctests"
#((tests ('mytest
(test-assert #t)
(test-assert #f))))
#f)

- Example:
https://bitbucket.org/ArneBab/wisp/src/7501dc0db3f8cebf49b48634719ab82b4a509a79/examples/doctests-test.scm
- Doctest-runner:
https://bitbucket.org/ArneBab/wisp/src/7501dc0db3f8cebf49b48634719ab82b4a509a79/examples/doctests.scm

Best wishes,
Arne
--
Unpolitisch sein
heißt politisch sein
ohne es zu merken

Loading...