[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: progv in scheme
Panicz Maciej Godek
Re: progv in scheme
Tue, 13 Sep 2011 20:48:59 +0200
2011/9/13, Ian Price <address@hidden>:
>> 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. :-)
The existence is asking for trouble :)
Actually I've been porting a pattern matcher described by
Peter Norvig (in his great "Paradigms of AI Programming")
from common lisp to scheme.
The pattern matcher differs in many ways from the one
provided with guile -- it is not implemented with reader
macros and therefore it does not syntactically bind the
variables that appear in the pattern forms; instead,
it returns an assoc list containing symbols and values.
Norvig allows to place arbitrary code within the pattern
forms, so a call to eval is inevitable in the long run;
I thought, however, that maybe there could be some other
way to introduce a variable to a scope.
I do like the pattern matcher designed by Andrew K. Wright
and written by Alex Shinn, but it lacks some capabilities,
and the pattern language is still too difficult for me to
apprehend, and so it is hard for me to modify it. (The
author didn't allow to use multiple ellipses at one
level, because he "didn't want to make it easy to construct
very expensive operations", and I don't know how to bypass
>> 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
> Strictly, this isn't what 'progv' does. 'progv' creates new _dynamic_
> bindings, not lexical ones. e.g.
> (setq *x* 1)
> (defun foo () (write *x*))
> 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)
>> (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"