Subject: Re: Keywords and CL-WHO
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 21 Sep 2006 08:37:43 -0500
Newsgroups: comp.lang.lisp
Message-ID: <YqudnU7DxdE6CI_YnZ2dnUVZ_tydnZ2d@speakeasy.net>
Ken Tilton  <kentilton@gmail.com> wrote:
+---------------
| Rob Warnock wrote:
| > Dustin Withers <fadeddata@gmail.com> wrote:
| > It appears that you are confusing macroexpansion time [which is
| > either part of compile-time or evaluation-time (for interpreted
| > code)] with run-time -- when the Common Lisp code actually executes.
| 
| Nah, it just so happens that cl-who does not evaluate that particular 
| argument. They could have written in differently and then the OP would 
| be all set.
+---------------

But... but... it's the &BODY argument of a *macro*. Macro arguments
*aren't* evaluated!

[Aside: HTOUT (and presumably, HTMLGEN as well) does it exactly the
same way as CL-WHO. (Sub)Forms starting with keywords are rewritten
into executable CL code; other (sub)forms are left as is. The final
result is returned from the macro and compiled/evaluated as usual.]

+---------------
| I do not use cl-who, but if I were in the OP's situation, I would cross 
| my fingers and examine the source to with-html-output. It might expand 
| into CALL-WITH-HTML-OUTPUT, which /would/ handle the runtime value of 
| the argument.
+---------------

Not really. Here's the entire definition of WITH-HTML-OUTPUT:

    (defmacro with-html-output ((var &optional stream
				     &key prologue
					  ((:indent *indent*) *indent*))
				&body body)
      "Transform the enclosed BODY consisting of HTML as s-expressions
    into Lisp code to write the corresponding HTML as strings to VAR -
    which should either hold a stream or which'll be bound to STREAM if
    supplied."
      (when (and *indent*
		 (not (integerp *indent*)))
	(setq *indent* 0))
      (when (eq prologue t)
	(setq prologue *prologue*))
      `(let ((,var ,(or stream var)))
	,(tree-to-commands body var prologue)))

The only important bit is the last two lines. Note that whatever
TREE-TO-COMMANDS returns is spliced into the code. No evaluation
whatsoever is done to BODY before being handed to TREE-TO-COMMANDS,
so what the OP wanted to do simply isn't possible. [At least, not
using the WITH-HTML-OUTPUT macro.]

+---------------
| If not, I would uncross my fingers so I can use the keyboard
| to hack a CALL-WITH-HTML-OUTPUT out of WITH-HTML-OUTPUT.
+---------------

Go back and look at my suggestion *not* to call TREE-TO-COMMANDS
directly:

      +--- The really ugly bit.
      |
      V
    (eval (cl-who::tree-to-commands (replace-tags-with-keywords my-tree)
                                    *standard-output*
                                    cl-who::*prologue*))

Given that MY-TREE is generated at *run-time* from reading an XML
document [he mentioned a purchase order -- presumably all possible
purchase orders are not known at compile time], do you really want
him to be calling EVAL there, at run-time? ...when a simple tree-walk
of MY-TREE could output the desired text *without* any use of EVAL?


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607