6.6 Traits
(require racket/trait) | package: base |
A trait is a collection of methods that can be converted to a mixin and then applied to a class. Before a trait is converted to a mixin, the methods of a trait can be individually renamed, and multiple traits can be merged to form a new trait.
syntax
(trait trait-clause ...)
trait-clause = (public maybe-renamed ...) | (pubment maybe-renamed ...) | (public-final maybe-renamed ...) | (override maybe-renamed ...) | (overment maybe-renamed ...) | (override-final maybe-renamed ...) | (augment maybe-renamed ...) | (augride maybe-renamed ...) | (augment-final maybe-renamed ...) | (inherit maybe-renamed ...) | (inherit/super maybe-renamed ...) | (inherit/inner maybe-renamed ...) | method-definition | (field field-declaration ...) | (inherit-field maybe-renamed ...)
External identifiers in trait, trait-exclude, trait-exclude-field, trait-alias, trait-rename, and trait-rename-field forms are subject to binding via define-member-name and define-local-member-name. Although private methods or fields are not allowed in a trait form, they can be simulated by using a public or field declaration and a name whose scope is limited to the trait form.
procedure
(trait->mixin tr) → (class? . -> . class?)
tr : trait?
(trait->mixin (trait trait-clause ...))
is equivalent to
(lambda (%) (class % trait-clause ... (super-new)))
Normally, however, a trait’s methods are changed and combined with other traits before converting to a mixin.
(define t1 (trait (define/public (m1) 1))) (define t2 (trait (define/public (m2) 2))) (define t3 (trait-sum t1 t2))
creates a trait t3 that is equivalent to
(trait (define/public (m1) 1) (define/public (m2) 2))
but t1 and t2 can still be used individually or combined with other traits.
When traits are combined with trait-sum, the combination drops inherit, inherit/super, inherit/inner, and inherit-field declarations when a definition is supplied for the same method or field name by another trait. The trait-sum operation fails (the exn:fail:contract exception is raised) if any of the traits to combine define a method or field with the same name, or if an inherit/super or inherit/inner declaration to be dropped is inconsistent with the supplied definition. In other words, declaring a method with inherit, inherit/super, or inherit/inner, does not count as defining the method; at the same time, for example, a trait that contains an inherit/super declaration for a method m cannot be combined with a trait that defines m as augment, since no class could satisfy the requirements of both augment and inherit/super when the trait is later converted to a mixin and applied to a class.
syntax
(trait-exclude trait-expr id)
A method declared with public, pubment, or public-final is replaced with an inherit declaration.
A method declared with override or override-final is replaced with an inherit/super declaration.
A method declared with augment, augride, or augment-final is replaced with an inherit/inner declaration.
A method declared with overment is not replaced with any inherit declaration.
If the trait produced by trait-expr has no method definition for id, the exn:fail:contract exception is raised.
syntax
(trait-exclude-field trait-expr id)
syntax
(trait-alias trait-expr id new-id)
syntax
(trait-rename trait-expr id new-id)
syntax
(trait-rename-field trait-expr id new-id)