[racket] contracts on functions that take arbitrary keyword arguments

From: Alexander D. Knauth (alexander at knauth.org)
Date: Sat Dec 28 16:40:57 EST 2013

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/0b0566ed/attachment.html>

Posted on the users mailing list.