scribble trait docs
svn: r8154
This commit is contained in:
parent
b9cc763355
commit
f80de2d73f
|
@ -1,7 +1,8 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@require["mz.ss"]
|
@(require "mz.ss"
|
||||||
@require[scheme/class]
|
scheme/class
|
||||||
@require[(for-syntax scheme/base)]
|
(for-syntax scheme/base)
|
||||||
|
(for-label scheme/trait))
|
||||||
|
|
||||||
@begin[
|
@begin[
|
||||||
|
|
||||||
|
@ -704,7 +705,7 @@ method. The internal name is used to access the method directly within
|
||||||
the class expression (including within @scheme[super] or
|
the class expression (including within @scheme[super] or
|
||||||
@scheme[inner] forms), while the external name is used with
|
@scheme[inner] forms), while the external name is used with
|
||||||
@scheme[send] and @scheme[generic] (see @secref["ivaraccess"]). If
|
@scheme[send] and @scheme[generic] (see @secref["ivaraccess"]). If
|
||||||
a single @scheme[identifier] is provided for a method declaration, the
|
a single @scheme[id] is provided for a method declaration, the
|
||||||
identifier is used for both the internal and external names.
|
identifier is used for both the internal and external names.
|
||||||
|
|
||||||
Method inheritance, overriding, and augmentation are based external
|
Method inheritance, overriding, and augmentation are based external
|
||||||
|
@ -1154,6 +1155,206 @@ Evaluation of a @scheme[mixin] form checks that the
|
||||||
|
|
||||||
@; ------------------------------------------------------------------------
|
@; ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "trait"]{Traits}
|
||||||
|
|
||||||
|
@note-lib-only[scheme/trait]
|
||||||
|
|
||||||
|
A @deftech{trait} is a collection of methods that can be converted to
|
||||||
|
a @tech{mixin} and then applied to a @tech{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.
|
||||||
|
|
||||||
|
@defform/subs[#:literals (public pubment public-final override override-final overment augment augride
|
||||||
|
augment-final private inherit inherit/super inherit/inner rename-super
|
||||||
|
inherit-field)
|
||||||
|
|
||||||
|
(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 ...)])]{
|
||||||
|
|
||||||
|
Creates a @tech{trait}. The body of a @scheme[trait] form is similar to the
|
||||||
|
body of a @scheme[class*] form, but restricted to non-private method
|
||||||
|
definitions. In particular, the grammar of
|
||||||
|
@scheme[maybe-renamed], @scheme[method-definition], and
|
||||||
|
@scheme[field-declaration] are the same as for @scheme[class*], and
|
||||||
|
every @scheme[method-definition] must have a corresponding declaration
|
||||||
|
(one of @scheme[public], @scheme[override], etc.). As in
|
||||||
|
@scheme[class], uses of method names in direct calls, @scheme[super]
|
||||||
|
calls, and @scheme[inner] calls depend on bringing method names into
|
||||||
|
scope via @scheme[inherit], @scheme[inherit/super],
|
||||||
|
@scheme[inherit/inner], and other method declarations in the same
|
||||||
|
trait; an exception, compared to @scheme[class] is that
|
||||||
|
@scheme[overment] binds a method name only in the corresponding
|
||||||
|
method, and not in other methods of the same trait. Finally, macros
|
||||||
|
such as @scheme[public*] and @scheme[define/public] work in
|
||||||
|
@scheme[trait] as in @scheme[class].
|
||||||
|
|
||||||
|
External identifiers in @scheme[trait], @scheme[trait-exclude],
|
||||||
|
@scheme[trait-exclude-field], @scheme[trait-alias],
|
||||||
|
@scheme[trait-rename], and @scheme[trait-rename-field] forms are
|
||||||
|
subject to binding via @scheme[define-member-name] and
|
||||||
|
@scheme[define-local-member-name]. Although @scheme[private] methods
|
||||||
|
or fields are not allowed in a @scheme[trait] form, they can be
|
||||||
|
simulated by using a @scheme[public] or @scheme[field] declaration and
|
||||||
|
a name whose scope is limited to the @scheme[trait] form.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(trait? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
Returns @scheme[#t] if @scheme[v] is a trait, @scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(trait->mixin [tr trait?]) (class? . -> . class?)]{
|
||||||
|
|
||||||
|
Converts a @tech{trait} to a @tech{mixin}, which can be applied to a
|
||||||
|
@tech{class} to produce a new @tech{class}. An expression of the form
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(trait->mixin
|
||||||
|
(trait
|
||||||
|
trait-clause ...))
|
||||||
|
]
|
||||||
|
|
||||||
|
is equivalent to
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(lambda (%)
|
||||||
|
(class %
|
||||||
|
trait-clause ...
|
||||||
|
(super-new)))
|
||||||
|
]
|
||||||
|
|
||||||
|
Normally, however, a trait's methods are changed and combined with
|
||||||
|
other traits before converting to a mixin.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(trait-sum [tr trait?] ...+) trait?]{
|
||||||
|
|
||||||
|
Produces a @tech{trait} that combines all of the methods of the given
|
||||||
|
@scheme[tr]s. For example,
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(define t1
|
||||||
|
(trait
|
||||||
|
(define/public (m1) 1)))
|
||||||
|
(define t2
|
||||||
|
(trait
|
||||||
|
(define/public (m2) 2)))
|
||||||
|
(define t3 (trait-sum t1 t2))
|
||||||
|
]
|
||||||
|
|
||||||
|
creates a trait @scheme[t3] that is equivalent to
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(trait
|
||||||
|
(define/public (m1) 1)
|
||||||
|
(define/public (m2) 2))
|
||||||
|
]
|
||||||
|
|
||||||
|
but @scheme[t1] and @scheme[t2] can still be used individually or
|
||||||
|
combined with other traits.
|
||||||
|
|
||||||
|
When traits are combined with @scheme[trait-sum], the combination
|
||||||
|
drops @scheme[inherit], @scheme[inherit/super],
|
||||||
|
@scheme[inherit/inner], and @scheme[inherit-field] declarations when a
|
||||||
|
definition is supplied for the same method or field name by another
|
||||||
|
trait. The @scheme[trait-sum] operation fails (the
|
||||||
|
@exnraise[exn:fail:contract]) if any of the traits to combine define a
|
||||||
|
method or field with the same name, or if an @scheme[inherit/super] or
|
||||||
|
@scheme[inherit/inner] declaration to be dropped is inconsistent with
|
||||||
|
the supplied definition. In other words, declaring a method with
|
||||||
|
@scheme[inherit], @scheme[inherit/super], or @scheme[inherit/inner],
|
||||||
|
does not count as defining the method; at the same time, for example,
|
||||||
|
a trait that contains an @scheme[inherit/super] declaration for a
|
||||||
|
method @scheme[m] cannot be combinaed with a trait that defines
|
||||||
|
@scheme[m] as @scheme[augment], since no class could satisfy the
|
||||||
|
requirements of both @scheme[augment] and @scheme[inherit/super] when
|
||||||
|
the trait is later converted to a mixin and applied to a class.}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(trait-exclude trait-expr id)]{
|
||||||
|
|
||||||
|
Produces a new @tech{trait} that is like the @tech{trait} result of
|
||||||
|
@scheme[trait-expr], but with the definition of a method named by
|
||||||
|
@scheme[id] removed; as the method definition is removed, either a
|
||||||
|
@scheme[inherit], @scheme[inherit/super], or @scheme[inherit/inner]
|
||||||
|
declaration is added:
|
||||||
|
|
||||||
|
@itemize{
|
||||||
|
|
||||||
|
@item{A method declared with @scheme[public], @scheme[pubment], or
|
||||||
|
@scheme[public-final] is replaced with a @scheme[inherit]
|
||||||
|
declaration.}
|
||||||
|
|
||||||
|
@item{A method declared with @scheme[override] or @scheme[override-final]
|
||||||
|
is replaced with a @scheme[inherit/super] declaration.}
|
||||||
|
|
||||||
|
@item{A method declared with @scheme[augment], @scheme[augride], or
|
||||||
|
@scheme[augment-final] is replaced with a @scheme[inherit/inner] declaration.}
|
||||||
|
|
||||||
|
@item{A method declared with @scheme[overment] is not replaced
|
||||||
|
with any @scheme[inherit] declaration.}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
If the trait produced by @scheme[trait-expr] has no method definition for
|
||||||
|
@scheme[id], the @exnraise[exn:fail:contract].}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(trait-exclude-field trait-expr id)]{
|
||||||
|
|
||||||
|
Produces a new @tech{trait} that is like the @tech{trait} result of
|
||||||
|
@scheme[trait-expr], but with the definition of a field named by
|
||||||
|
@scheme[id] removed; as the field definition is removed, an
|
||||||
|
@scheme[inherit-field] declaration is added.}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(trait-alias trait-expr id new-id)]{
|
||||||
|
|
||||||
|
Produces a new @tech{trait} that is like the @tech{trait} result of
|
||||||
|
@scheme[trait-expr], but the definition and declaration of the method
|
||||||
|
named by @scheme[id] is duplicated with the name @scheme[new-id]. The
|
||||||
|
consistency requirements for the resulting trait are the same as for
|
||||||
|
@scheme[trait-sum], otherwise the @exnraise[exn:fail:contract]. This
|
||||||
|
operation does not rename any other use of @scheme[id], such as in
|
||||||
|
method calls (even method calls to @scheme[identifer] in the cloned
|
||||||
|
definition for @scheme[new-id]).}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(trait-rename trait-expr id new-id)]{
|
||||||
|
|
||||||
|
Produces a new @tech{trait} that is like the @tech{trait} result of
|
||||||
|
@scheme[trait-expr], but all definitions and references to methods
|
||||||
|
named @scheme[id] are replaced by definitions and references to
|
||||||
|
methods named by @scheme[new-id]. The consistency requirements for the
|
||||||
|
resulting trait is the same as for @scheme[trait-sum], otherwise the
|
||||||
|
@exnraise[exn:fail:contract].}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(trait-rename-field trait-expr id new-id)]{
|
||||||
|
|
||||||
|
Produces a new @tech{trait} that is like the @tech{trait} result of
|
||||||
|
@scheme[trait-expr], but all definitions and references to fields
|
||||||
|
named @scheme[id] are replaced by definitions and references to fields
|
||||||
|
named by @scheme[new-id]. The consistency requirements for the
|
||||||
|
resulting trait is the same as for @scheme[trait-sum], otherwise the
|
||||||
|
@exnraise[exn:fail:contract].}
|
||||||
|
|
||||||
|
@; ------------------------------------------------------------------------
|
||||||
|
|
||||||
@section{Object and Class Contracts}
|
@section{Object and Class Contracts}
|
||||||
|
|
||||||
@defform/subs[
|
@defform/subs[
|
||||||
|
|
Loading…
Reference in New Issue
Block a user