[racket] struct generics and mutual dependencies

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Wed Aug 20 15:00:33 EDT 2014

We added these options to allow retrofitting methods on already defined
types. We've used it to break cyclic dependencies inside the standard
library, so I'd say it's the right way to do what you're trying to do.

Vincent


At Tue, 19 Aug 2014 01:29:39 -0400,
Jon Zeppieri wrote:
> 
> I do see another option. I could use either the #:defaults or
> #fast-defaults options to define-generics to separate the struct type
> definitions from the methods. I'm not sure if this is a legitimate use
> of the feature or an abuse. -J
> 
> 
> On Mon, Aug 18, 2014 at 11:44 PM, Jon Zeppieri <zeppieri at gmail.com> wrote:
> > Say I want to do basically the following, except with larger, more
> > complicated generic interfaces:
> >
> > ```racket
> > #lang racket/base
> >
> > (require racket/generic)
> >
> > (define-generics ->foo-provider
> >   (->foo ->foo-provider))
> >
> > (define-generics ->bar-provider
> >   (->bar ->bar-provider))
> >
> > (struct foo (x)
> >   #:methods gen:->foo-provider
> >   [(define (->foo f) f)]
> >
> >   #:methods gen:->bar-provider
> >   [(define (->bar f) (bar (foo-x f)))])
> >
> > (struct bar (x)
> >   #:methods gen:->foo-provider
> >   [(define (->foo b) (foo (bar-x b)))]
> >
> >   #:methods gen:->bar-provider
> >   [(define (->bar b) b)])
> > ```
> >
> > That is, I want to have struct types that can use generic methods to
> > construct instances of one another. Since the actual struct types are
> > rather more complicated than this example, I'd really like to split up
> > their implementations into separate modules. If I weren't using
> > generics, this would be straightforward; I'd put the struct type
> > definitions themselves in a module, or set of modules, and I'd put the
> > operations in modules specific to their respective struct types. The
> > modules containing the operations would be able to require all of the
> > struct type definitions, so they could freely construct instances of
> > one another.
> >
> > In the present case, however, the method implementations need to be
> > defined along with the struct type definition. I can't do something
> > like:
> >
> > ```
> > [(define ->foo bar->foo)]
> > ```
> > ... where bar->foo comes from a bar-specific module, because that
> > would lead to a circular dependency (bar->foo needs the foo
> > constructor, which is defined in this module, while this module needs
> > bar->foo).
> >
> > I could work around this with mutable bindings (either at the module
> > level or, better, in method dispatch), but I'm not fond of either
> > approach. With the right structure inspector maybe (?) it would be
> > possible to modify whatever dispatch table is actually used, but that
> > sounds hairy. I guess I'm wondering if some other trick is possible
> > here.
> >
> > -Jon
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.