[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: macros vs. blocks



At 10:56 AM -0800 11/18/02, Todd Proebsting wrote:
>SWAP can be trivially written with reference parameters.  I don't know
>SETF and ROTATEF.  Are there good examples of macros that cannot be
>written with closures and reference parameters?


What's a "reference parameter"?  <:-)


There are many complex "defining" forms that are better written
with macros, for example, adding a 'persistent' and 'volatile'
adjective to class definitions.

In a previous job, I wrote a bunch of Lisp macros to define
"server page" classes and "tags", a la JSP and taglibs.  A
simple tag can be defined like this:

  ;; Defines the (empty) element <hd:image-server/>
  (define-element image-server ()
    (show-string *image-server-url*))

This expands into a fair amount of code that glues the tag to the
(homegrown) HTTP server used in our product.

A more complex tag that has a non-trivial body and an attribute
can be defined like this:

  ;; Defines the element <hd:title-bar inverse="yes">This is a 
Title</hd:title-bar>
  (define-body-element title-bar (contents &key ((inverse?) nil))
    (include-html (if inverse? "inverse-title-bar-start" "title-bar-start"))
    (include-html contents)
    (include-html "title-bar-end"))

The macrology arranges for parsing of attributes and generating a sort
of HTML "closure" that contains the element body contents.

Compare this with the Java boilerplate that it replaces, where gluing
the tag to the server has to be done programmatically.  I include all
the package and import boilerplate, because they have to be included
for every tag, since each tag must be in its own source file.

[Historical note: we wrote the Lisp product first but our VCs insisted
that we rewrite the whole site in Java.  So the following Java code
was actually generated programmatically from the 'define-body-element'
shown above.]

  package com.hotdispatch.common.taglibs;

  import java.io.IOException;
  import javax.servlet.http.HttpSession;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.jsp.JspWriter;
  import javax.servlet.jsp.JspException;
  import javax.servlet.jsp.tagext.BodyTagSupport;
  import com.hotdispatch.common.utils.*;

  public class TitleBarTag extends BodyTagSupport
  {
      private boolean inverse = false;

      public boolean getInverse () {
          return this.inverse;
      }

      public void setInverse (boolean inverse) {
          this.inverse = inverse;
      }

      public int doStartTag () throws JspException {
          JspWriter out = pageContext.getOut();
          try {
              //---*** I've omitted the code that actually does the work!
          }
          catch (IOException e) {
              HDLog.logError("TitleBar:doStartTag", "error while 
executing tag", e);
          }
          return SKIP_BODY;
      }
  }