[racket] struct generics and mutual dependencies

From: Jon Zeppieri (zeppieri at gmail.com)
Date: Mon Aug 18 23:44:11 EDT 2014

Say I want to do basically the following, except with larger, more
complicated generic interfaces:

#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

[(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

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


Posted on the users mailing list.