[plt-scheme] how to disallow struct-copy on a particular structure type?
On Fri, Jul 10, 2009 at 06:23:40PM -0400, Carl Eastlund wrote:
> On Fri, Jul 10, 2009 at 6:16 PM, Richard Cobbe<cobbe at ccs.neu.edu> wrote:
> > I'm writing a module that defines and exports a structure, but it does
> > *not* export the default `make-foo' function. (The structure has 7 fields,
> > and not all combinations of values for those fields are legal, so I'm
> > exporting a wrapped version of the constructor that does validity checking
> > instead.)
> >
> > Is there a way to prevent clients from using struct-copy on this particular
> > structure (and thus circumventing the validity checks)? I know I could
> > simply not provide the main structure binding (i.e., `foo' for
> > `(define-struct foo (...))'), but that would also prevent clients from
> > using `match' on this kind of structure, which is too restrictive.
> >
> > Thanks,
> >
> > Richard
>
> Interesting problem. I don't know if there's a way to solve it
> directly. Here are a couple workarounds that pop to mind:
>
> One, you might hide 'foo', but export a match-expander ($foo or
> something similar) to make up for the lack of ordinary struct
> matching.
Oh yeah -- didn't think about that. And I even wrote a planet package
that would make this trivial.
> Two, you might construct two structure types: parent type foo (with
> all the fields you need) and child type bar (with no additional
> fields). Define all your functions to work with bar, and have bar in
> their contracts, but export the foo structure name. Matches and
> selectors and predicates for foo will all work on the bar values, but
> anything the user constructs (via struct-copy or whatever else) will
> not be acceptable to your bar functions.
I'll have to think about this -- this may be the best solution, not least
because `struct-copy' doesn't allow you to change inherited fields (at
least, not the last time I looked).
> Neither of these are perfect, but I don't know that there's any
> facility for what you describe. Personally I'd really like to see
> some API for controlling what's provided in those struct identifiers,
> for just this kind of use case.
That would indeed be nice.
Thanks,
Richard