[plt-scheme] Questions about contracts

From: Henk Boom (lunarc.lists at gmail.com)
Date: Mon Apr 16 00:37:50 EDT 2007

Hi, I'm trying to get a hang of the PLT contracts system. Coming from
Eiffel, it feels a little awkward. =(

I'm writing a simple object system, and I want to write a contract
which prevents someone from adding the same signal to an object twice.
Here's what I've written for this. It is a procedure which takes an
object and a signal name as parameters and adds the signal to the
object.

  (define/contract add-signal
    (->r ((object (and/c object?
                         (not/c (has-signal/c name))))
          (name symbol?))
         void?)
    (lambda (object name)
      (set-object-signals!
        object
        (cons (make-signal name #f '())
              (object-signals object)))))

>From looking at the error message I'm starting to worry about what
will happen with more complicated contracts:

---
> (define foo (new-object))
> (add-signal foo 'bar)
> (add-signal foo 'bar)
50: 49 broke the contract
  (->r ((object ...) (name ...)) ...)
on add-signal; expected <(and/c object? (not/c has-signal))>, given:
#<struct:object>
[unknown source]: (temp9 object)
[unknown source]: (val (temp9 object) (symbol?10 name))
[unknown source]: (rng-id (val (temp9 object) (symbol?10 name)))
[unknown source]: (let-values (((unused-id) (rng-id (val (temp9 ....)
(....))))) (check-post-expr->pp/h val #t src-...
---

It says that the contract on the first argument is broken, but it
doesn't show which part of it. In this specific case it can sort of be
inferred that it's the second component of the and/c which is failing,
but what will I do when I have more elaborate contracts on the
arguments?

    Henk


Posted on the users mailing list.