[racket] Contracts and submodules

From: Greg Hendershott (greghendershott at gmail.com)
Date: Tue Mar 5 16:59:42 EST 2013

Thank you for the "de-clutter" strategies. I realized I could do
something of this sort. One of the things I love the most about Racket
is the ability to do this. On the other hand sometimes that capability
can be distracting for me.

For example lately I've wanted to focus more on programming in Racket
-- as opposed to programming my programming in Racket. Get some more
projects done.

I seem to have a daemon running that tries to notice how/why I got
confused, created a bug, and so on, and ponder how to avoid that next
time. But sometimes that daemon needs to dump its observations in a
buffer for me to consider later, as opposed to preempting my main
thread. So the last few weeks I've been more GTD, less meta. Ergo some
grumbly.

Another daemon I seem to have running, is one calculating what might
help Racket gain greater acceptance "in industry". The constant
innovation is wonderful -- who can complain about better options for
things like modules, tests, correctness, and more. At certain stages
in the evolution it can perhaps result in a slightly unclear story
about what are the best or preferred practices. Particularly for folks
jumping in new to Racket (but not necessarily to programming in
general).

Anyway, enough talk of my personal daemons. :)

Seriously thanks again for your feedback and ideas.

On Tue, Mar 5, 2013 at 9:59 AM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
> 1. Clutter removal is built into Racket:
>
> (define-syntax (interface stx)
>   (syntax-case stx (subject-to)
>     [(interface name clauses ...)
>      ;; ==>
>      .. (provide (contract-out ..) ..) ..]))
>
> The above macro has become a standard in my recent projects where I place it into my ./Lib/contract.rkt library. It is part of an effort to develop a header-file style for Racket. And it is an effort to supply a way to selectively check contracts. [More soon. It is NOT about turning contracts off.]
>
> 2. Contract test issue acknowledged. I have run into this problem too during my recent construction of a game program. My work-around
>
> 3. Clutter removal is built into Racket:
>
> #lang racket
>
> #lang racket
>
> (define-syntax-rule
>   (tmod def-or-exp ...)
>   (module* test racket
>     (require rackunit (submod ".."))
>     (check-equal? 1 1)
>     def-or-exp ...))
>
> ;; -----------------------------------------
>
> (provide
>  (contract-out
>   (f (-> integer? integer?))))
>
> (define (f x) x)
>
> (tmod (check-equal? (f 2) 2)
>       (check-equal? (f 3) 2))
>
> Consider adding the above module to your ./Lib/contract.rkt library.
>
>
>
>
>
>
> On Mar 5, 2013, at 8:39 AM, Greg Hendershott wrote:
>
>> Not to flog this, but:
>>
>> Lately I've been trying to be a good little doobie and use `(provide
>> (contract-out))` instead of `define/contract`. Although it's more
>> typing/clutter, grumble grumble, I've been getting used to it.
>>
>> Unfortunately I discovered one gotcha: Using (module+ test <rackunit
>> tests>) means that the test bypasses the contract -- because it's a
>> submodule, and the contract is on the module boundary. So my unit
>> tests weren't exercising and validating the contract. I missed a buggy
>> contract this way.
>>
>> In hindsight this is all perfectly obvious. Just not from the guide.
>> To be fair using submodules for tests is a relatively recent practice
>> in Racket. But I wanted to point out the interaction in case it helps
>> anyone else who is trying to use module contracts and do unit tests
>> following the curent examples.
>>
>> One way to avoid this problem is instead of module+ use module*:
>>
>>  (module* test racket ;; To test module-boundary contracts, must use
>>                       ;; module* and (require (submod "..")).
>>    (require (submod ".."))
>>    ... check check check ...
>>    )
>>
>> Of course this adds even more "clutter", but it works.
>>
>> On Thu, Dec 27, 2012 at 3:31 PM, Matthias Felleisen
>> <matthias at ccs.neu.edu> wrote:
>>>
>>> I have added a note on this issue to the Style issue; see section 3.6. Strictly speaking, this prose probably belongs into the Contract guide. -- Matthias
>>>
>>>
>>>
>>> On Nov 30, 2012, at 5:17 PM, Ryan Culpepper wrote:
>>>
>>>> You can have mutually recursive functions with define/contract, but you can't with submodules.
>>>>
>>>> Ryan
>>>>
>>>> On 11/30/2012 05:04 PM, Ray Racine wrote:
>>>>> Why not make this explicit by deprecating define/contract and support
>>>>> this use case with a submodule.  They lightweight enough and makes
>>>>> boundary demarcations consistent, explicit and simple.  Module -> boundary.
>>>>>
>>>>> On Nov 30, 2012 12:05 PM, "Matthias Felleisen" <matthias at ccs.neu.edu
>>>>> <mailto:matthias at ccs.neu.edu>> wrote:
>>>>>
>>>>>
>>>>>   On Nov 30, 2012, at 10:15 AM, Greg Hendershott wrote:
>>>>>
>>>>>>> This is a complete misunderstanding.
>>>>>>
>>>>>> Sometimes I feel like a kid in the room while the adults are talking.
>>>>>> When it comes to contracts, I have to stipulate that most of you are
>>>>>> smarter than me and have thought about this longer than me.
>>>>>
>>>>>
>>>>>   Apologies. My opening wasn't meant to say "I am smarter" but I wanted
>>>>>   to send a strong message about define/contract. It really introduces a
>>>>>   boundary and in some strange sense your (possibly misleading)
>>>>>   microbenchmark
>>>>>   exposes this constraint too.
>>>>>
>>>>>
>>>>>
>>>>>   ____________________
>>>>>      Racket Users list:
>>>>>   http://lists.racket-lang.org/users
>>>>>
>>>>>
>>>>>
>>>>> ____________________
>>>>>  Racket Users list:
>>>>>  http://lists.racket-lang.org/users
>>>>>
>>>>
>>>> ____________________
>>>> Racket Users list:
>>>> http://lists.racket-lang.org/users
>>>
>>>
>>> ____________________
>>>  Racket Users list:
>>>  http://lists.racket-lang.org/users
>


Posted on the users mailing list.