guile-user
[Top][All Lists]
Advanced

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

Re: set-pair!


From: Clinton Ebadi
Subject: Re: set-pair!
Date: Wed, 20 Aug 2008 12:34:56 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux)

"Maciek Godek" <address@hidden> writes:

> Hi,
> I've been trying to write a function or macro that
> would work like this:
>
> (let ((a 0)(b 0))
>   (set-pair! '(a . b) '(1 . 2))
>   (cons a b)) ; => (1 . 2)
>
> I eventually wrote:
>
> (define (set-pair! pair values)
>   (let ( (e (the-environment)) (a (car pair)) (d (cdr pair)) )
>      (local-eval
>         `(begin
>              (set! ,a ,(car values))
>              (set! ,d ,(cdr values)))
>          e)))
>
> but it seems to work only for symbols defined in
> global scope. Does anyone know how to implement
> this form properly?

You should use a macro instead... something like:

(define-macro (mset! . forms)
  `(begin
     ,@(let mset-loop ((unprocessed-forms forms)
                       (processed-forms '()))
        (cond ((null? unprocessed-forms)
               (reverse! processed-forms))
              (else (mset-loop (cddr unprocessed-forms)
                               (cons `(set! ,(car unprocessed-forms)
                                            ,(cadr unprocessed-forms))
                                     processed-forms)))))))

(let ((a 0)
      (b 0))
  (mset! a 1 b 2) ; => (begin (set! a 1) (set! b 2))
  (cons a b)) ; => (1 . 2)

The syntax for mset! is the same as Common Lisp's setf[0]. You can
easily adjust it to take the form (mset! (variables) (values)) if you
really wanted. The macro version will interact properly with the local
environment, and still work whenever local-eval is removed.

Whenever you think you need local-eval you probably need a
macro. Destructively modifying environments at runtime is heavily
discouraged, and more or less deprecated (Guile acros and macros are
deprecated in favor of mmacros for a reason--runtime modification of
lexical environments is incompatible with a properly phase-separated
compiler).

[0] http://www.lispworks.com/documentation/HyperSpec/Body/m_setf_.htm

-- 
Danielle: well road signs were pissing me off
Danielle: I took one of them out, but the other haven't followed as
          planned




reply via email to

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