Lisp HUG Maillist Archive

Help with macro, please

In my HTTP package for LW I have a with-headers macro.

https://github.com/massung/http/blob/master/http.lisp#L250

It is used like so:

(with-headers ((content-length "Content-Length")
               (content-type "Content-Type" :if-not-found "text/plain"))
    (response-headers response)
  (print content-length)
  (print content-type))

However, I'd like to extend the macro so that the variables (e.g. content-length and content-type, among any others) are setf-able from within the macro body, which would overwrite the header value in the response (or request).

I've been trying to find a really good way to do this with a symbol-macrolet, but have been fairly unsuccessful, mostly because it requires an assoc call and I don't want to add the header in the :if-not-found case unless a setf is performed.

My attempts have roughly followed this train of thought:

* Create a 'place' variable that is the assoc lookup.
* Then create a symbol-macrolet that is defined as (second place), which is setf-able.

But, when place is nil, I'm not sure how to go about adding the header (and subsequently redefining the place). I'm also very willing to remove the :if-not-found keyword if it dramatically simplifies the problem.

Thanks in advance for any helpful tips.

Jeff M.

Re: Help with macro, please

Hi, does this help?

(let ((alist (list (cons 'x 3) (cons 'y 4) (cons 'z 5))))
  (flet (((setf lookup) (new-value key)
           (setf (cdr (assoc key alist)) new-value)))
    (symbol-macrolet ((y (lookup 'y)))
      (setf y 99)
      alist)))

;; => ((X . 3) (Y . 99) (Z . 5))

Regards,
lmj

On Mon, Apr 7, 2014 at 9:41 AM, Jeffrey Massung <massung@gmail.com> wrote:
> In my HTTP package for LW I have a with-headers macro.
>
> https://github.com/massung/http/blob/master/http.lisp#L250
>
> It is used like so:
>
> (with-headers ((content-length "Content-Length")
>                (content-type "Content-Type" :if-not-found "text/plain"))
>     (response-headers response)
>   (print content-length)
>   (print content-type))
>
> However, I'd like to extend the macro so that the variables (e.g.
> content-length and content-type, among any others) are setf-able from within
> the macro body, which would overwrite the header value in the response (or
> request).
>
> I've been trying to find a really good way to do this with a
> symbol-macrolet, but have been fairly unsuccessful, mostly because it
> requires an assoc call and I don't want to add the header in the
> :if-not-found case unless a setf is performed.
>
> My attempts have roughly followed this train of thought:
>
> * Create a 'place' variable that is the assoc lookup.
> * Then create a symbol-macrolet that is defined as (second place), which is
> setf-able.
>
> But, when place is nil, I'm not sure how to go about adding the header (and
> subsequently redefining the place). I'm also very willing to remove the
> :if-not-found keyword if it dramatically simplifies the problem.
>
> Thanks in advance for any helpful tips.
>
> Jeff M.

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Updated at: 2020-12-10 08:34 UTC