On May 25, 2010, at 1:42 PM, Norman Gray wrote:
> The contract
>> (provide/contract (new-statement
> (->* ()
> (statement/c)
> statement/c)))
>> allows me to call this function as
>> (new-statement "hello" #:s "there")
>> That is, the contract doesn't give the #:s keyword as an optional keyword argument, but apparently doesn't object to its presence. Is this the same or a related bug, or does a keyword contract only constrain the _type_ of a keyword value, and not its presence?
Right. Whether this is a bug or not is a good question to ask. Normally, I'd say very directly, "yes, it is a bug," since it allows the procedure to be used by the client in a way that the contract does not suggest.
However, we would like our contracts should be "erasable." That is, if a program with contracts evaluates to a value, then the same program with the contracts removed should evaluate to the same value. While we limit the scope of this statement for some language features, such as eq?, we need to decide whether reflective operations, like retrieving the keywords that a procedure supports, should return the same value on both contracted and uncontracted versions of the same procedure.
Even if we have the reflective operations return the same list of supported keywords on contracted and uncontracted versions of a function, use of the keyword could still be a contract error (instead of an application error), as it does not follow the contract. This is similar to the reflective operations that investigate the arity of a function -- right now they return different values on contracted and uncontracted versions of a procedure (if the contract describes a subset of the possible arity uses), but it's possible that both versions should have the same reported arity, and that uses at the "wrong" arities should be contract errors, not application errors.
However, the fix for these issues, along with some other, similar ones, will need to wait until some further surgery I'm currently performing on the contract system. The changes should clear up such issues automatically.
> Going slightly further afield, the procedure-reduce-keyword-arity procedure allows one to constrain the arity and allowed keywords of a procedure. This appears to be redundant when used with ->* contracts (that's not a complaint) -- is that correct, or am I missing something? It appears that procedure-reduce-keyword-arity provides a sort of lo-fi contract facility, acting essentially as an interface to lambda-case.
The former functionality existed before the latter, I believe. Also, see my statements about arity earlier -- the fact that -> and co. restrict the arity of the procedures to which they are applied may be seen as a bug, though uses at the unlisted arities should certainly be contract errors.
Stevie