guile-user
[Top][All Lists]
Advanced

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

Re: progv in scheme


From: Ian Price
Subject: Re: progv in scheme
Date: Tue, 13 Sep 2011 18:57:48 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

Panicz Maciej Godek <address@hidden> writes:

> Hello,
> Is there any clever way of binding values to the list of unknown
> symbols in scheme?
I have to admit, I don't understand why you would want to bind values
to a list of _unknown_ symbols; changing random bindings is just asking
for trouble. :-)

> In common lisp there is a form "progv" that takes the list of symbols
> and their corresponding values and binds them within the body of
> progv.
Strictly, this isn't what 'progv' does. 'progv' creates new _dynamic_
bindings, not lexical ones. e.g.

(setq *x* 1)
(defun foo () (write *x*))
(foo)
prints 1
(progv '(*x*) '(4) (foo))
prints 4

> It is possible to do it using eval, like this:
> (define (bind-and-eval symbols values body)
> (eval `((lambda ,symbols ,body) . ,values)
>       (interaction-environment)))
> (define-syntax let-symbols
> (syntax-rules ()
>   ((_ symbols values (body ...))
>    (bind-and-eval symbols values (quote (body ...))))))
>
> but using eval for this just seems too heavy. Is there any way of
> doing it that would be more legal?
Not really, doing so would break lexical scope. In a lexically
scoped language, the symbol isn't what matters; the "location" is. An
implementation is free to rename your identifiers, and once you reach
run-time, all the names have been forgotten anyway. Of course, there are
'unnatural' ways of expressing this, as you did with 'eval'.

If you know the list before hand, you can use match.

(use-modules (ice-9 match)

(match (list 1 2 3)
  ((a b c) (list 'success b c a))
  (else 'fail))
; => (success 2 3 1)

If you want 'dynamic variables', then Scheme does not provide them, but
there are 'fluids' or 'parameters' which behave similarly.

(define x (make-fluid))

(define (print)
  (write (fluid-ref x)))

(cons (fluid-ref x)
      (with-fluids* (list x) '(rebound)
        (lambda () (print) (fluid-ref x))))
;; => (#f . rebound)
;; prints 'rebound        

Hope that helps

-- 
Ian Price

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



reply via email to

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