[plt-scheme] exception in local variable access from augmented method
On Sat, 6 Dec 2008, Matthew Flatt wrote:
> At Fri, 5 Dec 2008 00:07:51 -0500 (EST), Dimitris Vyzovitis wrote:
>> I am trying to mutate a local variable from an augmented method, but all I
>> get is a horrible exception. Here is an example:
>> (define Frame%
>> (class frame%
>> (define foo 0)
>> (define (can-close?)
>> (printf "~a~n" foo)
>> (set! foo (add1 foo))
>> #t)
>> (augment can-close?)
>> (super-new)))
>>
>> (define xx (new Frame% (label "Foo") (width 300) (height 300)))
>> (send xx show #t)
>> (yield 'wait)
>>
>> <click>
>> 0
>> procedure application: expected procedure, given: 0; arguments were: 0 1
>
> I haven't been able to get that error when running the code above,
> either under Mac OS X or X11. I put "#lang scheme/gui" at the beginning
> of the code and tried running in both DrScheme (Module language) and
> MrEd. I'm assuming that "<click>" means clicking to close the frame.
yes. I am running with 'mred -iqz', X11
>
> Is there more to the program or a different way I should run it?
Aha, there is: there was a set! replacement that was loaded that I forgot
was there. The said set! replacement does expand to the built-in set!
(of course) and in general has worked for me as expected -- expect when
I try to mutate local variables inside lifted class methods (it happens
with override as well, not just augment).
So, after some digging, the problem is coming from the set!-transformer
expansion; here is a distilled version that triggers the problem:
(module test scheme/base
(require (for-syntax scheme/base))
(provide (rename-out (~set! set!)))
(define-syntax (~set! stx)
(syntax-case stx ()
((_ tgt v)
(and (identifier? #'tgt)
(set!-transformer? (syntax-local-value #'tgt (lambda () #f))))
((set!-transformer-procedure (syntax-local-value #'tgt)) stx))
((_ tgt v)
(datum->syntax stx (syntax-e #'(set! tgt v)))))))
(require 'test)
(define Frame% ...) ; as before
(define xx (new Frame% (label "Foo") (width 300) (height 300)))
(send xx show #t)
(yield 'wait)
<click> ; close the window
0
procedure application: expected procedure, given: 0; arguments were: 0 1
It seems the culprit here is the set! renaming breaking the transformer
syntax-id-rules (they match with free-identifier=?, don't they?)
-- vyzo