[racket] Is this a bug in contracts?
And Harry, do define certain contracts separately, e.g.,
(define shish/c (is-a?/c shish-D%))
On Jan 14, 2013, at 12:24 AM, Asumu Takikawa wrote:
> 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
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users