[racket] contracts ->i optional keyword syntax

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Aug 26 17:53:21 EDT 2014

On Aug 26, 2014, at 5:43 PM, Kevin Forchione <lysseus at gmail.com> wrote:

> 
> On Aug 24, 2014, at 2:09 PM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
> 
>> Before you make fondue, ask. As you can see, people answer and answer quickly. Indeed, Robby added an example to the Guide as he responded and pushed it out into the repo. The next release will have an example due to your posts. Thanks! 
>> 
>> Having said that, Racket is created by people who focus on systematic design of software. The contract system is an example of this; 
>> 
>>  -- it serves the purpose of creating software systematically (continuing the so-called Design by Contract line of work) 
>>  -- it itself is developed systematically with inquires into the semantics of contracts because we took contracts way beyond the primitive notion from the 1980s and 1990s. 
>> 
>> But, the existence of ->i and ->d should give you a hint that we occasionally make mistakes and we try to correct them without modifying existing code. ->d is mostly okay, but ->i is better. When Robby created ->i, he also used his experience with ->d to force programmers to list dependency variables explicitly. That's why you have to say "(lst)", for example. In addition, the language grows and with it, we have to grow the contract system. Keyword arguments is an example of that kind. 
>> 
>> As for the philosophy behind our contract system, I think the guide's opening section on boundaries brings across the idea that separates our contracts from old-style stuff. It may not become immediately clear, but when you program with contracts for a while, you will appreciate it. 
> 
> Wow! I am increasingly appreciating this approach (along with Racket’s systematic approach to design). 
> 
> I’m slowly converting my modules over to use contract-out and the ->i form makes it easy to see at a glance what the domains and ranges are, and I’m thinking the notation might be useful in the function definition’s comments as well. Is there a way to integrate unit testing into this approach? The (module+ test …) unit testing I’ve been doing is within the boundary of the mode and I wonder if there isn’t a way to simply move those test cases into another module (within the same file) and require it into the (module+ test …) form? 


Yes, you can use submodules to import the outer module thru the contract boundary and then run unit tests in the submodule: 


#lang racket

(provide 
 (contract-out
  (f (-> integer? integer?))))

;; ---------------------------------
;; implementation 

(module+ test (require rackunit))

(define (f x)
  x)

(module+ test 
  (require (submod ".."))
  (check-equal? (f 1) 1)
  (check-equal? (f 'a) 'a))


We should probably document this little trick somewhere. -- Matthias



Posted on the users mailing list.