Aha, thank you, very nice, ok so it can be done in demonstration now, though kind of not more than that.
What drove me to ask this question was that it could be used for some kinds of type checking and possibly as part of a type system, that maybe could be very useful.
Roughly approx what step would be needed to make (procedure-creator) also work for the compiled world? Is there any issue about that the underlying information is destroyed during compilation currently, due to inlining or alike?
Kind regards, Mikael
2011/3/11 Marc Feeley feeley@iro.umontreal.ca
On 2011-03-11, at 7:14 AM, Mikael wrote:
Dear Marc,
Is there any way to get which procedure a closure comes from? If not,
would it be very easy to implement? Just wanted to check.
Kind regards, Mikael
It is possible with interpreted code because the "run time environment" (rte) that is stored in the closures has back-pointers to the closure that created it (also known as the "container" procedure). Below is the code, and a demo.
Marc
(define (procedure-creator proc) (if (##interp-procedure? proc) (let* (($code (##interp-procedure-code proc)) (rte (##interp-procedure-rte proc))) (##extract-container $code rte)) #f)) ;; not possible with compiled code, so return #f
(define (make-adder3 x) (lambda (y) (lambda (z) (+ x y z))))
(define f ((make-adder3 11) 22))
(pretty-print (f 33)) (pretty-print (procedure-creator f))
(pp f) (pp (procedure-creator f)) (pp (procedure-creator (procedure-creator f))) (pp (procedure-creator (procedure-creator (procedure-creator f))))
(pp (eq? make-adder3 (procedure-creator (procedure-creator f))))
;; prints: ;; ;; 66 ;; #<procedure #2> ;; (lambda (z) (+ x y z)) ;; (lambda (y) (lambda (z) (+ x y z))) ;; (lambda (x) (lambda (y) (lambda (z) (+ x y z)))) ;; #f ;; #t