[racket] Contracts on subclasses/mixins

From: Gregory Woodhouse (gregwoodhouse at me.com)
Date: Mon Sep 10 15:35:52 EDT 2012

I have a contract

(define base-grid/c
  (class/c
   (given? (->m coord? coord? boolean?))
   (get-cell (->m coord? coord? digit?))
   (get-cell/given (->m coord? coord? (values digit? boolean?)))
   (set-cell! (->m coord? coord? digit? void?))
   (set-given! (->m coord? coord? digit? void?))
   (clear-cell! (->m coord? coord? void?))
   (clear-given! (->m coord? coord? void?))
   (complete? (->m boolean?))
   (creates-duplicate? (->m coord? coord? digit? boolean?))))

for my class base-grid%. As you can probably guess, the main things this class does is enforce the rule that there can be no duplicate digits in a single house (row, column, or 3x3 grid). In practice, it is used in conjunction with pencil-mixin (which adds support for pencil marks) and file-mixin (which allows puzzles to be loaded from or saved to disk). In fact, the only class I instantiate is grid%, defined like this

(define grid%
  (file-mixin
   (pencil-mixin base-grid%)))

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%. 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.

Posted on the users mailing list.