From: ··············@gmail.com
Subject: Problem with a macro from On Lisp
Date: 
Message-ID: <1123371036.507891.286660@g44g2000cwa.googlegroups.com>
Hi,

I am just learning about Common Lisp and one of the books I have looked
at is On Lisp by Paul Graham.  I found the with-struct macro very
useful-looking: it is a kind of destructuring macro that lets you refer
to members of a struct directly within its scope.  I copied it
carefully into my programs and found that it worked perfectly in
interpreted code, for example when I load the snippet below into the
REPL.  (This is a minimal snippet exhibiting my problem, it just prints
"Hello", as it should.)

===== LISP snippet
;;; prints arguments into a string, from Graham's On Lisp, p. 58
(defun mkstr (&rest args)
  (with-output-to-string (s)
                         (dolist (a args) (princ a s))))

;;; from Graham's On Lisp, p. 58
(defun symb (&rest args)
  (values (intern (apply #'mkstr args))))

;;; destructuring on structs, from Graham's On Lisp, p. 235
;;; Usage: (with-struct (visitor- name title) theo (list name title))
(defmacro with-struct ((name . fields) struct &body body)
  (let ((gs (gensym)))
    `(let ((,gs ,struct))
       (let ,(mapcar #'(lambda (f)
                         `(,f (,(symb name f) ,gs)))
                     fields)
         ,@body))))

(defstruct tstruct tfield)

(defun show-tfield (tstruct)
  (with-struct (tstruct- tfield) tstruct
               tfield))

(princ (show-tfield (make-tstruct :tfield "Hello")))
=====

However, when I compile-and-load into the REPL, it does not work, it
complains about SYMB being undefined.  For example, CLISP (2.32-3) says
===== CLISP output
** - Continuable Error
EVAL: undefined function SYMB
=====

I have checked that LispWorks (4.4.5) and OpenMCL (0.14.3) exhibits the
same behavior (namely, all works fine when interpreted, SYMB unknown
when compiled).

Is this a bug in "On Lisp", or am I overlooking something?  (I looked
at the errata on Graham's Web site and found no reference to this
particular macro.)

Thanks!

From: Steven M. Haflich
Subject: Re: Problem with a macro from On Lisp
Date: 
Message-ID: <oKcJe.324$911.143@newssvr21.news.prodigy.com>
··············@gmail.com wrote:
> However, when I compile-and-load into the REPL, it does not work, it
> complains about SYMB being undefined.  For example, CLISP (2.32-3) says

See in the ANS definition of defun (available at 
http://www.franz.com/support/documentation/7.0/ansicl/dictentr/defun.htm):

defun is not required to perform any compile-time side effects. In 
  particular, defun does not make the function definition available at 
compile time. An implementation may choose to store information about 
the function for the purposes of compile-time error-checking (such as 
checking the number of arguments on calls), or to enable the function to 
   be expanded inline.

The usual idiom for functions required by macros (which are required to
be expanded at compile-file time) is either to put an eval-when around 
the defun, or to put those defuns in a separate file taht is (compiled 
and) loaded earlier.

For simlicity, try the former:

(eval-when (compile load eval)
   (defun symb (&rest args)
     (values (intern (apply #'mkstr args))))
   )

 > Is this a bug in "On Lisp" ... ?

Unclear.  Paul Graham is very intelligent, very experienced, very 
effective, and it is worth seriously studying anything he writes. 
However, one suspects [WARNING: troll bait!!!] he might not be 
sufficiently expert in ANSI Common Lisp.  [DoublePlus WARNING!!!]  His 
subsequent work on ARC certainly reinforces this suspicion.
From: Barry Margolin
Subject: Re: Problem with a macro from On Lisp
Date: 
Message-ID: <barmar-46D437.22471206082005@comcast.dca.giganews.com>
In article <·················@newssvr21.news.prodigy.com>,
 "Steven M. Haflich" <···@alum.mit.edu> wrote:

> For simlicity, try the former:
> 
> (eval-when (compile load eval)

Showing your age, Steven.  That should be

(eval-when (:compile-toplevel :load-toplevel :execute)

>    (defun symb (&rest args)
>      (values (intern (apply #'mkstr args))))
>    )
> 
>  > Is this a bug in "On Lisp" ... ?
> 
> Unclear.  Paul Graham is very intelligent, very experienced, very 
> effective, and it is worth seriously studying anything he writes. 
> However, one suspects [WARNING: troll bait!!!] he might not be 
> sufficiently expert in ANSI Common Lisp.  [DoublePlus WARNING!!!]  His 
> subsequent work on ARC certainly reinforces this suspicion.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: ··············@gmail.com
Subject: Re: Problem with a macro from On Lisp
Date: 
Message-ID: <1123418112.793966.145980@f14g2000cwb.googlegroups.com>
Excellent help: I can now understand what went wrong, and I verified
that the eval-when thing actually fixes my problem.

Thank you very much!