[racket] Unexpected results with impersonators and make-keyword-procedure

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Mar 8 22:12:06 EDT 2015

I agree that this is a bug --- specific to impersonators that are not
chaperones --- and I've pushed a repair to the Git repo.

The general repair was to make impersonator-property predicates and
accessors sensitive to `prop:impersonator-of`. When a structure
impersoator does not have a particular impersonator property, but its
structure has the `prop:impersonator-of` property, then the structure
produced by `prop:impersonator-of` is checked (recursively). That
change fixes the problem with keyword procedures, because
`impersonator-procedure` on keyword-acepting procedure is implemented
through an internal structure type that has `prop:impersonator-of`.

Thanks for the report!

At Fri, 6 Mar 2015 20:04:10 -0500, Scott Moore wrote:
> Hi,
> I've run into some strange behavior with the interaction between
> impersonators and make-keyword-procedure. I expect that when not invoked
> with keywords, the result of make-keyword-procedure and a lambda with the
> same form should be equivalent. Instead, they behave differently when
> impersonated. I have included a small module that demonstrates the issue
> below. I expect that the two checks at the bottom should succeed.
> Thanks,
> Scott
> #lang racket
> (require rackunit)
> (define-values (prop:my-prop my-prop? my-prop-accessor)
>   (make-impersonator-property 'my-prop))
> (define (mark-with-my-prop val)
>   (impersonate-procedure
>    val
>    #f
>    prop:my-prop
>    #t))
> (define (mark-fun-mkp f)
>   (mark-with-my-prop
>    (make-keyword-procedure
>     (λ (kwds kwd-args . other-args)
>       (keyword-apply f kwds kwd-args other-args))
>     (λ args
>       (apply f args)))))
> (define (mark-fun-lambda f)
>   (mark-with-my-prop
>    (λ args
>      (apply f args))))
> (define (dummy-impersonator val)
>   (make-keyword-procedure
>    (λ (kwds kwd-args . other-args)
>      (apply values kwd-args other-args))
>    (λ args
>      (apply values args))))
> (define marked-mkp (mark-fun-mkp display))
> (define marked-lambda (mark-fun-lambda display))
> (check-eq? (my-prop? marked-lambda) (my-prop? marked-mkp))
> (check-eq? (my-prop? (impersonate-procedure marked-lambda
> (dummy-impersonator marked-lambda)))
>            (my-prop? (impersonate-procedure marked-mkp (dummy-impersonator
> marked-mkp))))
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.