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


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)
      ^^^^^^^^^^^^^^^^^^^^^^^^
Right here is the problem. You're binding ,rect-name in the lexical
env. of the let, so it'll be gone after you leave.

>      (let ((height: (lambda (str) (set-height! rect str)))
>            (width: (lambda (str) (set-width! rect str))))
>        ,@body
>        )))
>

You want to do something like this:

(defmacro define-rectangle (rect-name . body)
  `(define ,rect-name
     (let ((rect (make-rect))
	   (height: (lambda (str) (set-height! rect str)))
	   (width: (lambda (str) (set-width! rect str))))
       ,@body
       rect)))
  
[snipalufagus]
> 
> I've read all the docs on quasiquote and defmacro I can find, and
> examined the source to defmacro, and came away unenlightened :)

quasiquotes are great and sometimes very annoying. They aren't the
problem here, though.


> so I have a few questions:
> a) is there a better way to do this?

Could be... I'm more a lisper than a schemer, so there might be some
wild voodoo in guile that I'm unaware of ;)

> b) why does it work this way? 

lexical bindings

> 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
> 
> 

-- 
Greg