Function Documentation



On 08/14/2013 02:32 AM, Daniel Steinberg wrote:
>  In Maxima, the describe function can get documentation for some
>function. .... is there any way to define a doc string such that
>describe(foo) would return that string?

I already implemented, a long time ago, most or all of the
documentation improvements, that people are discussing--- and more. I
have not been following Maxima development recently; have not looked
at Rupert's changes. But, I understand his frustration about lack of
interest. OTOH, I believe it falls on the developer to organize and
advertise better. I just got busy with other things.

https://github.com/jlapeyre/mext

1) Multiple documentation databases/systems accessible through a single
interface:

  (%i7) set_all_doc_systems();
  (%o7) [devel-doc, max-doc, max-doc-sec, info-deffn-defvr, info-section,
                                                                     
simple-doc]
  (%i8) doc_system_list;
  (%o8) [devel-doc, max-doc, max-doc-sec, info-deffn-defvr, info-section,
                                                                     
simple-doc]
  (%i9) ?? keyword
  0 *arg-spec-keywords*  *(Internal item)
  1 Keyword Commands
  2 keywordify  *(Internal item)
  Enter space-separated numbers, `all' or `none': 2

   -- Internal Function: maxdoc::keywordify : defun keywordify (s)
    Convert a Maxima symbol to a lisp keyword. E.g. `$a' -> `:a' .

     Defined in source file: maxima-utils.lisp
     In package: maxdoc

Note that the source of the item appears in the list of matches. This
is an example of ...

2) what Ray Toy wants-- to return doc strings from internal
functions. `keywordify' is defined as follows (The first two lines
appear at the top of a each source file.)

---------
(doc-system:set-source-file-name "maxima-utils.lisp")
(doc-system:set-source-package "maxdoc")
(maxima::ddefun keywordify (s)
   "Convert a Maxima symbol to a lisp keyword. E.g. `$a' -> `:a' ."
   (intern (subseq (symbol-name s) 1) :keyword))
---------

I played with documenting existing Maxima code this way, because it
is very useful as I try to learn the code. But, I stopped because
my versions get out of sync with the official code. By the way, the CL
standard does not require doc strings to be retained, so one has
to do something else to capture them.

3) Robert Dodier does not want development documentation mixed in with
user documentation. No problem:

  (%i12) doc_system_list : [ "info-deffn-defvr", "info-section" ] $

  (%i13) ?? keyword   [ only one matching item remains ]

   38.2 Keyword Commands
   =====================  ...

4) Simple user documentation available via `describe'.

  (%i19) set_all_doc_systems() $

  (%i20) simple_doc_add("myplot2d", "This is my replacement for plot2d");
  (%o20)                             myplot2d
  (%i21) ?? plot2d
  0 myplot2d  *(User document)
  1 plot2d  (Functions and Variables for Plotting)
  Enter space-separated numbers, `all' or `none':

5) The maxdoc system is much more sophisticated. It has fields that
can be shown or hidden: eg author, copyright, implementation notes. It
has markup. I have a text driver and a latex (suitable for html)
driver, with switches for proper latex equations. Much of the
documentation can be autogenerated if functions are defined with the
macro defmfun1. It is designed to allow a driver to output texi
(i.e. it has similar tags), but I did not write this driver.

6) Each documentation system is different. But, there is a crude
(needs improvement), but uniform API so that they are all accessed in
the same way. (I wrote an interface from the stock info doc system to
this API.)  If someone were to write, say, a GUI for documentation
retrieval, the details of the doc systems would be hidden, and all of them
would be accessible in a uniform way. The following registers the simple-
doc system; it names the database and the functions used to access it.

  (doc-system::ds-make-and-register
    :name "simple-doc"
    :data *simple-doc-hashtable*
    :search-key-func  #'search-key
    :str-item-func  #'str-item
    :str-item-name-func  #'str-item-name)

The following resgisters the maxima section info pages.

  (doc-system::ds-make-and-register
   :name "max-doc-sec"
   :data *max-doc-section-hashtable*
   :search-key-func #'search-key-sec
   :str-item-func #'format-doc-section
   :str-item-name-func #'str-item-name-sec)

One thing I have not implemented is loading documentation without
loading code.

This all works with Maxima 5.28, and by now with 5.30. I was looking
through the 5.30 code for how to fix it. I guess that cl-info.lisp is
still in flux and there are various branches... but

I have some criticisms of the cl-info.lisp in 5.30: The two
documentation hashes (all these are in package cl-info)
*info-deffn-defvr-hashtable* and *info-section-hashtable* have been
replaced with the hashtable *info-tables*. The keys of *info-tables*
are lisp pathnames. Out of the box, there is one key-val pair. The
pathname (the key) gives the location of the info database.  The
associated value is a list of two hashtables-- the former
*info-deffn-defvr-hashtable* and *info-section-hashtable*.

So, at the highest level, data is retrieved from *info-tables* via
supplying a lisp pathname. What if someone wants to write a GUI or
any other sort of front end to the documentation, or maintain the
existing one? This implementation in 5.30 does not provide a clean
interface to the data (even muddier than before). To mention just two
reasons, installation directories are not consistent across platforms
and pathnames are not consistent across lisp implementations. (I also
wrote a pathname library for Maxima to isolate all the CL pathname
chaos from the code [we can't use the nice existing libraries because
of gcl], but that is another story). Instead, the documentation
databases should be in some kind of data structure with sensible keys
and fields giving information about the databases.

HTH,

John