> I think we all know this, but just to make sure the point is clear (in some 
> of the dicussion here, it doesn't seem that it is), the alternatives are 
> not only:
> 
> (a) Source code with docstrings (or fancy formatted docstrings with links, 
> etc.) and sparse comments, but no other explanatory text anywhere.
> 
> (b) Literate programming.

Actually, lisp has a long tradition of semicolon-style comments where

;;;; Chapter
;;;  Section
;;   Subsection
;    Paragraph or inline

With some Emacs hacking it would be possible to fold/unfold these
comments. I worked on a Transputer editor that had fold/unfold and it
was reasonably useful. I believe Emacs org-mode can also hide comments
on command. Michael Fogus (The Joy of Clojure) is a better org-mode
resource. John Kitchin (CMU professor) shows org-mode in his talk:

http://www.youtube.com/watch?v=1-dUkyn_fZA

I'm a "software blacksmith" and tend to create my own tools from
scratch so I can't give advice on org-mode, IDEs or other "store-bought"
solutions. :-)

> Of course long chunks of text are needed to explain algorithms, motivation, 
> paths not taken, etc.  Literate programming requires that those chunks be 
> inserted into the source file, and that you have to run the source file 
> through a filter to get rid of them.
> 
...[snip]...
> 
> The point is that these days, at least, I don't *want* a lot of text in the 
> file that contains my source code, even though I think that explanatory 
> documentation is *very* important, and even though I'd guess that I've 
> written more of it per line of code than the average programmer.  But 
> that's me.  Others find LP extremely beneficial, and I support that 
> strategy for those who like it.
> 
> (The desire to be able to see a lot of code at once is also one reason why 
> C-style code formatting is undesirable in a lisp language.)

I used comment-style documentation method in my youth. I created a
language, called KROPS, which was the implementation language for a
large expert system. It was pure lisp on a Symbolics machine so there
were no other documentation tools. This limited the style of comments to
the conventions mentioned above.

Returning to the code many years later (which is where LP really pays
off) the comments were extremely helpful but not sufficient. KROPS uses
a circular, self-modifying data structure which prints as a single,
solid block of code. Documenting and diagraming this structure is
necessary to understand it. ASCII tools are not sufficient for the
diagrams but the current tools are.

The code sat in long non-comment stretches. The comments that did exist
tended to follow the semicolon style mentioned above. Overall the code
follows a book-like convention but used pure source code. Snippets are
attached below to show the style.

Things to note are
   * The use of #|..|# (Common Lisp has 2 comment delimiter styles)
   * Higher organization of the comments
     - an intro to check that it works
     - a table of contents
     - the use of "levels" of semicolon structure
     - the use of docstrings on functions
     - the use of UPPERCASE in docstrings to highlight symbol names
     - the use of inline semicolons

Not shown are long uninterrupted stretches of code containing
only the docstring/uppercase and a few "inline" comments.

So it is possible to do some form of reasonably well documented
programming that is somewhat structured, involving only some
discipline on commenting style.



====================================================================
#| 
;; KROPS in common lisp
;;
;; Trivial test:
;;
;;  initialize the system:
;;    (PS-INITIALIZE)
;;
;;  define the class TEST:
;;    (LITERALIZE TEST A=)
;;
;;  create one rule:
;;    (P ASDF WHEN (TEST A= 1) THEN (PRINT "IT WORKS"))
;;
;;  create one working memory element:
;;    (MAKE TEST A= 1)
;;
;;  look for the rule to fire:
;;    (CS) ==> NIL.ASDF
;;
;;  run one rule:
;;    (RUN) ==> "IT WORKS"
;;
 
; STRUCTURE OF THIS FILE:
 
; 1.0 PACKAGE INFORMATION
; 2.0 VERSION VARIABLE
; 3.0 CHANGE LIST
; 4.0 IMPLEMENTATION PATCHES
; 5.0 DATA STRUCTURE DOCUMENTATION
;  5.1 RETE DATA STRUCTURES
;   5.1.1 R-NODE
;   5.1.2 NODES IN THE ALPHA RETE
;    5.1.2.1 R-A-PLAIN
;    5.1.2.2 R-A-OR
;    5.1.2.3 R-A-TRIG
;    5.1.2.4 R-B-A-DISTR
;   5.1.3 NODES IN THE BETA RETE
;    5.1.3.1 R-B-JOIN
;    5.1.3.2 R-B-SORT (sorted memory node)
;    5.1.3.3 R-B-P (PRODUCTION) NODES
;   5.1.4 OTHER DATA STRUCTURES
;    5.1.4.1 R-CS (A conflict set element)
;    5.1.4.2 R-B-COMMON (the vector portion of an R-B-JOIN node)
;    5.1.4.3 R-B-P-C (the vector portion of an R-B-P node)
;    5.1.4.4 R-B-ACC (an access vector)
;   5.1.5 MEMORIES
;    5.1.5.1 R-MEM (Rplacdable memory header)
;    5.1.5.2 R-MEM-ITEM (an element of R-MEM)
;    5.1.5.3 R-MEM-SORT (sorted memory)
;    5.1.5.4 R-UNIQUE
;  5.2 PARSER DATA STRUCTURES
;   5.2.1 INPUT SYNTAX
;   5.2.2 *RULE*
;   5.2.3 INTERNAL DATA STRUCTURES
;    5.2.3.1 PREDICATE
;    5.2.3.2 ORLIST
;    5.2.3.3 ANDLIST
;    5.2.3.4 TERM
;    5.2.3.5 TERMLIST
;    5.2.3.6 CENODE
;    5.2.3.7 ANDNODE
;    5.2.3.8 NOTNODE
;    5.2.3.9 SORTNODE
;   5.2.4 OUTPUT SYNTAX
;  5.3 COMPILER DATA STRUCTURES
;   5.3.1 *RHS-MAKES* ALIST
;   5.3.2 *PS-EXPRS* HASHTABLE
;   5.3.3 THE TOKEN
;   5.3.4 ACCESS FUNCTIONS
;   5.3.5 ACCESS PATHS
;   5.3.6 VARIABLES
;  5.4 OTHER DATA STRUCTURES
; 6.0 DEFVARS
; 7.0 DEFMACROS
;  7.1 GENERAL
;  7.2 PARSER
;  7.3 COMPILER
;  7.4 RETE FUNCTIONS
;  7.5 USER COMMANDS
;  7.6 RIGHT HAND SIDE MACROS
; 8.0 DEFUNS
;  8.1 GENERAL
;  8.2 PARSER
;  8.3 COMPILER
;  8.4 RETE FUNCTIONS
;  8.5 USER COMMANDS
; 9.0 TODO LIST
 
|#
 
; 1.0 PACKAGE INFORMATION
 
(provide :krops)

(make-package :krops)
(make-package :krep)
 
;(in-package 'krops :nicknames '(kb) :use :cl-user)
 
(export '(attributep attributes-of cestack context context= cs
             defrule excise excise-module famo
             findrule firecount for-all-matches-of
             ge gt le lisp-value literalize lt make makev
             make-using make-usingv match matches maximize minimize
             modify modifyv ne nomatch opserror p p-context
             p-remove-context pprule ppwm
             priority *ps-all-rules* ps-initialize ps-such-that
             ps-remove ps-reset pwatch
             remove-all remove-match rjust run say same-type
             ps-select select-set strategy tabto
             then watch when window-hook wm wme-extract wme-class=
             wme-time-tag= wnltt & ! +=))
 
(use-package 'cl-user)
 
; 2.0 VERSION VARIABLE
 
(defvar *ps-version* 0)
 
(setq *ps-version* 2)
 
(eval-when (eval load)
 (setf *features*
  (cons
   (intern (format nil "KROPS-VERSION-~a" *ps-version*) 'keyword)
   *features*)))
 
#| 
 
; 3.0 CHANGE LIST

;***********************************************************************
;version 03: dos2unix 
;            untabify
;            kb: to krep:
;            remove krep package from shadowing-use-package call
;version 02: change use-package from lisp to cl-user
;            add (make-package 'krep)
;            remove use of ki, change to krep
;            use keyword for package references
;            remove symbolic, lucid, gclisp conditional code
;version 01: SBCL translation 
;version 00: Conversion for Tires
;***********************************************************************
;version 86: add version info to *features* list
;version 85: change eval-when to include eval
 
; 5.0 DATA STRUCTURE DOCUMENTATION
 
;  5.1 RETE DATA STRUCTURES
 
; The RETE is composed of two parts, the alpha part and the beta part.
; Alpha tests are tests that can be performed by referencing only one
; working memory element. Beta tests are tests that require more than
; one working memory element. Thus,
;   (class attr= 1)
; would generate an alpha test because we need only index into the
; current working memory element to decide if some field in it has
; the value 1. But,
;   (class1 attr= <x>)
;   (class2 attr= <x>)
; would generate a beta test because we must look at two working memory
; elements to decide that their attr= fields match.
;
; There is one overall structure to a node in the rete network.
; This is called an R-NODE.
 
 
; 6.0 DEFVARS
 
(defvar *attr-id* nil)
(defvar *attr-ndx* nil)
(defvar *beta-tests* nil)
(defvar *ce-vars* nil)
 
; 7.0 DEFMACROS
 
;  7.1 GENERAL
 
(defmacro add1 (arg)
 `(the fixnum (+ 1 (the fixnum ,arg))))
 
 
(defun parse-symbol (symbol)
 "PARSE-SYMBOL takes a krops symbol and breaks it into three parts if
  it contains a trailing = sign. The purpose is to return the ROLE
  FACET and ACCESS-FUNCTION for the symbol. There are two cases:
  ROLE.FACETNAME= form and the ROLE= form. In the first case the
  ROLE is assigned to the ROLE field, the FACET is assigned the
  FACETNAME and the access function is assigneda constructed
  GET-facetname form. In the  second case the ROLE is assigned the
  ROLE, the facet defaults to VALUE and the ACCESS-FUNCTION
  is assigned GET-VALUE."
 (let ((role symbol) facet name access pos)
  (cond
   ((colonp symbol)
     (setq name (symbol-name symbol))
     (cond
       ((eq symbol '*=)
         (setq role nil)
         (setq facet nil)
         (setq access nil))
       ((setq pos (position #\. name))
         (setq role (intern (subseq name 0 pos)))
         (setq facet (intern (subseq name (1+ pos) (1- (length name)))))
         (setq access
          (intern (concatenate 'string "GET-" (string-upcase facet))
                  (find-package 'krep))))
       ('else
         (setq role (intern (subseq name 0 (1- (length name)))))
         (setq facet 'value)
         (setq access 'get-value)))))
   (values role facet access)))
 
... acres of code follow...




-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to