scribble trait docs

svn: r8154
This commit is contained in:
Matthew Flatt 2007-12-29 14:37:46 +00:00
parent b9cc763355
commit f80de2d73f

View File

@ -1,7 +1,8 @@
#lang scribble/doc
@require["mz.ss"]
@require[scheme/class]
@require[(for-syntax scheme/base)]
@(require "mz.ss"
scheme/class
(for-syntax scheme/base)
(for-label scheme/trait))
@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
@scheme[inner] forms), while the external name is used with
@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.
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}
@defform/subs[