Seems Keith found my prior reference too obscure. I was assuming that a someone fluent would Lisp could draw the analogy without help, and folks unfamiliar with Lisp probably could not follow the analogy without way more writing than I have time to do.
On reflection, that left out the folks not yet fluent with Lisp, so Keith’s puzzlement is justified.
The Ada project at UCI took a brilliantly simple approach. A recursive descent parser translated the Ada source text into a parse tree. The parse tree was (naturally) a Lisp s-expression, and could be saved and loaded using the usual Lisp save/load functions. The interpreter, pretty-printer, and compiler methods were attached to the Ada parse tree node identifiers as properties. This made for very small code fragments that were very quick to write.
For example the calling the Ada interpreter was simply: ` (ada-interpreter parse-tree)` and the code executed was like:
(ada-eval (getprop 'ada-interpreter (car parse-tree)) (cdr parse-tree))
The code fragment to interpret an IF statement might look like:
(cond ((ada-eval (car statement)) (ada-eval (cadr statement))) (T (ada-eval (caddr statement))) )
(I threw out my UCI Lisp manual years ago, so the above is only vaguely
The pretty-printer and compiler were similarly simple. The full-screen Ada editor (hot stuff at the time) ran the Ada pretty-printer to format the parse tree as the text to be edited, and on save ran the Ada parser to generate a parse tree from the text (and parse errors put you back in the editor).
The fact that the interpreter/editor/debugger were all components in the Lisp environment and readily extensible was a huge advantage.
In the Java world we get many of the same advantages. The Java compiler is simply Java code, and can be called by Java programs (though the overhead is higher). If you are using any of the Java IDEs with well-documented interfaces, it is possible to extend your programming environment.
In the XML world you get arbitrary self-describing data structures - a lot like data stored as Lisp s-expressions, only needing a bit more storage for the same data. XML is cool in almost exactly the same way that storing data is Lisp s-expressions was extremely useful. Walk an XML tree with a hash table on the side, and you get the same result as Lisp s-expressions with properties attached to identifiers in each node.
In a sense the Java + XML world is re-discovering some of the useful notions readily available to Lisp programmers twenty-odd years ago.