Dear all,
Just imagine, suppose we have two traits `spots-trait` and `stripes-trait`,
they are developed independently.
These two traits depend on a "private" method `helper` respectively.
See following code:
```
(define spots-trait
(trait
(define/public (helper)
(println "spots-trait helper"))
(define/public (eat/spots)
(println "spots-trait eat/spots")
(helper))
))
(define stripes-trait
(trait
(define/public (helper)
(println "stripes-trait helper"))
(define/public (eat/stripes)
(println "stripes-trait eat/spots")
(helper))
))
```
Now I want to define the 3rd trait (called `spots+stripes-trait`),
something like:
```
(define spots+stripes-trait
(trait-sum spots-trait stripes-trait))
```
But this is impossible because there is a name colliding (the`helper`
method).
One workaround to this problem is "renaming":
```
(define spots+stripes-trait
(trait-sum
(trait-rename spots-trait helper helper/spots)
(trait-rename stripes-trait helper helper/stripes)))
```
This works.
But is this a good way? (It looks not very "hygienic")
Note that the `helper` is just a "private" method, it should not be visible
to its user.
PS: It seems that Racket does not support private members for traits.
Although I don't think "private members" is a good idea because private
members are not friendly to unit-testing.
An alternative way is moving the private `helper` method to a different
trait, splitting the original responsibilities across multiple traits
leading to simpler, better designs.
See following code:
```
(define spots-helper-trait
(trait
(define/public (helper)
(println "spots-helper-trait helper"))
))
(define spots-core-trait
(trait
(inherit helper)
(define/public (eat/spots)
(println "spots-core-trait eat/spots")
(helper))
))
(define stripes-helper-trait
(trait
(define/public (helper)
(println "stripes-trait helper"))
))
(define stripes-core-trait
(trait
(inherit helper)
(define/public (eat/stripes)
(println "stripes-core-trait eat/spots")
(helper))
))
```
Now I can redefine `spots-trait` and `stripes-trait`.
My attempt is `trait-sum` the `spots-core-trait` and `spots-helper-trait`
first, and then "hide" the `helper`, something like:
```
(define spots-trait
(trait-hide ;; <-- attempt to hide `helper` method (Not real Racket)
(trait-sum spots-core-trait spots-helper-trait)
helper))
(define stripes-trait
(trait-hide ;; <-- attempt to hide `helper` method (Not real Racket)
(trait-sum stripes-core-trait stripes-helper-trait)
helper))
(define spots+stripes-trait
(trait-sum spots-trait stripes-trait))
```
Is this possible in Racket?
The advantage of "hiding" is that
1. The `spots-trait` now only exposes its interface `eat/spots `, we can
easily reuse it in other traits without worrying about name colliding (the
name `helper` is very commonly used, imo) .
2. Compared with the "renaming" solution, "hiding" looks more "hygienic",
because it can avoid further name colliding.
PS: I admit this example may be a bit weird, but you can think of "spots"
and "stripes" as some sort of service traits.
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/CAHWTsY%3DBCOBXc%2BL9JkR%2BCnS2htKadRnrkpx4w6oUMS5OhdOEtw%40mail.gmail.com.