unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* comparing procedures
@ 2008-01-25 19:39 Gregory Marton
  2008-01-26 13:10 ` Neil Jerram
  0 siblings, 1 reply; 2+ messages in thread
From: Gregory Marton @ 2008-01-25 19:39 UTC (permalink / raw)
  To: bug-guile

Hi folks,

I'm trying to write a meaningful comparison operator for procedures. 
Clearly this wants more than procedure-source, because variables in the 
source may be bound to different values in the procedure-environment.

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))
(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)

But it turns out that procedure-environment returns something which is not 
something these procedures take as an argument, it's an eval-closure.
(environment? bar-env) ===> #f
(environment? (car bar-env)) ===> #f

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

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.)

I did dig a little farther, because I can still do this:
(local-eval 'foo bar-env) ===> 3
and local-eval says:
   -- Scheme Procedure: local-eval exp [env]
       Evaluate EXP in its environment.  If ENV is supplied, it is the
       environment in which to evaluate EXP.  Otherwise, EXP must be a
       memoized code object (in which case, its environment is implicit).

But perhaps not all environments are created equal?

This is in 1.8.1 and 1.8.3.

Thanks, confusedly,
Grem

-- 
------ __@   Gregory A. Marton                http://csail.mit.edu/~gremio/
--- _`\<,_                                                                .
-- (*)/ (*)             Contents may have settled out of court.
~~~~~~~~~~~~~~~~-~~~~~~~~_~~~_~~~~~v~~~~^^^^~~~~~--~~~~~~~~~~~~~~~++~~~~~~~





^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: comparing procedures
  2008-01-25 19:39 comparing procedures Gregory Marton
@ 2008-01-26 13:10 ` Neil Jerram
  0 siblings, 0 replies; 2+ messages in thread
From: Neil Jerram @ 2008-01-26 13:10 UTC (permalink / raw)
  To: Gregory Marton; +Cc: bug-guile

Gregory Marton <gremio@csail.mit.edu> 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


neil@arudy:~$ 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





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-01-26 13:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-25 19:39 comparing procedures Gregory Marton
2008-01-26 13:10 ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).