[plt-scheme] mutual recursion in contracts
That's not a question of lazy ornot, it's a question of providing a
form for mut rec types.
-- Matthias
On May 7, 2004, at 4:34 PM, David A. Herman wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> I've noticed that contract expressions are evaluated immediately even
> though they aren't used until later. For example, the following code:
>
> (define/contract x
> (begin
> (printf "evaluating contract!")
> integer?)
> 'foo)
>
> outputs "evaluating contract!" and terminates successfully, but then
> any subsequent reference to x will fail with a contract error.
>
> This makes it hard to create syntactic forms that can produce
> definitions with mutually recursive contracts. Here's a simple
> example:
>
> ;; an even is one of:
> ;; - zero, i.e., (make-even #f)
> ;; - successor(odd)
> ;; an odd is successor(even)
>
> (define-type even ([pred (union odd? #f)]))
> (define-type odd ([pred even?]))
> =>
> (define-struct even (pred))
> (provide/contract (struct even ([pred odd?])))
> (define-struct odd (pred))
> (provide/contract (struct odd ([pred even?])))
>
> The above code causes an error because the provide/contract for even
> contains a forward reference to odd?. Of course, I can produce a
> letrec-like form so that I can reorder the expressions in the macro
> template, but in general I'd like to be able to have completely
> separate expressions with mutually recursive contracts.
>
> Clearly, in case contract expressions have side effects, you don't
> want to evaluate them multiple times. So it makes sense to evaluate
> them once. But would it make sense for contract expressions to be
> evaluated lazily, since they aren't needed at the time of the
> definition? I guess that's a little weird.
>
> Anyway, is there a good way for me to work around this? Am I stuck
> having to define a letrec-like form?
>
> Thanks,
> Dave