test material
parent
bbd727376f
commit
a66f25cb5d
@ -0,0 +1,5 @@
|
||||
#lang qtest/markdown
|
||||
|
||||
```
|
||||
|
||||
```
|
@ -0,0 +1,173 @@
|
||||
# Sequencing
|
||||
|
||||
Racket programmers prefer to write programs with as few side-effects as
|
||||
possible, since purely functional code is more easily tested and
|
||||
composed into larger programs. Interaction with the external
|
||||
environment, however, requires sequencing, such as when writing to a
|
||||
display, opening a graphical window, or manipulating a file on disk.
|
||||
|
||||
## 1. Effects Before: `begin`
|
||||
|
||||
> +\[missing\] in \[missing\] also documents `begin`.
|
||||
|
||||
A `begin` expression sequences expressions:
|
||||
|
||||
```racket
|
||||
(begin expr ...+)
|
||||
```
|
||||
|
||||
The `expr`s are evaluated in order, and the result of all but the last
|
||||
`expr` is ignored. The result from the last `expr` is the result of the
|
||||
`begin` form, and it is in tail position with respect to the `begin`
|
||||
form.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
(define (print-triangle height)
|
||||
(if (zero? height)
|
||||
(void)
|
||||
(begin
|
||||
(display (make-string height #\*))
|
||||
(newline)
|
||||
(print-triangle (sub1 height)))))
|
||||
|
||||
> (print-triangle 4)
|
||||
****
|
||||
***
|
||||
**
|
||||
*
|
||||
```
|
||||
|
||||
Many forms, such as `lambda` or `cond` support a sequence of expressions
|
||||
even without a `begin`. Such positions are sometimes said to have an
|
||||
_implicit begin_.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
(define (print-triangle height)
|
||||
(cond
|
||||
[(positive? height)
|
||||
(display (make-string height #\*))
|
||||
(newline)
|
||||
(print-triangle (sub1 height))]))
|
||||
|
||||
> (print-triangle 4)
|
||||
****
|
||||
***
|
||||
**
|
||||
*
|
||||
```
|
||||
|
||||
The `begin` form is special at the top level, at module level, or as a
|
||||
`body` after only internal definitions. In those positions, instead of
|
||||
forming an expression, the content of `begin` is spliced into the
|
||||
surrounding context.
|
||||
|
||||
Example:
|
||||
|
||||
```racket
|
||||
> (let ([curly 0])
|
||||
(begin
|
||||
(define moe (+ 1 curly))
|
||||
(define larry (+ 1 moe)))
|
||||
(list larry curly moe))
|
||||
'(2 0 1)
|
||||
```
|
||||
|
||||
This splicing behavior is mainly useful for macros, as we discuss later
|
||||
in \[missing\].
|
||||
|
||||
## 2. Effects After: `begin0`
|
||||
|
||||
> +\[missing\] in \[missing\] also documents `begin0`.
|
||||
|
||||
A `begin0` expression has the same syntax as a `begin` expression:
|
||||
|
||||
```racket
|
||||
(begin0 expr ...+)
|
||||
```
|
||||
|
||||
The difference is that `begin0` returns the result of the first `expr`,
|
||||
instead of the result of the last `expr`. The `begin0` form is useful
|
||||
for implementing side-effects that happen after a computation,
|
||||
especially in the case where the computation produces an unknown number
|
||||
of results.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
(define (log-times thunk)
|
||||
(printf "Start: ~s\n" (current-inexact-milliseconds))
|
||||
(begin0
|
||||
(thunk)
|
||||
(printf "End..: ~s\n" (current-inexact-milliseconds))))
|
||||
|
||||
> (log-times (lambda () (sleep 0.1) 0))
|
||||
Start: 1548117334950.433
|
||||
End..: 1548117335053.375
|
||||
0
|
||||
> (log-times (lambda () (values 1 2)))
|
||||
Start: 1548117335053.996
|
||||
End..: 1548117335054.022
|
||||
1
|
||||
2
|
||||
```
|
||||
|
||||
## 3. Effects If...: `when` and `unless`
|
||||
|
||||
> +\[missing\] in \[missing\] also documents `when` and `unless`.
|
||||
|
||||
The `when` form combines an `if`-style conditional with sequencing for
|
||||
the “then” clause and no “else” clause:
|
||||
|
||||
```racket
|
||||
(when test-expr then-body ...+)
|
||||
```
|
||||
|
||||
If `test-expr` produces a true value, then all of the `then-body`s are
|
||||
evaluated. The result of the last `then-body` is the result of the
|
||||
`when` form. Otherwise, no `then-body`s are evaluated and the result is
|
||||
`#<void>`.
|
||||
|
||||
The `unless` form is similar:
|
||||
|
||||
```racket
|
||||
(unless test-expr then-body ...+)
|
||||
```
|
||||
|
||||
The difference is that the `test-expr` result is inverted: the
|
||||
`then-body`s are evaluated only if the `test-expr` result is `#f`.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
(define (enumerate lst)
|
||||
(if (null? (cdr lst))
|
||||
(printf "~a.\n" (car lst))
|
||||
(begin
|
||||
(printf "~a, " (car lst))
|
||||
(when (null? (cdr (cdr lst)))
|
||||
(printf "and "))
|
||||
(enumerate (cdr lst)))))
|
||||
|
||||
> (enumerate '("Larry" "Curly" "Moe"))
|
||||
Larry, Curly, and Moe.
|
||||
```
|
||||
|
||||
```racket
|
||||
(define (print-triangle height)
|
||||
(unless (zero? height)
|
||||
(display (make-string height #\*))
|
||||
(newline)
|
||||
(print-triangle (sub1 height))))
|
||||
```
|
||||
|
||||
```racket
|
||||
> (print-triangle 4)
|
||||
****
|
||||
***
|
||||
**
|
||||
*
|
||||
```
|
@ -0,0 +1,24 @@
|
||||
# Booleans
|
||||
|
||||
Racket has two distinguished constants to represent boolean values: `#t`
|
||||
for true and `#f` for false. Uppercase `#T` and `#F` are parsed as the
|
||||
same values, but the lowercase forms are preferred.
|
||||
|
||||
The `boolean?` procedure recognizes the two boolean constants. In the
|
||||
result of a test expression for `if`, `cond`, `and`, `or`, etc.,
|
||||
however, any value other than `#f` counts as true.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> (= 2 (+ 1 1))
|
||||
#t
|
||||
> (boolean? #t)
|
||||
#t
|
||||
> (boolean? #f)
|
||||
#t
|
||||
> (boolean? "no")
|
||||
#f
|
||||
> (if "no" 1 0)
|
||||
1
|
||||
```
|
@ -0,0 +1,21 @@
|
||||
# Boxes
|
||||
|
||||
A _box_ is like a single-element vector. It can print as a quoted `#&`
|
||||
followed by the printed form of the boxed value. A `#&` form can also be
|
||||
used as an expression, but since the resulting box is constant, it has
|
||||
practically no use.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> (define b (box "apple"))
|
||||
> b
|
||||
'#&"apple"
|
||||
> (unbox b)
|
||||
"apple"
|
||||
> (set-box! b '(banana boat))
|
||||
> b
|
||||
'#&(banana boat)
|
||||
```
|
||||
|
||||
> +\[missing\] in \[missing\] provides more on boxes and box procedures.
|
@ -0,0 +1,48 @@
|
||||
# Simple Dispatch: `case`
|
||||
|
||||
The `case` form dispatches to a clause by matching the result of an
|
||||
expression to the values for the clause:
|
||||
|
||||
```racket
|
||||
(case expr
|
||||
[(datum ...+) body ...+]
|
||||
...)
|
||||
```
|
||||
|
||||
Each `datum` will be compared to the result of `expr` using `equal?`,
|
||||
and then the corresponding `body`s are evaluated. The `case` form can
|
||||
dispatch to the correct clause in _O_\(_log N_\)__ time for _N_
|
||||
`datum`s.
|
||||
|
||||
Multiple `datum`s can be supplied for each clause, and the corresponding
|
||||
`body`s are evaluated if any of the `datum`s match.
|
||||
|
||||
Example:
|
||||
|
||||
```racket
|
||||
> (let ([v (random 6)])
|
||||
(printf "~a\n" v)
|
||||
(case v
|
||||
[(0) 'zero]
|
||||
[(1) 'one]
|
||||
[(2) 'two]
|
||||
[(3 4 5) 'many]))
|
||||
0
|
||||
'zero
|
||||
```
|
||||
|
||||
The last clause of a `case` form can use `else`, just like `cond`:
|
||||
|
||||
Example:
|
||||
|
||||
```racket
|
||||
> (case (random 6)
|
||||
[(0) 'zero]
|
||||
[(1) 'one]
|
||||
[(2) 'two]
|
||||
[else 'many])
|
||||
'many
|
||||
```
|
||||
|
||||
For more general pattern matching \(but without the dispatch-time
|
||||
guarantee\), use `match`, which is introduced in \[missing\].
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
||||
# Graphics and GUIs
|
||||
|
||||
Racket provides many libraries for graphics and graphical user
|
||||
interfaces \(GUIs\):
|
||||
|
||||
* The `racket/draw` library provides basic drawing tools, including
|
||||
drawing contexts such as bitmaps and PostScript files.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `racket/gui` library provides GUI widgets such as windows,
|
||||
buttons, checkboxes, and text fields. The library also includes a
|
||||
sophisticated and extensible text editor.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `pict` library provides a more functional abstraction layer over
|
||||
`racket/draw`. This layer is especially useful for creating slide
|
||||
presentations with Slideshow, but it is also useful for creating
|
||||
images for Scribble documents or other drawing tasks. Pictures created
|
||||
with the `pict` library can be rendered to any drawing context.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `2htdp/image` library is similar to `pict`. It is more streamlined
|
||||
for pedagogical use, but also slightly more specific to screen and
|
||||
bitmap drawing.
|
||||
|
||||
See `2htdp/image` for more information.
|
||||
|
||||
* The `sgl` library provides OpenGL for 3-D graphics. The context for
|
||||
rendering OpenGL can be a window or bitmap created with `racket/gui`.
|
||||
|
||||
See the SGL documentation for more information.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,56 @@
|
||||
# Keywords
|
||||
|
||||
A _keyword_ value is similar to a symbol \(see \[missing\]\), but its
|
||||
printed form is prefixed with `#:`.
|
||||
|
||||
> +\[missing\] in \[missing\] documents the fine points of the syntax of
|
||||
> keywords.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> (string->keyword "apple")
|
||||
'#:apple
|
||||
> '#:apple
|
||||
'#:apple
|
||||
> (eq? '#:apple (string->keyword "apple"))
|
||||
#t
|
||||
```
|
||||
|
||||
More precisely, a keyword is analogous to an identifier; in the same way
|
||||
that an identifier can be quoted to produce a symbol, a keyword can be
|
||||
quoted to produce a value. The same term “keyword” is used in both
|
||||
cases, but we sometimes use _keyword value_ to refer more specifically
|
||||
to the result of a quote-keyword expression or of `string->keyword`. An
|
||||
unquoted keyword is not an expression, just as an unquoted identifier
|
||||
does not produce a symbol:
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> not-a-symbol-expression
|
||||
not-a-symbol-expression: undefined;
|
||||
cannot reference an identifier before its definition
|
||||
in module: top-level
|
||||
> #:not-a-keyword-expression
|
||||
eval:2:0: #%datum: keyword misused as an expression
|
||||
at: #:not-a-keyword-expression
|
||||
```
|
||||
|
||||
Despite their similarities, keywords are used in a different way than
|
||||
identifiers or symbols. Keywords are intended for use \(unquoted\) as
|
||||
special markers in argument lists and in certain syntactic forms. For
|
||||
run-time flags and enumerations, use symbols instead of keywords. The
|
||||
example below illustrates the distinct roles of keywords and symbols.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> (define dir (find-system-path 'temp-dir)) ; not '#:temp-dir
|
||||
> (with-output-to-file (build-path dir "stuff.txt")
|
||||
(lambda () (printf "example\n"))
|
||||
; optional #:mode argument can be 'text or 'binary
|
||||
#:mode 'text
|
||||
; optional #:exists argument can be 'replace, 'truncate, ...
|
||||
#:exists 'replace)
|
||||
```
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,156 @@
|
||||
# Pattern Matching
|
||||
|
||||
The `match` form supports pattern matching on arbitrary Racket values,
|
||||
as opposed to functions like `regexp-match` that compare regular
|
||||
expressions to byte and character sequences \(see \[missing\]\).
|
||||
|
||||
```racket
|
||||
(match target-expr
|
||||
[pattern expr ...+] ...)
|
||||
```
|
||||
|
||||
The `match` form takes the result of `target-expr` and tries to match
|
||||
each `pattern` in order. As soon as it finds a match, it evaluates the
|
||||
corresponding `expr` sequence to obtain the result for the `match` form.
|
||||
If `pattern` includes _pattern variables_, they are treated like
|
||||
wildcards, and each variable is bound in the `expr` to the input
|
||||
fragments that it matched.
|
||||
|
||||
Most Racket literal expressions can be used as patterns:
|
||||
|
||||
```racket
|
||||
> (match 2
|
||||
[1 'one]
|
||||
[2 'two]
|
||||
[3 'three])
|
||||
'two
|
||||
> (match #f
|
||||
[#t 'yes]
|
||||
[#f 'no])
|
||||
'no
|
||||
> (match "apple"
|
||||
['apple 'symbol]
|
||||
["apple" 'string]
|
||||
[#f 'boolean])
|
||||
'string
|
||||
```
|
||||
|
||||
Constructors like `cons`, `list`, and `vector` can be used to create
|
||||
patterns that match pairs, lists, and vectors:
|
||||
|
||||
```racket
|
||||
> (match '(1 2)
|
||||
[(list 0 1) 'one]
|
||||
[(list 1 2) 'two])
|
||||
'two
|
||||
> (match '(1 . 2)
|
||||
[(list 1 2) 'list]
|
||||
[(cons 1 2) 'pair])
|
||||
'pair
|
||||
> (match #(1 2)
|
||||
[(list 1 2) 'list]
|
||||
[(vector 1 2) 'vector])
|
||||
'vector
|
||||
```
|
||||
|
||||
A constructor bound with `struct` also can be used as a pattern
|
||||
constructor:
|
||||
|
||||
```racket
|
||||
> (struct shoe (size color))
|
||||
> (struct hat (size style))
|
||||
> (match (hat 23 'bowler)
|
||||
[(shoe 10 'white) "bottom"]
|
||||
[(hat 23 'bowler) "top"])
|
||||
"top"
|
||||
```
|
||||
|
||||
Unquoted, non-constructor identifiers in a pattern are pattern variables
|
||||
that are bound in the result expressions, except `_`, which does not
|
||||
bind \(and thus is usually used as a catch-all\):
|
||||
|
||||
```racket
|
||||
> (match '(1)
|
||||
[(list x) (+ x 1)]
|
||||
[(list x y) (+ x y)])
|
||||
2
|
||||
> (match '(1 2)
|
||||
[(list x) (+ x 1)]
|
||||
[(list x y) (+ x y)])
|
||||
3
|
||||
> (match (hat 23 'bowler)
|
||||
[(shoe sz col) sz]
|
||||
[(hat sz stl) sz])
|
||||
23
|
||||
> (match (hat 11 'cowboy)
|
||||
[(shoe sz 'black) 'a-good-shoe]
|
||||
[(hat sz 'bowler) 'a-good-hat]
|
||||
[_ 'something-else])
|
||||
'something-else
|
||||
```
|
||||
|
||||
An ellipsis, written `...`, acts like a Kleene star within a list or
|
||||
vector pattern: the preceding sub-pattern can be used to match any
|
||||
number of times for any number of consecutive elements of the list or
|
||||
vector. If a sub-pattern followed by an ellipsis includes a pattern
|
||||
variable, the variable matches multiple times, and it is bound in the
|
||||
result expression to a list of matches:
|
||||
|
||||
```racket
|
||||
> (match '(1 1 1)
|
||||
[(list 1 ...) 'ones]
|
||||
[_ 'other])
|
||||
'ones
|
||||
> (match '(1 1 2)
|
||||
[(list 1 ...) 'ones]
|
||||
[_ 'other])
|
||||
'other
|
||||
> (match '(1 2 3 4)
|
||||
[(list 1 x ... 4) x])
|
||||
'(2 3)
|
||||
> (match (list (hat 23 'bowler) (hat 22 'pork-pie))
|
||||
[(list (hat sz styl) ...) (apply + sz)])
|
||||
45
|
||||
```
|
||||
|
||||
Ellipses can be nested to match nested repetitions, and in that case,
|
||||
pattern variables can be bound to lists of lists of matches:
|
||||
|
||||
```racket
|
||||
> (match '((! 1) (! 2 2) (! 3 3 3))
|
||||
[(list (list '! x ...) ...) x])
|
||||
'((1) (2 2) (3 3 3))
|
||||
```
|
||||
|
||||
The `quasiquote` form \(see \[missing\] for more about it\) can also be
|
||||
used to build patterns. While unquoted portions of a normal quasiquoted
|
||||
form mean regular racket evaluation, here unquoted portions mean go back
|
||||
to regular pattern matching.
|
||||
|
||||
So, in the example below, the with expression is the pattern and it gets
|
||||
rewritten into the application expression, using quasiquote as a pattern
|
||||
in the first instance and quasiquote to build an expression in the
|
||||
second.
|
||||
|
||||
```racket
|
||||
> (match `{with {x 1} {+ x 1}}
|
||||
[`{with {,id ,rhs} ,body}
|
||||
`{{lambda {,id} ,body} ,rhs}])
|
||||
'((lambda (x) (+ x 1)) 1)
|
||||
```
|
||||
|
||||
For information on many more pattern forms, see `racket/match`.
|
||||
|
||||
Forms like `match-let` and `match-lambda` support patterns in positions
|
||||
that otherwise must be identifiers. For example, `match-let` generalizes
|
||||
`let` to a destructing bind:
|
||||
|
||||
```racket
|
||||
> (match-let ([(list x y z) '(1 2 3)])
|
||||
(list z y x))
|
||||
'(3 2 1)
|
||||
```
|
||||
|
||||
For information on these additional forms, see `racket/match`.
|
||||
|
||||
> +\[missing\] in \[missing\] provides more on pattern matching.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,63 @@
|
||||
# More Libraries
|
||||
|
||||
This guide covers only the Racket language and libraries that are
|
||||
documented in \[missing\]. The Racket distribution includes many
|
||||
additional libraries.
|
||||
|
||||
## 1. Graphics and GUIs
|
||||
|
||||
Racket provides many libraries for graphics and graphical user
|
||||
interfaces \(GUIs\):
|
||||
|
||||
* The `racket/draw` library provides basic drawing tools, including
|
||||
drawing contexts such as bitmaps and PostScript files.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `racket/gui` library provides GUI widgets such as windows,
|
||||
buttons, checkboxes, and text fields. The library also includes a
|
||||
sophisticated and extensible text editor.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `pict` library provides a more functional abstraction layer over
|
||||
`racket/draw`. This layer is especially useful for creating slide
|
||||
presentations with Slideshow, but it is also useful for creating
|
||||
images for Scribble documents or other drawing tasks. Pictures created
|
||||
with the `pict` library can be rendered to any drawing context.
|
||||
|
||||
See \[missing\] for more information.
|
||||
|
||||
* The `2htdp/image` library is similar to `pict`. It is more streamlined
|
||||
for pedagogical use, but also slightly more specific to screen and
|
||||
bitmap drawing.
|
||||
|
||||
See `2htdp/image` for more information.
|
||||
|
||||
* The `sgl` library provides OpenGL for 3-D graphics. The context for
|
||||
rendering OpenGL can be a window or bitmap created with `racket/gui`.
|
||||
|
||||
See the SGL documentation for more information.
|
||||
|
||||
## 2. The Web Server
|
||||
|
||||
\[missing\] describes the Racket web server, which supports servlets
|
||||
implemented in Racket.
|
||||
|
||||
## 3. Using Foreign Libraries
|
||||
|
||||
\[missing\] describes tools for using Racket to access libraries that
|
||||
are normally used by C programs.
|
||||
|
||||
## 4. And More
|
||||
|
||||
[Racket Documentation](../index.html) lists documentation for many other
|
||||
installed libraries. Run `raco docs` to find documentation for libraries
|
||||
that are installed on your system and specific to your user account.
|
||||
|
||||
[The Racket package repository](https://pkgs.racket-lang.org/) offer
|
||||
even more downloadable packages that are contributed by Racketeers.
|
||||
|
||||
The legacy [PLaneT](http://planet.racket-lang.org/) site offers
|
||||
additional packages, although maintained packages have generally
|
||||
migrated to the newer package repository.
|
@ -0,0 +1,151 @@
|
||||
# Dynamic Binding: `parameterize`
|
||||
|
||||
> +\[missing\] in \[missing\] also documents `parameterize`.
|
||||
|
||||
The `parameterize` form associates a new value with a _parameter_ during
|
||||
the evaluation of `body` expressions:
|
||||
|
||||
```racket
|
||||
(parameterize ([parameter-expr value-expr] ...)
|
||||
body ...+)
|
||||
```
|
||||
|
||||
> The term “parameter” is sometimes used to refer to the arguments of a
|
||||
> function, but “parameter” in Racket has the more specific meaning
|
||||
> described here.
|
||||
|
||||
For example, the `error-print-width` parameter controls how many
|
||||
characters of a value are printed in an error message:
|
||||
|
||||
```racket
|
||||
> (parameterize ([error-print-width 5])
|
||||
(car (expt 10 1024)))
|
||||
car: contract violation
|
||||
expected: pair?
|
||||
given: 10...
|
||||
> (parameterize ([error-print-width 10])
|
||||
(car (expt 10 1024)))
|
||||
car: contract violation
|
||||
expected: pair?
|
||||
given: 1000000...
|
||||
```
|
||||
|
||||
More generally, parameters implement a kind of dynamic binding. The
|
||||
`make-parameter` function takes any value and returns a new parameter
|
||||
that is initialized to the given value. Applying the parameter as a
|
||||
function returns its current value:
|
||||
|
||||
```racket
|
||||
> (define location (make-parameter "here"))
|
||||
> (location)
|
||||
"here"
|
||||
```
|
||||
|
||||
In a `parameterize` form, each `parameter-expr` must produce a
|
||||
parameter. During the evaluation of the `body`s, each specified
|
||||
parameter is given the result of the corresponding `value-expr`. When
|
||||
control leaves the `parameterize` form—either through a normal return,
|
||||
an exception, or some other escape—the parameter reverts to its earlier
|
||||
value:
|
||||
|
||||
```racket
|
||||
> (parameterize ([location "there"])
|
||||
(location))
|
||||
"there"
|
||||
> (location)
|
||||
"here"
|
||||
> (parameterize ([location "in a house"])
|
||||
(list (location)
|
||||
(parameterize ([location "with a mouse"])
|
||||
(location))
|
||||
(location)))
|
||||
'("in a house" "with a mouse" "in a house")
|
||||
> (parameterize ([location "in a box"])
|
||||
(car (location)))
|
||||
car: contract violation
|
||||
expected: pair?
|
||||
given: "in a box"
|
||||
> (location)
|
||||
"here"
|
||||
```
|
||||
|
||||
The `parameterize` form is not a binding form like `let`; each use of
|
||||
`location` above refers directly to the original definition. A
|
||||
`parameterize` form adjusts the value of a parameter during the whole
|
||||
time that the `parameterize` body is evaluated, even for uses of the
|
||||
parameter that are textually outside of the `parameterize` body:
|
||||
|
||||
```racket
|
||||
> (define (would-you-could-you?)
|
||||
(and (not (equal? (location) "here"))
|
||||
(not (equal? (location) "there"))))
|
||||
> (would-you-could-you?)
|
||||
#f
|
||||
> (parameterize ([location "on a bus"])
|
||||
(would-you-could-you?))
|
||||
#t
|
||||
```
|
||||
|
||||
If a use of a parameter is textually inside the body of a `parameterize`
|
||||
but not evaluated before the `parameterize` form produces a value, then
|
||||
the use does not see the value installed by the `parameterize` form:
|
||||
|
||||
```racket
|
||||
> (let ([get (parameterize ([location "with a fox"])
|
||||
(lambda () (location)))])
|
||||
(get))
|
||||
"here"
|
||||
```
|
||||
|
||||
The current binding of a parameter can be adjusted imperatively by
|
||||
calling the parameter as a function with a value. If a `parameterize`
|
||||
has adjusted the value of the parameter, then directly applying the
|
||||
parameter procedure affects only the value associated with the active
|
||||
`parameterize`:
|
||||
|
||||
```racket
|
||||
> (define (try-again! where)
|
||||
(location where))
|
||||
> (location)
|
||||
"here"
|
||||
> (parameterize ([location "on a train"])
|
||||
(list (location)
|
||||
(begin (try-again! "in a boat")
|
||||
(location))))
|
||||
'("on a train" "in a boat")
|
||||
> (location)
|
||||
"here"
|
||||
```
|
||||
|
||||
Using `parameterize` is generally preferable to updating a parameter
|
||||
value imperatively—for much the same reasons that binding a fresh
|
||||
variable with `let` is preferable to using `set!` \(see \[missing\]\).
|
||||
|
||||
It may seem that variables and `set!` can solve many of the same
|
||||
problems that parameters solve. For example, `lokation` could be defined
|
||||
as a string, and `set!` could be used to adjust its value:
|
||||
|
||||
```racket
|
||||
> (define lokation "here")
|
||||
> (define (would-ya-could-ya?)
|
||||
(and (not (equal? lokation "here"))
|
||||
(not (equal? lokation "there"))))
|
||||
> (set! lokation "on a bus")
|
||||
> (would-ya-could-ya?)
|
||||
#t
|
||||
```
|
||||
|
||||
Parameters, however, offer several crucial advantages over `set!`:
|
||||
|
||||
* The `parameterize` form helps automatically reset the value of a
|
||||
parameter when control escapes due to an exception. Adding exception
|
||||
handlers and other forms to rewind a `set!` is relatively tedious.
|
||||
|
||||
* Parameters work nicely with tail calls \(see \[missing\]\). The last
|
||||
`body` in a `parameterize` form is in tail position with respect to
|
||||
the `parameterize` form.
|
||||
|
||||
* Parameters work properly with threads \(see \[missing\]\). The
|
||||
`parameterize` form adjusts the value of a parameter only for
|
||||
evaluation in the current thread, which avoids race conditions with
|
||||
other threads.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@
|
||||
# Regexps
|
||||
|
||||
A _regexp_ is a pattern for regular-expression matching.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,51 @@
|
||||
# Vectors
|
||||
|
||||
A _vector_ is a fixed-length array of arbitrary values. Unlike a list, a
|
||||
vector supports constant-time access and update of its elements.
|
||||
|
||||
A vector prints similar to a list—as a parenthesized sequence of its
|
||||
elements—but a vector is prefixed with `#` after `'`, or it uses
|
||||
`vector` if one of its elements cannot be expressed with `quote`.
|
||||
|
||||
For a vector as an expression, an optional length can be supplied. Also,
|
||||
a vector as an expression implicitly `quote`s the forms for its content,
|
||||
which means that identifiers and parenthesized forms in a vector
|
||||
constant represent symbols and lists.
|
||||
|
||||
> +\[missing\] in \[missing\] documents the fine points of the syntax of
|
||||
> vectors.
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> #("a" "b" "c")
|
||||
'#("a" "b" "c")
|
||||
> #(name (that tune))
|
||||
'#(name (that tune))
|
||||
> #4(baldwin bruce)
|
||||
'#(baldwin bruce bruce bruce)
|
||||
> (vector-ref #("a" "b" "c") 1)
|
||||
"b"
|
||||
> (vector-ref #(name (that tune)) 1)
|
||||
'(that tune)
|
||||
```
|
||||
|
||||
Like strings, a vector is either mutable or immutable, and vectors
|
||||
written directly as expressions are immutable.
|
||||
|
||||
Vectors can be converted to lists and vice versa via `vector->list` and
|
||||
`list->vector`; such conversions are particularly useful in combination
|
||||
with predefined procedures on lists. When allocating extra lists seems
|
||||
too expensive, consider using looping forms like `for/fold`, which
|
||||
recognize vectors as well as lists.
|
||||
|
||||
Example:
|
||||
|
||||
```racket
|
||||
> (list->vector (map string-titlecase
|
||||
(vector->list #("three" "blind" "mice"))))
|
||||
'#("Three" "Blind" "Mice")
|
||||
```
|
||||
|
||||
> +\[missing\] in \[missing\] provides more on vectors and vector
|
||||
> procedures.
|
@ -0,0 +1,41 @@
|
||||
# Void and Undefined
|
||||
|
||||
Some procedures or expression forms have no need for a result value. For
|
||||
example, the `display` procedure is called only for the side-effect of
|
||||
writing output. In such cases the result value is normally a special
|
||||
constant that prints as `#<void>`. When the result of an expression is
|
||||
simply `#<void>`, the REPL does not print anything.
|
||||
|
||||
The `void` procedure takes any number of arguments and returns
|
||||
`#<void>`. \(That is, the identifier `void` is bound to a procedure that
|
||||
returns `#<void>`, instead of being bound directly to `#<void>`.\)
|
||||
|
||||
Examples:
|
||||
|
||||
```racket
|
||||
> (void)
|
||||
> (void 1 2 3)
|
||||
> (list (void))
|
||||
'(#<void>)
|
||||
```
|
||||
|
||||
The `undefined` constant, which prints as `#<undefined>`, is sometimes
|
||||
used as the result of a reference whose value is not yet available. In
|
||||
previous versions of Racket \(before version 6.1\), referencing a local
|
||||
binding too early produced `#<undefined>`; too-early references now
|
||||
raise an exception, instead.
|
||||
|
||||
> The `undefined` result can still be produced in some cases by the
|
||||
> `shared` form.
|
||||
|
||||
```racket
|
||||
(define (fails)
|
||||
(define x x)
|
||||
x)
|
||||
```
|
||||
|
||||
```racket
|
||||
> (fails)
|
||||
x: undefined;
|
||||
cannot use before initialization
|
||||
```
|
Loading…
Reference in New Issue