[racket] Generics and modules

From: Konrad Hinsen (konrad.hinsen at fastmail.net)
Date: Tue Aug 27 08:31:11 EDT 2013

Hi everyone,

I have started playing with generics and quickly got myself in trouble.

Consider the following two modules:


-- foo.rkt ------------------------------------------------
#lang racket

(provide (all-defined-out))

(require racket/generic)

(define-generics bar
  [baz bar])
-----------------------------------------------------------

-- foo-bar.rkt --------------------------------------------
#lang racket

(provide (all-defined-out))

(require (prefix-in foo: "foo.rkt"))

(define (baz x)
  (list x x))

(struct foo-bar (quux)
        #:methods foo:gen:bar
        [(define (foo:baz x) (baz (foo-bar-quux x)))])
-----------------------------------------------------------

Then, in a REPL:

    (require (prefix-in foo: "foo.rkt")
             "foo-bar.rkt")
    (foo:baz (foo-bar 42))

This yields the error message:

    baz: not implemented for #<foo-bar>

By trial and error I figured out that in the method definition I need
to use the method name as written in define-generics, in spite of the
(require (prefix-in ...)). No problem, it seems:

-----------------------------------------------------------
(struct foo-bar (quux)
        #:methods foo:gen:bar
        [(define (baz x) (baz (foo-bar-quux x)))])
-----------------------------------------------------------

But now the call to baz inside the method becomes a recursive call to
the method, rather than a call to the function baz defined in the
surrounding module. In fact, that's why I used (prefix-in ...) in the
first place.

I tried to get around this with a local binding:
-----------------------------------------------------------
(let ([temp baz])
  (struct foo-bar (quux)
          #:methods foo:gen:bar
          [(define (baz x) (temp (foo-bar-quux x)))]))
-----------------------------------------------------------

for which the punishment is:

   begin (possibly implicit): no expression after a sequence of internal definitions

Any ideas?

Konrad.

Posted on the users mailing list.