doc work (fix long filename)
svn: r6717
This commit is contained in:
parent
e0edc04bef
commit
ff1189600a
|
@ -272,12 +272,16 @@
|
|||
(current-subdirectory))
|
||||
(super get-dest-directory)))
|
||||
|
||||
(define/private (derive-filename d)
|
||||
(format "~a.html" (regexp-replace*
|
||||
"[^-a-zA-Z0-9_=]"
|
||||
(or (format "~a" (part-tag d))
|
||||
(content->string (part-title-content d)))
|
||||
"_")))
|
||||
(define/private (derive-filename d ht)
|
||||
(let ([fn (format "~a.html" (regexp-replace*
|
||||
"[^-a-zA-Z0-9_=]"
|
||||
(or (format "~a" (part-tag 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)
|
||||
(super collect ds (map (lambda (fn)
|
||||
|
@ -297,7 +301,7 @@
|
|||
1
|
||||
(add1 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))
|
||||
filename)])
|
||||
(super collect-part d parent ht number)))
|
||||
|
@ -417,7 +421,7 @@
|
|||
(make-element
|
||||
(if parent
|
||||
(make-target-url (if prev
|
||||
(derive-filename prev)
|
||||
(derive-filename prev ht)
|
||||
"index.html"))
|
||||
"nonavigation")
|
||||
prev-content)
|
||||
|
@ -426,14 +430,14 @@
|
|||
(if parent
|
||||
(make-target-url
|
||||
(if (toc-part? parent)
|
||||
(derive-filename parent)
|
||||
(derive-filename parent ht)
|
||||
"index.html"))
|
||||
"nonavigation")
|
||||
up-content)
|
||||
sep-element
|
||||
(make-element
|
||||
(if next
|
||||
(make-target-url (derive-filename next))
|
||||
(make-target-url (derive-filename next ht))
|
||||
"nonavigation")
|
||||
next-content))))))))
|
||||
d
|
||||
|
@ -447,7 +451,7 @@
|
|||
(next-separate-page)))
|
||||
;; Render as just a link, and put the actual
|
||||
;; 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))
|
||||
filename)])
|
||||
(parameterize ([on-separate-page #t])
|
||||
|
|
|
@ -39,13 +39,13 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s:
|
|||
@itemize{
|
||||
|
||||
@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 structure type.
|
||||
|
||||
@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]
|
||||
if it is an instance of the structure type, @scheme[#f]
|
||||
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))]}
|
||||
|
||||
@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
|
||||
structure type.
|
||||
|
||||
@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
|
||||
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
|
||||
structure type.
|
||||
|
||||
|
@ -68,6 +68,12 @@ are built from @scheme[_struct-id] and the @scheme[_field-id]s:
|
|||
(posn-x p)
|
||||
(set-posn-x! p 10)
|
||||
(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
|
||||
|
@ -76,7 +82,7 @@ type. For example, @scheme[(make-posn "apple" #f)] produces an
|
|||
instance of @scheme[posn], even though @scheme["apple"] and
|
||||
@scheme[#f] are not valid coordinates for the obvious uses of
|
||||
@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"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
||||
|
@ -141,11 +147,176 @@ field-name sequence:
|
|||
An instance of a transparent structure type prints like a vector, and
|
||||
it shows the content of the structure's fields. A transparent
|
||||
structure type also allows reflective operations, like
|
||||
@scheme[struct?] and @scheme[struct-info], to be used on its
|
||||
instances (see @secref["reflection"]).
|
||||
@scheme[struct?] and @scheme[struct-info], to be used on its instances
|
||||
(see @secref["reflection"]). Different values for @scheme[#:inspector]
|
||||
support more controlled access to reflective operations.
|
||||
|
||||
Structure types are opaque by default, because opaque structure
|
||||
instances provide more encapsulation guarantees. That is, a library
|
||||
can use an opaque structure to encapsulate data, and clients of the
|
||||
library cannot manipulate the data in the structure except as allowed
|
||||
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["derived.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 ...+)
|
||||
(let proc-id ([id init-expr] ...) body ...+)]]{
|
||||
|
|
Loading…
Reference in New Issue
Block a user