tiotolstoy
2020-10-3 07:16:56

@tiotolstoy has joined the channel


notjack
2020-10-3 10:23:42

@kellysmith12.21 I think a good use of define/contract is generic private utilities used by a module, since they’re unrelated to the module’s purpose and it’s not worth putting them in a separate file if they’re simple one-offs. But honestly the only thing I use define/contract for is debugging in the early stages of development of a module.


notjack
2020-10-3 10:25:33

@badkins it’s more about organization. Putting contracts and provide specs at the top of a module makes it easy to tell at a glance what the public API of the module is. This is really useful in codebases larger than a dozen or so modules. See also the style guide’s comments on module organization https://docs.racket-lang.org/style/Units_of_Code.html\|https://docs.racket-lang.org/style/Units_of_Code.html


notjack
2020-10-3 10:29:12

also, it’s much easier to verify that all the callers of some function are correct if you can see all the callsites in one file (and that file is reasonably sized). And sometimes a module has a valid reason to privately violate its own invariants while presenting a stricter interface to external code


badkins
2020-10-3 21:16:15

@notjack I’ll have to give that some thought. It’s been handy to have the contract at the function definition for me. It’s been a while, but I think that’s how I organized my Haskell functions also.



badkins
2020-10-3 21:27:16

I definitely see a benefit in having the contracts at the top in the provide, but I also like seeing the contract for a function at the definition. A comment might suffice in some cases for mature code.


rokitna
2020-10-3 22:35:41

Yeah, I really want contracts next to the functions. I only switched from define/contract to contract-out so that it would stop blaming the function definition site when I passed the wrong arguments to a function.


kellysmith12.21
2020-10-3 22:40:18

I also like keeping the contract next to the function definition. I supposed it’d be straightforward to make a define/contract-out form that provides the function. That would move the provide away from the traditional location at the top of the module, but having the signature with the definition helps keep things clear for me.


rokitna
2020-10-3 22:49:13

I still like keeping a list of my exported names in one place, so I’ve been meaning to write myself some kind of declaration form that would define both a function and a provide transformer for it at the same time, with the latter expanding into contract-out.


kellysmith12.21
2020-10-3 22:49:58

I like that idea.


rokitna
2020-10-3 23:05:10

It’s not that I don’t want to specify the contracts of what I export from a module, but I wanna put contracts on things I don’t export too, especially in case I want to switch on contract-checking for them if I’m tracking down a bug. I kind of want to think of every export as a recontract-out of selected parts of an internal API.


kellysmith12.21
2020-10-3 23:06:37

That would make debugging simpler.


kellysmith12.21
2020-10-4 04:02:10

Is there a provide form like struct-out, but that can attach contracts to the functions? It appears that they have to be manually provided.


kellysmith12.21
2020-10-4 04:11:57

Perhaps it’s preferable to use struct/contract then provide with struct-out?