* 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: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 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 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).