Re: On-line help for Python

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Mon, 15 Nov 1993 13:56:22 -0500

On Nov 15, 16:56, Guido.van.Rossum@cwi.nl wrote:
> Subject: Re: On-line help for Python
>
> > Issue: foo.help()
>
> [[I proposed adding a function help() to each module which looks up
> the file module.doc in sys.path.]]
>
> > position: against. help should be a builtin.
> >
> > why: consistant behaviour is a very good thing in a documentation
> > system. multiple instances of function needless work for parser.
>
> Making it a built-in has the problem that it fixes the behaviour
> unless you are very careful to make it extensible or overridable.
> What I could do is make a built-in help() that imports the standard
> module _help (written in Python) and calls a function _help.help(arg).
> This function could be clever and extract the module name if the
> argument is a module object, etc.
>
> > Issue: literate programming / embedded documentation
> >

I haven't used any of the literate programming tools ( WEB, etc. ) but
I've read the ideas. And one of the main notions seems to be that
keeping the documentation and the program source separate makes it
easier for them to get out of sync. Keeping them in the same file
( and automatically extracting each when needed ) encourages
synchronization. Even better, adding assertions and "sematic comments"
ENFORCES synchronization.

Interactive Lisp systems have long had the same idea - besides having
a way of changing the print representation of an object, ( similar
to python's __repr__ or __str__ ) they have usually had another
optional function that could define the descriptive string printed
by the "apropos" function.

I would propose that, rather than by doing help on a module basis,
with text in 'module.doc', the convention be that all objects can
optionally define a __help__ function, which will return a descriptive
string. Actually, I'ld like to propose reserving two functions -
one for a short one line description, ala 'apropos' , and another
for ( even more optionally ) a longer page ( or more ) length
description. The main reason for wanting 'help(object)' rather
than 'object.__help__()' is that 'help(object)', like repr(object),
would have some standard default, rather than raising an exception.

I worry that a general user-defined help function will diverge into
incompatable variants if it is not anchored with this or some similar
constraint.

Putting the help functions in the modules would be more in the spirit
of literate programming, and letting modules, classes, or any other
object have a help-string associated with it would be more object-
oriented in spirit.

builtin.help() can still be overridden with a application specific
help() function ( which itself can still use builtin.help in some
of it's lower levels. The only reasons for also wanting an imported
help module would be to modify:
(1) The highest level help string: what does help() return ?
(2) the default for objects with no __help__ function.

Both of which would seem desirable things to do.
Looking for the first help.py along sys.path makes better sense than
translating a separate 'PYTHONHELPPATH' symbol ( which would give the
possibility of getting the two variables out of sync ).
Is there an 'inheritance' method of handling #2 generally ? for
example: if no instance.__help__ exists, try Class.__help__ and then
module.__help__ , before falling back on a general '< thing > has
no help string'

It would be nice if the default one-line help could get help from
the parser so the minimal information would be how many arguments
the function/method expects. ( the default for functions and methods
that is. )

In fact - some of the ideas of literate programming were really based
around compiled languages with strict type-checking and possibly a
facility for assertions. They don't translate quite the same way to
more dynamic interpreted languages. I would suggest that the model
for a python help/doc facility, rather that the literate programming
model of extracting the program and/or documentation from the source
code, should be the ability of extracting documentation from the
running image.

The other feature of python that, I think IS a good match with
the spirit of literate programming is the fact that the indentation
in python has semantic + syntactic content and isn't JUST pretty-
printing. Comments and, in most other languages, indentation have
no "content" as far as the compiler/interpreter is concerned.
Assertions are a form of machine meaningful comments, and if you
are going to have indentation, it ought to either carry some meaning,
as in python, or be generated automatically by a pretty-printer
( or preferably, a code-browser/editor ) so there is no chance of
misleading indentation.

In general, I'm all for an online help. I often use object.__methods__
as a minimal online help. One reason I have sometimes carped on
orthogonality and consistency is that I don't usually program
with the manual at my elbow. I like to *read* it, but the less I
*need* it, the better!

[ ... and off of the main subject of this post, but still,
*somehow* connected: ]
>
> > bizarre idea: natural language generator to convert python code to
> > natural language
> >

I have often desired the inverse generator for C function
declarations: something to convert "pointer to function returning
pointer to array of struct ...". One is tempted to think that the
problem in figuring out the correct declaration is that C is TOO
terse, but I recently read an article on the evolution of C where
( Ritchie ? ) admitted that it was really a design flaw that those
declarations are so confusing: I don't remember to what he attributed
the problems - whether it was the precedence, or that "*" should have
been a postfix rather than a prefix operator, but he thought that one
minor ( but incompatable ) design change would have made it all make
MUCH more sense.

> Remember the COBOL fallacy.
>

Steve Majewski