Hi all,

Recently I read the paper "Classes and Mixins" by Matthew Flatt, Shriram
Krishnamurthi and Matthias Felleisen.

In this paper, the authors presented MIXEDJAVA.

In MIXEDJAVA,

> A programmer implements mixins in exactly the same
> way as a derived class, except that the programmer cannot
> rely on the implementation of the mixin's superclass, only
> on its interface. We consider this an advantage of mixins
> because it enforces the maxim "program to an interface, not
> an implementation".
>
It is very close to the mixin form in Racket, because we can specific
interface in the mixin form:

```
(mixin (interface-expr ...) (interface-expr ...)
  class-clause ...)
```

In Chapter 3, they also introduced an example (a maze adventure game, I
called it LockedMagicDoor) which uses the system.

My question is:

Is it possible to implement LockedMagicDoor in Racket?


I did some experiments but failed.

See following code (or
https://gist.github.com/chansey97/aecffabb2885c83fa040ba677bde5de4):

```
#lang racket

(define the-key 'the-key)
(define the-spell-book 'the-spell-book)

(define person%
  (class object%
    (init-field items h)
    (super-new)

    (define/public (has-item item)
      (member item items))

    (define/public (height)
      h)
    ))

(define door<%> (interface () can-open can-pass))

(define door-mixin
  (mixin () (door<%>)
    (super-new)

    (define/public (can-open p)
      (println "door% can-open")
      #t)

    (define/public (can-pass p)
      (println "door% can-pass")
      #t)
    ))

(define secure-door<%> (interface (door<%>) needed-item))

(define secure-mixin
  (mixin (door<%>) (secure-door<%>)
    (super-new)

    (define/public (needed-item) ;; error??
      (println "secure-mixin needed-item")
      #f)

    (define/override (can-open p)
      (println "secure-mixin can-open")
      (define item (needed-item))
      (cond
        ((not (send p has-item item)) (printf "You don't have the Key ~v\n"
item)
                                      #f)
        (else (printf "Using Key... ~v\n" item)
              (super can-open p))))
    ))

(define locked-needed-mixin
  (mixin (secure-door<%>) (secure-door<%>)
    (super-new)
    (define/override (needed-item)
      (println "locked-needed-mixin neededItem")
      the-key)
    ))

(define magic-needed-mixin
  (mixin (secure-door<%>) (secure-door<%>)
    (super-new)
    (define/override (needed-item)
      (println "magic-needed-mixin neededItem")
      the-spell-book)
    ))

(define door%
  (door-mixin object%))

(define locked-mixin (compose locked-needed-mixin secure-mixin))
(define magic-mixin (compose magic-needed-mixin secure-mixin))

(define locked-magic-mixin (compose locked-mixin magic-mixin))
(define locked-magic-door% (locked-magic-mixin door%))

(define door (new locked-magic-door%))
(send door can-open (new person% [items (list the-key the-spell-book)] [h
0.5]))

; class*: superclass already contains method
;   superclass: #<class:...agic-door-failed.rkt:62:2>
;   method name: needed-item
;   class name: ...agic-door-failed.rkt:36:2

```

The problem is how to implement `secure-mixin`?

Notice that since the `secure-mixin` is mixed into `locked-magic-door%`
twice, there will be two `needed-item` methods in the inheritance chain, so
they are naming conflict.

However in MIXEDJAVA, they do not conflict:

> Specifically, a composition m1 compose m2 contains two methods named
> x if both m1 and m2 declare x and m1's inheritance interface does not
> contain x. Both x methods are accessible in an instance of the composite
> mixin since the object can be viewed specifically as an instance of m1 or
> m2.
>
Can someone help me? (e.g. make some changes to this code above and let it
work in Racket)

Very thanks.


I also attempt to use Inner to simulate the behavior of MIXEDJAVA:

```
(define secure-mixin
  (mixin (door<%>) (secure-door<%>)
    (super-new)

    (define/pubment (needed-item)
      (println "secure-mixin needed-item")
      #f)

    (define/override (can-open p)
      (println "secure-mixin can-open")
      (define item (inner #f needed-item))
      (cond
        ((not (send p has-item item)) (printf "You don't have the Key ~v\n"
item)
                                      #f)
        (else (printf "Using Key... ~v\n" item)
              (super can-open p))))
    ))

(define locked-needed-mixin
  (mixin (secure-door<%>) (secure-door<%>)
    (super-new)
    (define/augride (needed-item)
      (println "locked-needed-mixin neededItem")
      the-key)
    ))

(define magic-needed-mixin
  (mixin (secure-door<%>) (secure-door<%>)
    (super-new)
    (define/augride (needed-item)
      (println "magic-needed-mixin neededItem")
      the-spell-book)
    ))
```

But still failed:

; class*: superclass already contains method
;   superclass: #<class:...y-pubment-failed.rkt:62:2>
;   method name: needed-item

See https://gist.github.com/chansey97/264d3435a8f506153709cc9804227fdf

PS: I also tried `overment` and `augment` for the `needed-item` in
`secure-mixin`, but failed as well (although the error messages are
different).


IMO, it seems that `Inner` can be used to simulate the behavior of
MIXEDJAVA, but I don't know how to do it.

Notice that in the paper, "Super and Inner — Together at Last!" by David S.
Goldberg, Robert Bruce Findler and Matthew Flatt, the authors originally
used `beta` and `java` to mark the methods, no need `pubment` a method
first. In that model, it may not be conflicting (just a very immature
opinion).

So can we use the `Inner` to simulate the behavior of MIXEDJAVA?


Another question:

In MIXEDJAVA, there is a `view` concept, which is very powerful.

Can we get the corresponding equivalent in Racket?

Very thanks.


Best regards,

Siyuan Chen

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAHWTsYnZCbRt2U%2Bt7JQPNt7rBNQAwSy8_4ycUqNkQ23ZOdncvQ%40mail.gmail.com.

Reply via email to