This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: befuddled user seeks help with defmacro



'defmacro' is a code transformer; for an introduction to how it works,
and the common problems you'll run into, look at Graham's 'ANSI Common
Lisp'.  I used guile's primitive 'macroexpand' to turn your code into
something that generates valid Scheme.  

I have only marginally tested this code:

(defmacro define-rectangle (rect-name . body)
  `(begin
     (define ,rect-name (make-rect))
     (let ((height: (lambda (str) (set-height! ,rect-name str)))
	   (width: (lambda (str) (set-width! ,rect-name str))))
       ,@body
       )))

Your example:

(define-rectangle fred
  (height: 10)
  (width: 12))

generates:

(begin 
  (define fred (make-rect)) 
  (let ((height: (lambda (str) (set-height! fred str))) 
	(width: (lambda (str) (set-width! fred str)))) 
    (height: 10) 
    (width: 12)))

with my changed version of define-rectangle.  I hope this helps,

-russ

Eric Moore <moore@chem.cmu.edu> writes:

> Ok, I was working with guile, and wanted to make an easier means for
> non-lisp saavy users to create and set some smobs I'd created.  I hit
> on a solution that looks more or less like (rectangles have been
> substituted as they're the canonical example ;):
> 
> (defmacro define-rectangle (rect-name . body)
>   `(let ((rect (make-rect)))
>      (define ,rect-name rect)
>      (let ((height: (lambda (str) (set-height! rect str)))
>            (width: (lambda (str) (set-width! rect str))))
>        ,@body
>        )))
> 
> with the intent being that something like:
> 
> (define-rectangle fred
>   (height: 10)
>   (width: 12))
> 
> would create a top-level binding of 'fred' to a 10x12 rectangle.
> 
> Unfortunately, it doesn't work.  I tried replacing the define with
> 
>      (define (quote ,rect-name) rect)
> 
> and
> 
>      (define ,(quote rect-name) rect)
> 
> still no luck.  However:
> 
> (defmacro define-string (string-name)
>    (define ,string-name "foo"))
> 
> does.
> 
> I've read all the docs on quasiquote and defmacro I can find, and
> examined the source to defmacro, and came away unenlightened :)
> 
> so I have a few questions:
> a) is there a better way to do this?
> b) why does it work this way? 
> c) how could I make it work? (even if the answer to 'a' is yes, I'd
>    like to understand defmacro better ;)
> 
> Thanks in Advance for your help!
>         -Eric
> 

--
No matter how hard you kick a dead dog, it still won't run.