I understood the feature request differently. I take it as wanting to
write a module like the following:
#lang racket
(provide
(with-declared-contracts-out
f
g))
(declare-contract f ....)
(define f ....)
(declare-contract g ....)
(define g ....)
That is, the contracts themselves are near the functions, so it's easy
to keep them in sync. And one can find the names provided by just
looking at the top of the module---but you only get the names, not the
contracts, so the interface is incomplete.
This should be easily doable with some compile-time state.
Ryan
On 12/14/2012 11:41 AM, Greg Hendershott wrote:
Matthias has vastly more experience and perspective in matters like
this; you would be wise to prefer his advice.
But if I understand correctly what you want, I think you could do this
yourself with a simple macro:
(define-syntax define/contract/provide
(syntax-rules ()
[(_ (id . args) contract body ...)
(begin
(define/contract (id . args) contract body ...)
(provide id))]
[(_ id contract expr)
(begin
(define/contract id contract expr)
(provide id))]))
That's the version I've used in some past projects. However: It uses
define/contract promiscuously, which is (a) not universally beloved
and (b) much slower than provide/contract in the current version of
Racket.
Instead I think you could flip it around to use provide/contract, instead:
(define-syntax define/provide/contract
(syntax-rules ()
[(_ (id . args) contract body ...)
(begin
(provide/contract (id . args) contract body ...)
(define id))]
[(_ id contract expr)
(begin
(provide/contract id contract expr)
(define id))]))
I _think_ that's essentially what you're asking for?
(Of course this means the function won't be protected by a contract
when called from inside the module, which could be considered bad,
good, or N/A. Just be aware.)
Any approach not using a single provide/contract list has the
disadvantage that Matthias explained: The module no longer has a
contiguous description of its interface in the source.
That's a serious disadvantage. Some might consider it mitigated if the
module has Scribble documentation. Also someone reading the source
might "collapse" in Emacs (or whatever) to quickly see all the
top-level definitions (although that would include any non-provided
items, so it's not perfect (unless the stock collapse is customized)).
You could also put a list in comments, I suppose.
On Fri, Dec 14, 2012 at 10:44 AM, Matthias Felleisen
<matth...@ccs.neu.edu> wrote:
It is critical to inform clients of the services that a module
provides. In the absence of types, contracts are the closest
information we have. Reading the implementation is against
all good SE ideas.
IF we could assume that people always programmed in DrRacket,
we could compromise and add a tool that synthesizes the interface
of a module in some way. Since some contributors break this guideline
all the time anyway, we should have such a tool available anyway.
BUT there are also people who use Emacs and the other editor.
So, if you want to be good, put provide contract-out at the top
of your module.
On Dec 14, 2012, at 1:02 AM, Harry Spier wrote:
If you place provide/contract at the beginning of a module it makes
the interface clear but it is separated from its function. If you
place it right before its function and not at the top of the module,
it makes the function clearer but the module interface is not so
clear.
Is it possible (would it be a good idea?) to provide a new form that
splits the provide/contract form into two parts. One part the
contract definition which you could place immediately before the
function definition and the second part a provide spec for inclusion
in a provide statement that included the function name but not the
contract spec.) . That way the contract definition can be by the
function definition and the function name can be in a provide
statement at the beginning of the module.
Harry Spier
_________________________
Racket Developers list:
http://lists.racket-lang.org/dev
_________________________
Racket Developers list:
http://lists.racket-lang.org/dev
_________________________
Racket Developers list:
http://lists.racket-lang.org/dev
_________________________
Racket Developers list:
http://lists.racket-lang.org/dev