[plt-scheme] Higher-order contracts for variable-arity functions
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"))
(provide/contract
[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."