From: David L. Rager
Subject: Using apply with a closure with unbound variables
Date: 
Message-ID: <d8pl0q$6q1$1@geraldo.cc.utexas.edu>
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

From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <42B05B95.5010606@no-spam-pleez.cs.utexas.edu>
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
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <42B074F4.2060109@no-spam-pleez.cs.utexas.edu>
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.
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <d8q05e$btk$1@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?

> what's wrong with special bindings?
> 
> (defvar *x*)
> (defparameter *closure* (function (lambda () (+ *x* 4))))
> (let ((*x* 9)) (apply *closure* nil))
> 
From: Geoffrey Summerhayes
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <6P7se.7278$yU.567529@news20.bellglobal.com>
"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 
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <d8sdgg$fet$1@geraldo.cc.utexas.edu>
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.
From: Barry Margolin
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <barmar-CEE791.20320415062005@comcast.dca.giganews.com>
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 ***
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <d8sdh3$fet$2@geraldo.cc.utexas.edu>
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
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <42B06358.60206@no-spam-pleez.cs.utexas.edu>
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?
> 
From: David L. Rager
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <42B063AD.4040903@no-spam-pleez.cs.utexas.edu>
> Examples that go through:
> (let ((q 5)) (p-let ((x 4) (y (+ 2 q)) (+ x y)))

Should be
(let ((q 5)) (p-let ((x 4) (y (+ 2 q))) (+ x y)))
From: Pascal Bourguignon
Subject: Re: Using apply with a closure with unbound variables
Date: 
Message-ID: <87hdfztnun.fsf@thalassa.informatimago.com>
"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