[racket] Is this a bug in contracts?
On 2013-01-13 22:02:44 -0500, Harry Spier wrote:
> Is this a bug in contracts? When I ran the following code the
> contract in onion% didn't give me an error, yet the contract is on an
> "init sh" but the class doesn't have an "init sh" it has an
> "init-field sh". See the line with the comment ;;;;;THIS LINE SHOULD
> USE init-field not init
No, this should be correct. An `init` specifies a subset of `init-field`
(it's not mutually exclusive with it).
> (define/contract onion%
> (class/c [init (sh (is-a?/c shish-D%))]) ;;;;;THIS LINE SHOULD USE init-field not init
> (class shish-D% (super-new)
> (init-field sh)
> (define/override (only-onions?)
> (and (send sh only-onions?) #t))))
>
> (send (new onion% [sh (new onion% [sh (new skewer%)])]) only-onions?)
Notice here that if we change this to:
(send (new onion% [sh 5]) only-onions?)
A contract error is raised appropriately because the init argument was
wrong, so the contract is clearly protecting the init argument. This is
the correct behavior, because an `init-field` clause just defines both
an init argument and a field. The class system doesn't track a separate
`init-field` thing. If you only specify the init contract, it only
protects the init part.
If you set the field like this:
(set-field! sh (new onion% [sh (new onion% [sh (new skewer%)])]) 5)
It does not raise a contract error. If you want to protect both, you
either need to revise the contract to
(class/c [init-field (sh (is-a?/c shish-D%))])
or
(class/c [init (sh (is-a?/c shish-D%))]
[field (sh (is-a?/c shish-D%))])
Cheers,
Asumu