[racket] Generics and modules

From: J. Ian Johnson (ianj at ccs.neu.edu)
Date: Tue Aug 27 12:18:59 EDT 2013

You'll want foo-bar-baz the field accessor to be bound to something else that won't be shadowed when you define foo-bar-baz the generic function. Your define-generics likely is not in the same scope as the struct foo-bar definition, since

(require racket/generic)
(define x 0)
(define-generics y
  [x y])

Leads to a syntax error that there is a duplicate definition of x. Since #:methods reintroduces the names from bar's definition context into the following [...] scope, you're hosed for using the name. However, you can use unsafe-struct-ref

#lang racket/load
(module A racket
 (require racket/generic)
 (provide gen:bar foo-bar-baz)
 (define-generics bar
   [foo-bar-baz bar]))

(module B racket
  (require (prefix-in foo: 'A) racket/generic racket/unsafe/ops)
  (provide (struct-out foo-bar))
  (struct foo-bar (baz)
          #:methods foo:gen:bar
          [(define/generic gfoo-bar-baz foo-bar-baz)
           (define (foo-bar-baz-accessor fb) (unsafe-struct-ref fb 0))
           (define (foo:foo-bar-baz fb)
             (gfoo-bar-baz (foo-bar-baz-accessor fb)))]))

(require 'B)
(display (foo-bar-baz (foo-bar 42)))

Since struct doesn't provide access to the struct-type's -ref function, I couldn't suggest using make-struct-field-accessor as a safer alternative.
Others know a better way?

----- Original Message -----
From: "Konrad Hinsen" <konrad.hinsen at fastmail.net>
To: users at racket-lang.org
Cc: "J. Ian Johnson" <ianj at ccs.neu.edu>
Sent: Tuesday, August 27, 2013 11:53:43 AM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] Generics and modules

J. Ian Johnson writes:

 > No, your function is just ill-founded. Do you mean to destruct x to
 > find an inner bar to call gen-foo-far-baz on it?

I want to make the field baz of struct foo-bar accessible through the
generic interface method foo-bar-baz.

The background is that struct foo-bar already exists and is used by
client modules, so I can't change its name or the names of its
fields. The generic interface in module foo also exists and is used by
client modules. I want to implement the interface for my struct.  Any
solution is fine that doesn't require me to change the already
published interfaces of the two modules.

My real situation is not quite as dramatic because none of this code
is published and I am the only user, so I could just change some name
and go on. But I am doing this as an exercise in modular design.


Posted on the users mailing list.