[racket] contracts on functions that take arbitrary keyword arguments

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Sat Dec 28 16:46:58 EST 2013

http://docs.racket-lang.org/reference/Building_New_Contract_Combinators.html?q=racketcontract

(But there is a new interface (the old one will continue to work of course)
in the git version)

Let me know if you have questions or get stuck and I'll try to improve the
docs.

Robby


On Sat, Dec 28, 2013 at 3:40 PM, Alexander D. Knauth
<alexander at knauth.org>wrote:

> What's the lower-level, projection-based api and how do I use it?
>
> On Dec 28, 2013, at 11:50 AM, Robby Findler wrote:
>
> I think you probably could make a contract that did what you were talking
> about in the first message in this thread, but you cannot do it with any of
> the existing contract combinators (->, ->*, case->, ->i, etc). You would
> have to use the lower-level, projection-based api to make a new combinator.
>
> But Matthias's advice is probably a better route.
>
> Robby
>
>
> On Sat, Dec 28, 2013 at 1:43 AM, Alexander D. Knauth <alexander at knauth.org
> > wrote:
>
>> The problem isn't with defining the function, the problem is with making
>> a contract for it.
>>
>> I can define the function fine, I just don't know how to write a contract
>> for it.  I used make-keyword-procedure to define the function, but is there
>> something like make-keyword-procedure-contract?  I could write my own error
>> code, but it would be better if I could express it as a contract.
>>
>> The actual concrete example is that I'm making my own version of send
>> that works with method-like procedures.
>>
>> #lang racket
>>
>> (define/contract current-send-object (parameter/c (or/c object? #f))
>>   (make-parameter #f))
>>
>> (define my-send
>>   (make-keyword-procedure
>>    (lambda (kws kw-args object proc . rest-args)
>>      (parameterize ([current-send-object object])
>>        (keyword-apply proc kws kw-args rest-args)))))
>>
>> (define point%
>>   (class object%
>>     (super-new)
>>     (init-field [x 0] [y 0])
>>     (define/public (get-x) x)
>>     (define/public (get-y) y)))
>>
>> (define (get-vector)
>>   (let* ([object (current-send-object)]
>>          [x (send object get-x)]
>>          [y (send object get-y)])
>>     (vector x y)))
>>
>> (define p (new point% [x 3] [y 5]))
>>
>> (require rackunit)
>>
>> (check-equal? (my-send p get-vector)
>>               (vector 3 5))
>>
>> (check-equal? (my-send p (compose vector->list get-vector))
>>               (list 3 5))
>>
>> that way you can define new "methods" without them being specified by the
>> class, and they're first class functions.  I wanted to be able to make a
>> contract for my-send (and my-send/apply etc.) that would check that object
>> is an object and that proc is a procedure, but still take arbitrary keyword
>> arguments and just pass them on to proc.
>>
>> On Dec 27, 2013, at 1:03 PM, Matthias Felleisen wrote:
>>
>>
>> This is a bit vague. Can you clarify the question with a concrete
>> example?
>>
>>
>> On Dec 26, 2013, at 7:45 PM, "Alexander D. Knauth" <alexander at knauth.org>
>> wrote:
>>
>> I want to make contracts on some apply-like functions that check some
>> arguments but just passes all the others (including keyword arguments) on
>> to a function (provided as an argument).  If there weren't any keyword
>> arguments, I could use a rest argument to do this, but that wouldn't work
>> with keyword arguments.  Is there a way to do something like a rest
>> argument for keyword-arguments in a contract?____________________
>>
>> Racket Users list:
>>
>> http://lists.racket-lang.org/users
>>
>>
>>
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20131228/2a83702e/attachment.html>

Posted on the users mailing list.