[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: comparing procedures
From: |
Neil Jerram |
Subject: |
Re: comparing procedures |
Date: |
Sat, 26 Jan 2008 13:10:52 +0000 |
User-agent: |
Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) |
Gregory Marton <address@hidden> writes:
> Hi folks,
>
> I'm trying to write a meaningful comparison operator for
> procedures.
Out of interest, why?
> Clearly this wants more than procedure-source, because
> variables in the source may be bound to different values in the
> procedure-environment.
Assuming that your objective is something like "will calling procedure
A have the same effect as calling procedure B", yes.
> I expected something like this to work:
> (define foo 3)
> (define bar (lambda (x) (+ x foo)))
> (define baz (lambda (x) (* x foo)))
> (define bar-env (procedure-environment bar))
> (define baz-env (procedure-environment baz))
OK up to here.
> (environment-fold
> bar-env
> (lambda (sym val so-far)
> (and so-far
> (environment-bound? baz-env sym)
> (equal? val (environment-ref baz-env sym))))
> #t)
Here is the problem. All of the environment-* procedures are an
experimental thing that actual has no current connection to the rest
of Guile.
> But it turns out that procedure-environment returns something which is
> not something these procedures take as an argument, it's an
> eval-closure.
Yes; an "eval-closure" is Guile's term for the top-level environment
of a module.
If the lambda had been defined in a non-top-level environment
(e.g. within a let), procedure-environment would give you something
like this:
(((a b c) . (3 #f (foo bar baz))) ; innermost lexical env vars
((s t) . ("hi" 23)) ; next outer lexical env vars
...
<eval-closure>) ; top level env
> I would have thought that this was the wrong procedure but for
> postings like this:
> http://www.cs.brown.edu/pipermail/plt-scheme/2005-August/009540.html
Well there's nothing wrong with procedure-environment. Perhaps you
could ask William Josephson if you can use his code?
> Could someone point me towards the right way to compare the
> environment of a procedure field by field? (Yes, I also have to make
> sure there are no extra fields in baz-env too, but that part I'll
> figure out.)
Given the above structure, you could compare the elements of the
list that procedure-environment returns. When you get to comparing
two <eval-closure>s, I think the only sensible thing is to use eq?.
I've appended some code below that I just used to explore this a bit.
> Thanks, confusedly,
> Grem
I'm afraid it is a bit confusing, with the environment-* procs sitting
there. I hope the above has helped.
Regards,
Neil
address@hidden:~$ guile
guile> (define p (let ((a 1) (b 2)) (lambda () (list 4 5 6))))
guile> p
#<procedure p ()>
guile> (procedure-environment p)
(((b a) 2 1) #<eval-closure b7c238b0>)
guile> (define q (lambda () #t)
)
guile> (procedure-environment q)
(#<eval-closure b7c238b0>)
guile> (define pe (procedure-environment p))
guile> (define qe (procedure-environment q))
guile> (list? pe)
#t
guile> (list? qe)
#t
guile> (list? (car pe))
#t
guile> (list? (car qe))
#f