[plt-scheme] how to disallow struct-copy on a particular structure type?

From: Carl Eastlund (carl.eastlund at gmail.com)
Date: Fri Jul 10 18:23:40 EDT 2009

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.

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.

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.

--Carl


Posted on the users mailing list.