Question

I have read the Racket guide 13.7.3 Parameterized Mixins

I use Parameterized Mixins to create a class good-eat-fish% from fish%

(define fish-interface
  (interface () eat get-size))

(define fish%
  (class* object% (fish-interface)
    (init size)
    (super-new)
    (define current-size size)
    (define/public (get-size) current-size)
    (define/public (eat other)
      (set! current-size (+ current-size (send other get-size))))))

(define (good-eat-mixin member-name)
  (define eat member-name)
  (mixin () ()
    (inherit eat)
    (define/public (good-eat y)
      (eat y) (eat y))))

(define good-eat-fish%
  ((good-eat-mixin (member-name-key eat)) fish%))

When I run the code the following error is raised:

"mixin: method was referenced in definition, but is not in any of the from-interfaces
  method name: eat
  from-interfaces:"

Does this error message indicate that there's no eat method?

If I change the code to

(define (good-eat-mixin member-name)
  (define eat member-name)
  (mixin (interface () eat) (interface () eat good-eat)
    (inherit eat)
    (define/public (good-eat y)
      (eat y) (eat y))))

I get this error:

interface: bad syntax in: interface

Unfortunately, I don't know why

interface () eat) 

is bad syntax.

Was it helpful?

Solution

For the first problem: mixins enforce a few checks for misuse, and you're running across them. For example, if you just do:

(mixin () ()
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

then the system detects that the code is trying to depend on an eat method that isn't a part of the mixin's declared interface. Your second attempt is closer, but you need extra parens. e.g., from

(mixin (interface () eat) (interface () eat good-eat)
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

to:

(mixin ((interface () eat)) ((interface () eat good-eat))
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

Give names to the interfaces so that this is easier to see:

(define eater<%> (interface () eat))
(define good-eater<%> (interface () good-eat))
...
(mixin (eater<%>) (good-eater<%>)
  ...)

Here's an example:

#lang racket

(define eater<%> (interface () eat))
(define good-eater<%> (interface () good-eat))

(define fish%
  (class* object% (eater<%>)
    (init size)
    (super-new)
    (define current-size size)
    (define/public (get-size) current-size)
    (define/public (eat other)
      (set! current-size (+ current-size (send other get-size))))))

(define fish-interface
  (interface () eat get-size))

(define good-eat-mixin
  (mixin (eater<%>) (good-eater<%>)
    (inherit eat)
    (super-new)
    (define/public (good-eat y)
      (eat y) (eat y))))

(define good-eat-fish%
  (good-eat-mixin fish%))

(define f1 (new good-eat-fish% [size 42]))
(define f2 (new good-eat-fish% [size 16]))
(send f1 eat f2)
(send f1 good-eat f2)
(send f1 get-size)

(I stripped out the member key stuff out of your example, just to simplify.)

I believe the class system in racket/class is nominal rather than structural.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top