guile-user
[Top][All Lists]
Advanced

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

Re: Function call inside macros


From: Alex Shinn
Subject: Re: Function call inside macros
Date: 01 Sep 2001 13:28:39 -0400
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.0.104

>>>>> "Sergey" == Sergey Dolin <address@hidden> writes:

    Sergey> Once again...  (define-macro (http:let binds body) `(let
    Sergey> (,@(http:uri-query-string->lists (getenv "QUERY_STRING"))
    Sergey> ,@binds) ,body))

    Sergey> This macro works well but _only_ one time. (Obviosly:
    Sergey> macro defined once with one value of QUERY_STRING)

Right.  The (getenv "QUERY_STRING") is being called and expanded in
the initial macro definition (compile-time, not run-time), so
thereafter all calls to that macro expansion will use the same value
of the QUERY_STRING (just like they re-use the same binds and body
without re-expanding the macro).  If you had multiple instances of the
http:let in your source file, each one would separately expand, and
could have different values of QUERY_STRING, but more likely you've
got a handler function for requests and it only does the http:let
once.

To do what you want you're going to have to use an eval, because
whatever you do inside the http:let could reference different
variables which may or may not be defined, and will have to be
compiled accordingly.  The following works (I also fixed it to accept
variable length bodies), though it's not very pretty:

(define-macro (http:let binds . body)
  `(eval (list (quote let)
               (append (http:uri-query-string->lists
                        (getenv "QUERY_STRING"))
                       (list (quote ,@binds)))
               (cons (quote begin) (quote (list ,@body))))
         (current-module)))

This will offer terrible performance.  What you're trying to do is
also awkward in general, because you don't know for certain what
variables are defined, and will have to wrap the whole thing in a
catch (apart from variable references, think what would happen if
someone decided to rebind `let').

It's probably better to simply keep the query-string in an alist or
hash and reference the values when you need them.

-- 
Alex Shinn <address@hidden>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]