[racket] when is `listof` the better contract

From: Matthew Butterick (mb at mbtype.com)
Date: Thu Dec 4 16:29:43 EST 2014

In what situations should one prefer the `listof` combinator over an equivalent predicate contract?

For instance, it seems to me that:

(λ(x) (and (list? x) (andmap pred? x)))

is a more-or-less equivalent way of saying this:

(listof pred?)

But in my experience the predicate version is always significantly faster. Thus, is it generally better to rewrite contracts to avoid `listof`? And if so, when is `listof` still preferred?

;; For instance.

#lang racket

(define/contract (f1 xs)
  ((listof integer?) . -> . any/c)

(define (integers? x) (and (list? x) (andmap integer? x)))
(define/contract (f2 xs)
  (integers? . -> . any/c)

(define (trial proc) (for ([i (in-range 1000)]) (proc (range 10000))))

(time (trial f1))
(time (trial f2))

Posted on the users mailing list.