eliot@phoenix.Princeton.EDU (Eliot Handelman) (03/07/89)
The situation is this: a process, represented as a closure, spawns a child, another closure. The parent then runs the child, and when the child finishes it returns to the parent. I am doing this using continuations, that is, the child is passed the parent closure which it then funcalls when it has finished. So the parent has to be able to pass itself to the child. I can let a closure reference itself in the following way: (defun make-closure () (let (-self-) (setq -self- #'(lambda () <this closure can now reference itself as -self->)))) Does this seem like a particularly bad idea? Is there some important reason why I would not want to do this? Is there some reason why I wouldn't want to use SETQ? Can this be done more elegantly? All criticism welcome. Thanks, Eliot
Krulwich-Bruce@cs.yale.edu (Bruce Krulwich) (03/07/89)
In article <6859@phoenix.Princeton.EDU>, eliot@phoenix (Eliot Handelman) writes: >The situation is this: a process, represented as a closure, spawns a >child, another closure. The parent then runs the child, and when the >child finishes it returns to the parent. I am doing this using continuations, >that is, the child is passed the parent closure which it then funcalls >when it has finished. So the parent has to be able to pass itself to the >child. > >(defun make-closure () > (let (-self-) > (setq -self- #'(lambda () > <this closure can now reference itself as -self->)))) > >Does this seem like a particularly bad idea? Is there some important reason >why I would not want to do this? Is there some reason why I wouldn't >want to use SETQ? Can this be done more elegantly? All criticism welcome. There is no need to use the LET/SETQ combination because the LABELS construct (CLtL p113) exists exactly for this reason. LABELS allows definition of local functions that can reference themselves and each other recursively. The above code can be written as: (defun make-closure () (labels ((-self- () <code that can reference -self-> )) -self-)) If you really tend towards the boroque you can use "Church's Y operator" which is defined in Scheme using: (define (y f) ((lambda (g) (lambda (h) ((f (g g)) h))) (lambda (g) (lambda (h) ((f (g g)) h))))) (the CL version would have alot of FUNCALL and #'s thrown in) to make recursive closures without using "explicit" recursion constructs. Using the above definition you can make a closure to recursively compute the factorial function by calling: (y (lambda (fn) (lambda (x) (if (zerop x) 1 (* x (fn (- x 1))))))) Anyway, LABELS is what you want. Bruce Krulwich
johnson@csli.STANFORD.EDU (Mark Johnson) (03/08/89)
Bruce Krulwich is quite correct - the LABELS form is what you need to make these self-referencing closures. His example contains a minor bug, however: he forgot to use #' in front of the final -self- form. The corrected version is: (defun make-closure () (labels ((self () (print 'hello))) #'self)) Too much Scheme! Someone else just sent a message on the net asking why CommonLisp uses different name spaces for variable and function definitions. Personally, I think that this is one of the worst features of CommonLisp. It makes my programs look like fields of #' symbols and funcalls. It is also one of the hardest things for students to learn - they get continually confused between the use of LIST as a function and a variable. (I know it's bad programming style, but people do do it). Mark Johnson
barmar@think.COM (Barry Margolin) (03/08/89)
In article <52880@yale-celray.yale.UUCP> Krulwich-Bruce@cs.yale.edu (Bruce Krulwich) writes: > (defun make-closure () > (labels ((-self- () <code that can reference -self-> )) > -self-)) Actually, the last form should be #'-self-, since LABELS binds the functional value, not the variable value, of the symbol. >If you really tend towards the boroque you can use "Church's Y operator" which >is defined in Scheme using: You could also simply use LETREC in Scheme. It binds a variable and arranges for the scope to include the value form. Barry Margolin Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
Krulwich-Bruce@cs.yale.edu (Bruce Krulwich) (03/08/89)
In article <37134@think.UUCP>, barmar@think (Barry Margolin) writes: >Actually, the last form should be #'-self-, since LABELS binds the >functional value, not the variable value, of the symbol. > >>If you really tend towards the boroque you can use "Church's Y operator" >>which is defined in Scheme using: > >You could also simply use LETREC in Scheme. It binds a variable and >arranges for the scope to include the value form. Scheme's LETREC is (essentially) the same as CL's LABELS. I was trying to show something different by discussion the Y operator. Bruce