[plt-scheme] Higher-order contracts for variable-arity functions

From: Carl Eastlund (carl.eastlund at gmail.com)
Date: Thu May 25 16:06:15 EDT 2006

On 5/25/06, Robby Findler <robby at cs.uchicago.edu> wrote:
> > I am not trying to apply a contract to a list.  I do not want to use
> > listof - my point is not to change listof, but to write an alternative
> > so that I may avoid using listof.
> You need an alternate lambda too; hence my suggestion to petition the
> R6RS authors.
> > In my interpretation, the fact that
> > the arguments are delivered in a list is a byproduct.  Only the list's
> > elements are actually arguments to the function, so I want to apply a
> > contract to the arguments that are passed in.  Conceptually, I want to
> > consider the contract as coming before the "list" is built around the
> > rest arguments.  Pragmatically, this may mean the contract system has
> > to destructure the list, apply contracts to each element, and rebuild
> > the list.  This should be safe, though - the list is fresh anyway,
> > replacing it with a different one shouldn't change anything.
> The contract system can't tell that the list won't be mutated/

(module foo mzscheme

  (require (lib "contract.ss"))

   [all? ([(any/c . -> . boolean?)] (listof any/c) . ->* . [boolean?])])

  (define (all? . args)
    (if (null? args)
        (error 'all? "Requires at least one argument.")
        (let* ([pred (car args)]
               [elems (cdr args)])
          (andmap pred elems))))


(require foo)
(apply all? number? (list 1 2 3 4))

In the above, all? is given its arguments as a list, and they arrive
as a list inside the implementation.  Nevertheless, the contract
system applies a function contract to the first argument.  I am only
asking for the same thing, but not having to stop after a fixed number
of positions.  It is not a question of a new mechanism, merely a new
use of an old mechanism.  If what I am asking for is unsound, then I
don't see how the above contract isn't unsound by the same argument.

Carl Eastlund
"Cynical, but technically correct."

Posted on the users mailing list.