Class constracts and equality

42 views
Skip to first unread message

Konrad Hinsen

unread,
Sep 1, 2015, 12:00:14 PM9/1/15
to us...@racket-lang.org
Hi everyone,

I am trying to add a contract to a class but find that the mere presence
of the contract breaks my code. Here is a minimal example that illustrates
the problem:

--------------------------------------------------
#lang racket

(define foo%
(class object%
(inspect #f)
(super-new)
(init-field value)))

(define/contract foo+c%
(class/c (init [value symbol?]))
foo%)

(module+ test
(require rackunit)
(check-equal? (make-object foo% 'bar)
(make-object foo% 'bar))
(check-equal? (make-object foo+c% 'bar)
(make-object foo+c% 'bar)))
--------------------------------------------------

My class foo% declares (inspect #f) to ensure that foo% objects can be
compared using equal?. As the test shows, this works fine. However, as
soon as I add a contract to my class, equality tests fail
systematically.

Am I using class contracts incorrectly? Or is this a bug, or a
feature? Is there a workaround?

Thanks in advance,
Konrad

Konrad Hinsen

unread,
Sep 1, 2015, 2:42:49 PM9/1/15
to Daniel Feltey, us...@racket-lang.org
On 01/09/15 18:45, Daniel Feltey wrote:

> I think this is expected, if you want to check for equality on instances
> of contracted classes you should use the `object=?` function which can
> "see through" the contract wrappers.
>
> http://docs.racket-lang.org/reference/objectutils.html?q=object%3D%3F#%28def._%28%28lib._racket%2Fprivate%2Fclass-internal..rkt%29._object~3d~3f%29%29

Thanks for the reference, but my interpretation of this is different. I
don't care about eq?, nor about testing how objects were created. I want
comparison by equal? by recursive application to the fields - just as
for transparent structures.

Konrad.

Asumu Takikawa

unread,
Sep 1, 2015, 3:20:58 PM9/1/15
to Konrad Hinsen, Daniel Feltey, us...@racket-lang.org
Hi Konrad,

On 2015-09-01 20:42:42 +0200, Konrad Hinsen wrote:
> Thanks for the reference, but my interpretation of this is different. I
> don't care about eq?, nor about testing how objects were created. I want
> comparison by equal? by recursive application to the fields - just as for
> transparent structures.

It seems like the problem is that the wrappers that the class contract
installs does not take into account whether the original class has an
inspector of #f or not.

In particular, the code for class contracts explicitly installs a value for the
inspector that doesn't allow inspection (there's a comment saying "No
inspection").

But maybe it's worth revisiting this part of the design. I can look into if
it's possible to have the contracted class inherit the inspect of the original
and whether that causes any problems.

Cheers,
Asumu

Konrad Hinsen

unread,
Sep 2, 2015, 2:42:00 AM9/2/15
to Asumu Takikawa, us...@racket-lang.org
Hi Asumu,

> In particular, the code for class contracts explicitly installs a value for the
> inspector that doesn't allow inspection (there's a comment saying "No
> inspection").

Thanks for exploring this, at least I now know what's going on!

> But maybe it's worth revisiting this part of the design. I can look into if
> it's possible to have the contracted class inherit the inspect of the original
> and whether that causes any problems.

That would be great, but if that's not possible, the next-best option would
be to document the restriction.

For now I'll remove the contract, as equality checking is clearly more
important for me.

Konrad.

Asumu Takikawa

unread,
Sep 10, 2015, 3:12:14 PM9/10/15
to Konrad Hinsen, us...@racket-lang.org
On 2015-09-02 08:41:21 +0200, Konrad Hinsen wrote:
> That would be great, but if that's not possible, the next-best option would
> be to document the restriction.

I now have a pull request that should address this:

https://github.com/plt/racket/pull/1044

I've only found one issue with this so far, which is that `object->vector` can
expose the difference between an object produced from a contracted class and a
regular object. This seems minor though.

Cheers,
Asumu

Konrad Hinsen

unread,
Sep 11, 2015, 3:42:44 AM9/11/15
to Asumu Takikawa, us...@racket-lang.org
Asumu Takikawa writes:

> On 2015-09-02 08:41:21 +0200, Konrad Hinsen wrote:
> > That would be great, but if that's not possible, the next-best option would
> > be to document the restriction.
>
> I now have a pull request that should address this:
>
> https://github.com/plt/racket/pull/1044

Thanks! I'll try this on my code when I find some time (mainly for installing
Racket from scratch).

> I've only found one issue with this so far, which is that `object->vector` can
> expose the difference between an object produced from a contracted class and a
> regular object. This seems minor though.

I assume that object->vector is mainly used by code analysis tools, so
the difference may even be of use. But I'll leave that question to people
who actually use object->vector!

Konrad.
Reply all
Reply to author
Forward
0 new messages