* progv in scheme
@ 2011-09-13 13:54 Panicz Maciej Godek
2011-09-13 14:25 ` Andrew Gwozdziewycz
2011-09-13 17:57 ` Ian Price
0 siblings, 2 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2011-09-13 13:54 UTC (permalink / raw)
To: guile-user
Hello,
Is there any clever way of binding values to the list of unknown
symbols in scheme?
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.
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?
Best regards,
M.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 13:54 progv in scheme Panicz Maciej Godek
@ 2011-09-13 14:25 ` Andrew Gwozdziewycz
2011-09-13 14:26 ` Andrew Gwozdziewycz
2011-09-13 16:04 ` Panicz Maciej Godek
2011-09-13 17:57 ` Ian Price
1 sibling, 2 replies; 14+ messages in thread
From: Andrew Gwozdziewycz @ 2011-09-13 14:25 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
On Tue, Sep 13, 2011 at 9:54 AM, Panicz Maciej Godek
<godek.maciek@gmail.com> wrote:
> Hello,
> Is there any clever way of binding values to the list of unknown
> symbols in scheme?
>
> 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.
>
> 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?
>
> Best regards,
> M.
Seems likely that you could use `syntax-case' to create a `let` out of these:
(define-syntax progv
(lambda (stx)
(define (create-bindings syms vals)
(datum->syntax stx (zip (syntax->datum syms) (syntax->datum vals))))
(syntax-case stx ()
((_ symbols values body ...)
(with-syntax ((bindings (create-bindings #'symbols #'values)))
#'(let bindings
(begin body ...)))))))
;; usage
(progv (foo bar baz) (1 2 3)
(format (current-output-port) "Values: ~a ~a ~a\n" foo bar baz))
;; output: "Values: 1 2 3"
Hope this helps!
Andrew
--
http://www.apgwoz.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 14:25 ` Andrew Gwozdziewycz
@ 2011-09-13 14:26 ` Andrew Gwozdziewycz
2011-09-13 16:04 ` Panicz Maciej Godek
1 sibling, 0 replies; 14+ messages in thread
From: Andrew Gwozdziewycz @ 2011-09-13 14:26 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
On Tue, Sep 13, 2011 at 10:25 AM, Andrew Gwozdziewycz <apgwoz@gmail.com> wrote:
> On Tue, Sep 13, 2011 at 9:54 AM, Panicz Maciej Godek
> <godek.maciek@gmail.com> wrote:
>> Hello,
>> Is there any clever way of binding values to the list of unknown
>> symbols in scheme?
>>
>> 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.
>>
>> 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?
>>
>> Best regards,
>> M.
>
> Seems likely that you could use `syntax-case' to create a `let` out of these:
>
> (define-syntax progv
> (lambda (stx)
> (define (create-bindings syms vals)
> (datum->syntax stx (zip (syntax->datum syms) (syntax->datum vals))))
> (syntax-case stx ()
> ((_ symbols values body ...)
> (with-syntax ((bindings (create-bindings #'symbols #'values)))
> #'(let bindings
> (begin body ...)))))))
>
>
>
> ;; usage
> (progv (foo bar baz) (1 2 3)
> (format (current-output-port) "Values: ~a ~a ~a\n" foo bar baz))
> ;; output: "Values: 1 2 3"
>
> Hope this helps!
>
> Andrew
I should point out that I'm using zip in srfi-1 (use-modules (srfi srfi-1))
--
http://www.apgwoz.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 14:25 ` Andrew Gwozdziewycz
2011-09-13 14:26 ` Andrew Gwozdziewycz
@ 2011-09-13 16:04 ` Panicz Maciej Godek
2011-09-13 16:35 ` Andrew Gwozdziewycz
2011-09-13 17:20 ` Ludovic Courtès
1 sibling, 2 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2011-09-13 16:04 UTC (permalink / raw)
To: Andrew Gwozdziewycz; +Cc: guile-user
2011/9/13, Andrew Gwozdziewycz <apgwoz@gmail.com>:
>
> Seems likely that you could use `syntax-case' to create a `let` out of
> these:
>
> (define-syntax progv
> (lambda (stx)
> (define (create-bindings syms vals)
> (datum->syntax stx (zip (syntax->datum syms) (syntax->datum vals))))
> (syntax-case stx ()
> ((_ symbols values body ...)
> (with-syntax ((bindings (create-bindings #'symbols #'values)))
> #'(let bindings
> (begin body ...)))))))
>
>
>
> ;; usage
> (progv (foo bar baz) (1 2 3)
> (format (current-output-port) "Values: ~a ~a ~a\n" foo bar baz))
> ;; output: "Values: 1 2 3"
Hey,
thanks for this code, maybe one day I will be able to comprehend it :)
for now, the problem is that I want to bind the variables that are
contained within a list, and that I don't know what's in that list.
So, the following code should work as well:
(let ((s '(foo bar baz))
(v '(1 2 3)))
(progv s v
(+ foo bar baz)))
===> 6
regards
M.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 16:04 ` Panicz Maciej Godek
@ 2011-09-13 16:35 ` Andrew Gwozdziewycz
2011-09-13 17:01 ` Bill Schottstaedt
2011-09-13 17:54 ` Bill Schottstaedt
2011-09-13 17:20 ` Ludovic Courtès
1 sibling, 2 replies; 14+ messages in thread
From: Andrew Gwozdziewycz @ 2011-09-13 16:35 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
On Tue, Sep 13, 2011 at 12:04 PM, Panicz Maciej Godek
<godek.maciek@gmail.com> wrote:
> 2011/9/13, Andrew Gwozdziewycz <apgwoz@gmail.com>:
>>
>> Seems likely that you could use `syntax-case' to create a `let` out of
>> these:
>>
>> (define-syntax progv
>> (lambda (stx)
>> (define (create-bindings syms vals)
>> (datum->syntax stx (zip (syntax->datum syms) (syntax->datum vals))))
>> (syntax-case stx ()
>> ((_ symbols values body ...)
>> (with-syntax ((bindings (create-bindings #'symbols #'values)))
>> #'(let bindings
>> (begin body ...)))))))
>>
>>
>>
>> ;; usage
>> (progv (foo bar baz) (1 2 3)
>> (format (current-output-port) "Values: ~a ~a ~a\n" foo bar baz))
>> ;; output: "Values: 1 2 3"
>
> Hey,
> thanks for this code, maybe one day I will be able to comprehend it :)
> for now, the problem is that I want to bind the variables that are
> contained within a list, and that I don't know what's in that list.
>
> So, the following code should work as well:
> (let ((s '(foo bar baz))
> (v '(1 2 3)))
> (progv s v
> (+ foo bar baz)))
> ===> 6
Ah, yes. I believe there's no way around using eval here. The
difficulty of course is compile time vs. runtime.
--
http://www.apgwoz.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 16:35 ` Andrew Gwozdziewycz
@ 2011-09-13 17:01 ` Bill Schottstaedt
2011-09-13 17:54 ` Bill Schottstaedt
1 sibling, 0 replies; 14+ messages in thread
From: Bill Schottstaedt @ 2011-09-13 17:01 UTC (permalink / raw)
To: guile-user
I think this works in Guile 1.8.7 (I don't have a later version):
(define-macro (progv vars vals . body)
`(let (,@(map (lambda (var val)
(list var val))
(cadr vars)
(cadr vals)))
,@body))
(progv '(one two) '(1 2) (+ one two))
3
Maybe prettier syntax:
(define-macro (progv vars vals . body)
`(let (,@(map (lambda (var val)
(list var val))
vars vals))
,@body))
(progv (one two) (1 2) (+ one two))
3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 16:04 ` Panicz Maciej Godek
2011-09-13 16:35 ` Andrew Gwozdziewycz
@ 2011-09-13 17:20 ` Ludovic Courtès
1 sibling, 0 replies; 14+ messages in thread
From: Ludovic Courtès @ 2011-09-13 17:20 UTC (permalink / raw)
To: guile-user
Hi,
Panicz Maciej Godek <godek.maciek@gmail.com> skribis:
> for now, the problem is that I want to bind the variables that are
> contained within a list, and that I don't know what's in that list.
I would recommend using (ice-9 match):
(match '(1 2 3)
((a b c) `((a . ,a) (b . ,b) (c . ,c))))
=> ((a . 1) (b . 2) (c . 3))
HTH,
Ludo’.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 16:35 ` Andrew Gwozdziewycz
2011-09-13 17:01 ` Bill Schottstaedt
@ 2011-09-13 17:54 ` Bill Schottstaedt
1 sibling, 0 replies; 14+ messages in thread
From: Bill Schottstaedt @ 2011-09-13 17:54 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
> and that I don't know what's in that list.
oops, I missed that requirement. hmmm -- there must be a way.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 13:54 progv in scheme Panicz Maciej Godek
2011-09-13 14:25 ` Andrew Gwozdziewycz
@ 2011-09-13 17:57 ` Ian Price
2011-09-13 18:48 ` Panicz Maciej Godek
1 sibling, 1 reply; 14+ messages in thread
From: Ian Price @ 2011-09-13 17:57 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
Panicz Maciej Godek <godek.maciek@gmail.com> 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"
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 17:57 ` Ian Price
@ 2011-09-13 18:48 ` Panicz Maciej Godek
2011-09-13 19:09 ` Bill Schottstaedt
0 siblings, 1 reply; 14+ messages in thread
From: Panicz Maciej Godek @ 2011-09-13 18:48 UTC (permalink / raw)
To: Ian Price; +Cc: guile-user
2011/9/13, Ian Price <ianprice90@googlemail.com>:
>> 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. :-)
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
this limitation)
Thanks,
M.
>> 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"
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 18:48 ` Panicz Maciej Godek
@ 2011-09-13 19:09 ` Bill Schottstaedt
2011-09-13 19:16 ` Andrew Gwozdziewycz
2011-09-15 18:11 ` Andy Wingo
0 siblings, 2 replies; 14+ messages in thread
From: Bill Schottstaedt @ 2011-09-13 19:09 UTC (permalink / raw)
To: Panicz Maciej Godek; +Cc: guile-user
if lambda were applicable, this would work in both cases:
(define-macro (progv vars vals . body)
`(apply (apply lambda ,vars ',body) ,vals))
> (let ((s '(one two)) (v '(1 2))) (progv s v (+ one two)))
3
> (progv '(one two) '(1 2) (+ one two))
3
(running a mystery scheme...)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 19:09 ` Bill Schottstaedt
@ 2011-09-13 19:16 ` Andrew Gwozdziewycz
2011-09-15 18:11 ` Andy Wingo
1 sibling, 0 replies; 14+ messages in thread
From: Andrew Gwozdziewycz @ 2011-09-13 19:16 UTC (permalink / raw)
To: Bill Schottstaedt; +Cc: guile-user
On Tue, Sep 13, 2011 at 3:09 PM, Bill Schottstaedt
<bil@ccrma.stanford.edu> wrote:
> if lambda were applicable, this would work in both cases:
>
> (define-macro (progv vars vals . body)
> `(apply (apply lambda ,vars ',body) ,vals))
>
>> (let ((s '(one two)) (v '(1 2))) (progv s v (+ one two)))
> 3
>> (progv '(one two) '(1 2) (+ one two))
> 3
>
> (running a mystery scheme...)
Bill-
It seems as though this would work actually in many schemes that do
incremental expansion of macros as part of their eval. If eval was
written as such:
(define (eval form env)
(cond
((self-evaluating? form) form)
((variable? form) (lookup env (car form)))
(...
((macro? form env) (eval (expand-macro (car form) (cdr form)) env))
...))
Then it seems as though it'd work perfectly fine. I haven't been using
guile very long, but it seems as though it's doing bytecode
compilation, which makes the story a bit different.
(I could totally be wrong of course)
--
http://www.apgwoz.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-13 19:09 ` Bill Schottstaedt
2011-09-13 19:16 ` Andrew Gwozdziewycz
@ 2011-09-15 18:11 ` Andy Wingo
2011-09-15 18:16 ` Andrew Gwozdziewycz
1 sibling, 1 reply; 14+ messages in thread
From: Andy Wingo @ 2011-09-15 18:11 UTC (permalink / raw)
To: Bill Schottstaedt; +Cc: guile-user
On Tue 13 Sep 2011 12:09, "Bill Schottstaedt" <bil@ccrma.Stanford.EDU> writes:
> if lambda were applicable, this would work in both cases:
>
> (define-macro (progv vars vals . body)
> `(apply (apply lambda ,vars ',body) ,vals))
That's fun! Makes me think of Kernel. I think you'd enjoy Kernel,
Bill, if you haven't seen it already.
http://fexpr.blogspot.com/2011/04/fexpr.html
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: progv in scheme
2011-09-15 18:11 ` Andy Wingo
@ 2011-09-15 18:16 ` Andrew Gwozdziewycz
0 siblings, 0 replies; 14+ messages in thread
From: Andrew Gwozdziewycz @ 2011-09-15 18:16 UTC (permalink / raw)
To: Andy Wingo; +Cc: Bill Schottstaedt, guile-user
That's exactly what I was thinking, Kernel that is. But, I didn't
wanna sound like an idiot saying, "if only we had FExprs"...
On Thu, Sep 15, 2011 at 2:11 PM, Andy Wingo <wingo@pobox.com> wrote:
> On Tue 13 Sep 2011 12:09, "Bill Schottstaedt" <bil@ccrma.Stanford.EDU> writes:
>
>> if lambda were applicable, this would work in both cases:
>>
>> (define-macro (progv vars vals . body)
>> `(apply (apply lambda ,vars ',body) ,vals))
>
> That's fun! Makes me think of Kernel. I think you'd enjoy Kernel,
> Bill, if you haven't seen it already.
>
> http://fexpr.blogspot.com/2011/04/fexpr.html
>
> Andy
> --
> http://wingolog.org/
>
>
--
http://www.apgwoz.com
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-09-15 18:16 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-13 13:54 progv in scheme Panicz Maciej Godek
2011-09-13 14:25 ` Andrew Gwozdziewycz
2011-09-13 14:26 ` Andrew Gwozdziewycz
2011-09-13 16:04 ` Panicz Maciej Godek
2011-09-13 16:35 ` Andrew Gwozdziewycz
2011-09-13 17:01 ` Bill Schottstaedt
2011-09-13 17:54 ` Bill Schottstaedt
2011-09-13 17:20 ` Ludovic Courtès
2011-09-13 17:57 ` Ian Price
2011-09-13 18:48 ` Panicz Maciej Godek
2011-09-13 19:09 ` Bill Schottstaedt
2011-09-13 19:16 ` Andrew Gwozdziewycz
2011-09-15 18:11 ` Andy Wingo
2011-09-15 18:16 ` Andrew Gwozdziewycz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).