doc work (fix long filename)
svn: r6717
This commit is contained in:
parent
e0edc04bef
commit
ff1189600a
|
@ -272,12 +272,16 @@
|
||||||
(current-subdirectory))
|
(current-subdirectory))
|
||||||
(super get-dest-directory)))
|
(super get-dest-directory)))
|
||||||
|
|
||||||
(define/private (derive-filename d)
|
(define/private (derive-filename d ht)
|
||||||
(format "~a.html" (regexp-replace*
|
(let ([fn (format "~a.html" (regexp-replace*
|
||||||
"[^-a-zA-Z0-9_=]"
|
"[^-a-zA-Z0-9_=]"
|
||||||
(or (format "~a" (part-tag d))
|
(or (format "~a" (part-tag d))
|
||||||
(content->string (part-title-content d)))
|
(content->string (part-title-content d)
|
||||||
"_")))
|
this d ht))
|
||||||
|
"_"))])
|
||||||
|
(when ((string-length fn) . >= . 100)
|
||||||
|
(error "file name too long (need a tag):" fn))
|
||||||
|
fn))
|
||||||
|
|
||||||
(define/override (collect ds fns)
|
(define/override (collect ds fns)
|
||||||
(super collect ds (map (lambda (fn)
|
(super collect ds (map (lambda (fn)
|
||||||
|
@ -297,7 +301,7 @@
|
||||||
1
|
1
|
||||||
(add1 prev-sub))])
|
(add1 prev-sub))])
|
||||||
(if (= 1 prev-sub)
|
(if (= 1 prev-sub)
|
||||||
(let ([filename (derive-filename d)])
|
(let ([filename (derive-filename d ht)])
|
||||||
(parameterize ([current-output-file (build-path (path-only (current-output-file))
|
(parameterize ([current-output-file (build-path (path-only (current-output-file))
|
||||||
filename)])
|
filename)])
|
||||||
(super collect-part d parent ht number)))
|
(super collect-part d parent ht number)))
|
||||||
|
@ -417,7 +421,7 @@
|
||||||
(make-element
|
(make-element
|
||||||
(if parent
|
(if parent
|
||||||
(make-target-url (if prev
|
(make-target-url (if prev
|
||||||
(derive-filename prev)
|
(derive-filename prev ht)
|
||||||
"index.html"))
|
"index.html"))
|
||||||
"nonavigation")
|
"nonavigation")
|
||||||
prev-content)
|
prev-content)
|
||||||
|
@ -426,14 +430,14 @@
|
||||||
(if parent
|
(if parent
|
||||||
(make-target-url
|
(make-target-url
|
||||||
(if (toc-part? parent)
|
(if (toc-part? parent)
|
||||||
(derive-filename parent)
|
(derive-filename parent ht)
|
||||||
"index.html"))
|
"index.html"))
|
||||||
"nonavigation")
|
"nonavigation")
|
||||||
up-content)
|
up-content)
|
||||||
sep-element
|
sep-element
|
||||||
(make-element
|
(make-element
|
||||||
(if next
|
(if next
|
||||||
(make-target-url (derive-filename next))
|
(make-target-url (derive-filename next ht))
|
||||||
"nonavigation")
|
"nonavigation")
|
||||||
next-content))))))))
|
next-content))))))))
|
||||||
d
|
d
|
||||||
|
@ -447,7 +451,7 @@
|
||||||
(next-separate-page)))
|
(next-separate-page)))
|
||||||
;; Render as just a link, and put the actual
|
;; Render as just a link, and put the actual
|
||||||
;; content in a new file:
|
;; content in a new file:
|
||||||
(let* ([filename (derive-filename d)]
|
(let* ([filename (derive-filename d ht)]
|
||||||
[full-path (build-path (path-only (current-output-file))
|
[full-path (build-path (path-only (current-output-file))
|
||||||
filename)])
|
filename)])
|
||||||
(parameterize ([on-separate-page #t])
|
(parameterize ([on-separate-page #t])
|
||||||
|
|
|
@ -39,13 +39,13 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s:
|
||||||
@itemize{
|
@itemize{
|
||||||
|
|
||||||
@item{@schemeidfont{make-}@scheme[_struct-id] : a
|
@item{@schemeidfont{make-}@scheme[_struct-id] : a
|
||||||
@defterm{constructor} function that takes as many arguments as
|
@deftech{constructor} function that takes as many arguments as
|
||||||
the number of @scheme[_field-id]s, and returns an instance of
|
the number of @scheme[_field-id]s, and returns an instance of
|
||||||
the structure type.
|
the structure type.
|
||||||
|
|
||||||
@examples[(make-posn 1 2)]}
|
@examples[(make-posn 1 2)]}
|
||||||
|
|
||||||
@item{@scheme[_struct-id]@schemeidfont{?} : a @defterm{predicate}
|
@item{@scheme[_struct-id]@schemeidfont{?} : a @deftech{predicate}
|
||||||
function that takes a single argument and returns @scheme[#t]
|
function that takes a single argument and returns @scheme[#t]
|
||||||
if it is an instance of the structure type, @scheme[#f]
|
if it is an instance of the structure type, @scheme[#f]
|
||||||
otherwise.
|
otherwise.
|
||||||
|
@ -53,14 +53,14 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s:
|
||||||
@examples[(posn? 3) (posn? (make-posn 1 2))]}
|
@examples[(posn? 3) (posn? (make-posn 1 2))]}
|
||||||
|
|
||||||
@item{@scheme[_struct-id]@schemeidfont{-}@scheme[_field-id] : for
|
@item{@scheme[_struct-id]@schemeidfont{-}@scheme[_field-id] : for
|
||||||
each @scheme[_field-id], an @defterm{accessor} that extracts
|
each @scheme[_field-id], an @deftech{accessor} that extracts
|
||||||
the value of the corresponding field from an instance of the
|
the value of the corresponding field from an instance of the
|
||||||
structure type.
|
structure type.
|
||||||
|
|
||||||
@examples[(posn-x (make-posn 1 2)) (posn-y (make-posn 1 2))]}
|
@examples[(posn-x (make-posn 1 2)) (posn-y (make-posn 1 2))]}
|
||||||
|
|
||||||
@item{@schemeidfont{set-}@scheme[_struct-id]@schemeidfont{-}@scheme[_field-id]@schemeidfont{!} : for
|
@item{@schemeidfont{set-}@scheme[_struct-id]@schemeidfont{-}@scheme[_field-id]@schemeidfont{!} : for
|
||||||
each @scheme[_field-id], a @defterm{mutator} that sets
|
each @scheme[_field-id], a @deftech{mutator} that sets
|
||||||
the value of the corresponding field in an instance of the
|
the value of the corresponding field in an instance of the
|
||||||
structure type.
|
structure type.
|
||||||
|
|
||||||
|
@ -68,6 +68,12 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s:
|
||||||
(posn-x p)
|
(posn-x p)
|
||||||
(set-posn-x! p 10)
|
(set-posn-x! p 10)
|
||||||
(posn-x p)]}
|
(posn-x p)]}
|
||||||
|
|
||||||
|
@item{@schemeidfont{struct:}@scheme[_struct-id] : a
|
||||||
|
@deftech{structure type descriptor}, which is a value that
|
||||||
|
represents the structure type (as opposed to a single instance)
|
||||||
|
for certain reflective operations.}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
A @scheme[define-struct] form places no constraints on the kinds of
|
A @scheme[define-struct] form places no constraints on the kinds of
|
||||||
|
@ -76,7 +82,7 @@ type. For example, @scheme[(make-posn "apple" #f)] produces an
|
||||||
instance of @scheme[posn], even though @scheme["apple"] and
|
instance of @scheme[posn], even though @scheme["apple"] and
|
||||||
@scheme[#f] are not valid coordinates for the obvious uses of
|
@scheme[#f] are not valid coordinates for the obvious uses of
|
||||||
@scheme[posn] instances. Enforcing constraints on field values, such
|
@scheme[posn] instances. Enforcing constraints on field values, such
|
||||||
as requiring them to be numbers, is the job of a contract, as
|
as requiring them to be numbers, is normally the job of a contract, as
|
||||||
discussed later in @secref["guide:contracts"].
|
discussed later in @secref["guide:contracts"].
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
@; ------------------------------------------------------------
|
||||||
|
@ -114,7 +120,7 @@ p
|
||||||
]
|
]
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
@; ------------------------------------------------------------
|
||||||
@section{Opaque versus Transparent Stucture Types}
|
@section[#:tag "guide:trans-struct"]{Opaque versus Transparent Stucture Types}
|
||||||
|
|
||||||
With a structure type definition like
|
With a structure type definition like
|
||||||
|
|
||||||
|
@ -141,11 +147,176 @@ field-name sequence:
|
||||||
An instance of a transparent structure type prints like a vector, and
|
An instance of a transparent structure type prints like a vector, and
|
||||||
it shows the content of the structure's fields. A transparent
|
it shows the content of the structure's fields. A transparent
|
||||||
structure type also allows reflective operations, like
|
structure type also allows reflective operations, like
|
||||||
@scheme[struct?] and @scheme[struct-info], to be used on its
|
@scheme[struct?] and @scheme[struct-info], to be used on its instances
|
||||||
instances (see @secref["reflection"]).
|
(see @secref["reflection"]). Different values for @scheme[#:inspector]
|
||||||
|
support more controlled access to reflective operations.
|
||||||
|
|
||||||
Structure types are opaque by default, because opaque structure
|
Structure types are opaque by default, because opaque structure
|
||||||
instances provide more encapsulation guarantees. That is, a library
|
instances provide more encapsulation guarantees. That is, a library
|
||||||
can use an opaque structure to encapsulate data, and clients of the
|
can use an opaque structure to encapsulate data, and clients of the
|
||||||
library cannot manipulate the data in the structure except as allowed
|
library cannot manipulate the data in the structure except as allowed
|
||||||
by the library.
|
by the library.
|
||||||
|
|
||||||
|
@; ------------------------------------------------------------
|
||||||
|
@section{More Structure Type Options}
|
||||||
|
|
||||||
|
The full syntax of @scheme[define-struct] supports many options, both
|
||||||
|
at the structure-type level and at the level of individual fields:
|
||||||
|
|
||||||
|
@specform/subs[(define-struct id-maybe-super (field ...)
|
||||||
|
struct-option ...)
|
||||||
|
([id-maybe-super struct-id
|
||||||
|
(struct-id super-id)]
|
||||||
|
[field field-id
|
||||||
|
[field-id field-option ...]])]
|
||||||
|
|
||||||
|
A @scheme[_struct-option] always starts with a keyword:
|
||||||
|
|
||||||
|
@specspecsubform[#:immutable]{
|
||||||
|
|
||||||
|
Causes all fields of the structure type to be immutable, and
|
||||||
|
supresses the definition of @tech{mutator} procedures.
|
||||||
|
|
||||||
|
@defexamples[(define-struct fixed-posn (x y) #:immutable)
|
||||||
|
(set-fixed-posn-x! (make-fixed-posn 1 2) 0)]
|
||||||
|
|
||||||
|
Th @scheme[#:immutable] option can also be used as a
|
||||||
|
@scheme[_field-option], in which case it makes an individual field
|
||||||
|
immutable.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define-struct person ([name #:immutable] age))
|
||||||
|
(define friend (make-person "Barney" 5))
|
||||||
|
(set-person-age! friend 6)
|
||||||
|
(set-person-name! friend "Mary")]}
|
||||||
|
|
||||||
|
@specspecsubform[(code:line #:inspector inspector-expr)]{
|
||||||
|
Controls reflective access to structure instances, as discussed
|
||||||
|
in the previous section (@secref["guide:trans-struct"]).
|
||||||
|
}
|
||||||
|
|
||||||
|
@specspecsubform[(code:line #:auto-value auto-expr)]{
|
||||||
|
|
||||||
|
Specifies a value to be used for all automatic fields in the
|
||||||
|
structure type, where an automatic field is indicated by the
|
||||||
|
@scheme[#:auto] @scheme[_field-option]. The structure type's
|
||||||
|
constructor omits arguments for automatic fields.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define-struct posn (x y [z #:auto])
|
||||||
|
#:inspector #f
|
||||||
|
#:auto-value 0)
|
||||||
|
(make-posn 1 2)
|
||||||
|
]}
|
||||||
|
|
||||||
|
@specspecsubform[(code:line #:guard guard-expr)]{
|
||||||
|
Specifies a guard procedure to be called whenever an instance of
|
||||||
|
the structure type is created. The guard takes as many arguments
|
||||||
|
as non-automatic fields in the structure type, and it should return
|
||||||
|
the same number of values. The guard can raise an exception if one
|
||||||
|
of the given arguments is unacceptable, or it can convert an
|
||||||
|
argument.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define-struct thing (name)
|
||||||
|
#:inspector #f
|
||||||
|
#:guard (lambda (name type-name)
|
||||||
|
(cond
|
||||||
|
[(string? name) name]
|
||||||
|
[(number? name)
|
||||||
|
(number->string name)]
|
||||||
|
[else (error "bad name" name)])))
|
||||||
|
(make-thing "apple")
|
||||||
|
(make-thing 1/2)
|
||||||
|
(make-thing #f)]
|
||||||
|
|
||||||
|
Unlike the constructor for a procedure type, the guard is called even when
|
||||||
|
subtype instances are created. In that case, only the fields accepted by
|
||||||
|
the constructor are provided to the guard (but the subtype's guard gets
|
||||||
|
both the original fields and fields added by the subtype).
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define-struct (person thing) (age)
|
||||||
|
#:inspector #f
|
||||||
|
#:guard (lambda (name age type-name)
|
||||||
|
(if (negative? age)
|
||||||
|
(error "bad age" age)
|
||||||
|
(values name age))))
|
||||||
|
(make-person "John" 10)
|
||||||
|
(make-person "Mary" -1)
|
||||||
|
(make-person #f 10)]}
|
||||||
|
|
||||||
|
@specspecsubform[(code:line #:property prop-expr val-exr)]{
|
||||||
|
Associates a property and value with the structure type. For
|
||||||
|
example, the @scheme[prop:procedure] property allows a structure
|
||||||
|
instance to be used as a function; the property value determines
|
||||||
|
how a call is implemented when using the structure as a function.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define-struct greeter (name)
|
||||||
|
#:property prop:procedure
|
||||||
|
(lambda (self other)
|
||||||
|
(string-append
|
||||||
|
"Hi " other
|
||||||
|
", I'm " (greeter-name self))))
|
||||||
|
(define joe-greet (make-greeter "Joe"))
|
||||||
|
(greeter-name joe-greet)
|
||||||
|
(joe-greet "Mary")
|
||||||
|
(joe-greet "John")]}
|
||||||
|
|
||||||
|
@specspecsubform[(code:line #:super super-expr)]{
|
||||||
|
|
||||||
|
An alternative to supplying a @scheme[super-id] next to
|
||||||
|
@scheme[struct-id]. Instead of the name of a structure type (which is
|
||||||
|
not an expression), @scheme[super-expr] should produce a
|
||||||
|
@tech{structure type descriptor} value. An advantage of
|
||||||
|
@scheme[#:super] is that structure type descriptors are values, so
|
||||||
|
they can be passed to procedures.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define (make-raven-constructor super-type)
|
||||||
|
(define-struct raven ()
|
||||||
|
#:super super-type
|
||||||
|
#:inspector #f
|
||||||
|
#:property prop:procedure (lambda (self)
|
||||||
|
'nevermore))
|
||||||
|
make-raven)
|
||||||
|
(let ([r ((make-raven-constructor struct:posn) 1 2)])
|
||||||
|
(list r (r)))
|
||||||
|
(let ([r ((make-raven-constructor struct:thing) "apple")])
|
||||||
|
(list r (r)))]}
|
||||||
|
|
||||||
|
|
||||||
|
@; ------------------------------------------------------------
|
||||||
|
@section{Structure Type Generativity}
|
||||||
|
|
||||||
|
Each time that a @scheme[define-struct] form is evaluated, it
|
||||||
|
generates a structure type that is distinct from all existing
|
||||||
|
structure types, even if some other structure type has the same name
|
||||||
|
and fields.
|
||||||
|
|
||||||
|
This generativity is useful for enforcing abstractions and
|
||||||
|
implementing programs such as interpreters, but beware of placing a
|
||||||
|
@scheme[define-struct] form in positions that are evaluated multiple
|
||||||
|
times.
|
||||||
|
|
||||||
|
@defexamples[
|
||||||
|
(define (add-bigger-fish lst)
|
||||||
|
(define-struct fish (size) #:inspector #f)
|
||||||
|
(cond
|
||||||
|
[(null? lst) (list (make-fish 1))]
|
||||||
|
[else (cons (make-fish (* 2 (fish-size (car lst))))
|
||||||
|
lst)]))
|
||||||
|
|
||||||
|
(add-bigger-fish null)
|
||||||
|
(add-bigger-fish (add-bigger-fish null))
|
||||||
|
]
|
||||||
|
@defs+int[
|
||||||
|
[(define-struct fish (size) #:inspector #f)
|
||||||
|
(define (add-bigger-fish lst)
|
||||||
|
(cond
|
||||||
|
[(null? lst) (list (make-fish 1))]
|
||||||
|
[else (cons (make-fish (* 2 (fish-size (car lst))))
|
||||||
|
lst)]))]
|
||||||
|
(add-bigger-fish (add-bigger-fish null))
|
||||||
|
]
|
||||||
|
|
|
@ -17,6 +17,7 @@ language.
|
||||||
@include-section["syntax.scrbl"]
|
@include-section["syntax.scrbl"]
|
||||||
@include-section["derived.scrbl"]
|
@include-section["derived.scrbl"]
|
||||||
@include-section["data.scrbl"]
|
@include-section["data.scrbl"]
|
||||||
|
@include-section["struct.scrbl"]
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
196
collects/scribblings/reference/struct.scrbl
Normal file
196
collects/scribblings/reference/struct.scrbl
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
#reader(lib "docreader.ss" "scribble")
|
||||||
|
@require["mz.ss"]
|
||||||
|
|
||||||
|
@title[#:tag "mz:structures"]{Structures}
|
||||||
|
|
||||||
|
A @pidefterm{structure type} is a record datatype composing a number
|
||||||
|
of @idefterm{fields}. A @pidefterm{structure}, an instance of a
|
||||||
|
structure type, is a first-class value that contains a value for each
|
||||||
|
field of the structure type. A structure instance is created with a
|
||||||
|
type-specific @tech{constructor} procedure, and its field values are
|
||||||
|
accessed and changed with type-specific @tech{accessor} and
|
||||||
|
@tech{mutator} procedures. In addition, each structure type has a
|
||||||
|
@tech{predicate} procedure that answers @scheme[#t] for instances of
|
||||||
|
the structure type and @scheme[#f] for any other value.
|
||||||
|
|
||||||
|
A structure type's fields are essentially unnamed, though names are
|
||||||
|
supported for error-reporting purposes. The constructor procedure
|
||||||
|
takes one value for each field of the structure type, except that some
|
||||||
|
of the fields of a structure type can be @deftech{automatic fields};
|
||||||
|
the @tech{automatic fields} are initialized to a constant that is
|
||||||
|
associated with the structure type, and the corresponding arguments
|
||||||
|
are omitted for the constructor procedure. All automatic fields in a
|
||||||
|
structure type follow the non-automatic fields.
|
||||||
|
|
||||||
|
A structure type can be created as a @pidefterm{structure subtype} of
|
||||||
|
an existing base structure type. An instance of a structure subtype
|
||||||
|
can always be used as an instance of the base structure type, but the
|
||||||
|
subtype gets its own predicate procedure, and it may have its own
|
||||||
|
fields in addition to the fields of the base type.
|
||||||
|
|
||||||
|
A structure subtype ``inherits'' the fields of its base type. If the
|
||||||
|
base type has @math{m} fields, and if @math{n} fields are specified
|
||||||
|
for the new structure subtype, then the resulting structure type has
|
||||||
|
@math{m+n} fields. The value for automatic fields can be different in
|
||||||
|
a subtype than in its base type.
|
||||||
|
|
||||||
|
If @math{m'} of the original @math{m} fields are non-automatic (where
|
||||||
|
@math{m'<m}), and @math{n'} of the new fields are automatic (where
|
||||||
|
@math{n'<n}), then @math{m'+n'} field values must be provided to the
|
||||||
|
subtype's constructor procedure. Values for the first @math{m} fields
|
||||||
|
of a subtype instance are accessed with selector procedures for the
|
||||||
|
original base type (or its supertypes), and the last @math{n} are
|
||||||
|
accessed with subtype-specific selectors. Subtype-specific
|
||||||
|
@tech{accessors} and @tech{mutators} for the first @math{m} fields do
|
||||||
|
not exist.
|
||||||
|
|
||||||
|
@section{Creating Structure Types}
|
||||||
|
|
||||||
|
@defproc[(make-struct-type [name symbol?]
|
||||||
|
[super-type (or/c struct-type? false/c)]
|
||||||
|
[init-field-k non-negative-exact-integer?]
|
||||||
|
[auto-field-k non-negative-exact-integer?]
|
||||||
|
[auto-v any/c #f]
|
||||||
|
[props (listof (cons/c struct-type-property?
|
||||||
|
any/c))
|
||||||
|
null]
|
||||||
|
[inspector (or/c inspector? false/c)
|
||||||
|
(current-inspector)]
|
||||||
|
[proc-spec (or/c procedure?
|
||||||
|
non-negative-exact-integer?
|
||||||
|
false/c)
|
||||||
|
#f]
|
||||||
|
[immutables (listof non-negative-exact-integer?)
|
||||||
|
null]
|
||||||
|
[guard (or/c procedure? false/c) #f])
|
||||||
|
struct-type?]{
|
||||||
|
|
||||||
|
Creates a new structure type. The @scheme[name] argument is used as
|
||||||
|
the type name. If @scheme[super-type] is not @scheme[#f], the new type
|
||||||
|
is a subtype of the corresponding structure type.
|
||||||
|
|
||||||
|
The new structure type has @scheme[(+ init-field-k auto-field-k)]
|
||||||
|
fields (in addition to any fields from @scheme[super-type]), but only
|
||||||
|
@scheme[init-field-k] constructor arguments (in addition to any
|
||||||
|
constructor arguments from @scheme[super-type]). The remaining
|
||||||
|
fields are initialized with @scheme[auto-v].
|
||||||
|
|
||||||
|
The @scheme{props} argument is a list of pairs, where the @scheme[car]
|
||||||
|
of each pair is a structure type property descriptor, and the
|
||||||
|
@scheme[cdr] is an arbitrary value. See @secref["mz:structprops"] for
|
||||||
|
more information about properties.
|
||||||
|
|
||||||
|
The @scheme[inspector] argument controls access to reflective
|
||||||
|
information about the structure type and its instances; see
|
||||||
|
@secref["mz:inspectors"] for more information.
|
||||||
|
|
||||||
|
If @scheme[proc-spec] is an integer or procedure, instances of the
|
||||||
|
structure type act as procedures. See @secref["mz:procstructs"] for
|
||||||
|
further information. Providing a non-@scheme[#f] value for
|
||||||
|
@scheme[proc-spec] is the same as pairing the value with
|
||||||
|
@scheme[prop:procedure] in @scheme[props], plus including
|
||||||
|
@scheme[proc-spec] in @scheme[immutables] when
|
||||||
|
@scheme[proc-spec] is an integer.
|
||||||
|
|
||||||
|
The @scheme[immutables] argument provides a list of field
|
||||||
|
positions. Each element in the list must be unique, otherwise
|
||||||
|
@exnraise[exn:fail:contract]. Each element must also fall in the range
|
||||||
|
@scheme[0] (inclusive) to @scheme[init-field-k] (exclusive), otherwise
|
||||||
|
@exnraise[exn:fail:contract].
|
||||||
|
|
||||||
|
The @scheme[guard-proc] argument is either a procedure of @math{n}
|
||||||
|
arguments or @scheme[#f], where @math{n} is the number of arguments
|
||||||
|
for the new structure type's constructor (i.e., @scheme[init-field-k]
|
||||||
|
plus constructor arguments implied by @scheme[super-type], if any). If
|
||||||
|
@scheme[guard-proc] is a procedure, then the procedure is called
|
||||||
|
whenever an instance of the type is constructed, or whenever an
|
||||||
|
instance of a subtype is created. The arguments to
|
||||||
|
@scheme[guard-proc] are the values provided for the structure's first
|
||||||
|
@math{n} fields, followed by the name of the instantiated structure
|
||||||
|
type (which is @scheme[name], unless a subtype is instantiated). The
|
||||||
|
@scheme[guard-proc] result must be @math{n} values, which become the
|
||||||
|
actual values for the structure's fields. The @scheme[guard-proc] can
|
||||||
|
raise an exception to prevent creation of a structure with the given
|
||||||
|
field values. If a structure subtype has its own guard, the subtype
|
||||||
|
guard is applied first, and the first @math{n} values produced by the
|
||||||
|
subtype's guard procedure become the first @math{n} arguments to
|
||||||
|
@scheme[guard-proc].
|
||||||
|
|
||||||
|
The result of @scheme[make-struct-type] is five values:
|
||||||
|
%
|
||||||
|
@itemize{
|
||||||
|
|
||||||
|
@item{a @tech{structure type descriptor},}
|
||||||
|
|
||||||
|
@item{a @tech{constructor} procedure,}
|
||||||
|
|
||||||
|
@item{a @tech{predicate} procedure,}
|
||||||
|
|
||||||
|
@item{an @tech{accessor} procedure, which consumes a structure and a field
|
||||||
|
index between @math{0} (inclusive) and
|
||||||
|
@math{@scheme[init-field-k]+@scheme[auto-field-k]} (exclusive),
|
||||||
|
and}
|
||||||
|
|
||||||
|
@item{a @tech{mutator} procedure, which consumes a structure, a field
|
||||||
|
index, and a field value.}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(define-values (struct:a make-a a? a-ref a-set!)
|
||||||
|
(make-struct-type 'a #f 2 1 'uninitialized))
|
||||||
|
(define an-a (make-a 'x 'y))
|
||||||
|
(a-ref an-a 1)
|
||||||
|
(a-ref an-a 2)
|
||||||
|
(define a-first (make-struct-field-accessor a-ref 0))
|
||||||
|
(a-first an-a)
|
||||||
|
|
||||||
|
(define-values (struct:b make-b b? b-ref b-set!)
|
||||||
|
(make-struct-type 'b struct:a 1 2 'b-uninitialized))
|
||||||
|
(define a-b (make-b 'x 'y 'z))
|
||||||
|
(a-ref a-b 1)
|
||||||
|
(a-ref a-b 2)
|
||||||
|
(b-ref a-b 0)
|
||||||
|
(b-ref a-b 1)
|
||||||
|
(b-ref a-b 2)
|
||||||
|
|
||||||
|
(define-values (struct:c make-c c? c-ref c-set!)
|
||||||
|
(make-struct-type 'c struct:b 0 0 #f null (make-inspector) #f null
|
||||||
|
(code:comment #,(t "guard checks for a number, and makes it inexact"))
|
||||||
|
(lambda (a1 a2 b1 name)
|
||||||
|
(unless (number? a2)
|
||||||
|
(error (string->symbol (format "make-~a" name))
|
||||||
|
"second field must be a number"))
|
||||||
|
(values a1 (exact->inexact a2) b1))))
|
||||||
|
(make-c 'x 'y 'z)
|
||||||
|
(define a-c (make-c 'x 2 'z))
|
||||||
|
(a-ref a-c 1)
|
||||||
|
]}
|
||||||
|
|
||||||
|
@defproc[(make-struct-field-accessor [accessor-proc procedure?]
|
||||||
|
[field-pos-k exact-nonnegative-integer?]
|
||||||
|
[field-name symbol?])
|
||||||
|
procedure?]{
|
||||||
|
|
||||||
|
Returns a field accessor that is equivalent to @scheme[(lambda (s)
|
||||||
|
(accessor-proc s field-pos-k))]. The @scheme[accessor-proc] must be
|
||||||
|
an @tech{accessor} returned by @scheme[make-struct-type]. The name of the
|
||||||
|
resulting procedure for debugging purposes is derived from
|
||||||
|
@scheme[field-name] and the name of @scheme[accessor-proc]'s
|
||||||
|
structure type.
|
||||||
|
|
||||||
|
For examples, see @scheme[make-struct-type].}
|
||||||
|
|
||||||
|
@defproc[(make-struct-field-mutator [mutator-proc procedure?]
|
||||||
|
[field-pos-k exact-nonnegative-integer?]
|
||||||
|
[field-name symbol?])
|
||||||
|
procedure?]{
|
||||||
|
|
||||||
|
Returns a field mutator that is equivalent to @scheme[(lambda (s v)
|
||||||
|
(mutator-proc s field-pos-k v))]. The @scheme[mutator-proc] must be
|
||||||
|
a @tech{mutator} returned by @scheme[make-struct-type]. The name of the
|
||||||
|
resulting procedure for debugging purposes is derived from
|
||||||
|
@scheme[field-name] and the name of @scheme[mutator-proc]'s
|
||||||
|
structure type.
|
||||||
|
|
||||||
|
For examples, see @scheme[make-struct-type].}
|
|
@ -354,7 +354,7 @@ Like @scheme[lambda], but without support for keyword or optional arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
@section[#:tag "mz:let"]{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
||||||
|
|
||||||
@defform*[[(let ([id val-expr] ...) body ...+)
|
@defform*[[(let ([id val-expr] ...) body ...+)
|
||||||
(let proc-id ([id init-expr] ...) body ...+)]]{
|
(let proc-id ([id init-expr] ...) body ...+)]]{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user