[racket] strange behavior with class/c, class, and define/contract---user error or Racket bug?

From: Christopher (ultimatemacfanatic at gmail.com)
Date: Sun Jun 23 13:05:04 EDT 2013

Racketeers,

If I were 100% sure this was a bug, I might pass this on to the Racket developer list or some other collective with responsibility for correcting errant behavior, but being a new Racket user, I could easily just be ignorant of how the syntactic handlers involved are supposed to work.

Therefore, I pose to you these brief snippets of code with Racket's response and ask if you can help me determine whether it is doing what it is supposed to, and, if so, then what the Racket reasoning is for giving it this particular behavior.

So, this gives an error as expected:

#lang racket

(define/contract my-string%
  (class/c (field [string-thing string?]))
  (class object%
    (super-new)))

(print (new my-string%))

[running the code produces the following:]

Welcome to DrRacket, version 5.3.4 [3m].
Language: racket; memory limit: 128 MB.
. . ../../Applications/Racket v5.3.4/collects/racket/contract/private/blame.rkt:132:0: my-string%: broke its contract
 no public field string-thing
 in: (class/c (field (string-thing string?)))
 contract from: (definition my-string%)
 blaming: (definition my-string%)
 at: unsaved-editor24875:3.17
> 

I declared a field in the class contract that was not defined in the actual class.  I would want Racket to complain about this, and it does.

However, this does NOT work as expected (changed class/c keyword from "field" to "init"):

#lang racket

(define/contract my-string%
  (class/c (init [string-thing string?]))
  (class object%
    (super-new)))

(print (new my-string%))

[running the code produces the following:]

Welcome to DrRacket, version 5.3.4 [3m].
Language: racket; memory limit: 128 MB.
(object:my-string% ...)
> 

In other words, when I declare an initialization parameter in the class contract which is absent from the class declaration and is not inherited, I expect a contract violation exception to be raised, similar to the one above for the non-existant field, either on execution of the define/contract clause or later when I try to instantiate the class with new.  However, Racket does not complain at all---at neither location.

If Racket does not check that init parameters declared in class/c are actually present in the class itself or one of its superclasses, why does the class/c form allow them to be declared at all?  Is it just for documentation?

I appreciate the feedback.  Thanks!

---Christopher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130623/685e9d50/attachment.html>

Posted on the users mailing list.