[racket] why would the order of contract predicates make a difference?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Aug 12 18:30:31 EDT 2013

Both contracts are wrong, but the error manifests itself differently. i fixed the first one and rewrote the test: 

#lang racket/base
(require racket/contract)

(define/contract (proc1 . items)
  (() #:rest (and/c (λ(items) (even? (length items))) (listof symbol?)) . ->* . symbol?)
  'proc1-finished)

(proc1 'foo 'bar)
(with-handlers ((exn:fail:contract? void))
  (proc1 'foo)
  (error "test went wrong")) 


(define/contract (proc2 . items)
  (() #:rest (and (listof symbol?) (λ(items) (even? (length items)))) . ->* . symbol?)
  'proc2-finished)

(proc2 'foo 'bar) ; gives 'proc2-finished
(proc2 'foo) ; gives contract violation

I leave it to you to figure out why the mistake didn't materialize itself in the other order. 


On Aug 12, 2013, at 6:25 PM, Matthew Butterick wrote:

> This contract intends to check if the rest argument is a) a list of symbols and b) has an even number of elements.
> 
> The only difference (apparent to me) between proc1 and proc2 is the ordering of the contract predicates. Yet they give different results — proc1 seems to ignore the even? condition. Why would this be so?
> 
> 
> #lang racket/base
> (require racket/contract)
> 
> (define/contract (proc1 . items)
>   (() #:rest (and (λ(items) (even? (length items))) (listof symbol?)) . ->* . symbol?)
>   'proc1-finished)
> 
> (proc1 'foo 'bar) ; gives 'proc1-finished
> (proc1 'foo) ; gives 'proc1-finished, but why? I would expect contract violation
> 
> 
> (define/contract (proc2 . items)
>   (() #:rest (and (listof symbol?) (λ(items) (even? (length items)))) . ->* . symbol?)
>   'proc2-finished)
> 
> (proc2 'foo 'bar) ; gives 'proc2-finished
> (proc2 'foo) ; gives contract violation
> 
> 
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



Posted on the users mailing list.