[racket] Contracts on subclasses/mixins

From: Gregory Woodhouse (gregwoodhouse at me.com)
Date: Mon Sep 10 17:37:42 EDT 2012

Thanks. That's important because I do override a few methods. For example, set-cell! erases pencil marks and clear-cell! puts them back in. But in most cases the methods are not overridden. 

Sent from my iPhone

On Sep 10, 2012, at 1:23 PM, Asumu Takikawa <asumu at ccs.neu.edu> wrote:

> On 2012-09-10 12:35:52 -0700, Gregory Woodhouse wrote:
>> Now, here's my question. provide grid% with its own contract-out
>> clause. It seems rather redundant (and presumably unnecessary) to
>> repeat the methods from base-grid% in the contract for grid%.
> 
> You don't need to repeat the contracts unless you actually override
> these methods. You can think of class/c contracts as being tied to
> a particular *implementation* of the method. If you don't
> re-implement the method, specifying extra contracts only serves to
> move around the responsibility for the implementation.
> 
>> My guess is that if I do not do this base-grid% will be blamed for any
>> contract violations in the base class rather than grid%. Is this
>> correct? Or will it even work? I don't mind if base-grid% is blamed
>> for the contract violation. In fact, it may be preferable because it
>> is more specific.
> 
> Yes, that should be correct. Here's a simple example that I think
> illustrates what you're talking about:
> 
>  #lang racket
> 
>  (define/contract c1%
>    (class/c [f (->m odd? odd?)])
>    (class object%
>      (super-new)
>      ;; broken method
>      (define/public (f x) 2)))
> 
>  (define/contract (mix base)
>    (-> (class/c)
>        (class/c [g (->m odd?)]))
>    (class base
>      (super-new)
>      (inherit f)
>      (define/public (g) (f 1))))
> 
>  (send (new (mix c1%)) f 2)
> 
> The method `f` is contracted only in the base class `c1%`.
> When invoking the method on the result of the mixin with
> a good argument, you get a contract violation blaming the
> method implementation in `c1%`.
> 
> If, instead, you had overriden `f` in the mixin, then the
> contract is not checked.
> 
> If it turns out that you want to say `f` should *always*
> be protected by some contract no matter who implements it,
> you might consider using an interface contract.
> 
> Cheers,
> Asumu

Posted on the users mailing list.