Paolo,
> Some time ago, I read Knuth's works on literate programming and played
> with noweb, and this seemed interesting, at least for static languages
> like C. But I always wondered how this approach fits in the dynamic,
> interactive style of Lisp development. If you write a chunk, how can
> you evaluate it? Do you delay evaluation/testing until all related
> chunks can be tangled into into code? Do you have tools to evaluate
> chunks in a Lisp REPL?
sorry for the delay... was on vacation.
i write everything as a literate program these days. my method of working
is only effective if you use emacs, noweb, xdvi and make but it works well.
i'm always working on large lisp programs (the current one for work is about
15k lines including documentation and most all of the axiom ones are large)
if you follow this long explanation that you'll see that you can get a very
fast "edit-debug-test-doc" cycle going (which is vital to programming).
i no longer feel the need to execute individual functions (which is a
big change for me as i used to do this all the time) now that machines
are "fast enough". i hack 10 lines or so, build a test case into the
literate program as a chunk and then do a complete rebuild cycle.
if you wanted you could create a shell buffer, rename it to something
else, start lisp in it, and you can use your standard eval-sexpression
keystrokes on it. Since the code blocks exist as quoted text in chunks
it would be easy to do. as i said i no longer feel the need...
i change the pamphlet file, hit cntrl-x e, and the file is saved,
recompiled, the tests are run in the shell buffer, and the documentation
is automatically updated in the xdvi buffer.
thus at every moment the source, tests, and documentation are up to date.
i chose latex because it is world-standard machinery.
i chose noweb because it is language independent.
i chose emacs because it lets me do everything in one editor.
i'm advocating using these tools rather than "documentation in code"
like javadoc because the javadoc/lisp comments/;;; ;; ;/etc method
promotes a commenting style which assumes you understand a LOT about
the program while reading the comment. This is fine if you're the
developer but not very useful if you're the user or new maintainer.
various inline doc tools have been advocated here.
i'm advocating using these tools rather than "internals documents"
or separate documentation because i've never seen the documentation
keep up with the source. you always find chapters that say "gotta
write this". docbook-style tools have been advocated here.
i'm not sure that my local process is useful for other people but
i'm certain that literate programming is a step in the right direction.
the whole idea of writing for people rather than for machines is vital.
t
=================================================================
in detail you need to know a few things (which you almost certainly
know already but...)
*) emacs allows you to run a shell in a buffer
*) emacs allows you to create a command using "cntrl-X (" and execute
that command with "cntrl-X e"
*) literate programs are just latex documents with 2 additional "tags"
\begin{docuemnt}
...
latex markup
...
<<foo>>= <--- definition of code chunk
(source code)
@
...
latex markup
...
<<foo>> <--- use of code chunk
...
the "<<foo>>=" defines a block of code which ends at the "@"
the "<<foo>>" uses the block of code.
the "notangle" preprocessor walks across the literate program in two
passes. first it looks for the defintions and adds them to a hash
table under the "foo" string (the string can be anything). the second
pass looks for the special tag "<<*>>=" and extracts it to standard
output. if it encounters a "<<foo>>" tag it recursively expands it
by looking it up in the hashtable.
the "noweave" preprocessor converts the chunk tags to verbatim so
that the source code is quoted inline.
*) notangle will (by default) extract the chunk name tag <<*>>
i make the code in the <<*>> be a Makefile that builds and tests
the code. For instance,
\section{Makefile}
<<*>>=
TANGLE=/usr/local/bin/NOTANGLE
WEAVE=/usr/local/bin/NOWEAVE
LATEX=/usr/bin/latex
LISP=/sei/lisp
MAKEINDEX=/usr/bin/makeindex
all: code doc run
code: tpd.pamphlet
${TANGLE} -Rlisp tpd.pamphlet >tpd.lisp
doc:
${WEAVE} -t8 -delay tpd.pamphlet >tpd.tex
${LATEX} tpd.tex 2>/dev/null 1>/dev/null
${MAKEINDEX} tpd.idx
${LATEX} tpd.tex 2>/dev/null 1>/dev/null
run:
cat tpd.lisp | ${LISP}
remake:
${TANGLE} -t8 tpd.pamphlet >Makefile.tpd
@
*) the latex process will generate a dvi file (e.g. tpd.dvi)
if you run "xdvi tpd.dvi &" on the file you get an xdvi display
which has the magic property that it will automatically update
every time it gets the focus.
*) the whole trick to "sewing it all together" is to
1) split the emacs buffer (cntrl-X 2)
2) start a shell in one buffer (meta-x shell)
3) edit your file in the second buffer (cntrl-x cntrl-f tpd.pamphlet)
4) create an emacs macro
cntrl-x ( <-- create a keyboard macro
cntrl-x cntrl-s <-- save the tpd.pamphlet changes
cntrl-o <-- switch to the shell buffer
meta-> <-- go to the end of the shell buffer
makefile -f Makefile.tpd <-- execute the makefile
cntrl-x o <-- switch back to tpd.pamphlet
cntrl-x ) <-- save the keyboard macro
5) change the tpd.pamphlet file
6) cntrl-x e <-- execute the keyboard macro
7) check the lisp execution output
8) switch focus to the xdvi window and check the doc changes
_______________________________________________
Gardeners mailing list
[email protected]
http://www.lispniks.com/mailman/listinfo/gardeners