Hello All,
I would like to be able to do the following, and I'm guessing the spec
prohibits it. Here's the code that demonstrates:
(setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
(apply *tmp* nil)
The story: I need to be able to bind values in the current environment
to free variables inside a function closure. This almost by definition
violates the concept of a closure, so I'm not sure it can be done, but I
am sure this is a great place to ask.
Thanks,
David
A way to add bindings to a closure's list of bindings would work....
David L. Rager wrote:
> Hello All,
>
> I would like to be able to do the following, and I'm guessing the spec
> prohibits it. Here's the code that demonstrates:
>
> (setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
> (apply *tmp* nil)
>
> The story: I need to be able to bind values in the current environment
> to free variables inside a function closure. This almost by definition
> violates the concept of a closure, so I'm not sure it can be done, but I
> am sure this is a great place to ask.
>
> Thanks,
> David
This is what I meant to post as my original problem - sorry about the
confusion:
(setf *closure* (function (lambda () (+ x 4))))
(let ((x 9)) (apply *closure* nil))
From: Sam Steingold
Subject: Re: Using apply with a closure with unbound variables
Date:
Message-ID: <uekb3jvor.fsf@gnu.org>
> * David L. Rager <·······@ab-fcnz-cyrrm.pf.hgrknf.rqh> [2005-06-15 13:35:32 -0500]:
>
> This is what I meant to post as my original problem - sorry about the
> confusion:
>
> (setf *closure* (function (lambda () (+ x 4))))
> (let ((x 9)) (apply *closure* nil))
what's wrong with special bindings?
(defvar *x*)
(defparameter *closure* (function (lambda () (+ *x* 4))))
(let ((*x* 9)) (apply *closure* nil))
--
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://ffii.org/> <http://www.dhimmi.com/> <http://www.camera.org>
<http://www.memri.org/> <http://pmw.org.il/> <http://www.mideasttruth.com/>
The difference between theory and practice is that in theory there isn't any.
Unfortunately, I'm trying to avoid manually finding every variable that
needs to be defined - I think it would equate to searching the body of a
let expression for all free variables, and making them arguments to the
function saved in *closure*.
Thanks for the response - are there further developments on this idea or
any other ideas?
> what's wrong with special bindings?
>
> (defvar *x*)
> (defparameter *closure* (function (lambda () (+ *x* 4))))
> (let ((*x* 9)) (apply *closure* nil))
>
"David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> wrote in message ·················@geraldo.cc.utexas.edu...
> Unfortunately, I'm trying to avoid manually finding every variable that needs to be defined - I think it would equate to searching
> the body of a let expression for all free variables, and making them arguments to the function saved in *closure*.
>
> Thanks for the response - are there further developments on this idea or any other ideas?
>
Is this what you're trying to do?
(defmacro p-let(bindings body)
`(let ,bindings
(declare (special ,@(mapcar (lambda (x)
(if (atom x) x (first x)))
bindings)))
,body))
> (defparameter *closure* (lambda() (let ((y 5)) (+ x y))))
*CLOSURE*
> (p-let ((x 3)) (funcall *closure*))
8
--
Geoff
Pretty darn close - I think we can consider this topic closed with your
suggestion :).
Thx.
From: Sam Steingold
Subject: Re: Using apply with a closure with unbound variables
Date:
Message-ID: <uis0egmce.fsf@gnu.org>
> * David L. Rager <·······@ab-fcnz-cyrrm.pf.hgrknf.rqh> [2005-06-15 14:39:20 -0500]:
>
> Unfortunately, I'm trying to avoid manually finding every variable
> that needs to be defined - I think it would equate to searching the
> body of a let expression for all free variables, and making them
> arguments to the function saved in *closure*.
this is a bad approach - like using implicit variables in Fortran.
you are setting yourself up for a big mess.
--
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.memri.org/> <http://www.dhimmi.com/>
<http://ffii.org/> <http://www.iris.org.il> <http://www.mideasttruth.com/>
Beauty is only a light switch away.
From: Kent M Pitman
Subject: Re: Using apply with a closure with unbound variables
Date:
Message-ID: <ubr65ybck.fsf@nhplace.com>
"David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> writes:
> Unfortunately, I'm trying to avoid manually finding every variable
> that needs to be defined - I think it would equate to searching the
> body of a let expression for all free variables, and making them
> arguments to the function saved in *closure*.
>
> Thanks for the response - are there further developments on this idea
> or any other ideas?
>
> > what's wrong with special bindings?
> > (defvar *x*)
> > (defparameter *closure* (function (lambda () (+ *x* 4))))
> > (let ((*x* 9)) (apply *closure* nil))
> >
This is the place where we are to ask:
What are you REALLY trying to do?
Your problem is expressed in terms of a programmatic desire,
rather than as a True Problem. Back up, go meta, or do whatever
you have to do to explain how you got this far down the alley.
In article <················@no-spam-pleez.cs.utexas.edu>,
"David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> wrote:
> This is what I meant to post as my original problem - sorry about the
> confusion:
>
> (setf *closure* (function (lambda () (+ x 4))))
> (let ((x 9)) (apply *closure* nil))
By default, LET creates lexical bindings, which means they're only
visible to code lexically within its body. Since the body of that
closure is outside the LET, it cannot access the local binding. You'd
need to declare X special in the LET and the closure for them to find
each other (most implementations will do this automatically for the
closure, because they can see that there's no surrounding binding of the
free variable, but you still have to make it explicit for the LET).
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Thanks for the explanation
> By default, LET creates lexical bindings, which means they're only
> visible to code lexically within its body. Since the body of that
> closure is outside the LET, it cannot access the local binding. You'd
> need to declare X special in the LET and the closure for them to find
> each other (most implementations will do this automatically for the
> closure, because they can see that there's no surrounding binding of the
> free variable, but you still have to make it explicit for the LET).
>
From: Marco Baringer
Subject: Re: Using apply with a closure with unbound variables
Date:
Message-ID: <m2fyvj35sc.fsf@soma.local>
"David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> writes:
> Hello All,
>
> I would like to be able to do the following, and I'm guessing the spec
> prohibits it. Here's the code that demonstrates:
>
> (setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
> (apply *tmp* nil)
>
> The story: I need to be able to bind values in the current environment
> to free variables inside a function closure. This almost by definition
> violates the concept of a closure, so I'm not sure it can be done, but
> I am sure this is a great place to ask.
i don't understannd the question, can you send some of code which
defines these closures you need to work with?
--
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
-Leonard Cohen
Sure - please don't kill me for writing a recursive macro. Also, you
might want to read this code from the bottom of the post, since it's
sequential. I think I addressed all the relevant functions.
(defmacro function-for-funcall (x)
`(function (lambda () ,x)))
(defmacro assoc-for-binding (x)
`(cons (quote ,(car x)) ; label for the function closure
(function-for-funcall ,(cadr x))))
;; returns an association list of labels and function closures Ex:
;; ((x . fobj4)
;; (y . fobj5))
;; fobj means function object/closure
(defmacro assoc-for-bindings (x)
(if (atom x)
nil
`(cons (assoc-for-binding ,(car x))
;; taking ,cdr x and not ,(assoc-f...cdr x) forces lazy
;; evaluation
(assoc-for-bindings ,(cdr x)))))
;;; separate-bindings-and-closures takes the list
;;; ((x . fobj4) (y . fobj5)) and returns
;;; ((x y) (fobj4 fobj5))
;;; parallelize-fn is a function I wrote - all we need to know is that
;;; in the way I call it, the call:
;;; (parallelize-fn 'identity-list (fobj4 fobj5)) returns:
;;; (list (apply fobj4 nil) (apply fobj5 nil))
(defun p-let-fn (binding-and-closure-list body-closure)
(mv-let (binding-list closure-list)
(separate-bindings-and-closures binding-and-closure-list)
(do-let binding-list
(parallelize-fn 'identity-list closure-list)
body-closure)))
;;; you can already see the problem since, p-let-fn takes a
;;; closure for the body of the let as illustrated below
(defmacro p-let (bindings body) ;(&rest rst)
`(p-let-fn
`,(assoc-for-bindings ,bindings)
(function-for-funcall ,body)))
;;; There are restrictions on the amount of parallelization, but I
;;; have removed them to make the example a little simpler
Examples that go through:
(p-let ((x 4) (y 7)) (+ x y))
(p-let ((x 4) (y (+ 2 5)) (+ x y))
(let ((q 5)) (p-let ((x 4) (y (+ 2 q)) (+ x y)))
Example that does not go through, and my current problem:
(let ((q 5)) (p-let ((x 4)) (+ x q)))
Thanks,
David
Marco Baringer wrote:
> "David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> writes:
>
>
>>Hello All,
>>
>>I would like to be able to do the following, and I'm guessing the spec
>>prohibits it. Here's the code that demonstrates:
>>
>>(setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
>>(apply *tmp* nil)
>>
>>The story: I need to be able to bind values in the current environment
>>to free variables inside a function closure. This almost by definition
>>violates the concept of a closure, so I'm not sure it can be done, but
>>I am sure this is a great place to ask.
>
>
> i don't understannd the question, can you send some of code which
> defines these closures you need to work with?
>
"David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> writes:
> I would like to be able to do the following, and I'm guessing the spec
> prohibits it. Here's the code that demonstrates:
>
> (setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
> (apply *tmp* nil)
What is assoc-for-bindings?
> The story: I need to be able to bind values in the current environment
> to free variables inside a function closure. This almost by definition
> violates the concept of a closure, so I'm not sure it can be done, but
> I am sure this is a great place to ask.
(defparameter *tmp* (let ((q 9)) (lambda (x) (list x q))))
(apply *tmp* nil) ; here I bind the 'free variable' x to the constant nil.
(let ((y 3)) (apply *tmp* y)) ; here I bind the 'free variable' x to the
; value of the lexical variable y.
--
__Pascal Bourguignon__ http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he does not
want merely because you think it would be good for him. -- Robert Heinlein
From: Thomas A. Russ
Subject: Re: Using apply with a closure with unbound variables
Date:
Message-ID: <ymihdfwu8x7.fsf@sevak.isi.edu>
Pascal Bourguignon <···@informatimago.com> writes:
>
> "David L. Rager" <·······@no-spam-pleez.cs.utexas.edu> writes:
> > I would like to be able to do the following, and I'm guessing the spec
> > prohibits it. Here's the code that demonstrates:
> >
> > (setf *tmp* (let ((q 9)) (assoc-for-bindings ((x q)))))
> > (apply *tmp* nil)
>
> What is assoc-for-bindings?
>
> > The story: I need to be able to bind values in the current environment
> > to free variables inside a function closure. This almost by definition
> > violates the concept of a closure, so I'm not sure it can be done, but
> > I am sure this is a great place to ask.
>
> (defparameter *tmp* (let ((q 9)) (lambda (x) (list x q))))
> (apply *tmp* nil) ; here I bind the 'free variable' x to the constant nil.
Actually, not quite. It doesn't get a binding, since the last argument
to APPLY is a list of argument values. This would work with FUNCALL instead.
> (let ((y 3)) (apply *tmp* y)) ; here I bind the 'free variable' x to the
> ; value of the lexical variable y.
Same thing. You need either (list y) or FUNCALL.
--
Thomas A. Russ, USC/Information Sciences Institute