[plt-scheme] Procedure equality
On Apr 30, 2009, at 4:24 PM, Alex Shinn wrote:
> Abdulaziz Ghuloum <aghuloum at gmail.com> writes:
>
>> It can go both ways.
>>
>> For example, the expression
>>
>> (let ([foo (lambda () 42)])
>> (eq? foo foo))
>>
>> might be transformed after copy propagation to
>>
>> (eq? (lambda () 42) (lambda () 42))
>>
>> and this expression may evaluate to #f.
>>
>> The same nonguarantee applies to numbers (afaik). For example
>>
>> (let ([x 1.0]) (eq? x x))
>>
>> may return #f.
>
> Isn't the trick here to order the optimization passes so
> that the (eq? x x) => #t rewrite always occurs before the
> copy propagation pass? ;)
No actually. That's insufficient. Consider:
(let ([foo 1.0])
(let ([bar foo])
(eq? foo bar)))
So, you try to do your (eq? x x) => #t rewrites first. Nothing
there, so, you move on.
Now you can copy propagate variables only, and you end up with
(let ([foo 1.0])
(eq? foo foo))
but you already missed that optimization. And if you succeed
that pass (or perform simultaneously with it) a pass that does
copy propagation of constants, you end up with
(eq? 1.0 1.0)
So, doing (eq? x x) => #t rewrites first does not cut it. You
need to do more work (like what Matthew described) in order to
guarantee that you can both copy-propagate and at the same time
maintain that `(let ([x <expr>]) (eq? x x))' always holds.
Also, most effective optimizers do not work as a set of little
micro optimization passes. See Chapter 4 of Oscar Waddell's
dissertation for why that's so.
Aziz,,,