Merge branch 'master' of github.com:racket/racket
This commit is contained in:
commit
37beaf7813
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -24,3 +24,10 @@ compiled/
|
|||
.DS_Store
|
||||
*.bak
|
||||
TAGS
|
||||
|
||||
# generated by patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# coredumps
|
||||
*.core
|
||||
|
|
|
@ -42,7 +42,7 @@ script:
|
|||
- raco test -l tests/net/encoders
|
||||
- raco test -l tests/openssl/basic
|
||||
- raco test -l tests/openssl/https
|
||||
- raco test -l tests/match/plt-match-tests
|
||||
- raco test -l tests/match/main
|
||||
- raco test -l tests/zo-path
|
||||
- raco test -l tests/xml/test
|
||||
- raco test -l tests/db/all-tests
|
||||
|
|
12
INSTALL.txt
12
INSTALL.txt
|
@ -514,12 +514,20 @@ In more detail:
|
|||
`make'. The `README' value is used as a file name to download
|
||||
from the server.
|
||||
|
||||
For a Mac OS X installer, set `SIGN_IDENTITY' to sign the
|
||||
installer, where the value of `SIGN_IDENTITY' is the name to
|
||||
To create a ".tgz" archive instead of an installer (or any
|
||||
platform), set `TGZ_MODE' to "--tgz".
|
||||
|
||||
For a Mac OS X installer, set `SIGN_IDENTITY' as the name to
|
||||
which the signing certificate is associated. Set `MAC_PKG_MODE'
|
||||
to "--mac-pkg" to create a ".pkg" installer instead of a ".dmg"
|
||||
image.
|
||||
|
||||
For a Windows installer, set `OSSLSIGNCODE_ARGS_BASE64` as a
|
||||
Base64 encoding of an S-expression for a list of argument strings
|
||||
for `osslsigncode`. The `-n', `-t', `-in', and `-out' arguments
|
||||
are provided to `osslsigncode` automatically, so supply the
|
||||
others.
|
||||
|
||||
The `SERVER_CATALOG_PATH' and `SERVER_COLLECTS_PATH' makefile
|
||||
variables specify paths at `SERVER' plus `SERVER_PORT' to access
|
||||
the package catalog and pre-built "collects" tree needed for a
|
||||
|
|
37
Makefile
37
Makefile
|
@ -36,7 +36,11 @@ WIN32_RUN_RACKET = $(WIN32_PLAIN_RACKET) -G racket/etc -X racket/collects
|
|||
RUN_RACO = $(RUN_RACKET) -N raco -l- raco
|
||||
WIN32_RUN_RACO = $(WIN32_RUN_RACKET) -N raco -l- raco
|
||||
|
||||
DEFAULT_SRC_CATALOG = http://pkgs.racket-lang.org
|
||||
DEFAULT_SRC_CATALOG = https://pkgs.racket-lang.org
|
||||
|
||||
# Belongs in the "Configuration options" section, but here
|
||||
# to accomodate nmake:
|
||||
SRC_CATALOG = $(DEFAULT_SRC_CATALOG)
|
||||
|
||||
CPUS =
|
||||
|
||||
|
@ -69,7 +73,7 @@ plain-in-place:
|
|||
|
||||
win32-in-place:
|
||||
$(MAKE) win32-base
|
||||
$(MAKE) win32-pkgs-catalog
|
||||
$(MAKE) win32-pkgs-catalog SRC_CATALOG="$(SRC_CATALOG)"
|
||||
$(WIN32_RUN_RACO) pkg update $(UPDATE_PKGS_ARGS)
|
||||
$(WIN32_RUN_RACO) pkg install $(INSTALL_PKGS_ARGS)
|
||||
$(WIN32_RUN_RACO) setup --only-foreign-libs $(ALL_PLT_SETUP_OPTIONS)
|
||||
|
@ -194,8 +198,8 @@ racket/src/build/cross/Makefile: racket/src/configure racket/src/Makefile.in
|
|||
# end in "_q" or "_qq", don't use any quote marks on the right-hand
|
||||
# side of its definition.
|
||||
|
||||
# Catalog for package sources:
|
||||
SRC_CATALOG = $(DEFAULT_SRC_CATALOG)
|
||||
# Catalog for package sources (defined above):
|
||||
# SRC_CATALOG = $(DEFAULT_SRC_CATALOG)
|
||||
|
||||
# A URL embedded in documentation for remote searches, where a Racket
|
||||
# version and search key are added as query fields to the URL, and ""
|
||||
|
@ -234,6 +238,9 @@ VERSIONLESS_MODE =
|
|||
# instead of a ".dmg" for drag-and-drop installation:
|
||||
MAC_PKG_MODE =
|
||||
|
||||
# Set to "--tgz" to create a ".tgz" archive instead of an installer:
|
||||
TGZ_MODE =
|
||||
|
||||
# Set to "--source --no-setup" to include packages in an installer
|
||||
# (or archive) only in source form:
|
||||
PKG_SOURCE_MODE =
|
||||
|
@ -264,10 +271,14 @@ BUILD_STAMP =
|
|||
# the default as the version number:
|
||||
INSTALL_NAME =
|
||||
|
||||
# A signing identity (spaces allowed) for Mac OS X binaries in an
|
||||
# For Mac OS X, a signing identity (spaces allowed) for binaries in an
|
||||
# installer:
|
||||
SIGN_IDENTITY =
|
||||
|
||||
# For Windows, `osslsigncode' arguments other than `-n', `-t', `-in',
|
||||
# and `-out' as a Base64-encoded, S-expression, list of strings:
|
||||
OSSLSIGNCODE_ARGS_BASE64 =
|
||||
|
||||
# URL for a README file to include in an installer (empty for none,
|
||||
# spaces allowed):
|
||||
README = http://$(SVR_PRT)/README.txt
|
||||
|
@ -339,8 +350,10 @@ pkgs-catalog:
|
|||
$(RUN_RACKET) $(PKGS_CONFIG) "$(DEFAULT_SRC_CATALOG)" "$(SRC_CATALOG)"
|
||||
$(RUN_RACKET) racket/src/pkgs-check.rkt racket/share/pkgs-catalog
|
||||
|
||||
COPY_PKGS_ARGS = PLAIN_RACKET="$(WIN32_PLAIN_RACKET)" SRC_CATALOG="$(SRC_CATALOG)"
|
||||
|
||||
win32-pkgs-catalog:
|
||||
$(MAKE) pkgs-catalog PLAIN_RACKET="$(WIN32_PLAIN_RACKET)"
|
||||
$(MAKE) pkgs-catalog $(COPY_PKGS_ARGS)
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# On a server platform (for an installer build):
|
||||
|
@ -443,11 +456,12 @@ PROP_ARGS = SERVER=$(SERVER) SERVER_PORT=$(SERVER_PORT) SERVER_HOSTS="$(SERVER_H
|
|||
PKGS="$(PKGS)" PLAIN_RACKET="$(PLAIN_RACKET)" BUILD_STAMP="$(BUILD_STAMP)" \
|
||||
RELEASE_MODE=$(RELEASE_MODE) SOURCE_MODE=$(SOURCE_MODE) \
|
||||
VERSIONLESS_MODE=$(VERSIONLESS_MODE) MAC_PKG_MODE=$(MAC_PKG_MODE) \
|
||||
PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)"\
|
||||
PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)" \
|
||||
DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \
|
||||
DIST_DIR=$(DIST_DIR) DIST_SUFFIX=$(DIST_SUFFIX) UPLOAD="$(UPLOAD)" \
|
||||
DIST_DESC="$(DIST_DESC)" README="$(README)" SIGN_IDENTITY="$(SIGN_IDENTITY)"\
|
||||
JOB_OPTIONS="$(JOB_OPTIONS)"
|
||||
DIST_DESC="$(DIST_DESC)" README="$(README)" SIGN_IDENTITY="$(SIGN_IDENTITY)" \
|
||||
OSSLSIGNCODE_ARGS_BASE64="$(OSSLSIGNCODE_ARGS_BASE64)" JOB_OPTIONS="$(JOB_OPTIONS)" \
|
||||
TGZ_MODE=$(TGZ_MODE)
|
||||
|
||||
COPY_ARGS = $(PROP_ARGS) \
|
||||
SERVER_CATALOG_PATH=$(SERVER_CATALOG_PATH) SERVER_COLLECTS_PATH=$(SERVER_COLLECTS_PATH)
|
||||
|
@ -496,9 +510,10 @@ bundle-from-server:
|
|||
$(RACKET) -l setup/unixstyle-install post-adjust "$(SOURCE_MODE)" "$(PKG_SOURCE_MODE)" racket bundle/racket
|
||||
|
||||
UPLOAD_q = --readme "$(README)" --upload "$(UPLOAD)" --desc "$(DIST_DESC)"
|
||||
DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) $(VERSIONLESS_MODE) $(MAC_PKG_MODE) \
|
||||
DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) $(VERSIONLESS_MODE) \
|
||||
$(MAC_PKG_MODE) $(TGZ_MODE) \
|
||||
"$(DIST_NAME)" $(DIST_BASE) $(DIST_DIR) "$(DIST_SUFFIX)" \
|
||||
"$(SIGN_IDENTITY)"
|
||||
"$(SIGN_IDENTITY)" "$(OSSLSIGNCODE_ARGS_BASE64)"
|
||||
|
||||
# Create an installer from the build (with installed packages) that's
|
||||
# in "bundle/racket":
|
||||
|
|
|
@ -5,7 +5,7 @@ License
|
|||
-------
|
||||
|
||||
Racket
|
||||
Copyright (c) 2010-2015 PLT Design Inc.
|
||||
Copyright (c) 2010-2016 PLT Design Inc.
|
||||
|
||||
Racket is distributed under the GNU Lesser General Public License
|
||||
(LGPL). This implies that you may link Racket into proprietary
|
||||
|
|
|
@ -24,7 +24,7 @@ test_script:
|
|||
- racket\raco.exe test -l tests/net/encoders
|
||||
- racket\raco.exe test -l tests/openssl/basic
|
||||
- racket\raco.exe test -l tests/openssl/https
|
||||
- racket\raco.exe test -l tests/match/plt-match-tests
|
||||
- racket\raco.exe test -l tests/match/main
|
||||
- racket\raco.exe test -l tests/zo-path
|
||||
- racket\raco.exe test -l tests/xml/test
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
at-exp-lib
|
||||
Copyright (c) 2010-2015 PLT Design Inc.
|
||||
Copyright (c) 2010-2016 PLT Design Inc.
|
||||
|
||||
This package is distributed under the GNU Lesser General Public
|
||||
License (LGPL). This means that you can link this package into proprietary
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
base
|
||||
Copyright (c) 2010-2015 PLT Design Inc.
|
||||
Copyright (c) 2010-2016 PLT Design Inc.
|
||||
|
||||
This package is distributed under the GNU Lesser General Public
|
||||
License (LGPL). This means that you can link this package into proprietary
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
(define collection 'multi)
|
||||
|
||||
(define version "6.3.0.2")
|
||||
(define version "6.4.0.1")
|
||||
|
||||
(define deps `("racket-lib"
|
||||
["racket" #:version ,version]))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
racket-doc
|
||||
Copyright (c) 2010-2015 PLT Design Inc.
|
||||
Copyright (c) 2010-2016 PLT Design Inc.
|
||||
|
||||
This package is distributed under the GNU Lesser General Public
|
||||
License (LGPL). This means that you can link this package into proprietary
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require scribblings/reference/mz (for-label compatibility/package))
|
||||
|
||||
@(define pack-eval (make-base-eval))
|
||||
@interaction-eval[#:eval pack-eval (require compatibility/package)]
|
||||
@examples[#:hidden #:eval pack-eval (require compatibility/package)]
|
||||
|
||||
@title[#:tag "compatibility-package"]{Limiting Scope: @racket[define-package], @racket[open-package], ...}
|
||||
|
||||
|
@ -61,11 +61,11 @@ is the exported one.
|
|||
(define-package presents (doll)
|
||||
(define doll "Molly Coddle")
|
||||
(define robot "Destructo"))
|
||||
doll
|
||||
robot
|
||||
(eval:error doll)
|
||||
(eval:error robot)
|
||||
(open-package presents)
|
||||
doll
|
||||
robot
|
||||
(eval:error robot)
|
||||
(define-package big-russian-doll (middle-russian-doll)
|
||||
(define-package middle-russian-doll (little-russian-doll)
|
||||
(define little-russian-doll "Anastasia")))
|
||||
|
@ -95,7 +95,7 @@ the defined bindings remain hidden outside the
|
|||
(package-begin
|
||||
(define secret "mimi")
|
||||
(list secret))
|
||||
secret
|
||||
(eval:error secret)
|
||||
]}
|
||||
|
||||
@deftogether[(
|
||||
|
|
|
@ -11,14 +11,16 @@ directories, files, and symbolic links, and owner
|
|||
information is not preserved; the owner that is stored in the archive
|
||||
is always ``root.''
|
||||
|
||||
Symbolic links (on Unix and Mac OS X) are not followed, and the path
|
||||
Symbolic links (on Unix and Mac OS X) are not followed by default, and the path
|
||||
in a link must be less than 100 bytes.}
|
||||
|
||||
|
||||
@defproc[(tar [tar-file path-string?]
|
||||
[path path-string?] ...
|
||||
[#:follow-links? follow-links? any/c #f]
|
||||
[#:exists-ok? exists-ok? any/c #f]
|
||||
[#:path-prefix path-prefix (or/c #f path-string?) #f]
|
||||
[#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f]
|
||||
[#:get-timestamp get-timestamp
|
||||
(path? . -> . exact-integer?)
|
||||
(if timestamp
|
||||
|
@ -32,7 +34,8 @@ relative paths for existing directories and files (i.e., relative
|
|||
to the current directory). If a nested path is provided as a
|
||||
@racket[path], its ancestor directories are also added to the
|
||||
resulting tar file, up to the current directory (using
|
||||
@racket[pathlist-closure]).
|
||||
@racket[pathlist-closure]). If @racket[follow-links?] is false, then
|
||||
symbolic links are included in the resulting tar file as links.
|
||||
|
||||
If @racket[exists-ok?] is @racket[#f], then an exception is raised if
|
||||
@racket[tar-file] exists already. If @racket[exists-ok?] is true, then
|
||||
|
@ -45,12 +48,16 @@ The @racket[get-timestamp] function is used to obtain the modification
|
|||
date to record in the archive for each file or directory.
|
||||
|
||||
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.}
|
||||
#:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}]}
|
||||
#:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}
|
||||
#:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}
|
||||
#:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]}
|
||||
|
||||
|
||||
@defproc[(tar->output [paths (listof path?)]
|
||||
[out output-port? (current-output-port)]
|
||||
[#:follow-links? follow-links? any/c #f]
|
||||
[#:path-prefix path-prefix (or/c #f path-string?) #f]
|
||||
[#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f]
|
||||
[#:get-timestamp get-timestamp
|
||||
(path? . -> . exact-integer?)
|
||||
(if timestamp
|
||||
|
@ -64,11 +71,14 @@ archive that is written directly to the @racket[out]. The specified
|
|||
content is not automatically added, and nested directories are added
|
||||
without parent directories.
|
||||
|
||||
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.}]}
|
||||
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.}
|
||||
#:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}
|
||||
#:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]}
|
||||
|
||||
|
||||
@defproc[(tar-gzip [tar-file path-string?]
|
||||
[paths path-string?] ...
|
||||
[#:follow-links? follow-links? any/c #f]
|
||||
[#:exists-ok? exists-ok? any/c #f]
|
||||
[#:path-prefix path-prefix (or/c #f path-string?) #f]
|
||||
[#:get-timestamp get-timestamp
|
||||
|
@ -81,4 +91,5 @@ without parent directories.
|
|||
Like @racket[tar], but compresses the resulting file with @racket[gzip].
|
||||
|
||||
@history[#:changed "6.0.0.3" @elem{Added the @racket[#:get-timestamp] argument.}
|
||||
#:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}]}
|
||||
#:changed "6.1.1.1" @elem{Added the @racket[#:exists-ok?] argument.}
|
||||
#:changed "6.3.0.3" @elem{Added the @racket[#:follow-links?] argument.}]}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"base"
|
||||
"net-lib"
|
||||
"sandbox-lib"
|
||||
"scribble-lib"
|
||||
["scribble-lib" #:version "1.14"]
|
||||
"racket-index"))
|
||||
(define build-deps '("rackunit-doc"
|
||||
"compatibility"
|
||||
|
|
|
@ -29,8 +29,10 @@ or with the Racket distribution. In particular:
|
|||
included in the Racket distribution for Windows.}
|
||||
|
||||
@item{For Mac OS X, @racketmodname[openssl] depends on
|
||||
@filepath{libssl.dylib} and @filepath{libcrypto.dylib}, which are
|
||||
provided by Mac OS X 10.2 and later.}
|
||||
@filepath{libssl.dylib} and @filepath{libcrypto.dylib}. Although those
|
||||
libraries are provided by Mac OS X 10.2 and later, their use is
|
||||
deprecated, so the Racket distribution for Mac OS X includes newer
|
||||
versions.}
|
||||
|
||||
@item{For Unix, @racketmodname[openssl] depends on
|
||||
@filepath{libssl.so} and @filepath{libcrypto.so}, which must be
|
||||
|
@ -66,7 +68,9 @@ using the functions described in @secref["cert-procs"].
|
|||
[port-no (integer-in 1 65535)]
|
||||
[client-protocol
|
||||
(or/c ssl-client-context?
|
||||
'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'secure
|
||||
'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
|
@ -75,6 +79,10 @@ Connect to the host given by @racket[hostname], on the port given by
|
|||
return values are as for @racket[tcp-connect]: an input port and an
|
||||
output port.
|
||||
|
||||
The default @racket['auto] protocol is @bold{insecure}. Use
|
||||
@racket['secure] for a secure connection. See
|
||||
@racket[ssl-secure-client-context] for details.
|
||||
|
||||
The optional @racket[client-protocol] argument determines which
|
||||
encryption protocol is used, whether the server's certificate is
|
||||
checked, etc. The argument can be either a client context created by
|
||||
|
@ -104,14 +112,16 @@ well-defined communication pattern, where theres no question of
|
|||
whether the other end is supposed to be sending or reading data.
|
||||
}
|
||||
|
||||
}
|
||||
@history[#:changed "6.3.0.12" @elem{Added @racket['secure] for
|
||||
@racket[client-protocol].}]}
|
||||
|
||||
@defproc[(ssl-connect/enable-break
|
||||
[hostname string?]
|
||||
[port-no (integer-in 1 65535)]
|
||||
[client-protocol
|
||||
(or/c ssl-client-context?
|
||||
'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
|
@ -149,11 +159,13 @@ The context is cached, so different calls to
|
|||
|
||||
|
||||
@defproc[(ssl-make-client-context
|
||||
[protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12) 'auto])
|
||||
[protocol (or/c 'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto])
|
||||
ssl-client-context?]{
|
||||
|
||||
Creates a context to be supplied to @racket[ssl-connect]. The context
|
||||
is @bold{insecure} unless additional steps are taken; see
|
||||
is @bold{insecure} unless @racket['secure] is supplied or additional steps are taken; see
|
||||
@racket[ssl-secure-client-context] for details.
|
||||
|
||||
The client context identifies a communication protocol (as selected by
|
||||
|
@ -164,6 +176,7 @@ certificates.
|
|||
|
||||
The @racket[protocol] should be one of the following:
|
||||
@itemize[
|
||||
@item{@racket['secure] : Equivalent to @racket[(ssl-secure-client-context)].}
|
||||
@item{@racket['auto] : Automatically negotiates the protocol version
|
||||
from those that this library considers sufficiently secure---currently
|
||||
TLS versions 1.0 and higher, but subject to change.}
|
||||
|
@ -182,27 +195,29 @@ Note that SSL 2.0 support has been removed from many platforms.}
|
|||
]
|
||||
|
||||
Not all protocol versions are supported by all servers. The
|
||||
@racket['auto] option offers broad compatibility at a reasonable level
|
||||
@racket['secure] and @racket['auto] options offer broad compatibility at a reasonable level
|
||||
of security. Note that the security of connections depends on more
|
||||
than the protocol version; see @racket[ssl-secure-client-context] for
|
||||
details.
|
||||
|
||||
Not all protocol versions are available on all platforms. See also
|
||||
details. See also
|
||||
@racket[supported-client-protocols] and
|
||||
@racket[supported-server-protocols].
|
||||
|
||||
@history[
|
||||
#:changed "6.1" @elem{Added @racket['tls11] and @racket['tls12].}
|
||||
#:changed "6.1.1.3" @elem{Default to new @racket['auto] and disabled SSL
|
||||
2.0 and 3.0 by default.}
|
||||
2.0 and 3.0 by default.}
|
||||
#:changed "6.3.0.12" @elem{Added @racket['secure].}
|
||||
]}
|
||||
|
||||
|
||||
@defproc[(supported-client-protocols)
|
||||
(listof (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{
|
||||
(listof (or/c 'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{
|
||||
|
||||
Returns a list of symbols representing protocols that are supported
|
||||
for clients on the current platform.}
|
||||
for clients on the current platform.
|
||||
|
||||
@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]}
|
||||
|
||||
|
||||
@defproc[(ssl-client-context? [v any/c]) boolean?]{
|
||||
|
@ -212,7 +227,7 @@ Returns @racket[#t] if @racket[v] is a value produced by
|
|||
|
||||
@history[#:added "6.0.1.3"]}
|
||||
|
||||
@defproc[(ssl-max-client-protocol) (or/c 'sslv2 sslv3 'tls 'tls11 'tls12 #f)]{
|
||||
@defproc[(ssl-max-client-protocol) (or/c 'sslv2 'sslv3 'tls 'tls11 'tls12 #f)]{
|
||||
|
||||
Returns the most recent SSL/TLS protocol version supported by the
|
||||
current platform for client connections.
|
||||
|
@ -231,13 +246,15 @@ current platform for client connections.
|
|||
[hostname-or-#f (or/c string? #f) #f]
|
||||
[server-protocol
|
||||
(or/c ssl-server-context?
|
||||
'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto])
|
||||
ssl-listener?]{
|
||||
|
||||
Like @racket[tcp-listen], but the result is an SSL listener. The extra optional
|
||||
@racket[server-protocol] is as for @racket[ssl-connect], except that a
|
||||
context must be a server context instead of a client context.
|
||||
context must be a server context instead of a client context, and
|
||||
@racket['secure] is simply an alias for @racket['auto].
|
||||
|
||||
Call @racket[ssl-load-certificate-chain!] and
|
||||
@racket[ssl-load-private-key!] to avoid a @emph{no shared cipher}
|
||||
|
@ -250,7 +267,9 @@ An SSL listener is a synchronizable value (see @racket[sync]). It is
|
|||
ready---with itself as its value---when the underlying TCP listener is
|
||||
ready. At that point, however, accepting a connection with
|
||||
@racket[ssl-accept] may not complete immediately, because
|
||||
further communication is needed to establish the connection.}
|
||||
further communication is needed to establish the connection.
|
||||
|
||||
@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
|
@ -298,11 +317,16 @@ Returns @racket[#t] of @racket[v] is an SSL port produced by
|
|||
|
||||
|
||||
@defproc[(ssl-make-server-context
|
||||
[protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
[protocol (or/c 'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto])
|
||||
ssl-server-context?]{
|
||||
|
||||
Like @racket[ssl-make-client-context], but creates a server context.}
|
||||
Like @racket[ssl-make-client-context], but creates a server context.
|
||||
For a server context, the @racket['secure] protocol is the same as
|
||||
@racket['auto].
|
||||
|
||||
@history[#:changed "6.3.0.12" @elem{Added @racket['secure].}]}
|
||||
|
||||
|
||||
@defproc[(ssl-server-context? [v any/c]) boolean?]{
|
||||
|
@ -311,14 +335,16 @@ Returns @racket[#t] if @racket[v] is a value produced by
|
|||
@racket[ssl-make-server-context], @racket[#f] otherwise.}
|
||||
|
||||
@defproc[(supported-server-protocols)
|
||||
(listof (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{
|
||||
(listof (or/c 'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12))]{
|
||||
|
||||
Returns a list of symbols representing protocols that are supported
|
||||
for servers on the current platform.
|
||||
|
||||
@history[#:added "6.0.1.3"]}
|
||||
@history[#:added "6.0.1.3"
|
||||
#:changed "6.3.0.12" @elem{Added @racket['secure].}]}
|
||||
|
||||
@defproc[(ssl-max-server-protocol) (or/c 'sslv2 sslv3 'tls 'tls11 'tls12 #f)]{
|
||||
@defproc[(ssl-max-server-protocol) (or/c 'sslv2 'sslv3 'tls 'tls11 'tls12 #f)]{
|
||||
|
||||
Returns the most recent SSL/TLS protocol version supported by the
|
||||
current platform for server connections.
|
||||
|
@ -340,7 +366,8 @@ current platform for server connections.
|
|||
ssl-make-server-context
|
||||
ssl-make-client-context)
|
||||
protocol)]
|
||||
[#:encrypt protocol (or/c 'auto 'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
[#:encrypt protocol (or/c 'secure 'auto
|
||||
'sslv2-or-v3 'sslv2 'sslv3 'tls 'tls11 'tls12)
|
||||
'auto]
|
||||
[#:close-original? close-original? boolean? #f]
|
||||
[#:shutdown-on-close? shutdown-on-close? boolean? #f]
|
||||
|
|
|
@ -53,3 +53,4 @@ to the @exec{raco pkg} sub-subcommands.
|
|||
@include-section["name.scrbl"]
|
||||
@include-section["db.scrbl"]
|
||||
@include-section["dirs-catalog.scrbl"]
|
||||
@include-section["envvars.scrbl"]
|
||||
|
|
14
pkgs/racket-doc/pkg/scribblings/envvars.scrbl
Normal file
14
pkgs/racket-doc/pkg/scribblings/envvars.scrbl
Normal file
|
@ -0,0 +1,14 @@
|
|||
#lang scribble/manual
|
||||
@(require "common.rkt")
|
||||
|
||||
@title[#:tag "envvars"]{Package Management Environment Variables}
|
||||
|
||||
If the @indexed-envvar{PLT_PKG_SSL_NO_VERIFY} environment variable is
|
||||
set, server certificates are not validated for HTTPS connections. When
|
||||
accessing Git servers over HTTPS, @envvar{GIT_SSL_NO_VERIFY} must be
|
||||
set, too, to disable certificate validation.
|
||||
|
||||
As noted in the specification of GitHub-repository package sources, if
|
||||
the @envvar{PLT_USE_GITHUB_API} environment variable is set, GitHub
|
||||
packages are obtained using the GitHub API protocol instead of using
|
||||
the Git protocol.
|
|
@ -131,7 +131,7 @@ treated as a explicitly installed package.
|
|||
|
||||
The PLT @tech{package catalog} at
|
||||
|
||||
@centerline{@url{http://pkgs.racket-lang.org}}
|
||||
@centerline{@url{https://pkgs.racket-lang.org}}
|
||||
|
||||
provides a centralized listing of available Racket packages. The PLT
|
||||
@tech{package catalog} normally will be the first place you check when
|
||||
|
@ -445,7 +445,7 @@ by a simple name until it is listed on a @tech{package catalog}.
|
|||
|
||||
If you'd like to use the PLT @tech{package catalog}, browse
|
||||
to
|
||||
@link["http://pkgs.racket-lang.org/"]{http://pkgs.racket-lang.org/}
|
||||
@link["https://pkgs.racket-lang.org/"]{https://pkgs.racket-lang.org/}
|
||||
and upload a new package. You will need to create an account and log
|
||||
in first.
|
||||
|
||||
|
@ -558,7 +558,7 @@ In your @racket[info.rkt], you should:
|
|||
]
|
||||
|
||||
Finally, when listing your package on
|
||||
@url{http://pkgs.racket-lang-org}, you should supply a GitHub source
|
||||
@url{https://pkgs.racket-lang-org}, you should supply a GitHub source
|
||||
using the URL format
|
||||
@tt{github://github.com/@nonterm{user}/@nonterm{repo}/@nonterm{rev}@optional{/@nonterm{path}}} (not
|
||||
the @tt{git://} or @exec{http://} format).
|
||||
|
|
|
@ -102,7 +102,7 @@ develops only a few of them. The intended workflow is as follows:
|
|||
|
||||
@commandline{@command{update} --lookup --catalog @nonterm{catalog} --clone @nonterm{path-to}/@nonterm{pkg-name}}
|
||||
|
||||
A suitable @nonterm{catalog} might be @url{http://pkgs.racket-lang.org}.}
|
||||
A suitable @nonterm{catalog} might be @url{https://pkgs.racket-lang.org}.}
|
||||
|
||||
@item{A newly cloned package will have the specified (or existing
|
||||
installation's) repository as its Git @exec{origin}. If you want to
|
||||
|
|
|
@ -337,7 +337,7 @@ URL indicates a remote server, and a @litchar{file://} URL indicates a
|
|||
local catalog in the form of an SQLite database or a directory tree.
|
||||
|
||||
PLT supports two @tech{package catalog} servers that are enabled by
|
||||
default: @url{http://pkgs.racket-lang.org} for new packages and
|
||||
default: @url{https://pkgs.racket-lang.org} for new packages and
|
||||
@url{http://planet-compats.racket-lang.org} for automatically
|
||||
generated packages for old @|PLaneT| packages. Anyone may host a
|
||||
@tech{package catalog}, and any file-serving HTTP host can act
|
||||
|
@ -1426,10 +1426,10 @@ tests, and documentation from a package before installing it.
|
|||
site (where a Racket distribution downloaded from the site is
|
||||
configured to consult the site for packages), at least for packages
|
||||
associated with the distribution. Beware that
|
||||
@url{http://pkgs.racket-lang.org/} generally refers to @tech{source
|
||||
@url{https://pkgs.racket-lang.org/} generally refers to @tech{source
|
||||
packages}, not @tech{built packages}. In the near future, built
|
||||
variants of the @url{http://pkgs.racket-lang.org/} packages will be
|
||||
provided at @url{http://pkg-build.racket-lang.org/catalog/}.
|
||||
variants of the @url{https://pkgs.racket-lang.org/} packages will be
|
||||
provided at @url{https://pkg-build.racket-lang.org/catalog/}.
|
||||
|
||||
Some packages have been split at the source level into separate
|
||||
library, test, and documentation packages. For example,
|
||||
|
|
|
@ -209,6 +209,14 @@ A constant for use with @racket[com-invoke] in place of an optional
|
|||
argument.}
|
||||
|
||||
|
||||
@defproc[(com-omit? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] is @racket[com-omit], @racket[#f]
|
||||
otherwise.
|
||||
|
||||
@history[#:added "6.3.0.3"]}
|
||||
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section{COM Properties}
|
||||
|
|
|
@ -1081,7 +1081,8 @@ below for a more efficient approach.
|
|||
(property (code:line #:alignment alignment-expr)
|
||||
(code:line #:malloc-mode malloc-mode-expr)
|
||||
(code:line #:property prop-expr val-expr)
|
||||
#:no-equal)]
|
||||
#:no-equal
|
||||
#:define-unsafe)]
|
||||
#:contracts ([offset-expr exact-integer?]
|
||||
[alignment-expr (or/c #f 1 2 4 8 16)]
|
||||
[malloc-mode-expr (one-of/c 'raw 'atomic 'nonatomic
|
||||
|
@ -1130,7 +1131,16 @@ The resulting bindings are as follows:
|
|||
@item{@racketidfont{set-}@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{!}
|
||||
: a mutator function for each @racket[field-id].}
|
||||
|
||||
@item{@racketvarfont{id}: structure-type information compatible with
|
||||
@item{@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{-offset}
|
||||
: the absolute offset, in bytes, of each @racket[field-id], if @racket[#:define-unsafe] is present.}
|
||||
|
||||
@item{@racketidfont{unsafe-}@racketvarfont{id}@racketidfont{-}@racket[field-id]
|
||||
: an unsafe accessor function for each @racket[field-id], if @racket[#:define-unsafe] is present.}
|
||||
|
||||
@item{@racketidfont{unsafe-set-}@racketvarfont{id}@racketidfont{-}@racket[field-id]@racketidfont{!}
|
||||
: an unsafe mutator function for each @racket[field-id], if @racket[#:define-unsafe] is present.}
|
||||
|
||||
@item{@racketvarfont{id}: structure-type information compatible with
|
||||
@racket[struct-out] or @racket[match] (but not @racket[struct] or
|
||||
@racket[define-struct]);
|
||||
currently, this information is correct only when no @racket[super-id]
|
||||
|
@ -1328,7 +1338,8 @@ expects arguments for both the super fields and the new ones:
|
|||
]
|
||||
|
||||
@history[#:changed "6.0.0.6" @elem{Added @racket[#:malloc-mode].}
|
||||
#:changed "6.1.1.8" @elem{Added @racket[#:offset] for fields.}]}
|
||||
#:changed "6.1.1.8" @elem{Added @racket[#:offset] for fields.}
|
||||
#:changed "6.3.0.13" @elem{Added @racket[#:define-unsafe].}]}
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -453,7 +453,7 @@ A @racket[_struct-option] always starts with a keyword:
|
|||
@racket[#:auto] field option. The constructor procedure does not
|
||||
accept arguments for automatic fields. Automatic fields are
|
||||
implicitly mutable (via reflective operations), but mutator
|
||||
functions are bound only if @racket[#:mutator] is also specified.
|
||||
functions are bound only if @racket[#:mutable] is also specified.
|
||||
|
||||
@defexamples[
|
||||
(struct posn (x y [z #:auto])
|
||||
|
|
|
@ -16,7 +16,7 @@ into details---covering much of the Racket toolbox, but leaving
|
|||
precise details to @|Racket| and other reference manuals.
|
||||
|
||||
@margin-note{The source of this manual is available on
|
||||
@hyperlink["https://github.com/plt/racket/tree/master/pkgs/racket-doc/scribblings/guide"]{GitHub}.}
|
||||
@hyperlink["https://github.com/racket/racket/tree/master/pkgs/racket-doc/scribblings/guide"]{GitHub}.}
|
||||
|
||||
@table-of-contents[]
|
||||
|
||||
|
|
|
@ -69,10 +69,11 @@ file:
|
|||
(close-output-port out)
|
||||
]
|
||||
|
||||
Instead of having to match @racket[open-input-file] and
|
||||
@racket[open-output-file] calls, most Racket programmers will instead
|
||||
use @racket[call-with-output-file], which takes a function to call
|
||||
with the output port; when the function returns, the port is closed.
|
||||
Instead of having to match the open calls with close calls, most Racket
|
||||
programmers will use the @racket[call-with-input-file] and
|
||||
@racket[call-with-output-file] functions which take a function to call to carry
|
||||
out the desired operation. This function gets as its only argument the port,
|
||||
which is automatically opened and closed for the operation.
|
||||
|
||||
@examples[
|
||||
#:eval io-eval
|
||||
|
@ -318,7 +319,7 @@ Other structure types created by @racket[struct], which offer
|
|||
more abstraction than @tech{prefab} structure types, normally
|
||||
@racket[write] either using @racketresultfont{#<....>} notation (for
|
||||
opaque structure types) or using @racketresultfont{#(....)} vector
|
||||
notation (for transparent structure types). In neither can the
|
||||
notation (for transparent structure types). In neither case can the
|
||||
result be read back in as an instance of the structure type:
|
||||
|
||||
@interaction[
|
||||
|
|
|
@ -79,11 +79,11 @@ The difference is that each @racket[_id] is available for use in later
|
|||
visible one.
|
||||
|
||||
@examples[
|
||||
(let* ([x (list "Borroughs")]
|
||||
(let* ([x (list "Burroughs")]
|
||||
[y (cons "Rice" x)]
|
||||
[z (cons "Edgar" y)])
|
||||
(list x y z))
|
||||
(let* ([name (list "Borroughs")]
|
||||
(let* ([name (list "Burroughs")]
|
||||
[name (cons "Rice" name)]
|
||||
[name (cons "Edgar" name)])
|
||||
name)
|
||||
|
@ -93,7 +93,7 @@ In other words, a @racket[let*] form is equivalent to nested
|
|||
@racket[let] forms, each with a single binding:
|
||||
|
||||
@interaction[
|
||||
(let ([name (list "Borroughs")])
|
||||
(let ([name (list "Burroughs")])
|
||||
(let ([name (cons "Rice" name)])
|
||||
(let ([name (cons "Edgar" name)])
|
||||
name)))
|
||||
|
|
|
@ -74,15 +74,7 @@ by @racket[and]ing or @racket[or]ing:
|
|||
(ormap number? (list "a" "b" 6))
|
||||
]
|
||||
|
||||
The @racket[filter] function keeps elements for which the body result
|
||||
is true, and discards elements for which it is @racket[#f]:
|
||||
|
||||
@interaction[
|
||||
(filter string? (list "a" "b" 6))
|
||||
(filter positive? (list 1 -2 6 7 0))
|
||||
]
|
||||
|
||||
The @racket[map], @racket[andmap], @racket[ormap], and @racket[filter]
|
||||
The @racket[map], @racket[andmap], and @racket[ormap]
|
||||
functions can all handle multiple lists, instead of just a single
|
||||
list. The lists must all have the same length, and the given function
|
||||
must accept one argument for each list:
|
||||
|
@ -93,6 +85,14 @@ must accept one argument for each list:
|
|||
(list 6 3 7))
|
||||
]
|
||||
|
||||
The @racket[filter] function keeps elements for which the body result
|
||||
is true, and discards elements for which it is @racket[#f]:
|
||||
|
||||
@interaction[
|
||||
(filter string? (list "a" "b" 6))
|
||||
(filter positive? (list 1 -2 6 7 0))
|
||||
]
|
||||
|
||||
The @racket[foldl] function generalizes some iteration functions. It
|
||||
uses the per-element function to both process an element and combine
|
||||
it with the ``current'' value, so the per-element function takes an
|
||||
|
|
|
@ -15,6 +15,8 @@ make simple transformations easy to implement and reliable to
|
|||
use. Racket also supports arbitrary macro transformers that are
|
||||
implemented in Racket---or in a macro-extended variant of Racket.
|
||||
|
||||
(For a bottom-up introduction of Racket macro, you may refer to: @(hyperlink "http://www.greghendershott.com/fear-of-macros/" "Fear of Macros"))
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
|
|
@ -28,7 +28,7 @@ many other installed libraries. Run @exec{raco docs} to find
|
|||
documentation for libraries that are installed on your system and
|
||||
specific to your user account.
|
||||
|
||||
@link["http://pkgs.racket-lang.org/"]{The Racket package repository}
|
||||
@link["https://pkgs.racket-lang.org/"]{The Racket package repository}
|
||||
offer even more downloadable packages that are contributed by
|
||||
Racketeers.
|
||||
|
||||
|
|
|
@ -453,11 +453,11 @@ Step-by-step, expansion proceeds as follows:
|
|||
@racketblock[
|
||||
(define-for-cbr do-f (a b)
|
||||
() (swap a b))
|
||||
=> (define-for-cbr do-f (b)
|
||||
(unsyntax @tt{=>}) (define-for-cbr do-f (b)
|
||||
([a get_1 put_1]) (swap a b))
|
||||
=> (define-for-cbr do-f ()
|
||||
(unsyntax @tt{=>}) (define-for-cbr do-f ()
|
||||
([a get_1 put_1] [b get_2 put_2]) (swap a b))
|
||||
=> (define (do-f get_1 get_2 put_1 put_2)
|
||||
(unsyntax @tt{=>}) (define (do-f get_1 get_2 put_1 put_2)
|
||||
(define-get/put-id a get_1 put_1)
|
||||
(define-get/put-id b get_2 put_2)
|
||||
(swap a b))
|
||||
|
|
|
@ -471,7 +471,7 @@ then the expansion of the @racket[let] form to implement
|
|||
automatically converts the closure to pass itself @racket[n] as an
|
||||
argument instead.
|
||||
|
||||
@section{Reachability and Garbage Collection}
|
||||
@section[#:tag "Reachability and Garbage Collection"]{Reachability and Garbage Collection}
|
||||
|
||||
In general, Racket re-uses the storage for a value when the
|
||||
garbage collector can prove that the object is unreachable from
|
||||
|
@ -534,7 +534,7 @@ There are a number of exceptions, however:
|
|||
@item{Interned symbols are allocated only once (per place). A table inside
|
||||
Racket tracks this allocation so a symbol may not become garbage
|
||||
because that table holds onto it.}
|
||||
@item{Reachability is only approximate with the CGC collector (i.e.,
|
||||
@item{Reachability is only approximate with the @tech{CGC} collector (i.e.,
|
||||
a value may appear reachable to that collector when there is,
|
||||
in fact, no way to reach it anymore.}]
|
||||
|
||||
|
@ -577,3 +577,53 @@ occurrence of the variable @racket[_fishes]. That constitutes
|
|||
a reference to the list, ensuring that the list is not itself
|
||||
garbage collected, and thus the red fish is not either.
|
||||
|
||||
|
||||
@section{Reducing Garbage Collection Pauses}
|
||||
|
||||
By default, Racket's @tech{generational garbage collector} creates
|
||||
brief pauses for frequent @deftech{minor collections}, which inspect
|
||||
only the most recently allocated objects, and long pauses for infrequent
|
||||
@deftech{major collections}, which re-inspect all memory.
|
||||
|
||||
For some applications, such as animations and games,
|
||||
long pauses due to a major collection can interfere
|
||||
unacceptably with a program's operation. To reduce major-collection
|
||||
pauses, the Racket garbage collector supports @deftech{incremental
|
||||
garbage-collection} mode. In incremental mode, minor collections
|
||||
create longer (but still relatively short) pauses by performing extra
|
||||
work toward the next major collection. If all goes well, most of a
|
||||
major collection's work has been performed by minor collections the
|
||||
time that a major collection is needed, so the major collection's
|
||||
pause is as short as a minor collection's pause. Incremental mode
|
||||
tends to run more slowly overall, but it can
|
||||
provide much more consistent real-time behavior.
|
||||
|
||||
If the @envvar{PLT_INCREMENTAL_GC} environment variable is set
|
||||
to a value that starts with @litchar{1}, @litchar{y}, or @litchar{Y}
|
||||
when Racket starts, incremental mode is permanently enabled. Since
|
||||
incremental mode is only useful for certain parts of some programs,
|
||||
however, and since the need for incremental mode is a property of a
|
||||
program rather than its environment, the preferred way to enable
|
||||
incremental mode is with @racket[(collect-garbage 'incremental)].
|
||||
|
||||
Calling @racket[(collect-garbage 'incremental)] does not perform an
|
||||
immediate garbage collection, but instead requests that each minor
|
||||
collection perform incremental work up to the next major collection.
|
||||
The request expires with the next major collection. Make a call to
|
||||
@racket[(collect-garbage 'incremental)] in any repeating task within
|
||||
an application that needs to be responsive in real time. Force a
|
||||
full collection with @racket[(collect-garbage)] just before an initial
|
||||
@racket[(collect-garbage 'incremental)] to initiate incremental mode
|
||||
from an optimal state.
|
||||
|
||||
To check whether incremental mode is use and how it affects pause
|
||||
times, enable @tt{debug}-level logging output for the
|
||||
@racketidfont{GC} topic. For example,
|
||||
|
||||
@commandline{racket -W "debuG@"@"GC error" main.rkt}
|
||||
|
||||
runs @filepath{main.rkt} with garbage-collection logging to stderr
|
||||
(while preserving @tt{error}-level logging for all topics). Minor
|
||||
collections are reported by @litchar{min} lines, increment-mode minor
|
||||
collection are reported with @litchar{mIn} lines, and major
|
||||
collections are reported with @litchar{MAJ} lines.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#lang scribble/doc
|
||||
@(require "utils.rkt")
|
||||
@(require "utils.rkt"
|
||||
scribble/bnf)
|
||||
|
||||
@(define cgc-v-3m "CGC versus 3m")
|
||||
|
||||
|
@ -114,16 +115,28 @@ To embed Racket CGC in a program, follow these steps:
|
|||
into the top-level environment.
|
||||
|
||||
To embed a module like @racketmodname[racket/base] (along with all
|
||||
its dependencies), use @exec{raco ctool --c-mods}, which generates a C file
|
||||
its dependencies), use
|
||||
@seclink["c-mods" #:doc raco-doc]{@exec{raco ctool --c-mods @nonterm{dest}}},
|
||||
which generates a C file @nonterm{dest}
|
||||
that contains modules in bytecode form as encapsulated in a static
|
||||
array. The generated C file defines a @cppi{declare_modules}
|
||||
function that takes a @cpp{Scheme_Env*}, installs the modules into
|
||||
the environment, and adjusts the module name resolver to access the
|
||||
embedded declarations.
|
||||
embedded declarations. If embedded modules refer to runtime files
|
||||
that need to be carried along, supply @DFlag{runtime} to
|
||||
@exec{raco ctool --c-mods} to collect the runtime files into a
|
||||
directory; see @secref[#:doc raco-doc "c-mods"] for more information.
|
||||
|
||||
Alternately, use @cpp{scheme_set_collects_path} and
|
||||
Alternatively, use @cpp{scheme_set_collects_path} and
|
||||
@cpp{scheme_init_collection_paths} to configure and install a path
|
||||
for finding modules at run time.}
|
||||
for finding modules at run time.
|
||||
|
||||
On Windows, @exec{raco ctool --c-mods @nonterm{dest} --runtime
|
||||
@nonterm{dest-dir}} includes in @nonterm{dest-dir} optional DLLs
|
||||
that are referenced by the Racket library to support @tech[#:doc
|
||||
reference-doc]{extflonums} and @racket[bytes-open-converter]. Call
|
||||
@cpp{scheme_set_dll_path} to register @nonterm{dest-dir} so that
|
||||
those DLLs can be found at run time.}
|
||||
|
||||
@item{Access Racket through @cppi{scheme_dynamic_require},
|
||||
@cppi{scheme_load}, @cppi{scheme_eval}, and/or other functions
|
||||
|
|
|
@ -91,6 +91,15 @@ Like @cpp{scheme_init_collection_paths_post}, but with @racket[null]
|
|||
as the last argument.}
|
||||
|
||||
|
||||
@function[(void scheme_set_dll_path
|
||||
[wchar_t* path])]{
|
||||
|
||||
On Windows only, sets the path used to find optional DLLs that are used
|
||||
by the runtime system: @filepath{longdouble.dll} and one of @filepath{iconv.dll},
|
||||
@filepath{libiconv.dll}, or @filepath{libiconv-2.dll}. The given @var{path}
|
||||
should be an absolute path.}
|
||||
|
||||
|
||||
@function[(void scheme_seal_parameters)]{
|
||||
|
||||
Takes a snapshot of the current values of built-in parameters. These
|
||||
|
|
|
@ -41,7 +41,7 @@ source distribution from @url{http://download.racket-lang.org};
|
|||
detailed build instructions are in the @filepath{README} file in the
|
||||
top-level @filepath{src} directory. You can also get the latest
|
||||
sources from the @tt{git} repository at
|
||||
@url{https://github.com/plt/racket}, but beware that the repository is
|
||||
@url{https://github.com/racket/racket}, but beware that the repository is
|
||||
one step away from a normal source distribution, and it provides build
|
||||
modes that are more suitable for developing Racket itself; see
|
||||
@filepath{INSTALL.txt} in the @tt{git} repository for more
|
||||
|
|
|
@ -45,6 +45,13 @@ through the following indices:
|
|||
@item{@cppdef{MZCONFIG_CAN_READ_COMPILED} --- @racket[read-accept-compiled]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_BOX} --- @racket[read-accept-box]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_PIPE_QUOTE} --- @racket[read-accept-bar-quote]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_DOT} --- @racket[read-accept-dot]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_INFIX_DOT} --- @racket[read-accept-infix-dot]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_QUASI} --- @racket[read-accept-quasiquote]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_READER} --- @racket[read-accept-reader]}
|
||||
@item{@cppdef{MZCONFIG_CAN_READ_LANG} --- @racket[read-accept-lang]}
|
||||
@item{@cppdef{MZCONFIG_READ_DECIMAL_INEXACT} --- @racket[read-decimal-as-inexact]}
|
||||
@item{@cppdef{MZCONFIG_READ_CDOT} --- @racket[read-cdot]}
|
||||
|
||||
@item{@cppdef{MZCONFIG_PRINT_GRAPH} --- @racket[print-graph]}
|
||||
@item{@cppdef{MZCONFIG_PRINT_STRUCT} --- @racket[print-struct]}
|
||||
|
@ -53,6 +60,8 @@ through the following indices:
|
|||
@item{@cppdef{MZCONFIG_CASE_SENS} --- @racket[read-case-sensitive]}
|
||||
@item{@cppdef{MZCONFIG_SQUARE_BRACKETS_ARE_PARENS} --- @racket[read-square-brackets-as-parens]}
|
||||
@item{@cppdef{MZCONFIG_CURLY_BRACES_ARE_PARENS} --- @racket[read-curly-braces-as-parens]}
|
||||
@item{@cppdef{MZCONFIG_SQUARE_BRACKETS_ARE_TAGGED} --- @racket[read-square-brackets-with-tag]}
|
||||
@item{@cppdef{MZCONFIG_CURLY_BRACES_ARE_TAGGED} --- @racket[read-curly-braces-with-tag]}
|
||||
|
||||
@item{@cppdef{MZCONFIG_ERROR_PRINT_WIDTH} --- @racket[error-print-width]}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
function subfunction
|
||||
FormatD
|
||||
tech-place
|
||||
reference-doc raco-doc
|
||||
(except-out (all-from-out scribble/manual) var)
|
||||
(for-label (all-from-out scheme/base)))
|
||||
|
||||
|
@ -157,8 +158,11 @@
|
|||
|
||||
(define mzc (exec "raco ctool"))
|
||||
|
||||
(define reference-doc '(lib "scribblings/reference/reference.scrbl"))
|
||||
(define raco-doc '(lib "scribblings/raco/raco.scrbl"))
|
||||
|
||||
(define (refsecref s)
|
||||
(secref #:doc '(lib "scribblings/reference/reference.scrbl") s))
|
||||
(secref #:doc reference-doc s))
|
||||
|
||||
(define Racket
|
||||
(other-manual '(lib "scribblings/reference/reference.scrbl")))
|
||||
|
|
|
@ -747,7 +747,7 @@ import a library of control operators:
|
|||
Specifically, we need @racket[prompt] and @racket[abort] from
|
||||
@racketmodname[racket/control]. We use @racket[prompt] to mark the
|
||||
place where a servlet is started, so that we can abort a computation
|
||||
to that point. Change @racket[handle] by wrapping an @racket[prompt]
|
||||
to that point. Change @racket[handle] by wrapping a @racket[prompt]
|
||||
around the call to @racket[dispatch]:
|
||||
|
||||
@racketblock[
|
||||
|
|
|
@ -49,7 +49,10 @@ created executable. Such modules can be explicitly included using the
|
|||
@racket[define-runtime-path] to embed references to the run-time files
|
||||
in the executable; the files are then copied and packaged together
|
||||
with the executable when creating a distribution (as described in
|
||||
@secref["exe-dist"]).
|
||||
@secref["exe-dist"]). Finally, a submodule is included if its
|
||||
enclosing module is included and the submodule contains a
|
||||
sub-submodule named @racketidfont{declare-preserve-for-embedding}
|
||||
(where the implementation of the sub-submodule is ignored).
|
||||
|
||||
Modules that are implemented directly by extensions---i.e., extensions
|
||||
that are automatically loaded from @racket[(build-path "compiled"
|
||||
|
@ -172,6 +175,9 @@ The @exec{raco exe} command accepts the following command-line flags:
|
|||
|
||||
]
|
||||
|
||||
@history[#:changed "6.3.0.11" @elem{Added support for
|
||||
@racketidfont{declare-preserve-for-embedding}.}]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@include-section["exe-api.scrbl"]
|
||||
|
|
|
@ -452,9 +452,13 @@ Optional @filepath{info.rkt} fields trigger additional actions by
|
|||
]
|
||||
|
||||
The @racket[_category] list specifies how to show the document in
|
||||
the root table of contents. The list must start with a symbol,
|
||||
usually one of the following categories, which are ordered as
|
||||
below in the root documentation page:
|
||||
the root table of contents. The list must start with a category,
|
||||
which determines where the manual appears in the root
|
||||
documentation page. A category is either a string or a symbol. If
|
||||
it is a string, then the string is the category label on the root
|
||||
page. If it is a symbol, then a default category label is
|
||||
used. The available symbols and the order of categories on the
|
||||
root documentation page is as below:
|
||||
|
||||
@itemize[
|
||||
|
||||
|
@ -483,6 +487,8 @@ Optional @filepath{info.rkt} fields trigger additional actions by
|
|||
@item{@racket['interop] : Documentation for interoperability
|
||||
tools and libraries.}
|
||||
|
||||
@item{All string categories as ordered by @racket[string<=?].}
|
||||
|
||||
@item{@racket['library] : Documentation for libraries; this
|
||||
category is the default and used for unrecognized category
|
||||
symbols.}
|
||||
|
|
|
@ -274,12 +274,17 @@ binding, constructor, etc.}
|
|||
The @racket[lang-info] value specifies an optional module path that
|
||||
provides information about the module's implementation language.
|
||||
|
||||
The @racket[internal-module-context] value describes the lexical
|
||||
context of the body of the module. This value is used by
|
||||
@racket[module->namespace]. A @racket[#f] value means that the
|
||||
context is unavailable or empty. A @racket[#t] value means that the
|
||||
context is computed by re-importing all required modules. A
|
||||
syntax-object value embeds an arbitrary lexical context.
|
||||
The @racket[internal-context] value describes the lexical context of
|
||||
the body of the module. This value is used by
|
||||
@racket[module->namespace]. A @racket[#f] value means that the
|
||||
context is unavailable or empty. A @racket[#t] value means that the
|
||||
context is computed by re-importing all required modules. A
|
||||
syntax-object value embeds lexical information; the syntax object
|
||||
should contain a vector of two elements, where the first element of
|
||||
the vector is a syntax object for the module's body, which includes
|
||||
the outside-edge and inside-edge scopes, and the second element of
|
||||
the vector is a syntax object that has just the module's inside-edge
|
||||
scope.
|
||||
|
||||
The @racket[binding-names] value provides additional information to
|
||||
@racket[module->namespace] to correlate symbol names for variables
|
||||
|
|
|
@ -70,27 +70,27 @@ synchronization} when @racket[(async-channel-put ach v)] would return
|
|||
a value (i.e., when the channel holds fewer values already than its
|
||||
limit); @resultItself{asychronous channel-put event}.}
|
||||
|
||||
@defexamples[#:eval (async-eval)
|
||||
(define (server input-channel output-channel)
|
||||
(thread (lambda ()
|
||||
(define (get)
|
||||
(async-channel-get input-channel))
|
||||
(define (put x)
|
||||
(async-channel-put output-channel x))
|
||||
(define (do-large-computation)
|
||||
(sqrt 9))
|
||||
(let loop ([data (get)])
|
||||
(case data
|
||||
[(quit) (void)]
|
||||
[(add) (begin
|
||||
(put (+ 1 (get)))
|
||||
(loop (get)))]
|
||||
[(long) (begin
|
||||
(put (do-large-computation))
|
||||
(loop (get)))])))))
|
||||
|
||||
(define to-server (make-async-channel))
|
||||
(define from-server (make-async-channel))
|
||||
@examples[#:eval (async-eval) #:once
|
||||
(eval:no-prompt
|
||||
(define (server input-channel output-channel)
|
||||
(thread (lambda ()
|
||||
(define (get)
|
||||
(async-channel-get input-channel))
|
||||
(define (put x)
|
||||
(async-channel-put output-channel x))
|
||||
(define (do-large-computation)
|
||||
(sqrt 9))
|
||||
(let loop ([data (get)])
|
||||
(case data
|
||||
[(quit) (void)]
|
||||
[(add) (begin
|
||||
(put (+ 1 (get)))
|
||||
(loop (get)))]
|
||||
[(long) (begin
|
||||
(put (do-large-computation))
|
||||
(loop (get)))])))))
|
||||
(define to-server (make-async-channel))
|
||||
(define from-server (make-async-channel)))
|
||||
|
||||
(server to-server from-server)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt" scribble/eval (for-label racket/block))
|
||||
@(require "mz.rkt" (for-label racket/block))
|
||||
|
||||
@(define ev (make-base-eval))
|
||||
@(ev '(require racket/block))
|
||||
|
|
|
@ -643,7 +643,7 @@ normally identified by @racket[""]). See also
|
|||
@section{Additional Byte String Functions}
|
||||
@note-lib[racket/bytes]
|
||||
@(define string-eval (make-base-eval))
|
||||
@(interaction-eval #:eval string-eval (require racket/bytes racket/list))
|
||||
@@examples[#:hidden #:eval string-eval (require racket/bytes racket/list)]
|
||||
|
||||
@defproc[(bytes-append* [str bytes?] ... [strs (listof bytes?)]) bytes?]{
|
||||
@; Note: this is exactly the same description as the one for append*
|
||||
|
|
|
@ -191,18 +191,31 @@ required keyword arguments of @racket[wrapper-proc] must be a subset
|
|||
of the required keywords of @racket[proc].
|
||||
|
||||
For applications without keywords, the result of @racket[wrapper-proc]
|
||||
must be either the same number of values as supplied to it or one more
|
||||
than the number of supplied values, where an extra result is supplied
|
||||
before the others. The additional result, if any, must be a procedure
|
||||
must be at least the same number of values as supplied to it.
|
||||
Additional results can be supplied---before the values that correspond
|
||||
to the supplied values---in the following pattern:
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{An optional procedure, @racket[_result-wrapper-proc], which
|
||||
will be applied to the results of @racket[proc]; followed by}
|
||||
|
||||
@item{any number of repetitions of @racket['mark _key _val] (i.e.,
|
||||
three values), where the call @racket[_proc] is wrapped to
|
||||
install a @tech{continuation mark} @racket[_key] and @racket[_val].}
|
||||
|
||||
]
|
||||
|
||||
If @racket[_result-wrapper-proc] is produced, it must be a procedure
|
||||
that accepts as many results as produced by @racket[proc]; it must
|
||||
return the same number of results. If @racket[wrapper-proc] returns
|
||||
the same number of values as it is given (i.e., it does not return a
|
||||
procedure to impersonator @racket[proc]'s result), then @racket[proc] is
|
||||
called in @tech{tail position} with respect to the call to the impersonator.
|
||||
return the same number of results. If @racket[_result-wrapper-proc] is
|
||||
not supplied, then @racket[proc] is called in @tech{tail position}
|
||||
with respect to the call to the impersonator.
|
||||
|
||||
For applications that include keyword arguments, @racket[wrapper-proc]
|
||||
must return an additional value before any other values but after the
|
||||
result-impersonating procedure (if any). The additional value must be a
|
||||
must return an additional value before any other values but after
|
||||
@racket[_result-wrapper-proc] and @racket['mark _key _val]
|
||||
sequences (if any). The additional value must be a
|
||||
list of replacements for the keyword arguments that were supplied to the
|
||||
impersonator (i.e., not counting optional arguments that were
|
||||
not supplied). The arguments must be ordered according to the sorted
|
||||
|
@ -229,7 +242,51 @@ for @racket[(car prop-val)] in the call's continuation---then the value is
|
|||
also installed as an immediate value for @racket[(car prop-val)] as a
|
||||
mark during the call to @racket[wrapper-proc] (which allows tail-calls
|
||||
of impersonators with respect to wrapping impersonators to be detected within
|
||||
@racket[wrapper-proc]).}
|
||||
@racket[wrapper-proc]).
|
||||
|
||||
@history[#:changed "6.3.0.5" @elem{Added support for @racket['mark
|
||||
_key _val] results from
|
||||
@racket[wrapper-proc].}]
|
||||
|
||||
@examples[
|
||||
|
||||
(define (add15 x) (+ x 15))
|
||||
(define add15+print
|
||||
(impersonate-procedure add15
|
||||
(λ (x)
|
||||
(printf "called with ~s\n" x)
|
||||
(values (λ (res)
|
||||
(printf "returned ~s\n" res)
|
||||
res)
|
||||
x))))
|
||||
(add15 27)
|
||||
(add15+print 27)
|
||||
|
||||
(define-values (imp-prop:p1 imp-prop:p1? imp-prop:p1-get)
|
||||
(make-impersonator-property 'imp-prop:p1))
|
||||
(define-values (imp-prop:p2 imp-prop:p2? imp-prop:p2-get)
|
||||
(make-impersonator-property 'imp-prop:p2))
|
||||
|
||||
(define add15.2 (impersonate-procedure add15 #f imp-prop:p1 11))
|
||||
(add15.2 2)
|
||||
(imp-prop:p1? add15.2)
|
||||
(imp-prop:p1-get add15.2)
|
||||
(imp-prop:p2? add15.2)
|
||||
|
||||
(define add15.3 (impersonate-procedure add15.2 #f imp-prop:p2 13))
|
||||
(add15.3 3)
|
||||
(imp-prop:p1? add15.3)
|
||||
(imp-prop:p1-get add15.3)
|
||||
(imp-prop:p2? add15.3)
|
||||
(imp-prop:p2-get add15.3)
|
||||
|
||||
(define add15.4 (impersonate-procedure add15.3 #f imp-prop:p1 101))
|
||||
(add15.4 4)
|
||||
(imp-prop:p1? add15.4)
|
||||
(imp-prop:p1-get add15.4)
|
||||
(imp-prop:p2? add15.4)
|
||||
(imp-prop:p2-get add15.4)]
|
||||
}
|
||||
|
||||
@defproc[(impersonate-procedure* [proc procedure?]
|
||||
[wrapper-proc (or/c procedure? #f)]
|
||||
|
@ -389,6 +446,7 @@ or override impersonator-property values of @racket[box].}
|
|||
[remove-proc (hash? any/c . -> . any/c)]
|
||||
[key-proc (hash? any/c . -> . any/c)]
|
||||
[clear-proc (or/c #f (hash? . -> . any)) #f]
|
||||
[equal-key-proc (or/c #f (hash? any/c . -> . any/c)) #f]
|
||||
[prop impersonator-property?]
|
||||
[prop-val any] ... ...)
|
||||
(and/c hash? impersonator?)]{
|
||||
|
@ -404,7 +462,7 @@ In addition, operations like
|
|||
@racket[hash-iterate-key] or @racket[hash-map], which extract
|
||||
keys from the table, use @racket[key-proc] to filter keys extracted
|
||||
from the table. Operations like @racket[hash-iterate-value] or
|
||||
@racket[hash-iterate-map] implicitly use @racket[hash-ref] and
|
||||
@racket[hash-values] implicitly use @racket[hash-ref] and
|
||||
therefore redirect through @racket[ref-proc].
|
||||
|
||||
The @racket[ref-proc] must accept @racket[hash] and a key passed
|
||||
|
@ -442,6 +500,19 @@ If @racket[clear-proc] is @racket[#f], then @racket[hash-clear] or
|
|||
@racket[hash-clear!] on the impersonator is implemented using
|
||||
@racket[hash-iterate-key] and @racket[hash-remove] or @racket[hash-remove!].
|
||||
|
||||
If @racket[equal-key-proc] is not @racket[#f], it effectively
|
||||
interposes on calls to @racket[equal?], @racket[equal-hash-code], and
|
||||
@racket[equal-secondary-hash-code] for the keys of @racket[hash]. The
|
||||
@racket[equal-key-proc] must accept as its arguments @racket[hash] and
|
||||
a key that is either mapped by @racket[hash] or passed to
|
||||
@racket[hash-ref], etc., where the latter has potentially been
|
||||
adjusted by the corresponding @racket[ref-proc], etc@|.__| The result
|
||||
is a value that is passed to @racket[equal?],
|
||||
@racket[equal-hash-code], and @racket[equal-secondary-hash-code] as
|
||||
needed to hash and compare keys. In the case of @racket[hash-set!] or
|
||||
@racket[hash-set], the key that is passed to @racket[equal-key-proc]
|
||||
is the one stored in the hash table for future lookup.
|
||||
|
||||
The @racket[hash-iterate-value], @racket[hash-map], or
|
||||
@racket[hash-for-each] functions use a combination of
|
||||
@racket[hash-iterate-key] and @racket[hash-ref]. If a key
|
||||
|
@ -450,7 +521,10 @@ produced by @racket[key-proc] does not yield a value through
|
|||
|
||||
Pairs of @racket[prop] and @racket[prop-val] (the number of arguments
|
||||
to @racket[impersonate-hash] must be odd) add impersonator properties
|
||||
or override impersonator-property values of @racket[hash].}
|
||||
or override impersonator-property values of @racket[hash].
|
||||
|
||||
@history[#:changed "6.3.0.11" @elem{Added the @racket[equal-key-proc]
|
||||
argument.}]}
|
||||
|
||||
|
||||
@defproc[(impersonate-channel [channel channel?]
|
||||
|
@ -745,6 +819,7 @@ the same value or a chaperone of the value that it is given. The
|
|||
[remove-proc (hash? any/c . -> . any/c)]
|
||||
[key-proc (hash? any/c . -> . any/c)]
|
||||
[clear-proc (or/c #f (hash? . -> . any)) #f]
|
||||
[equal-key-proc (or/c #f (hash? any/c . -> . any/c)) #f]
|
||||
[prop impersonator-property?]
|
||||
[prop-val any] ... ...)
|
||||
(and/c hash? chaperone?)]{
|
||||
|
@ -754,8 +829,12 @@ and support for immutable hashes. The @racket[ref-proc] procedure must
|
|||
return a found value or a chaperone of the value. The
|
||||
@racket[set-proc] procedure must produce two values: the key that it
|
||||
is given or a chaperone of the key and the value that it is given or a
|
||||
chaperone of the value. The @racket[remove-proc] and @racket[key-proc]
|
||||
procedures must produce the given key or a chaperone of the key.}
|
||||
chaperone of the value. The @racket[remove-proc], @racket[key-proc],
|
||||
and @racket[equal-key-proc]
|
||||
procedures must produce the given key or a chaperone of the key.
|
||||
|
||||
@history[#:changed "6.3.0.11" @elem{Added the @racket[equal-key-proc]
|
||||
argument.}]}
|
||||
|
||||
@defproc[(chaperone-struct-type [struct-type struct-type?]
|
||||
[struct-info-proc procedure?]
|
||||
|
@ -867,11 +946,12 @@ procedure.
|
|||
(lambda (n) (* n 2))
|
||||
(lambda (n) (+ n 1))))
|
||||
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(abort-current-continuation bad-chaperone 5))
|
||||
bad-chaperone
|
||||
(lambda (n) n))
|
||||
(eval:error
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(abort-current-continuation bad-chaperone 5))
|
||||
bad-chaperone
|
||||
(lambda (n) n)))
|
||||
|
||||
(define good-chaperone
|
||||
(chaperone-prompt-tag
|
||||
|
@ -909,10 +989,11 @@ given.
|
|||
(lambda (l) (map char-upcase l))
|
||||
string->list))
|
||||
|
||||
(with-continuation-mark bad-chaperone "timballo"
|
||||
(continuation-mark-set-first
|
||||
(current-continuation-marks)
|
||||
bad-chaperone))
|
||||
(eval:error
|
||||
(with-continuation-mark bad-chaperone "timballo"
|
||||
(continuation-mark-set-first
|
||||
(current-continuation-marks)
|
||||
bad-chaperone)))
|
||||
|
||||
(define (checker s)
|
||||
(if (> (string-length s) 5)
|
||||
|
|
|
@ -71,11 +71,10 @@
|
|||
|
||||
)
|
||||
|
||||
@(interaction-eval #:eval class-eval (require racket/class racket/contract))
|
||||
@(interaction-eval
|
||||
#:eval class-ctc-eval
|
||||
(require racket/class racket/contract))
|
||||
|
||||
@examples[#:hidden #:eval class-eval
|
||||
(require racket/class racket/contract)]
|
||||
@examples[#:hidden #:eval class-ctc-eval
|
||||
(require racket/class racket/contract)]
|
||||
|
||||
@title[#:tag "mzlib:class" #:style 'toc]{Classes and Objects}
|
||||
|
||||
|
@ -196,8 +195,9 @@ is the most specific requirement from its superinterfaces. If the
|
|||
superinterfaces specify inconsistent derivation requirements, the
|
||||
@exnraise[exn:fail:object].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-ctc-eval
|
||||
#:no-prompt
|
||||
(define file-interface<%>
|
||||
(interface () open close read-byte write-byte))
|
||||
(define directory-interface<%>
|
||||
|
@ -226,8 +226,9 @@ extended to produce the internal structure type for instances of the
|
|||
class (so that no information about fields is accessible to the
|
||||
structure type property's guard, if any).
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
#:no-prompt
|
||||
(define i<%> (interface* () ([prop:custom-write
|
||||
(lambda (obj port mode) (void))])
|
||||
method1 method2 method3))
|
||||
|
@ -387,8 +388,9 @@ calling subclass augmentations of methods (see
|
|||
|
||||
Like @racket[class*], but omits the @racket[_interface-expr]s, for the case that none are needed.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
#:no-prompt
|
||||
(define book-class%
|
||||
(class object%
|
||||
(field (pages 5))
|
||||
|
@ -404,15 +406,16 @@ to the current object (i.e., the object being initialized or whose
|
|||
method was called). Use outside the body of a @racket[class*] form is
|
||||
a syntax error.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
(define (describe obj)
|
||||
(printf "Hello ~a\n" obj))
|
||||
(define table%
|
||||
(class object%
|
||||
(define/public (describe-self)
|
||||
(describe this))
|
||||
(super-new)))
|
||||
(eval:no-prompt
|
||||
(define (describe obj)
|
||||
(printf "Hello ~a\n" obj))
|
||||
(define table%
|
||||
(class object%
|
||||
(define/public (describe-self)
|
||||
(describe this))
|
||||
(super-new))))
|
||||
(send (new table%) describe-self)
|
||||
]}
|
||||
|
||||
|
@ -423,21 +426,22 @@ of the current object (i.e., the object being initialized or whose
|
|||
method was called). Use outside the body of a @racket[class*] form is
|
||||
a syntax error.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
(define account%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field balance)
|
||||
(define/public (add n)
|
||||
(new this% [balance (+ n balance)]))))
|
||||
(define savings%
|
||||
(class account%
|
||||
(super-new)
|
||||
(inherit-field balance)
|
||||
(define interest 0.04)
|
||||
(define/public (add-interest)
|
||||
(send this add (* interest balance)))))
|
||||
(eval:no-prompt
|
||||
(define account%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field balance)
|
||||
(define/public (add n)
|
||||
(new this% [balance (+ n balance)]))))
|
||||
(define savings%
|
||||
(class account%
|
||||
(super-new)
|
||||
(inherit-field balance)
|
||||
(define interest 0.04)
|
||||
(define/public (add-interest)
|
||||
(send this add (* interest balance))))))
|
||||
(let* ([acct (new savings% [balance 500])]
|
||||
[acct (send acct add 500)]
|
||||
[acct (send acct add-interest)])
|
||||
|
@ -447,7 +451,7 @@ a syntax error.
|
|||
@defclassforms[
|
||||
[(inspect inspector-expr) ()]
|
||||
[(init init-decl ...) ("clinitvars")
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(class object%
|
||||
(super-new)
|
||||
(init turnip
|
||||
|
@ -455,7 +459,7 @@ a syntax error.
|
|||
[carrot 'good]
|
||||
[(internal-rutabaga rutabaga) 'okay]))]]
|
||||
[(init-field init-decl ...) ("clinitvars" "clfields")
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field turkey
|
||||
|
@ -463,181 +467,202 @@ a syntax error.
|
|||
[chicken 7]
|
||||
[(internal-emu emu) 13]))]]
|
||||
[(field field-decl ...) ("clfields")
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(class object%
|
||||
(super-new)
|
||||
(field [minestrone 'ready]
|
||||
[(internal-coq-au-vin coq-au-vin) 'stewing]))]]
|
||||
[(inherit-field maybe-renamed ...) ("clfields")
|
||||
@defexamples[#:eval class-eval
|
||||
(define cookbook%
|
||||
(class object%
|
||||
(super-new)
|
||||
(field [recipes '(caldo-verde oyakodon eggs-benedict)]
|
||||
[pages 389])))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define cookbook%
|
||||
(class object%
|
||||
(super-new)
|
||||
(field [recipes '(caldo-verde oyakodon eggs-benedict)]
|
||||
[pages 389]))))
|
||||
(class cookbook%
|
||||
(super-new)
|
||||
(inherit-field recipes
|
||||
[internal-pages pages]))]]
|
||||
[* ((init-rest id) (init-rest)) ("clinitvars")
|
||||
@defexamples[#:eval class-eval
|
||||
(define fruit-basket%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-rest fruits)
|
||||
(displayln fruits)))
|
||||
(make-object fruit-basket% 'kiwi 'lychee 'melon)]]
|
||||
[(public maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define jumper%
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define fruit-basket%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define (skip) 'skip)
|
||||
(define (hop) 'hop)
|
||||
(public skip [hop jump])))
|
||||
(init-rest fruits)
|
||||
(displayln fruits))))
|
||||
(make-object fruit-basket% 'kiwi 'lychee 'melon)]]
|
||||
[(public maybe-renamed ...) ("clmethoddefs")
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define jumper%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define (skip) 'skip)
|
||||
(define (hop) 'hop)
|
||||
(public skip [hop jump]))))
|
||||
(send (new jumper%) skip)
|
||||
(send (new jumper%) jump)]]
|
||||
[(pubment maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define runner%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define (run) 'run)
|
||||
(define (trot) 'trot)
|
||||
(pubment run [trot jog])))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define runner%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define (run) 'run)
|
||||
(define (trot) 'trot)
|
||||
(pubment run [trot jog]))))
|
||||
(send (new runner%) run)
|
||||
(send (new runner%) jog)]]
|
||||
[(public-final maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define point%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field [x 0] [y 0])
|
||||
(define (get-x) x)
|
||||
(define (do-get-y) y)
|
||||
(public-final get-x [do-get-y get-y])))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define point%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field [x 0] [y 0])
|
||||
(define (get-x) x)
|
||||
(define (do-get-y) y)
|
||||
(public-final get-x [do-get-y get-y]))))
|
||||
(send (new point% [x 1] [y 3]) get-y)
|
||||
(class point%
|
||||
(super-new)
|
||||
(define (get-x) 3.14)
|
||||
(override get-x))]]
|
||||
(eval:error
|
||||
(class point%
|
||||
(super-new)
|
||||
(define (get-x) 3.14)
|
||||
(override get-x)))]]
|
||||
[(override maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define sheep%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (bleat)
|
||||
(displayln "baaaaaaaaah"))))
|
||||
(define confused-sheep%
|
||||
(class sheep%
|
||||
(super-new)
|
||||
(define (bleat)
|
||||
(super bleat)
|
||||
(displayln "???"))
|
||||
(override bleat)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define sheep%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (bleat)
|
||||
(displayln "baaaaaaaaah")))))
|
||||
(eval:no-prompt
|
||||
(define confused-sheep%
|
||||
(class sheep%
|
||||
(super-new)
|
||||
(define (bleat)
|
||||
(super bleat)
|
||||
(displayln "???"))
|
||||
(override bleat))))
|
||||
(send (new sheep%) bleat)
|
||||
(send (new confused-sheep%) bleat)]]
|
||||
[(overment maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define turkey%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (gobble)
|
||||
(displayln "gobble gobble"))))
|
||||
(define extra-turkey%
|
||||
(class turkey%
|
||||
(super-new)
|
||||
(define (gobble)
|
||||
(super gobble)
|
||||
(displayln "gobble gobble gobble")
|
||||
(inner (void) gobble))
|
||||
(overment gobble)))
|
||||
(define cyborg-turkey%
|
||||
(class extra-turkey%
|
||||
(super-new)
|
||||
(define/augment (gobble)
|
||||
(displayln "110011111011111100010110001011011001100101"))))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define turkey%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (gobble)
|
||||
(displayln "gobble gobble")))))
|
||||
(eval:no-prompt
|
||||
(define extra-turkey%
|
||||
(class turkey%
|
||||
(super-new)
|
||||
(define (gobble)
|
||||
(super gobble)
|
||||
(displayln "gobble gobble gobble")
|
||||
(inner (void) gobble))
|
||||
(overment gobble))))
|
||||
(eval:no-prompt
|
||||
(define cyborg-turkey%
|
||||
(class extra-turkey%
|
||||
(super-new)
|
||||
(define/augment (gobble)
|
||||
(displayln "110011111011111100010110001011011001100101")))))
|
||||
(send (new extra-turkey%) gobble)
|
||||
(send (new cyborg-turkey%) gobble)]]
|
||||
[(override-final maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define meeper%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (meep)
|
||||
(displayln "meep"))))
|
||||
(define final-meeper%
|
||||
(class meeper%
|
||||
(super-new)
|
||||
(define (meep)
|
||||
(super meep)
|
||||
(displayln "This meeping ends with me"))
|
||||
(override-final meep)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define meeper%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (meep)
|
||||
(displayln "meep")))))
|
||||
(eval:no-prompt
|
||||
(define final-meeper%
|
||||
(class meeper%
|
||||
(super-new)
|
||||
(define (meep)
|
||||
(super meep)
|
||||
(displayln "This meeping ends with me"))
|
||||
(override-final meep))))
|
||||
(send (new meeper%) meep)
|
||||
(send (new final-meeper%) meep)]]
|
||||
[(augment maybe-renamed ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define buzzer%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/pubment (buzz)
|
||||
(displayln "bzzzt")
|
||||
(inner (void) buzz))))
|
||||
(define loud-buzzer%
|
||||
(class buzzer%
|
||||
(super-new)
|
||||
(define (buzz)
|
||||
(displayln "BZZZZZZZZZT"))
|
||||
(augment buzz)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define buzzer%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/pubment (buzz)
|
||||
(displayln "bzzzt")
|
||||
(inner (void) buzz)))))
|
||||
(eval:no-prompt
|
||||
(define loud-buzzer%
|
||||
(class buzzer%
|
||||
(super-new)
|
||||
(define (buzz)
|
||||
(displayln "BZZZZZZZZZT"))
|
||||
(augment buzz))))
|
||||
(send (new buzzer%) buzz)
|
||||
(send (new loud-buzzer%) buzz)]]
|
||||
[(augride maybe-renamed ...) ("clmethoddefs")]
|
||||
[(augment-final maybe-renamed ...) ("clmethoddefs")]
|
||||
[(private id ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define light%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define on? #t)
|
||||
(define (toggle) (set! on? (not on?)))
|
||||
(private toggle)
|
||||
(define (flick) (toggle))
|
||||
(public flick)))
|
||||
(send (new light%) toggle)
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define light%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define on? #t)
|
||||
(define (toggle) (set! on? (not on?)))
|
||||
(private toggle)
|
||||
(define (flick) (toggle))
|
||||
(public flick))))
|
||||
(eval:error (send (new light%) toggle))
|
||||
(send (new light%) flick)]]
|
||||
[(abstract id ...) ("clmethoddefs")
|
||||
@defexamples[#:eval class-eval
|
||||
(define train%
|
||||
(class object%
|
||||
(super-new)
|
||||
(abstract get-speed)
|
||||
(init-field [position 0])
|
||||
(define/public (move)
|
||||
(new this% [position (+ position (get-speed))]))))
|
||||
(define acela%
|
||||
(class train%
|
||||
(super-new)
|
||||
(define/override (get-speed) 241)))
|
||||
(define talgo-350%
|
||||
(class train%
|
||||
(super-new)
|
||||
(define/override (get-speed) 330)))
|
||||
(new train%)
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define train%
|
||||
(class object%
|
||||
(super-new)
|
||||
(abstract get-speed)
|
||||
(init-field [position 0])
|
||||
(define/public (move)
|
||||
(new this% [position (+ position (get-speed))])))))
|
||||
(eval:no-prompt
|
||||
(define acela%
|
||||
(class train%
|
||||
(super-new)
|
||||
(define/override (get-speed) 241))))
|
||||
(eval:no-prompt
|
||||
(define talgo-350%
|
||||
(class train%
|
||||
(super-new)
|
||||
(define/override (get-speed) 330))))
|
||||
(eval:error (new train%))
|
||||
(send (new acela%) move)]]
|
||||
[(inherit maybe-renamed ...) ("classinherit")
|
||||
@defexamples[#:eval class-eval
|
||||
(define alarm%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (alarm)
|
||||
(displayln "beeeeeeeep"))))
|
||||
(define car-alarm%
|
||||
(class alarm%
|
||||
(super-new)
|
||||
(init-field proximity)
|
||||
(inherit alarm)
|
||||
(when (< proximity 10)
|
||||
(alarm))))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define alarm%
|
||||
(class object%
|
||||
(super-new)
|
||||
(define/public (alarm)
|
||||
(displayln "beeeeeeeep")))))
|
||||
(eval:no-prompt
|
||||
(define car-alarm%
|
||||
(class alarm%
|
||||
(super-new)
|
||||
(init-field proximity)
|
||||
(inherit alarm)
|
||||
(when (< proximity 10)
|
||||
(alarm)))))
|
||||
(new car-alarm% [proximity 5])]]
|
||||
[(inherit/super maybe-renamed ...) ("classinherit")]
|
||||
[(inherit/inner maybe-renamed ...) ("classinherit")]
|
||||
|
@ -1067,21 +1092,22 @@ hidden name (except as a top-level definition). The
|
|||
@racket[interface->method-names] procedure does not expose hidden
|
||||
names.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
(define-values (r o)
|
||||
(let ()
|
||||
(define-local-member-name m)
|
||||
(define c% (class object%
|
||||
(define/public (m) 10)
|
||||
(super-new)))
|
||||
(define o (new c%))
|
||||
(eval:no-prompt
|
||||
(define-values (r o)
|
||||
(let ()
|
||||
(define-local-member-name m)
|
||||
(define c% (class object%
|
||||
(define/public (m) 10)
|
||||
(super-new)))
|
||||
(define o (new c%))
|
||||
|
||||
(values (send o m)
|
||||
o)))
|
||||
(values (send o m)
|
||||
o))))
|
||||
|
||||
r
|
||||
(send o m)
|
||||
(eval:error (send o m))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -1121,28 +1147,27 @@ Produces an integer hash code consistent with
|
|||
@racket[member-name-key=?] comparisons, analogous to
|
||||
@racket[equal-hash-code].}
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval class-eval
|
||||
(define (make-c% key)
|
||||
(define-member-name m key)
|
||||
(class object%
|
||||
(define/public (m) 10)
|
||||
(super-new)))
|
||||
(eval:no-prompt
|
||||
(define (make-c% key)
|
||||
(define-member-name m key)
|
||||
(class object%
|
||||
(define/public (m) 10)
|
||||
(super-new))))
|
||||
|
||||
(send (new (make-c% (member-name-key m))) m)
|
||||
(send (new (make-c% (member-name-key p))) m)
|
||||
(eval:error (send (new (make-c% (member-name-key p))) m))
|
||||
(send (new (make-c% (member-name-key p))) p)
|
||||
]
|
||||
|
||||
@defs+int[
|
||||
#:eval class-eval
|
||||
[(define (fresh-c%)
|
||||
(eval:no-prompt
|
||||
(define (fresh-c%)
|
||||
(let ([key (generate-member-key)])
|
||||
(values (make-c% key) key)))
|
||||
|
||||
(define-values (fc% key) (fresh-c%))]
|
||||
(define-values (fc% key) (fresh-c%)))
|
||||
|
||||
(send (new fc%) m)
|
||||
(eval:error (send (new fc%) m))
|
||||
(let ()
|
||||
(define-member-name p key)
|
||||
(send (new fc%) p))
|
||||
|
@ -1352,15 +1377,16 @@ the last method call, which is expected to be an object. Each
|
|||
|
||||
This is the functional analogue of @racket[send*].
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
(define point%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field [x 0] [y 0])
|
||||
(define/public (move-x dx)
|
||||
(new this% [x (+ x dx)]))
|
||||
(define/public (move-y dy)
|
||||
(new this% [y (+ y dy)]))))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define point%
|
||||
(class object%
|
||||
(super-new)
|
||||
(init-field [x 0] [y 0])
|
||||
(define/public (move-x dx)
|
||||
(new this% [x (+ x dx)]))
|
||||
(define/public (move-y dy)
|
||||
(new this% [y (+ y dy)])))))
|
||||
|
||||
(send+ (new point%)
|
||||
(move-x 5)
|
||||
|
@ -1802,21 +1828,21 @@ The external contracts are as follows:
|
|||
If only the field name is present, this is equivalent to insisting only
|
||||
that the method is present in the class.
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
(define woody%
|
||||
(class object%
|
||||
(define/public (draw who)
|
||||
(format "reach for the sky, ~a" who))
|
||||
(super-new)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define woody%
|
||||
(class object%
|
||||
(define/public (draw who)
|
||||
(format "reach for the sky, ~a" who))
|
||||
(super-new)))
|
||||
|
||||
(define/contract woody+c%
|
||||
(class/c [draw (->m symbol? string?)])
|
||||
woody%)
|
||||
(define/contract woody+c%
|
||||
(class/c [draw (->m symbol? string?)])
|
||||
woody%))
|
||||
|
||||
(send (new woody%) draw #f)
|
||||
(send (new woody+c%) draw 'zurg)
|
||||
(send (new woody+c%) draw #f)]
|
||||
(eval:error (send (new woody+c%) draw #f))]
|
||||
}
|
||||
@item{An external field contract, tagged with @racket[field], describes the
|
||||
behavior of the value contained in that field when accessed from outside
|
||||
|
@ -1827,28 +1853,29 @@ The external contracts are as follows:
|
|||
If only the field name is present, this is equivalent to using the
|
||||
contract @racket[any/c] (but it is checked more efficiently).
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
(define woody/hat%
|
||||
(class woody%
|
||||
(field [hat-location 'uninitialized])
|
||||
(define/public (lose-hat) (set! hat-location 'lost))
|
||||
(define/public (find-hat) (set! hat-location 'on-head))
|
||||
(super-new)))
|
||||
(define/contract woody/hat+c%
|
||||
(class/c [draw (->m symbol? string?)]
|
||||
[lose-hat (->m void?)]
|
||||
[find-hat (->m void?)]
|
||||
(field [hat-location (or/c 'on-head 'lost)]))
|
||||
woody/hat%)
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define woody/hat%
|
||||
(class woody%
|
||||
(field [hat-location 'uninitialized])
|
||||
(define/public (lose-hat) (set! hat-location 'lost))
|
||||
(define/public (find-hat) (set! hat-location 'on-head))
|
||||
(super-new)))
|
||||
(define/contract woody/hat+c%
|
||||
(class/c [draw (->m symbol? string?)]
|
||||
[lose-hat (->m void?)]
|
||||
[find-hat (->m void?)]
|
||||
(field [hat-location (or/c 'on-head 'lost)]))
|
||||
woody/hat%))
|
||||
|
||||
(get-field hat-location (new woody/hat%))
|
||||
(let ([woody (new woody/hat+c%)])
|
||||
(send woody lose-hat)
|
||||
(get-field hat-location woody))
|
||||
(get-field hat-location (new woody/hat+c%))
|
||||
(let ([woody (new woody/hat+c%)])
|
||||
(set-field! hat-location woody 'under-the-dresser))]
|
||||
(eval:error (get-field hat-location (new woody/hat+c%)))
|
||||
(eval:error
|
||||
(let ([woody (new woody/hat+c%)])
|
||||
(set-field! hat-location woody 'under-the-dresser)))]
|
||||
|
||||
}
|
||||
@item{An initialization argument contract, tagged with @racket[init],
|
||||
|
@ -1861,28 +1888,29 @@ The external contracts are as follows:
|
|||
If only the initialization argument name is present, this is equivalent to using the
|
||||
contract @racket[any/c] (but it is checked more efficiently).
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
(define woody/init-hat%
|
||||
(class woody%
|
||||
(init init-hat-location)
|
||||
(field [hat-location init-hat-location])
|
||||
(define/public (lose-hat) (set! hat-location 'lost))
|
||||
(define/public (find-hat) (set! hat-location 'on-head))
|
||||
(super-new)))
|
||||
(define/contract woody/init-hat+c%
|
||||
(class/c [draw (->m symbol? string?)]
|
||||
[lose-hat (->m void?)]
|
||||
[find-hat (->m void?)]
|
||||
(init [init-hat-location (or/c 'on-head 'lost)])
|
||||
(field [hat-location (or/c 'on-head 'lost)]))
|
||||
woody/init-hat%)
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define woody/init-hat%
|
||||
(class woody%
|
||||
(init init-hat-location)
|
||||
(field [hat-location init-hat-location])
|
||||
(define/public (lose-hat) (set! hat-location 'lost))
|
||||
(define/public (find-hat) (set! hat-location 'on-head))
|
||||
(super-new)))
|
||||
(define/contract woody/init-hat+c%
|
||||
(class/c [draw (->m symbol? string?)]
|
||||
[lose-hat (->m void?)]
|
||||
[find-hat (->m void?)]
|
||||
(init [init-hat-location (or/c 'on-head 'lost)])
|
||||
(field [hat-location (or/c 'on-head 'lost)]))
|
||||
woody/init-hat%))
|
||||
(get-field hat-location
|
||||
(new woody/init-hat+c%
|
||||
[init-hat-location 'lost]))
|
||||
(get-field hat-location
|
||||
(new woody/init-hat+c%
|
||||
[init-hat-location 'slinkys-mouth]))]
|
||||
(eval:error
|
||||
(get-field hat-location
|
||||
(new woody/init-hat+c%
|
||||
[init-hat-location 'slinkys-mouth])))]
|
||||
|
||||
}
|
||||
@item{The contracts listed in an @racket[init-field] section are
|
||||
|
@ -1906,18 +1934,19 @@ As with the external contracts, when a method or field name is specified
|
|||
contracted class's method implementation is no longer the entry point
|
||||
for dynamic dispatch.
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
@examples[#:eval class-eval
|
||||
(new (class woody+c%
|
||||
(inherit draw)
|
||||
(super-new)
|
||||
(printf "woody sez: “~a”\n" (draw "evil dr porkchop"))))
|
||||
(define/contract woody+c-inherit%
|
||||
(class/c (inherit [draw (->m symbol? string?)]))
|
||||
woody+c%)
|
||||
(new (class woody+c-inherit%
|
||||
(inherit draw)
|
||||
(printf "woody sez: ~a\n" (draw "evil dr porkchop"))))]
|
||||
(eval:no-prompt
|
||||
(define/contract woody+c-inherit%
|
||||
(class/c (inherit [draw (->m symbol? string?)]))
|
||||
woody+c%))
|
||||
(eval:error
|
||||
(new (class woody+c-inherit%
|
||||
(inherit draw)
|
||||
(printf "woody sez: ~a\n" (draw "evil dr porkchop")))))]
|
||||
|
||||
}
|
||||
@item{A method contract tagged with @racket[super] describes the behavior of
|
||||
|
@ -1932,18 +1961,18 @@ As with the external contracts, when a method or field name is specified
|
|||
contract the controls how the @racket[super] methods must
|
||||
be invoked.
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
(define/contract woody2+c%
|
||||
(class/c (super [draw (->m symbol? string?)]))
|
||||
(class woody%
|
||||
(define/override draw
|
||||
(case-lambda
|
||||
[(a) (super draw a)]
|
||||
[(a b) (string-append (super draw a)
|
||||
" and "
|
||||
(super draw b))]))
|
||||
(super-new)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define/contract woody2+c%
|
||||
(class/c (super [draw (->m symbol? string?)]))
|
||||
(class woody%
|
||||
(define/override draw
|
||||
(case-lambda
|
||||
[(a) (super draw a)]
|
||||
[(a b) (string-append (super draw a)
|
||||
" and "
|
||||
(super draw b))]))
|
||||
(super-new))))
|
||||
(send (new woody2+c%) draw 'evil-dr-porkchop 'zurg)
|
||||
(send (new woody2+c%) draw "evil dr porkchop" "zurg")]
|
||||
|
||||
|
@ -1971,27 +2000,28 @@ As with the external contracts, when a method or field name is specified
|
|||
add a contract to make sure that overriding @racket[draw]
|
||||
doesn't break @racket[draw2].
|
||||
|
||||
@defexamples[#:eval
|
||||
class-eval
|
||||
(define/contract woody2+override/c%
|
||||
(class/c (override [draw (->m symbol? string?)]))
|
||||
(class woody+c%
|
||||
(inherit draw)
|
||||
(define/public (draw2 a b)
|
||||
(string-append (draw a)
|
||||
" and "
|
||||
(draw b)))
|
||||
(super-new)))
|
||||
@examples[#:eval class-eval
|
||||
(eval:no-prompt
|
||||
(define/contract woody2+override/c%
|
||||
(class/c (override [draw (->m symbol? string?)]))
|
||||
(class woody+c%
|
||||
(inherit draw)
|
||||
(define/public (draw2 a b)
|
||||
(string-append (draw a)
|
||||
" and "
|
||||
(draw b)))
|
||||
(super-new)))
|
||||
|
||||
(define woody2+broken-draw
|
||||
(class woody2+override/c%
|
||||
(define/override (draw x)
|
||||
'not-a-string)
|
||||
(super-new)))
|
||||
|
||||
(send (new woody2+broken-draw) draw2
|
||||
'evil-dr-porkchop
|
||||
'zurg)]
|
||||
(define woody2+broken-draw
|
||||
(class woody2+override/c%
|
||||
(define/override (draw x)
|
||||
'not-a-string)
|
||||
(super-new))))
|
||||
|
||||
(eval:error
|
||||
(send (new woody2+broken-draw) draw2
|
||||
'evil-dr-porkchop
|
||||
'zurg))]
|
||||
|
||||
|
||||
}
|
||||
|
@ -2390,7 +2420,7 @@ A @racket[print] request is directed to @racket[custom-write].}
|
|||
|
||||
Returns @racket[#t] if @racket[v] is an object, @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(object? (new object%))
|
||||
(object? object%)
|
||||
(object? "clam chowder")
|
||||
|
@ -2401,7 +2431,7 @@ Returns @racket[#t] if @racket[v] is an object, @racket[#f] otherwise.
|
|||
|
||||
Returns @racket[#t] if @racket[v] is a class, @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(class? object%)
|
||||
(class? (class object% (super-new)))
|
||||
(class? (new object%))
|
||||
|
@ -2413,7 +2443,7 @@ Returns @racket[#t] if @racket[v] is a class, @racket[#f] otherwise.
|
|||
|
||||
Returns @racket[#t] if @racket[v] is an interface, @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(interface? (interface () empty cons first rest))
|
||||
(interface? object%)
|
||||
(interface? "gazpacho")
|
||||
|
@ -2424,7 +2454,7 @@ Returns @racket[#t] if @racket[v] is an interface, @racket[#f] otherwise.
|
|||
|
||||
Returns @racket[#t] if @racket[v] is a @tech{generic}, @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define c%
|
||||
(class object%
|
||||
(super-new)
|
||||
|
@ -2448,7 +2478,7 @@ This procedure is similar in spirit to
|
|||
@racket[eq?] but also works properly with contracts
|
||||
(and has a stronger guarantee).
|
||||
|
||||
@defexamples[#:eval class-ctc-eval
|
||||
@examples[#:eval class-ctc-eval
|
||||
(define obj-1 (new object%))
|
||||
(define obj-2 (new object%))
|
||||
(define/contract obj-3 (object/c) obj-1)
|
||||
|
@ -2468,7 +2498,7 @@ This procedure is similar in spirit to
|
|||
Like @racket[object=?], but accepts @racket[#f] for either argument and
|
||||
returns @racket[#t] if both arguments are @racket[#f].
|
||||
|
||||
@defexamples[#:eval class-ctc-eval
|
||||
@examples[#:eval class-ctc-eval
|
||||
(object-or-false=? #f (new object%))
|
||||
(object-or-false=? (new object%) #f)
|
||||
(object-or-false=? #f #f)
|
||||
|
@ -2482,7 +2512,7 @@ returns @racket[#t] if both arguments are @racket[#f].
|
|||
Returns a vector representing @racket[object] that shows its
|
||||
inspectable fields, analogous to @racket[struct->vector].
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(object->vector (new object%))
|
||||
(object->vector (new (class object%
|
||||
(super-new)
|
||||
|
@ -2494,7 +2524,7 @@ inspectable fields, analogous to @racket[struct->vector].
|
|||
|
||||
Returns the interface implicitly defined by @racket[class].
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(class->interface object%)
|
||||
]}
|
||||
|
||||
|
@ -2504,7 +2534,7 @@ Returns the interface implicitly defined by @racket[class].
|
|||
Returns the interface implicitly defined by the class of
|
||||
@racket[object].
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(object-interface (new object%))
|
||||
]}
|
||||
|
||||
|
@ -2515,7 +2545,7 @@ Returns @racket[#t] if @racket[v] is an instance of a class
|
|||
@racket[type] or a class that implements an interface @racket[type],
|
||||
@racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define point<%> (interface () get-x get-y))
|
||||
(define 2d-point%
|
||||
(class* object% (point<%>)
|
||||
|
@ -2536,7 +2566,7 @@ Returns @racket[#t] if @racket[v] is an instance of a class
|
|||
Returns @racket[#t] if @racket[v] is a class derived from (or equal
|
||||
to) @racket[cls], @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(subclass? (class object% (super-new)) object%)
|
||||
(subclass? object% (class object% (super-new)))
|
||||
(subclass? object% object%)
|
||||
|
@ -2548,7 +2578,7 @@ to) @racket[cls], @racket[#f] otherwise.
|
|||
Returns @racket[#t] if @racket[v] is a class that implements
|
||||
@racket[intf], @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define i<%> (interface () go))
|
||||
(define c%
|
||||
(class* object% (i<%>)
|
||||
|
@ -2565,7 +2595,7 @@ Returns @racket[#t] if @racket[v] is a class that implements
|
|||
Returns @racket[#t] if @racket[v] is an interface that extends
|
||||
@racket[intf], @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define point<%> (interface () get-x get-y))
|
||||
(define colored-point<%> (interface (point<%>) color))
|
||||
|
||||
|
@ -2581,7 +2611,7 @@ Returns @racket[#t] if @racket[intf] (or any of its ancestor
|
|||
interfaces) includes a member with the name @racket[sym], @racket[#f]
|
||||
otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define i<%> (interface () get-x get-y))
|
||||
(method-in-interface? 'get-x i<%>)
|
||||
(method-in-interface? 'get-z i<%>)
|
||||
|
@ -2595,7 +2625,7 @@ including methods inherited from superinterfaces, but not including
|
|||
methods whose names are local (i.e., declared with
|
||||
@racket[define-local-member-name]).
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define i<%> (interface () get-x get-y))
|
||||
(interface->method-names i<%>)
|
||||
]}
|
||||
|
@ -2607,7 +2637,7 @@ methods whose names are local (i.e., declared with
|
|||
Returns @racket[#t] if @racket[object] has a method named @racket[sym]
|
||||
that accepts @racket[cnt] arguments, @racket[#f] otherwise.
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(define c%
|
||||
(class object%
|
||||
(super-new)
|
||||
|
@ -2628,7 +2658,7 @@ Returns a list of all of the names of the fields bound in
|
|||
not including fields whose names are local (i.e., declared with
|
||||
@racket[define-local-member-name]).
|
||||
|
||||
@defexamples[#:eval class-eval
|
||||
@examples[#:eval class-eval
|
||||
(field-names (new object%))
|
||||
(field-names (new (class object% (super-new) (field [x 0] [y 0]))))
|
||||
]}
|
||||
|
|
|
@ -182,25 +182,63 @@ If there are multiple higher-order contracts, @racket[or/c] uses
|
|||
them. More precisely, when an @racket[or/c] is checked, it first
|
||||
checks all of the @tech{flat contracts}. If none of them pass, it
|
||||
calls @racket[contract-first-order-passes?] with each of the
|
||||
higher-order contracts, taking the first one that returns
|
||||
true as the contract for the value.
|
||||
|
||||
higher-order contracts. If only one returns true, @racket[or/c] uses
|
||||
that contract. If none of them return true, it signals a contract
|
||||
violation. If more than one returns true, it also signals a contract
|
||||
violation.
|
||||
For example, this contract
|
||||
@racketblock[
|
||||
(or/c (-> number? number?)
|
||||
(-> string? string? string?))
|
||||
]
|
||||
accepts a function like this one: @racket[(lambda args ...)],
|
||||
using the @racket[(-> number? number?)] contract on it, ignoring
|
||||
the @racket[(-> string? string? string?)] contract since it came
|
||||
second.
|
||||
does not accept a function like this one: @racket[(lambda args ...)]
|
||||
since it cannot tell which of the two arrow contracts should be used
|
||||
with the function.
|
||||
|
||||
If all of its arguments are @racket[list-contract?]s, then @racket[or/c]
|
||||
returns a @racket[list-contract?].
|
||||
}
|
||||
|
||||
@history[#:changed "6.3" @list{Adjusted @racket[or/c] so that it
|
||||
takes the first higher-order contract instead of insisting that
|
||||
there be exactly one higher-order contract for a given value.}]
|
||||
@defproc[(first-or/c [contract contract?] ...)
|
||||
contract?]{
|
||||
|
||||
Takes any number of contracts and returns a contract that
|
||||
accepts any value that any one of the contracts accepts
|
||||
individually.
|
||||
|
||||
The @racket[first-or/c] result tests any value by applying the
|
||||
contracts in order from left to right. Thus, a contract
|
||||
such as @racket[(first-or/c (not/c real?) positive?)]
|
||||
is guaranteed to only invoke the
|
||||
@racket[positive?] predicate on real numbers.
|
||||
|
||||
If all of the arguments are procedures or @tech{flat
|
||||
contracts}, the result is a @tech{flat contract} and
|
||||
similarly if all of the arguments are @tech{chaperone
|
||||
contracts} the result is too. Otherwise, the result is an
|
||||
@tech{impersonator contract}.
|
||||
|
||||
If there are multiple higher-order contracts,
|
||||
@racket[first-or/c] uses @racket[contract-first-order-passes?]
|
||||
to distinguish between them. More precisely, when an
|
||||
@racket[first-or/c] is checked, it checks the first order passes
|
||||
of the first contract against the value. If it succeeds,
|
||||
then it uses only that contract. If it fails, then it moves
|
||||
to the second contract, continuing until it finds one of
|
||||
the contracts where the first order check succeeds. If none
|
||||
of them do, a contract violation is signaled.
|
||||
|
||||
For example, this contract
|
||||
@racketblock[
|
||||
(first-or/c (-> number? number?)
|
||||
(-> string? string? string?))]
|
||||
accepts the function @racket[(λ args 0)],
|
||||
applying the @racket[(->number? number?)] contract to the function
|
||||
because it comes first, even though
|
||||
@racket[(-> string? string? string?)] also applies.
|
||||
|
||||
If all of its arguments are @racket[list-contract?]s, then @racket[first-or/c]
|
||||
returns a @racket[list-contract?].
|
||||
}
|
||||
|
||||
@defproc[(and/c [contract contract?] ...) contract?]{
|
||||
|
@ -217,7 +255,7 @@ the contracts in order, from left to right.}
|
|||
|
||||
@defproc[(not/c [flat-contract flat-contract?]) flat-contract?]{
|
||||
|
||||
Accepts a flat contracts or a predicate and returns a flat contract
|
||||
Accepts a flat contract or a predicate and returns a flat contract
|
||||
that checks the inverse of the argument.}
|
||||
|
||||
|
||||
|
@ -328,7 +366,12 @@ is a chaperone contract, then the result will be a chaperone contract.
|
|||
|
||||
When a higher-order @racket[vectorof] contract is applied to a vector, the result
|
||||
is not @racket[eq?] to the input. The result will be a copy for immutable vectors
|
||||
and a @tech{chaperone} or @tech{impersonator} of the input for mutable vectors.}
|
||||
and a @tech{chaperone} or @tech{impersonator} of the input for mutable vectors,
|
||||
unless the @racket[c] argument is a flat contract and the vector is immutable,
|
||||
in which case the result is the original vector.
|
||||
|
||||
@history[#:changed "6.3.0.5" @list{Changed flat vector contracts to not copy
|
||||
immutable vectors.}]}
|
||||
|
||||
|
||||
@defproc[(vector-immutableof [c contract?]) contract?]{
|
||||
|
@ -397,13 +440,14 @@ Returns a contract that recognizes a list whose every element matches
|
|||
the contract @racket[c]. Beware that when this contract is applied to
|
||||
a value, the result is not necessarily @racket[eq?] to the input.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract some-numbers
|
||||
(listof number?)
|
||||
(list 1 2 3))
|
||||
(define/contract just-one-number
|
||||
(listof number?)
|
||||
11)]
|
||||
(eval:error
|
||||
(define/contract just-one-number
|
||||
(listof number?)
|
||||
11))]
|
||||
|
||||
}
|
||||
|
||||
|
@ -414,14 +458,15 @@ Returns a contract that recognizes non-empty lists whose elements match
|
|||
the contract @racket[c]. Beware that when this contract is applied to
|
||||
a value, the result is not necessarily @racket[eq?] to the input.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract some-numbers
|
||||
(non-empty-listof number?)
|
||||
(list 1 2 3))
|
||||
|
||||
(define/contract not-enough-numbers
|
||||
(non-empty-listof number?)
|
||||
(list))]
|
||||
(eval:error
|
||||
(define/contract not-enough-numbers
|
||||
(non-empty-listof number?)
|
||||
(list)))]
|
||||
}
|
||||
|
||||
@defproc[(list*of [c contract?]) contract?]{
|
||||
|
@ -433,14 +478,15 @@ its @racket[cdr] position is expected to be @racket[(list*of c)]. Otherwise,
|
|||
it is expected to match @racket[c]. Beware that when this contract is applied to
|
||||
a value, the result is not necessarily @racket[eq?] to the input.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract improper-numbers
|
||||
(list*of number?)
|
||||
(cons 1 (cons 2 3)))
|
||||
|
||||
(define/contract not-improper-numbers
|
||||
(list*of number?)
|
||||
(list 1 2 3))]
|
||||
(eval:error
|
||||
(define/contract not-improper-numbers
|
||||
(list*of number?)
|
||||
(list 1 2 3)))]
|
||||
|
||||
@history[#:added "6.1.1.1"]
|
||||
}
|
||||
|
@ -456,14 +502,15 @@ necessarily @racket[eq?] to the input.
|
|||
If the @racket[cdr-c] contract is a @racket[list-contract?], then
|
||||
@racket[cons/c] returns a @racket[list-contract?].
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract a-pair-of-numbers
|
||||
(cons/c number? number?)
|
||||
(cons 1 2))
|
||||
|
||||
(define/contract not-a-pair-of-numbers
|
||||
(cons/c number? number?)
|
||||
(cons #f #t))]
|
||||
(eval:error
|
||||
(define/contract not-a-pair-of-numbers
|
||||
(cons/c number? number?)
|
||||
(cons #f #t)))]
|
||||
|
||||
@history[#:changed "6.0.1.13" @list{Added the @racket[list-contract?] propagating behavior.}]
|
||||
}
|
||||
|
@ -482,14 +529,15 @@ In the first case, the contract on the @racket[cdr-id] portion of the contract
|
|||
may depend on the value in the @racket[car-id] portion of the pair and in
|
||||
the second case, the reverse is true.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract an-ordered-pair-of-reals
|
||||
(cons/dc [hd real?] [tl (hd) (>=/c hd)])
|
||||
(cons 1 2))
|
||||
|
||||
(define/contract not-an-ordered-pair-of-reals
|
||||
(cons/dc [hd real?] [tl (hd) (>=/c hd)])
|
||||
(cons 2 1))]
|
||||
(eval:error
|
||||
(define/contract not-an-ordered-pair-of-reals
|
||||
(cons/dc [hd real?] [tl (hd) (>=/c hd)])
|
||||
(cons 2 1)))]
|
||||
|
||||
@history[#:added "6.1.1.6"]
|
||||
}
|
||||
|
@ -610,7 +658,7 @@ Produces a contract on parameters whose values must match
|
|||
@racket[_out]. When the value in the contracted parameter
|
||||
is set, it must match @racket[_in].
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract current-snack
|
||||
(parameter/c string?)
|
||||
(make-parameter "potato-chip"))
|
||||
|
@ -620,9 +668,10 @@ is set, it must match @racket[_in].
|
|||
(parameter/c string? baked/c)
|
||||
(make-parameter "turkey" (λ (s) (string-append "roasted " s))))
|
||||
|
||||
(current-snack 'not-a-snack)
|
||||
(parameterize ([current-dinner "tofurkey"])
|
||||
(current-dinner))
|
||||
(eval:error (current-snack 'not-a-snack))
|
||||
(eval:error
|
||||
(parameterize ([current-dinner "tofurkey"])
|
||||
(current-dinner)))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -640,18 +689,18 @@ Produces a contract for procedures that accept @racket[n] argument
|
|||
Produces a contract that recognizes @racket[hash] tables with keys and values
|
||||
as specified by the @racket[key] and @racket[val] arguments.
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract good-hash
|
||||
(hash/c integer? boolean?)
|
||||
(hash 1 #t
|
||||
2 #f
|
||||
3 #t))
|
||||
(define/contract bad-hash
|
||||
(hash/c integer? boolean?)
|
||||
(hash 1 "elephant"
|
||||
2 "monkey"
|
||||
3 "manatee"))]
|
||||
(eval:error
|
||||
(define/contract bad-hash
|
||||
(hash/c integer? boolean?)
|
||||
(hash 1 "elephant"
|
||||
2 "monkey"
|
||||
3 "manatee")))]
|
||||
|
||||
There are a number of technicalities that control how @racket[hash/c] contracts
|
||||
behave.
|
||||
|
@ -660,17 +709,15 @@ behave.
|
|||
a flat contract, and the @racket[key] and @racket[val] arguments must also be flat
|
||||
contracts.
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(flat-contract? (hash/c integer? boolean?))
|
||||
(flat-contract? (hash/c integer? boolean? #:flat? #t))
|
||||
(hash/c integer? (-> integer? integer?) #:flat? #t)]
|
||||
(eval:error (hash/c integer? (-> integer? integer?) #:flat? #t))]
|
||||
|
||||
Such flat contracts will be unsound if applied to mutable hash tables,
|
||||
as they will not check future mutations to the hash table.
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define original-h (make-hasheq))
|
||||
(define/contract ctc-h
|
||||
(hash/c integer? boolean? #:flat? #t)
|
||||
|
@ -682,15 +729,13 @@ If the @racket[immutable] argument is @racket[#t] and the @racket[key] and
|
|||
@racket[val] arguments are @racket[flat-contract?]s, the result will be a
|
||||
@racket[flat-contract?].
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(flat-contract? (hash/c integer? boolean? #:immutable #t))]
|
||||
|
||||
If either the domain or the range is a @racket[chaperone-contract?], then the result will
|
||||
be a @racket[chaperone-contract?].
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(flat-contract? (hash/c (-> integer? integer?) boolean?
|
||||
#:immutable #t))
|
||||
(chaperone-contract? (hash/c (-> integer? integer?) boolean?
|
||||
|
@ -701,11 +746,11 @@ be a @racket[chaperone-contract?].
|
|||
If the @racket[key] argument is a @racket[chaperone-contract?] but not a
|
||||
@racket[flat-contract?], then the resulting contract
|
||||
can be applied only to @racket[equal?]-based hash tables.
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
(define/contract h
|
||||
(hash/c (-> integer? integer?) any/c)
|
||||
(make-hasheq))]
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(eval:error
|
||||
(define/contract h
|
||||
(hash/c (-> integer? integer?) any/c)
|
||||
(make-hasheq)))]
|
||||
Also, when such a @racket[hash/c] contract is applied to a hash table, the result is not
|
||||
@racket[eq?]
|
||||
to the input. The result of applying the contract will be a copy for immutable hash tables,
|
||||
|
@ -734,16 +779,16 @@ for mutable hash tables.
|
|||
and it may also be @racket['impersonator], in which case they may be any @racket[contract?]s.
|
||||
The default is @racket['chaperone].
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract h
|
||||
(hash/dc [k real?] [v (k) (>=/c k)])
|
||||
(hash 1 3
|
||||
2 4))
|
||||
(define/contract h
|
||||
(hash/dc [k real?] [v (k) (>=/c k)])
|
||||
(hash 3 1
|
||||
4 2))]
|
||||
(eval:error
|
||||
(define/contract h
|
||||
(hash/dc [k real?] [v (k) (>=/c k)])
|
||||
(hash 3 1
|
||||
4 2)))]
|
||||
|
||||
|
||||
}
|
||||
|
@ -758,12 +803,12 @@ is a chaperone contract. Otherwise, the resulting contract is an impersonator
|
|||
contract. When a channel contract is applied to a channel, the resulting channel
|
||||
is not @racket[eq?] to the input.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract chan
|
||||
(channel/c string?)
|
||||
(make-channel))
|
||||
(thread (λ () (channel-get chan)))
|
||||
(channel-put chan 'not-a-string)
|
||||
(eval:error (channel-put chan 'not-a-string))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -789,19 +834,20 @@ If @racket[maybe-call/cc] is provided, then the provided contracts
|
|||
are used to check the return values from a continuation captured with
|
||||
@racket[call-with-current-continuation].
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract tag
|
||||
(prompt-tag/c (-> number? string?))
|
||||
(make-continuation-prompt-tag))
|
||||
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(number->string
|
||||
(call-with-composable-continuation
|
||||
(lambda (k)
|
||||
(abort-current-continuation tag k)))))
|
||||
tag
|
||||
(lambda (k) (k "not a number")))
|
||||
(eval:error
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(number->string
|
||||
(call-with-composable-continuation
|
||||
(lambda (k)
|
||||
(abort-current-continuation tag k)))))
|
||||
tag
|
||||
(lambda (k) (k "not a number"))))
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -815,17 +861,18 @@ If the argument @racket[contract] is a chaperone contract, the resulting
|
|||
contract will also be a @tech{chaperone} contract. Otherwise, the contract is
|
||||
an @tech{impersonator} contract.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract mark-key
|
||||
(continuation-mark-key/c (-> symbol? (listof symbol?)))
|
||||
(make-continuation-mark-key))
|
||||
|
||||
(with-continuation-mark
|
||||
mark-key
|
||||
(lambda (s) (append s '(truffle fudge ganache)))
|
||||
(let ([mark-value (continuation-mark-set-first
|
||||
(current-continuation-marks) mark-key)])
|
||||
(mark-value "chocolate-bar")))
|
||||
(eval:error
|
||||
(with-continuation-mark
|
||||
mark-key
|
||||
(lambda (s) (append s '(truffle fudge ganache)))
|
||||
(let ([mark-value (continuation-mark-set-first
|
||||
(current-continuation-marks) mark-key)])
|
||||
(mark-value "chocolate-bar"))))
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -837,7 +884,7 @@ Returns a contract that recognizes @tech{synchronizable event}s whose
|
|||
The resulting contract is always a @tech{chaperone} contract and its
|
||||
arguments must all be chaperone contracts.
|
||||
|
||||
@defexamples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract my-evt
|
||||
(evt/c evt?)
|
||||
always-evt)
|
||||
|
@ -845,7 +892,7 @@ arguments must all be chaperone contracts.
|
|||
(evt/c number? number?)
|
||||
(alarm-evt (+ (current-inexact-milliseconds) 50)))
|
||||
(sync my-evt)
|
||||
(sync failing-evt)
|
||||
(eval:error (sync failing-evt))
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1047,18 +1094,21 @@ symbols, and that return a symbol.
|
|||
}
|
||||
|
||||
@defform*/subs[#:literals (any values)
|
||||
[(->i (mandatory-dependent-dom ...)
|
||||
[(->i maybe-chaperone
|
||||
(mandatory-dependent-dom ...)
|
||||
dependent-rest
|
||||
pre-condition
|
||||
dependent-range
|
||||
post-condition)
|
||||
(->i (mandatory-dependent-dom ...)
|
||||
(->i maybe-chaperone
|
||||
(mandatory-dependent-dom ...)
|
||||
(optional-dependent-dom ...)
|
||||
dependent-rest
|
||||
pre-condition
|
||||
dependent-range
|
||||
post-condition)]
|
||||
([mandatory-dependent-dom id+ctc
|
||||
([maybe-chaperone #:chaperone (code:line)]
|
||||
[mandatory-dependent-dom id+ctc
|
||||
(code:line keyword id+ctc)]
|
||||
[optional-dependent-dom id+ctc
|
||||
(code:line keyword id+ctc)]
|
||||
|
@ -1093,6 +1143,12 @@ combinator in that each argument and result is named and these names can
|
|||
be used in the subcontracts and in the pre-/post-condition clauses.
|
||||
In other words, @racket[->i] expresses dependencies among arguments and results.
|
||||
|
||||
The optional first keyword argument to @racket[->i] indicates if the result
|
||||
contract will be a chaperone. If it is @racket[#:chaperone], all of the contract for the arguments
|
||||
and results must be chaperone contracts and the result of @racket[->i] will be
|
||||
a chaperone contract. If it is not present, then the result
|
||||
contract will not be a chaperone contract.
|
||||
|
||||
The first sub-form of a @racket[->i] contract covers the mandatory and the
|
||||
second sub-form covers the optional arguments. Following that is an optional
|
||||
rest-args contract, and an optional pre-condition. The pre-condition is
|
||||
|
@ -1329,14 +1385,14 @@ by some @racket[x] in positive position with respect to @racket[parametric->/c])
|
|||
are checked for the appropriate wrapper. If they have it, they are unwrapped;
|
||||
if they do not, a contract violation is signaled.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define/contract (check x y)
|
||||
(parametric->/c [X] (boolean? X . -> . X))
|
||||
(if (or (not x) (equal? y 'surprise))
|
||||
'invalid
|
||||
y))
|
||||
(check #t 'ok)
|
||||
(check #f 'ignored)
|
||||
(eval:error (check #f 'ignored))
|
||||
(check #t 'surprise)
|
||||
]
|
||||
}
|
||||
|
@ -1546,8 +1602,7 @@ the export.
|
|||
should be reported in terms of the public module instead of the
|
||||
private one.
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(module private-implementation racket/base
|
||||
(require racket/contract)
|
||||
(define (recip x) (/ 1 x))
|
||||
|
@ -1560,7 +1615,7 @@ the export.
|
|||
(provide (recontract-out recip)))
|
||||
|
||||
(require 'public)
|
||||
(recip +nan.0)]
|
||||
(eval:error (recip +nan.0))]
|
||||
|
||||
Replacing the use of @racket[recontract-out] with just
|
||||
@racket[recip] would result in a contract violation blaming
|
||||
|
@ -1628,7 +1683,7 @@ For the definition of @racket[free-var-list], see @racket[with-contract].
|
|||
(-> real? real?)
|
||||
(* 660 fr))
|
||||
(code:comment "a contract violation expected here:")
|
||||
(furlongs->feet "not a furlong")
|
||||
(eval:error (furlongs->feet "not a furlong"))
|
||||
]
|
||||
|
||||
The @racket[define/contract] form treats the individual definition as
|
||||
|
@ -1639,7 +1694,7 @@ positions of the contract. Since the contract boundary is
|
|||
between the definition and the surrounding context, references to
|
||||
@racket[id] inside the @racket[define/contract] form are not checked.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(code:comment "an unsual predicate that prints when called")
|
||||
(define (printing-int? x)
|
||||
(displayln "I was called")
|
||||
|
@ -1649,7 +1704,7 @@ between the definition and the surrounding context, references to
|
|||
(if (zero? n)
|
||||
1
|
||||
(* n (fact (sub1 n)))))
|
||||
(fact 5) (code:comment "only prints twice, not for each recursive call")
|
||||
(code:line (fact 5) (code:comment "only prints twice, not for each recursive call"))
|
||||
]
|
||||
|
||||
If a free-var-list is given, then any uses of the free variables
|
||||
|
@ -1657,7 +1712,7 @@ inside the @racket[body] will be protected with contracts that
|
|||
blame the context of the @racket[define/contract] form for the positive
|
||||
positions and the @racket[define/contract] form for the negative ones.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define (integer->binary-string n)
|
||||
(number->string n 2))
|
||||
(define/contract (numbers->strings lst)
|
||||
|
@ -1665,7 +1720,7 @@ positions and the @racket[define/contract] form for the negative ones.
|
|||
#:freevar integer->binary-string (-> exact-integer? string?)
|
||||
(code:comment "mistake, lst might contain inexact numbers")
|
||||
(map integer->binary-string lst))
|
||||
(numbers->strings '(4.0 3.3 5.8))
|
||||
(eval:error (numbers->strings '(4.0 3.3 5.8)))
|
||||
]}
|
||||
|
||||
@defform*[[(define-struct/contract struct-id ([field contract-expr] ...)
|
||||
|
@ -1682,15 +1737,15 @@ The @racket[define-struct/contract] form only allows a subset of the
|
|||
@racket[#:auto-value], @racket[#:omit-define-syntaxes], @racket[#:property] and
|
||||
@racket[#:omit-define-values].
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define-struct/contract fish ([color number?]))
|
||||
(make-fish 5)
|
||||
(make-fish #f)
|
||||
(eval:error (make-fish #f))
|
||||
|
||||
(define-struct/contract (salmon fish) ([ocean symbol?]))
|
||||
(make-salmon 5 'atlantic)
|
||||
(make-salmon 5 #f)
|
||||
(make-salmon #f 'pacific)
|
||||
(eval:error (make-salmon 5 #f))
|
||||
(eval:error (make-salmon #f 'pacific))
|
||||
]}
|
||||
|
||||
@defform[(invariant-assertion invariant-expr expr)]{
|
||||
|
@ -1707,7 +1762,7 @@ The @racket[define-struct/contract] form only allows a subset of the
|
|||
recursive calls, when an invariant is used on the right-hand
|
||||
side of a definition:
|
||||
|
||||
@examples[#:eval
|
||||
@examples[#:eval
|
||||
furlongs->feet-eval
|
||||
(define furlongss->feets
|
||||
(invariant-assertion
|
||||
|
@ -1723,7 +1778,7 @@ The @racket[define-struct/contract] form only allows a subset of the
|
|||
|
||||
(furlongss->feets (list 1 2 3))
|
||||
|
||||
(furlongss->feets (list 1 327 3))]
|
||||
(eval:error (furlongss->feets (list 1 327 3)))]
|
||||
|
||||
@history[#:added "6.0.1.11"]
|
||||
|
||||
|
@ -1767,8 +1822,7 @@ The @racket[define-struct/contract] form only allows a subset of the
|
|||
it can be any of the things that the third argument to @racket[datum->syntax]
|
||||
can be.
|
||||
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(module server racket/base
|
||||
(require racket/contract/base)
|
||||
(define (f x) #f)
|
||||
|
@ -1780,8 +1834,8 @@ The @racket[define-struct/contract] form only allows a subset of the
|
|||
(define (servers-fault) (g 1))
|
||||
(provide servers-fault clients-fault))
|
||||
(require 'client)
|
||||
(clients-fault)
|
||||
(servers-fault)]
|
||||
(eval:error (clients-fault))
|
||||
(eval:error (servers-fault))]
|
||||
|
||||
}
|
||||
|
||||
|
@ -1813,10 +1867,9 @@ produces @racket[#f], no name is printed. Otherwise, it is also formatted as by
|
|||
@racket[display]. More precisely, the @racket[value-name-expr] ends up in the
|
||||
@racket[blame-name] field of the blame record, which is used as the first portion
|
||||
of the error message.
|
||||
@examples[#:eval
|
||||
(contract-eval)
|
||||
(contract integer? #f 'pos 'neg 'timothy #f)
|
||||
(contract integer? #f 'pos 'neg #f #f)]
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(eval:error (contract integer? #f 'pos 'neg 'timothy #f))
|
||||
(eval:error (contract integer? #f 'pos 'neg #f #f))]
|
||||
|
||||
If specified, @racket[source-location-expr] indicates the source location
|
||||
reported by contract violations. The expression must produce a @racket[srcloc]
|
||||
|
@ -1922,11 +1975,14 @@ contracts is @racketresult[anonymous-chaperone-contract], and for flat
|
|||
contracts is @racketresult[anonymous-flat-contract].
|
||||
|
||||
The first-order predicate @racket[test] can be used to determine which values
|
||||
the contract applies to; usually, this is the set of values for which the
|
||||
the contract applies to; this must be the set of values for which the
|
||||
contract fails immediately without any higher-order wrapping. This test is used
|
||||
by @racket[contract-first-order-passes?], and indirectly by @racket[or/c] to
|
||||
determine which of multiple higher-order contracts to wrap a value with. The
|
||||
default test accepts any value.
|
||||
by @racket[contract-first-order-passes?], and indirectly by @racket[or/c]
|
||||
and @racket[from-or/c] to determine which higher-order contract to wrap a
|
||||
value with when there are multiple higher-order contracts to choose from.
|
||||
The default test accepts any value. The predicate should be influenced by
|
||||
the value of @racket[(contract-first-order-okay-to-give-up?)] (see it's documentation
|
||||
for more explanation).
|
||||
|
||||
The @racket[late-neg-proj] defines the behavior of applying the contract. If it is
|
||||
supplied, it accepts a blame object that does not have a value for
|
||||
|
@ -1948,6 +2004,14 @@ first-order test fails, and produces the value unchanged otherwise.
|
|||
The @racket[val-first-proj] is like @racket[late-neg-proj], except with
|
||||
an extra layer of currying.
|
||||
|
||||
At least one of the @racket[late-neg-proj], @racket[proj],
|
||||
@racket[val-first-proj], or @racket[first-order] must be non-@racket[#f].
|
||||
|
||||
The projection arguments (@racket[late-neg-proj], @racket[proj], and
|
||||
@racket[val-first-proj]) must be in sync with the @racket[test] argument.
|
||||
In particular, if the test argument returns @racket[#f] for some value,
|
||||
then the projections must raise a blame error for that value.
|
||||
|
||||
Projections for chaperone contracts must produce a value that passes
|
||||
@racket[chaperone-of?] when compared with the original, uncontracted value.
|
||||
Projections for flat contracts must fail precisely when the first-order test
|
||||
|
@ -1959,16 +2023,18 @@ flat contracts do not need to supply an explicit projection.
|
|||
|
||||
The @racket[stronger] argument is used to implement @racket[contract-stronger?]. The
|
||||
first argument is always the contract itself and the second argument is whatever
|
||||
was passed as the second argument to @racket[contract-stronger?].
|
||||
was passed as the second argument to @racket[contract-stronger?]. If no
|
||||
@racket[stronger] argument is supplied, then a default that compares its arguments
|
||||
with @racket[equal?] is used.
|
||||
|
||||
The @racket[is-list-contract?] argument is used by the @racket[list-contract?] predicate
|
||||
to determine if this is a contract that accepts only @racket[list?] values.
|
||||
|
||||
@defexamples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define int/c
|
||||
(make-flat-contract #:name 'int/c #:first-order integer?))
|
||||
(contract int/c 1 'positive 'negative)
|
||||
(contract int/c "not one" 'positive 'negative)
|
||||
(eval:error (contract int/c "not one" 'positive 'negative))
|
||||
(int/c 1)
|
||||
(int/c "not one")
|
||||
(define int->int/c
|
||||
|
@ -1987,12 +2053,12 @@ to determine if this is a contract that accepts only @racket[list?] values.
|
|||
b f
|
||||
'(expected "a function of one argument" given: "~e")
|
||||
f)))))))
|
||||
(contract int->int/c "not fun" 'positive 'negative)
|
||||
(eval:error (contract int->int/c "not fun" 'positive 'negative))
|
||||
(define halve
|
||||
(contract int->int/c (λ (x) (/ x 2)) 'positive 'negative))
|
||||
(halve 2)
|
||||
(halve 1/2)
|
||||
(halve 1)
|
||||
(eval:error (halve 1/2))
|
||||
(eval:error (halve 1))
|
||||
]
|
||||
|
||||
@history[#:changed "6.0.1.13" @list{Added the @racket[#:list-contract?] argument.}]
|
||||
|
@ -2057,12 +2123,69 @@ contracts. The error messages assume that the function named by
|
|||
@history[#:added "6.1.1.5"]
|
||||
}
|
||||
|
||||
@defproc[(get/build-late-neg-projection [c contract?])
|
||||
(-> contract? blame? (-> any/c any/c any/c))]{
|
||||
Returns the @racket[_late-neg] projection for @racket[c].
|
||||
|
||||
If @racket[c] does not have a @racket[_late-neg] contract,
|
||||
then this function uses the original projection for it
|
||||
and logs a warning to the @racket['racket/contract] logger.
|
||||
|
||||
See @racket[make-contract] for more details.
|
||||
|
||||
@history[#:added "6.2.900.11"]
|
||||
}
|
||||
|
||||
@defparam[skip-projection-wrapper? wrap? boolean? #:value #f]{
|
||||
The functions @racket[make-chaperone-contract] and
|
||||
@racket[build-chaperone-contract-property] wrap their
|
||||
arguments to ensure that the result of the projections
|
||||
are chaperones of the input. This layer of wrapping can,
|
||||
in some cases, introduce unwanted overhead into contract
|
||||
checking. If this parameter's value is @racket[#t]
|
||||
during the dynamic extent of the call to either of those
|
||||
functions, the wrapping (and thus the checks) are skipped.
|
||||
}
|
||||
|
||||
@subsection{Blame Objects}
|
||||
|
||||
@defproc[(blame? [x any/c]) boolean?]{
|
||||
This predicate recognizes @|blame-objects|.
|
||||
}
|
||||
|
||||
@defproc[(raise-blame-error [b blame?]
|
||||
[x any/c]
|
||||
[fmt (or/c string?
|
||||
(listof (or/c string?
|
||||
'given 'given:
|
||||
'expected 'expected:)))]
|
||||
[v any/c] ...)
|
||||
none/c]{
|
||||
|
||||
Signals a contract violation. The first argument, @racket[b], records the
|
||||
current blame information, including positive and negative parties, the name of
|
||||
the contract, the name of the value, and the source location of the contract
|
||||
application. The second argument, @racket[x], is the value that failed to
|
||||
satisfy the contract.
|
||||
|
||||
The remaining arguments are a format string,
|
||||
@racket[fmt], and its arguments, @racket[v ...], specifying an error message
|
||||
specific to the precise violation.
|
||||
|
||||
If @racket[fmt] is a list, then the elements are concatenated together
|
||||
(with spaces added, unless there are already spaces at the ends of the strings),
|
||||
after first replacing symbols with either their string counterparts, or
|
||||
replacing @racket['given] with @racket["produced"] and
|
||||
@racket['expected] with @racket["promised"], depending on whether or not
|
||||
the @racket[b] argument has been swapped or not (see @racket[blame-swap]).
|
||||
|
||||
If @racket[fmt] contains the symbols @racket['given:] or @racket['expected:],
|
||||
they are replaced like @racket['given:] and @racket['expected:] are, but
|
||||
the replacements are prefixed with the string @racket["\n "] to conform
|
||||
to the error message guidelines in @secref["err-msg-conventions"].
|
||||
|
||||
}
|
||||
|
||||
@defproc[(blame-add-context [blame blame?]
|
||||
[context (or/c string? #f)]
|
||||
[#:important important (or/c string? #f) #f]
|
||||
|
@ -2078,12 +2201,12 @@ contracts. The error messages assume that the function named by
|
|||
or @racket["a conjunct of"] (in the case of an @racket[and/c] contract).
|
||||
|
||||
For example, consider this contract violation:
|
||||
@interaction[#:eval (contract-eval)
|
||||
@examples[#:label #f #:eval (contract-eval) #:once
|
||||
(define/contract f
|
||||
(list/c (-> integer? integer?))
|
||||
(list (λ (x) x)))
|
||||
|
||||
((car f) #f)
|
||||
(eval:error ((car f) #f))
|
||||
]
|
||||
It shows that the portion of the contract being violated is the first
|
||||
occurrence of @racket[integer?], because the @racket[->] and
|
||||
|
@ -2163,39 +2286,18 @@ the other; both are provided for convenience and clarity.
|
|||
and negative parties of @racket[b] respectively.
|
||||
}
|
||||
|
||||
@defproc[(raise-blame-error [b blame?]
|
||||
[x any/c]
|
||||
[fmt (or/c string?
|
||||
(listof (or/c string?
|
||||
'given 'given:
|
||||
'expected 'expected:)))]
|
||||
[v any/c] ...)
|
||||
none/c]{
|
||||
|
||||
Signals a contract violation. The first argument, @racket[b], records the
|
||||
current blame information, including positive and negative parties, the name of
|
||||
the contract, the name of the value, and the source location of the contract
|
||||
application. The second argument, @racket[x], is the value that failed to
|
||||
satisfy the contract.
|
||||
|
||||
The remaining arguments are a format string,
|
||||
@racket[fmt], and its arguments, @racket[v ...], specifying an error message
|
||||
specific to the precise violation.
|
||||
|
||||
If @racket[fmt] is a list, then the elements are concatenated together
|
||||
(with spaces added, unless there are already spaces at the ends of the strings),
|
||||
after first replacing symbols with either their string counterparts, or
|
||||
replacing @racket['given] with @racket["produced"] and
|
||||
@racket['expected] with @racket["promised"], depending on whether or not
|
||||
the @racket[b] argument has been swapped or not (see @racket[blame-swap]).
|
||||
|
||||
If @racket[fmt] contains the symbols @racket['given:] or @racket['expected:],
|
||||
they are replaced like @racket['given:] and @racket['expected:] are, but
|
||||
the replacements are prefixed with the string @racket["\n "] to conform
|
||||
to the error message guidelines in @secref["err-msg-conventions"].
|
||||
|
||||
@defproc[(blame-missing-party? [b blame?]) boolean?]{
|
||||
Returns @racket[#t] when @racket[b] does not have both parties.
|
||||
}
|
||||
|
||||
@defproc[(blame-add-missing-party [b (and/c blame? blame-missing-party?)]
|
||||
[missing-party any/c])
|
||||
(and/c blame? (not/c blame-missing-party?))]{
|
||||
Produces a new blame object like @racket[b], except that the missing
|
||||
party is replaced with @racket[missing-party].
|
||||
}
|
||||
|
||||
|
||||
@defstruct[(exn:fail:contract:blame exn:fail:contract) ([object blame?])]{
|
||||
This exception is raised to signal a contract error. The @racket[object]
|
||||
field contains a @|blame-object| associated with a contract violation.
|
||||
|
@ -2217,7 +2319,7 @@ returns a string that is put into the contract error
|
|||
message. Note that the value is often already included in
|
||||
the message that indicates the violation.
|
||||
|
||||
@defexamples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(define (show-blame-error blame value message)
|
||||
(string-append
|
||||
"Contract Violation!\n"
|
||||
|
@ -2233,8 +2335,8 @@ the message that indicates the violation.
|
|||
(-> integer? integer?)
|
||||
(/ x 2))
|
||||
(f 2)
|
||||
(f 1)
|
||||
(f 1/2)
|
||||
(eval:error (f 1))
|
||||
(eval:error (f 1/2))
|
||||
]
|
||||
|
||||
}
|
||||
|
@ -2282,10 +2384,17 @@ is expected to be the contract on the value).
|
|||
@defthing[impersonator-prop:blame impersonator-property?]
|
||||
)]{
|
||||
These properties attach a blame information to the protected structure,
|
||||
chaperone, or impersonator value. The function @racket[blame-contract?]
|
||||
chaperone, or impersonator value. The function @racket[has-blame?]
|
||||
returns @racket[#t] for values that have one of these properties, and
|
||||
@racket[blame-contract] extracts the value from the property (which
|
||||
is expected to be the blame record for the contract on the value).
|
||||
@racket[value-blame] extracts the value from the property.
|
||||
|
||||
The value is expected to be the blame record for the contract on the value or
|
||||
a @racket[cons]-pair of a blame record with a missing party and the missing
|
||||
party. The @racket[value-blame] function reassembles the arguments of the pair
|
||||
into a complete blame record using @racket[blame-add-missing-party]. If
|
||||
the value has one of the properties, but the value is not a blame object
|
||||
or a pair whose @racket[car] position is a blame object, then @racket[has-blame?]
|
||||
returns @racket[#f] but @racket[value-blame] returns @racket[#f].
|
||||
}
|
||||
|
||||
@deftogether[(
|
||||
|
@ -2448,34 +2557,39 @@ is expected to be the blame record for the contract on the value).
|
|||
(λ (c) (λ (fuel) (values void '())))]
|
||||
[#:list-contract? is-list-contract? (-> contract? boolean?) (λ (c) #f)])
|
||||
contract-property?])]{
|
||||
|
||||
@italic{The precise details of the
|
||||
@racket[val-first-projection] argument
|
||||
are subject to change. (Probably
|
||||
also the default values of the @racket[project]
|
||||
arguments will change.)}
|
||||
|
||||
|
||||
These functions build the arguments for @racket[prop:contract],
|
||||
@racket[prop:chaperone-contract], and @racket[prop:flat-contract], respectively.
|
||||
|
||||
A @deftech{contract property} specifies the behavior of a structure when used as
|
||||
a contract. It is specified in terms of five accessors: @racket[get-name],
|
||||
which produces a description to @racket[write] as part of a contract violation;
|
||||
@racket[get-first-order], which produces a first-order predicate to be used by
|
||||
@racket[contract-first-order-passes?]; @racket[get-projection], which
|
||||
produces a blame-tracking projection defining the behavior of the contract;
|
||||
@racket[stronger], which is a predicate that determines whether this contract
|
||||
(passed in the first argument) is stronger than some other contract (passed
|
||||
in the second argument); @racket[generate], which returns a thunk
|
||||
that generates random values matching the contract (using @racket[contract-random-generate-fail])
|
||||
to indicate failure) or @racket[#f] to indicate
|
||||
that random generation for this contract isn't supported; @racket[exercise],
|
||||
which returns a function that exercises values matching the contract (e.g.,
|
||||
if it is a function contract, it may call the function) and a list of contracts
|
||||
whose values will be generated by this process; and @racket[is-flat-contract?],
|
||||
which is used by @racket[flat-contract?] to determine if this contract
|
||||
accepts only @racket[list?]s.
|
||||
a contract. It is specified in terms of seven properties:
|
||||
@itemlist[
|
||||
@item{@racket[get-name] which produces a description to @racket[write] as part
|
||||
of a contract violation;}
|
||||
@item{@racket[get-first-order], which produces a first-order predicate to be
|
||||
used by @racket[contract-first-order-passes?];}
|
||||
@item{@racket[get-late-neg-projection], which produces a blame-tracking projection
|
||||
defining the behavior of the contract (The @racket[get-projection]
|
||||
and @racket[get-val-first-projection] arguments also specify the projection,
|
||||
but using a different signature. They are here for backwards compatibility.);}
|
||||
@item{@racket[stronger], a predicate that determines whether this
|
||||
contract (passed in the first argument) is stronger than some other
|
||||
contract (passed in the second argument) and whose default always
|
||||
returns @racket[#f];}
|
||||
@item{@racket[generate], which returns a thunk that generates random values
|
||||
matching the contract (using @racket[contract-random-generate-fail])
|
||||
to indicate failure) or @racket[#f] to indicate that random
|
||||
generation for this contract isn't supported;}
|
||||
@item{@racket[exercise], which returns a function that exercises values
|
||||
matching the contract (e.g., if it is a function contract, it may call
|
||||
the function) and a list of contracts whose values will be generated
|
||||
by this process;}
|
||||
@item{and @racket[is-list-contract?], which is used by @racket[flat-contract?]
|
||||
to determine if this contract accepts only @racket[list?]s.}
|
||||
]
|
||||
|
||||
At least one of the @racket[late-neg-proj], @racket[proj],
|
||||
@racket[val-first-proj], or @racket[first-order] must be non-@racket[#f].
|
||||
|
||||
These accessors are passed as (optional) keyword arguments to
|
||||
@racket[build-contract-property], and are applied to instances of the
|
||||
|
@ -2615,17 +2729,20 @@ are below):
|
|||
Returns @racket[#t] if the contract @racket[x] accepts either fewer
|
||||
or the same number of values as @racket[y] does.
|
||||
|
||||
Contracts that are the same (i.e., where @racket[x] is @racket[equal?]
|
||||
to @racket[y]) are considered to always be stronger than each other.
|
||||
|
||||
This function is conservative, so it may return @racket[#f] when
|
||||
@racket[x] does, in fact, accept fewer values.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(contract-stronger? integer? integer?)
|
||||
(contract-stronger? (between/c 25 75) (between/c 0 100))
|
||||
(contract-stronger? (between/c 0 100) (between/c 25 75))
|
||||
(contract-stronger? (between/c -10 0) (between/c 0 10))
|
||||
|
||||
(contract-stronger? (λ (x) (and (real? x) (<= x (random 10))))
|
||||
(λ (x) (and (real? x) (<= x (+ 100 (random 10))))))]
|
||||
(contract-stronger? (λ (x) (and (real? x) (<= x 0)))
|
||||
(λ (x) (and (real? x) (<= x 100))))]
|
||||
|
||||
|
||||
}
|
||||
|
@ -2641,7 +2758,11 @@ If it returns @racket[#f], the contract is guaranteed not to
|
|||
hold for that value; if it returns @racket[#t], the contract
|
||||
may or may not hold. If the contract is a first-order
|
||||
contract, a result of @racket[#t] guarantees that the
|
||||
contract holds.}
|
||||
contract holds.
|
||||
|
||||
See also @racket[contract-first-order-okay-to-give-up?] and
|
||||
@racket[contract-first-order-try-less-hard].
|
||||
}
|
||||
|
||||
@defproc[(contract-first-order [c contract?]) (-> any/c boolean?)]{
|
||||
Produces the first-order test used by @racket[or/c] to match values to
|
||||
|
@ -2727,8 +2848,28 @@ Produces the name used to describe the contract in error messages.
|
|||
@history[#:added "6.0.1.12"]
|
||||
}
|
||||
|
||||
@defproc[(contract-late-neg-projection [c contract?]) (-> blame? (-> any/c (or/c #f any/c) any/c))]{
|
||||
Produces the projection defining a contract's behavior.
|
||||
|
||||
The first argument, @racket[blame?] object encapsulates information about
|
||||
the contract checking, mostly used to create a meaningful error message if
|
||||
a contract violation is detected. The resulting function's first argument
|
||||
is the value that should have the contract and its second argument is
|
||||
a ``missing party'' from the blame object, to be passed to @racket[raise-contract-error].
|
||||
|
||||
If possible, use this function instead of @racket[contract-val-first-projection] or
|
||||
@racket[contract-projection].
|
||||
}
|
||||
|
||||
|
||||
@defproc[(contract-projection [c contract?]) (-> blame? (-> any/c any/c))]{
|
||||
Produces the projection defining a contract's behavior on protected values.
|
||||
Produces the projection defining a contract's behavior. See also
|
||||
@racket[contract-late-neg-projection].
|
||||
}
|
||||
|
||||
@defproc[(contract-val-first-projection [c contract?]) (-> blame? (-> any/c (-> any/c any/c)))]{
|
||||
Produces the projection defining a contract's behavior.
|
||||
See also @racket[contract-late-neg-projection].
|
||||
}
|
||||
|
||||
@defproc[(make-none/c [sexp-name any/c]) contract?]{
|
||||
|
@ -2772,13 +2913,15 @@ expression, then @racket[opt/c] raises an error using
|
|||
@racket[id] as the name of the primitive, instead of using
|
||||
the name @racket[opt/c].
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
(define/contract (f x)
|
||||
(opt/c '(not-a-contract))
|
||||
x)
|
||||
(define/contract (f x)
|
||||
(opt/c '(not-a-contract) #:error-name define/contract)
|
||||
x)]
|
||||
@examples[#:eval (contract-eval) #:once
|
||||
(eval:error
|
||||
(define/contract (f x)
|
||||
(opt/c '(not-a-contract))
|
||||
x))
|
||||
(eval:error
|
||||
(define/contract (f x)
|
||||
(opt/c '(not-a-contract) #:error-name define/contract)
|
||||
x))]
|
||||
}
|
||||
|
||||
|
||||
|
@ -2837,6 +2980,35 @@ currently being checked.
|
|||
@history[#:added "6.3"]
|
||||
}
|
||||
|
||||
@defform[(contract-first-order-okay-to-give-up?)]{
|
||||
This form returns a boolean that controls the result
|
||||
of first-order contact checks. More specifically, if
|
||||
it returns @racket[#t], then a first-order check may
|
||||
return @racket[#t] even when the entire first-order
|
||||
checks have not happened. If it returns @racket[#f]
|
||||
then the first order checks must continue until a
|
||||
definitive answer is returned.
|
||||
|
||||
This will only return @racket[#t] in the dynamic
|
||||
extent of @racket[or/c] or @racket[first-or/c]'s
|
||||
checking to determine which branch to use.
|
||||
|
||||
@history[#:added "6.3.0.9"]
|
||||
}
|
||||
@defform[(contract-first-order-try-less-hard e)]{
|
||||
Encourages first-order checks that happen in the
|
||||
dynamic-extent of @racket[e] to be more likely to
|
||||
give up. That is, makes it more likely that
|
||||
@racket[contract-first-order-okay-to-give-up?] might
|
||||
return @racket[#t].
|
||||
|
||||
If not in the dynamic-extent of @racket[or/c]'s or
|
||||
@racket[first-or/c]'s checking to determine the branch,
|
||||
then this form has no effect.
|
||||
|
||||
@history[#:added "6.3.0.9"]
|
||||
}
|
||||
|
||||
@defproc[(if/c [predicate (-> any/c any/c)]
|
||||
[then-contract contract?]
|
||||
[else-contract contract?])
|
||||
|
|
|
@ -455,7 +455,7 @@ The arguments implement the port as follows:
|
|||
|
||||
;; The port doesn't supply procedures to implement progress events:
|
||||
(port-provides-progress-evts? infinite-ones)
|
||||
(port-progress-evt infinite-ones)
|
||||
(eval:error (port-progress-evt infinite-ones))
|
||||
|
||||
;; Non-byte port results:
|
||||
(define infinite-voids
|
||||
|
@ -464,7 +464,7 @@ The arguments implement the port as follows:
|
|||
(lambda (s) (lambda args 'void))
|
||||
(lambda (skip s evt) (lambda args 'void))
|
||||
void))
|
||||
(read-char infinite-voids)
|
||||
(eval:error (read-char infinite-voids))
|
||||
(read-char-or-special infinite-voids)
|
||||
|
||||
;; This port produces 0, 1, 2, 0, 1, 2, etc., but it is not
|
||||
|
|
|
@ -47,25 +47,27 @@ angle brackets in @racket[write] and @racket[print] mode and no brackets in
|
|||
@racket[display] mode. Elements of the tuple are printed recursively,
|
||||
so that graph and cycle structure can be represented.
|
||||
|
||||
@defexamples[
|
||||
(define (tuple-print tuple port mode)
|
||||
(when mode (write-string "<" port))
|
||||
(let ([l (tuple-ref tuple)]
|
||||
[recur (case mode
|
||||
[(#t) write]
|
||||
[(#f) display]
|
||||
[else (lambda (p port) (print p port mode))])])
|
||||
(unless (zero? (vector-length l))
|
||||
(recur (vector-ref l 0) port)
|
||||
(for-each (lambda (e)
|
||||
(write-string ", " port)
|
||||
(recur e port))
|
||||
(cdr (vector->list l)))))
|
||||
(when mode (write-string ">" port)))
|
||||
@examples[
|
||||
(eval:no-prompt
|
||||
(define (tuple-print tuple port mode)
|
||||
(when mode (write-string "<" port))
|
||||
(let ([l (tuple-ref tuple)]
|
||||
[recur (case mode
|
||||
[(#t) write]
|
||||
[(#f) display]
|
||||
[else (lambda (p port) (print p port mode))])])
|
||||
(unless (zero? (vector-length l))
|
||||
(recur (vector-ref l 0) port)
|
||||
(for-each (lambda (e)
|
||||
(write-string ", " port)
|
||||
(recur e port))
|
||||
(cdr (vector->list l)))))
|
||||
(when mode (write-string ">" port))))
|
||||
|
||||
(struct tuple (ref)
|
||||
#:methods gen:custom-write
|
||||
[(define write-proc tuple-print)])
|
||||
(eval:no-prompt
|
||||
(struct tuple (ref)
|
||||
#:methods gen:custom-write
|
||||
[(define write-proc tuple-print)]))
|
||||
|
||||
(display (tuple #(1 2 "a")))
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
racket/generic))
|
||||
|
||||
@(define posn-eval (make-base-eval))
|
||||
@(interaction-eval #:eval posn-eval
|
||||
(require racket/match racket/stream (for-syntax racket/base)))
|
||||
@examples[#:hidden #:eval posn-eval
|
||||
(require racket/match racket/stream (for-syntax racket/base))]
|
||||
|
||||
@title[#:tag "define-struct"]{Defining Structure Types: @racket[struct]}
|
||||
|
||||
|
@ -141,7 +141,7 @@ multiple times, attaches a property value to the structure type; see
|
|||
(unless (and (real? temp) (>= temp -273.15))
|
||||
(error "not a valid temperature"))
|
||||
temp))
|
||||
(celsius -275)
|
||||
(eval:error (celsius -275))
|
||||
]
|
||||
|
||||
@margin-note{Use the @racket[prop:procedure] property to implement an
|
||||
|
@ -195,7 +195,7 @@ name, as do the various procedures that are bound by @racket[struct].
|
|||
@examples[#:eval posn-eval
|
||||
(struct circle (radius) #:reflection-name '<circle>)
|
||||
(circle 15)
|
||||
(circle-radius "bad")
|
||||
(eval:error (circle-radius "bad"))
|
||||
]
|
||||
|
||||
If @racket[#:methods gen:name method-defs] is provided, then
|
||||
|
@ -225,11 +225,12 @@ supplied, then the @racket[struct] form is equivalent to
|
|||
|
||||
@examples[#:eval posn-eval
|
||||
(struct square (side) #:omit-define-syntaxes)
|
||||
(match (square 5)
|
||||
(code:comment "fails to match because syntax is omitted")
|
||||
[(struct square x) x])
|
||||
(eval:error
|
||||
(match (square 5)
|
||||
(code:comment "fails to match because syntax is omitted")
|
||||
[(struct square x) x]))
|
||||
(struct ellipse (width height) #:omit-define-values)
|
||||
ellipse-width
|
||||
(eval:error ellipse-width)
|
||||
]
|
||||
|
||||
If @racket[#:auto] is supplied as a @racket[field-option], then the
|
||||
|
@ -247,20 +248,20 @@ error is reported. If any @racket[field-option] or
|
|||
@racket[struct-option] keyword is repeated, other than
|
||||
@racket[#:property], a syntax error is reported.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval posn-eval
|
||||
(struct posn (x y [z #:auto])
|
||||
#:auto-value 0
|
||||
#:transparent)
|
||||
(eval:no-prompt
|
||||
(struct posn (x y [z #:auto #:mutable])
|
||||
#:auto-value 0
|
||||
#:transparent))
|
||||
(posn 1 2)
|
||||
(posn? (posn 1 2))
|
||||
(posn-y (posn 1 2))
|
||||
]
|
||||
(posn-z (posn 1 2))
|
||||
|
||||
@defs+int[
|
||||
#:eval posn-eval
|
||||
[(struct color-posn posn (hue) #:mutable)
|
||||
(define cp (color-posn 1 2 "blue"))]
|
||||
(eval:no-prompt
|
||||
(struct color-posn posn (hue) #:mutable)
|
||||
(define cp (color-posn 1 2 "blue")))
|
||||
(color-posn-hue cp)
|
||||
cp
|
||||
(set-posn-z! cp 3)
|
||||
|
@ -280,11 +281,12 @@ expression is an exact, non-negative integer that corresponds to the
|
|||
position within the structure declaration of the field named by
|
||||
@racket[field-id].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval posn-eval
|
||||
(struct mood-procedure (base rating)
|
||||
#:property prop:procedure (struct-field-index base))
|
||||
(define happy+ (mood-procedure add1 10))
|
||||
(eval:no-prompt
|
||||
(struct mood-procedure (base rating)
|
||||
#:property prop:procedure (struct-field-index base))
|
||||
(define happy+ (mood-procedure add1 10)))
|
||||
(happy+ 2)
|
||||
(mood-procedure-rating happy+)
|
||||
]}
|
||||
|
@ -305,11 +307,12 @@ provided.
|
|||
This form is provided for backwards compatibility; @racket[struct] is
|
||||
preferred.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval posn-eval
|
||||
(define-struct posn (x y [z #:auto])
|
||||
#:auto-value 0
|
||||
#:transparent)
|
||||
(eval:no-prompt
|
||||
(define-struct posn (x y [z #:auto])
|
||||
#:auto-value 0
|
||||
#:transparent))
|
||||
(make-posn 1 2)
|
||||
(posn? (make-posn 1 2))
|
||||
(posn-y (make-posn 1 2))
|
||||
|
@ -326,20 +329,21 @@ the sub-form for error reporting is that it starts with @racket[id].
|
|||
The @racket[define-struct/derived] form is intended for use by macros
|
||||
that expand to @racket[define-struct].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval posn-eval
|
||||
(define-syntax (define-xy-struct stx)
|
||||
(syntax-case stx ()
|
||||
[(ds name . rest)
|
||||
(with-syntax ([orig stx])
|
||||
#'(define-struct/derived orig name (x y) . rest))]))
|
||||
(eval:no-prompt
|
||||
(define-syntax (define-xy-struct stx)
|
||||
(syntax-case stx ()
|
||||
[(ds name . rest)
|
||||
(with-syntax ([orig stx])
|
||||
#'(define-struct/derived orig name (x y) . rest))])))
|
||||
|
||||
(define-xy-struct posn)
|
||||
(posn-x (make-posn 1 2))
|
||||
(define-xy-struct posn #:mutable)
|
||||
(set-posn-x! (make-posn 1 2) 0)
|
||||
(code:comment "this next line will cause an error due to a bad keyword")
|
||||
(define-xy-struct posn #:bad-option)
|
||||
(eval:error (define-xy-struct posn #:bad-option))
|
||||
]}
|
||||
|
||||
@; ----------------------------------------
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt" scribble/eval (for-label racket/generic))
|
||||
@(require "mz.rkt" (for-label racket/generic))
|
||||
|
||||
@(define dict-eval (make-base-eval))
|
||||
@(interaction-eval #:eval dict-eval (require racket/dict racket/generic))
|
||||
@examples[#:hidden #:eval dict-eval (require racket/dict racket/generic)]
|
||||
|
||||
@title[#:tag "dicts"]{Dictionaries}
|
||||
|
||||
|
@ -200,12 +200,12 @@ result:
|
|||
@examples[
|
||||
#:eval dict-eval
|
||||
(dict-ref #hash((a . "apple") (b . "beer")) 'a)
|
||||
(dict-ref #hash((a . "apple") (b . "beer")) 'c)
|
||||
(eval:error (dict-ref #hash((a . "apple") (b . "beer")) 'c))
|
||||
(dict-ref #hash((a . "apple") (b . "beer")) 'c #f)
|
||||
(dict-ref '((a . "apple") (b . "banana")) 'b)
|
||||
(dict-ref #("apple" "banana") 1)
|
||||
(dict-ref #("apple" "banana") 3 #f)
|
||||
(dict-ref #("apple" "banana") -3 #f)
|
||||
(eval:error (dict-ref #("apple" "banana") -3 #f))
|
||||
]}
|
||||
|
||||
@defproc[(dict-set! [dict (and/c dict? (not/c immutable?))]
|
||||
|
@ -461,10 +461,10 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and
|
|||
|
||||
@examples[
|
||||
#:eval dict-eval
|
||||
(dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'a)
|
||||
(dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'a #f)
|
||||
(dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'c 'cabbage)
|
||||
(define h (make-hasheq '((a . "apple") (b . "beer"))))
|
||||
(dict-ref h 'c)
|
||||
(eval:error (dict-ref h 'c))
|
||||
(dict-ref! h 'c (λ () 'cabbage))
|
||||
(dict-ref h 'c)
|
||||
]}
|
||||
|
@ -486,7 +486,7 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and
|
|||
@examples[
|
||||
#:eval dict-eval
|
||||
(define h (make-hash))
|
||||
(dict-update! h 'a add1)
|
||||
(eval:error (dict-update! h 'a add1))
|
||||
(dict-update! h 'a add1 0)
|
||||
h
|
||||
(define v (vector #f #f #f))
|
||||
|
@ -512,7 +512,7 @@ Supported for any @racket[dict] that implements @racket[dict-ref] and
|
|||
|
||||
@examples[
|
||||
#:eval dict-eval
|
||||
(dict-update #hash() 'a add1)
|
||||
(eval:error (dict-update #hash() 'a add1))
|
||||
(dict-update #hash() 'a add1 0)
|
||||
(dict-update #hash((a . "apple") (b . "beer")) 'b string-length)
|
||||
]}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/struct
|
||||
scribble/eval
|
||||
"mz.rkt"
|
||||
(for-label racket/async-channel))
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ exception handler obtains control, and the handler itself is
|
|||
(+ 5 (raise (make-my-exception
|
||||
"failed"
|
||||
(current-continuation-marks)))))
|
||||
(raise 'failed #t)
|
||||
(eval:error (raise 'failed #t))
|
||||
]}
|
||||
|
||||
@defproc*[([(error [sym symbol?]) any]
|
||||
|
@ -145,9 +145,9 @@ In all cases, the constructed message string is passed to
|
|||
@racket[make-exn:fail], and the resulting exception is raised.
|
||||
|
||||
@examples[
|
||||
(error 'failed)
|
||||
(error "failed" 23 'pizza (list 1 2 3))
|
||||
(error 'method-a "failed because ~a" "no argument supplied")
|
||||
(eval:error (error 'failed))
|
||||
(eval:error (error "failed" 23 'pizza (list 1 2 3)))
|
||||
(eval:error (error 'method-a "failed because ~a" "no argument supplied"))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -187,17 +187,17 @@ message names the bad argument and also lists the other arguments. If
|
|||
(if (not (integer? bits))
|
||||
(raise-argument-error 'feed-machine "integer?" bits)
|
||||
"fed the machine"))
|
||||
(feed-machine 'turkey)
|
||||
(eval:error (feed-machine 'turkey))
|
||||
(define (feed-cow animal)
|
||||
(if (not (eq? animal 'cow))
|
||||
(raise-argument-error 'feed-cow "'cow" animal)
|
||||
"fed the cow"))
|
||||
(feed-cow 'turkey)
|
||||
(eval:error (feed-cow 'turkey))
|
||||
(define (feed-animals cow sheep goose cat)
|
||||
(if (not (eq? goose 'goose))
|
||||
(raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
|
||||
"fed the animals"))
|
||||
(feed-animals 'cow 'sheep 'dog 'cat)
|
||||
(eval:error (feed-animals 'cow 'sheep 'dog 'cat))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -224,10 +224,11 @@ using the error value conversion handler (see
|
|||
@racket[error-value->string-handler]).
|
||||
|
||||
@examples[
|
||||
(eval:error
|
||||
(raise-arguments-error 'eat
|
||||
"fish is smaller than its given meal"
|
||||
"fish" 12
|
||||
"meal" 13)
|
||||
"meal" 13))
|
||||
]}
|
||||
|
||||
|
||||
|
@ -254,10 +255,10 @@ less than} the size of a collection---for example, @racket[(sub1
|
|||
(vector-length _vec))], @racket[(sub1 (length _lst))], and so on.
|
||||
|
||||
@examples[
|
||||
(raise-range-error 'vector-ref "vector" "starting " 5 #(1 2 3 4) 0 3)
|
||||
(raise-range-error 'vector-ref "vector" "ending " 5 #(1 2 3 4) 0 3)
|
||||
(raise-range-error 'vector-ref "vector" "" 3 #() 0 -1)
|
||||
(raise-range-error 'vector-ref "vector" "ending " 1 #(1 2 3 4) 2 3 0)
|
||||
(eval:error (raise-range-error 'vector-ref "vector" "starting " 5 #(1 2 3 4) 0 3))
|
||||
(eval:error (raise-range-error 'vector-ref "vector" "ending " 5 #(1 2 3 4) 0 3))
|
||||
(eval:error (raise-range-error 'vector-ref "vector" "" 3 #() 0 -1))
|
||||
(eval:error (raise-range-error 'vector-ref "vector" "ending " 1 #(1 2 3 4) 2 3 0))
|
||||
]}
|
||||
|
||||
|
||||
|
|
|
@ -109,14 +109,14 @@ Like @racket[flsin], @racket[flcos], @racket[fltan], @racket[flasin],
|
|||
@defproc[(->extfl [a exact-integer?]) extflonum?]
|
||||
@defproc[(extfl->exact-integer [a extflonum?]) exact-integer?]
|
||||
@defproc[(real->extfl [a real?]) extflonum?]
|
||||
@defproc[(extfl->exact [a real?]) (and/c real? exact?)]
|
||||
@defproc[(extfl->inexact [a real?]) flonum?]
|
||||
@defproc[(extfl->exact [a extflonum?]) (and/c real? exact?)]
|
||||
@defproc[(extfl->inexact [a extflonum?]) flonum?]
|
||||
)]{
|
||||
|
||||
The first four are like @racket[->fl], @racket[fl->exact],
|
||||
@racket[fl->real], @racket[inexact->exact], but for @tech{extflonums}.
|
||||
The @racket[extfl->inexact] function converts a @tech{extflonum} to
|
||||
its closest @racket{flonum} approximation.}
|
||||
its closest @tech{flonum} approximation.}
|
||||
|
||||
@; ------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt" (for-label racket/fasl))
|
||||
|
||||
@(define fasl-eval (make-base-eval))
|
||||
@(interaction-eval #:eval fasl-eval (require racket/fasl))
|
||||
@examples[#:hidden #:eval fasl-eval (require racket/fasl)]
|
||||
|
||||
@title[#:tag "fasl"]{Fast-Load Serialization}
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
(delete-file i)))))
|
||||
(clean)
|
||||
(begin0
|
||||
(defexamples #:eval my-eval
|
||||
expr ...)
|
||||
(examples #:eval my-eval
|
||||
expr ...)
|
||||
(clean)))]))
|
||||
|
||||
"")
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
setup/cross-system))
|
||||
|
||||
@(define file-eval (make-base-eval))
|
||||
@(interaction-eval #:eval file-eval (begin (require racket/file) (define filename (make-temporary-file))))
|
||||
@examples[#:hidden #:eval file-eval
|
||||
(require racket/file)
|
||||
(define filename (make-temporary-file))]
|
||||
|
||||
|
||||
@title{Filesystem}
|
||||
|
@ -296,7 +298,7 @@ exists---to the path @racket[new]. If the file or directory is not
|
|||
renamed successfully, the @exnraise[exn:fail:filesystem].
|
||||
|
||||
This procedure can be used to move a file/directory to a different
|
||||
directory (on the same disk) as well as rename a file/directory within
|
||||
directory (on the same filesystem) as well as rename a file/directory within
|
||||
a directory. Unless @racket[exists-ok?] is provided as a true value,
|
||||
@racket[new] cannot refer to an existing file or directory. Even if
|
||||
@racket[exists-ok?] is true, @racket[new] cannot refer to an existing
|
||||
|
@ -639,13 +641,18 @@ In addition to the bindings described below,
|
|||
@tech{phase level} 1, since string constants are often used as
|
||||
compile-time expressions with @racket[define-runtime-path].
|
||||
|
||||
@defform[(define-runtime-path id expr)]{
|
||||
@defform[(define-runtime-path id maybe-runtime?-id expr)
|
||||
#:grammar ([maybe-runtime? code:blank
|
||||
(code:line #:runtime?-id runtime?-id)])]{
|
||||
|
||||
Uses @racket[expr] as both a compile-time (i.e., @tech{phase} 1)
|
||||
expression and a run-time (i.e., @tech{phase} 0) expression. In either
|
||||
context, @racket[expr] should produce a path, a string that represents
|
||||
a path, a list of the form @racket[(list 'lib _str ...+)], or a list
|
||||
of the form @racket[(list 'so _str)] or @racket[(list 'so _str _vers)].
|
||||
If @racket[runtime?-id] is provided, then it is bound in the context
|
||||
of @racket[expr] to @racket[#f] for the compile-time instance of
|
||||
@racket[expr] and @racket[#t] for the run-time instance of @racket[expr].
|
||||
|
||||
For run time, @racket[id] is bound to a path that is based on the
|
||||
result of @racket[expr]. The path is normally computed by taking a
|
||||
|
@ -779,23 +786,25 @@ Examples:
|
|||
[(windows) '(so "ssleay32")]
|
||||
[else '(so "libssl")]))
|
||||
(define libssl (ffi-lib libssl-so))
|
||||
]}
|
||||
]
|
||||
|
||||
@history[#:changed "6.4" @elem{Added @racket[#:runtime?-id].}]}
|
||||
|
||||
|
||||
@defform[(define-runtime-paths (id ...) expr)]{
|
||||
@defform[(define-runtime-paths (id ...) maybe-runtime?-id expr)]{
|
||||
|
||||
Like @racket[define-runtime-path], but declares and binds multiple
|
||||
paths at once. The @racket[expr] should produce as many values as
|
||||
@racket[id]s.}
|
||||
|
||||
|
||||
@defform[(define-runtime-path-list id expr)]{
|
||||
@defform[(define-runtime-path-list id maybe-runtime?-id expr)]{
|
||||
|
||||
Like @racket[define-runtime-path], but @racket[expr] should produce a
|
||||
list of paths.}
|
||||
|
||||
|
||||
@defform[(define-runtime-module-path-index id module-path-expr)]{
|
||||
@defform[(define-runtime-module-path-index id maybe-runtime?-id module-path-expr)]{
|
||||
|
||||
Similar to @racket[define-runtime-path], but @racket[id] is bound to a
|
||||
@tech{module path index} that encapsulates the result of
|
||||
|
@ -977,6 +986,7 @@ exists and is removed by another thread or process before
|
|||
|
||||
@defproc[(find-files [predicate (path? . -> . any/c)]
|
||||
[start-path (or/c path-string? #f) #f]
|
||||
[#:skip-filtered-directory? skip-filtered-directory? #f]
|
||||
[#:follow-links? follow-links? #f])
|
||||
(listof path?)]{
|
||||
|
||||
|
@ -997,6 +1007,10 @@ paths in the former case and relative paths in the latter. Another
|
|||
difference is that @racket[predicate] is not called for the current
|
||||
directory when @racket[start-path] is @racket[#f].
|
||||
|
||||
If @racket[skip-filtered-directory?] is true, then when
|
||||
@racket[predicate] returns @racket[#f] for a directory, the
|
||||
directory's content is not traversed.
|
||||
|
||||
If @racket[follow-links?] is true, the @racket[find-files] traversal
|
||||
follows links, and links are not included in the result. If
|
||||
@racket[follow-links?] is @racket[#f], then links are not followed,
|
||||
|
@ -1007,10 +1021,15 @@ directory, then @racket[predicate] will be called exactly once with
|
|||
@racket[start-path] as the argument.
|
||||
|
||||
The @racket[find-files] procedure raises an exception if it encounters
|
||||
a directory for which @racket[directory-list] fails.}
|
||||
a directory for which @racket[directory-list] fails.
|
||||
|
||||
@history[#:changed "6.3.0.11" @elem{Added the
|
||||
@racket[#:skip-filtered-directory?]
|
||||
argument.}]}
|
||||
|
||||
@defproc[(pathlist-closure [path-list (listof path-string?)]
|
||||
[#:follow-links? follow-links? #f])
|
||||
[#:path-filter path-filter (or/c #f (path? . -> . any/c)) #f]
|
||||
[#:follow-links? follow-links? any/c #f])
|
||||
(listof path?)]{
|
||||
|
||||
Given a list of paths, either absolute or relative to the current
|
||||
|
@ -1023,17 +1042,25 @@ directory, returns a list such that
|
|||
twice);}
|
||||
|
||||
@item{if a path refers to directory, all of its descendants are also
|
||||
included in the result;}
|
||||
included in the result, except as omitted by @racket[path-filter];}
|
||||
|
||||
@item{ancestor directories appear before their descendants in the
|
||||
result list.}
|
||||
result list, as long as they are not misordered in the given
|
||||
@racket[path-list].}
|
||||
|
||||
]
|
||||
|
||||
If @racket[path-filter] is a procedure, then it is applied to each
|
||||
descendant of a directory. If @racket[path-filter] returns
|
||||
@racket[#f], then the descendant (and any of its descendants, in the
|
||||
case of a subdirectory) are omitted from the result.
|
||||
|
||||
If @racket[follow-links?] is true, then the traversal of directories
|
||||
and files follows links, and the link paths are not included in the
|
||||
result. If @racket[follow-links?] is @racket[#f], then he result list
|
||||
includes paths to link and the links are not followed.}
|
||||
result. If @racket[follow-links?] is @racket[#f], then the result list
|
||||
includes paths to link and the links are not followed.
|
||||
|
||||
@history[#:changed "6.3.0.11" @elem{Added the @racket[#:path-filter] argument.}]}
|
||||
|
||||
|
||||
@defproc[(fold-files [proc (or/c (path? (or/c 'file 'dir 'link) any/c
|
||||
|
@ -1428,7 +1455,7 @@ and bitwise operations such as @racket[bitwise-ior], and
|
|||
@racket[bitwise-and].}
|
||||
|
||||
|
||||
@(interaction-eval #:eval file-eval (begin
|
||||
(delete-file filename)
|
||||
(delete-file (make-lock-file-name filename))))
|
||||
@examples[#:hidden #:eval file-eval
|
||||
(delete-file filename)
|
||||
(delete-file (make-lock-file-name filename))]
|
||||
@(close-eval file-eval)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
racket/require))
|
||||
|
||||
@(define flfx-eval (make-base-eval))
|
||||
@(interaction-eval #:eval flfx-eval (require racket/fixnum))
|
||||
@examples[#:hidden #:eval flfx-eval (require racket/fixnum)]
|
||||
|
||||
|
||||
@title[#:tag "fixnums"]{Fixnums}
|
||||
|
@ -104,6 +104,10 @@ Two @tech{fxvectors} are @racket[equal?] if they have the same length,
|
|||
and if the values in corresponding slots of the @tech{fxvectors} are
|
||||
@racket[equal?].
|
||||
|
||||
A printed @tech{fxvector} starts with @litchar{#fx(}, optionally with
|
||||
a number between the @litchar{#fx} and
|
||||
@litchar{(}. @see-read-print["vector" #:print "vectors"]{fxvectors}
|
||||
|
||||
@defproc[(fxvector? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] is a @tech{fxvector}, @racket[#f] otherwise.}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt" (for-label racket/flonum))
|
||||
|
||||
@(define fl-eval (make-base-eval))
|
||||
@(interaction-eval #:eval fl-eval (require racket/flonum))
|
||||
@examples[#:hidden #:eval fl-eval (require racket/flonum)]
|
||||
|
||||
@title[#:tag "flonums"]{Flonums}
|
||||
|
||||
|
@ -163,6 +163,10 @@ Two @tech{flvectors} are @racket[equal?] if they have the same length,
|
|||
and if the values in corresponding slots of the @tech{flvectors} are
|
||||
@racket[equal?].
|
||||
|
||||
A printed @tech{flvector} starts with @litchar{#fl(}, optionally with
|
||||
a number between the @litchar{#fl} and
|
||||
@litchar{(}. @see-read-print["vector" #:print "vectors"]{flvectors}
|
||||
|
||||
@defproc[(flvector? [v any/c]) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[v] is a @tech{flvector}, @racket[#f] otherwise.}
|
||||
|
|
|
@ -379,10 +379,11 @@ source for all syntax errors.
|
|||
|
||||
@code:comment{If we misuse for/digits, we can get good error reporting}
|
||||
@code:comment{because the use of orig-datum allows for source correlation:}
|
||||
(for/digits
|
||||
[a (in-list '(1 2 3))]
|
||||
[b (in-list '(4 5 6))]
|
||||
(+ a b))
|
||||
(eval:error
|
||||
(for/digits
|
||||
[a (in-list '(1 2 3))]
|
||||
[b (in-list '(4 5 6))]
|
||||
(+ a b)))
|
||||
|
||||
(for/digits
|
||||
([a (in-list '(1 2 3))]
|
||||
|
@ -426,10 +427,11 @@ Like @racket[for*/fold], but the extra @racket[orig-datum] is used as the source
|
|||
(values (+ n (* d k)) (* k 10)))])
|
||||
n))]))
|
||||
|
||||
(for*/digits
|
||||
[ds (in-list '((8 3) (1 1)))]
|
||||
[d (in-list ds)]
|
||||
d)
|
||||
(eval:error
|
||||
(for*/digits
|
||||
[ds (in-list '((8 3) (1 1)))]
|
||||
[d (in-list ds)]
|
||||
d))
|
||||
|
||||
(for*/digits
|
||||
([ds (in-list '((8 3) (1 1)))]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/manual
|
||||
scribble/struct
|
||||
scribble/eval
|
||||
"mz.rkt"
|
||||
(for-label racket/contract
|
||||
racket/math
|
||||
|
@ -40,7 +39,7 @@ with @racket[separator] between consecutive items, and then pads or
|
|||
truncates the string to be at least @racket[min-width] characters and
|
||||
at most @racket[max-width] characters.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~a "north")
|
||||
(~a 'south)
|
||||
(~a #"east")
|
||||
|
@ -70,7 +69,7 @@ truncated and the end of the string is replaced with
|
|||
@racket[limit-marker]. If @racket[limit-marker] is longer than
|
||||
@racket[max-width], an exception is raised.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~a "abcde" #:max-width 5)
|
||||
(~a "abcde" #:max-width 4)
|
||||
(~a "abcde" #:max-width 4 #:limit-marker "*")
|
||||
|
@ -95,7 +94,7 @@ of @racket[right-pad-string] in its entirety. Thus left padding starts
|
|||
with the start of @racket[left-pad-string] and right padding ends with
|
||||
the end of @racket[right-pad-string].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~a "apple" #:min-width 20 #:align 'left)
|
||||
(~a "pear" #:min-width 20 #:align 'left #:right-pad-string " .")
|
||||
(~a "plum" #:min-width 20 #:align 'right #:left-pad-string ". ")
|
||||
|
@ -107,7 +106,7 @@ Use @racket[width] to set both @racket[max-width] and @racket[min-width]
|
|||
simultaneously, ensuring that the resulting string is exactly
|
||||
@racket[width] characters long:
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:label #f #:eval the-eval
|
||||
(~a "terse" #:width 6)
|
||||
(~a "loquacious" #:width 6)
|
||||
]
|
||||
|
@ -131,7 +130,7 @@ Like @racket[~a], but each value is converted like @racket[(format
|
|||
"~v" v)], the default separator is @racket[" "], and the default limit
|
||||
marker is @racket["..."].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~v "north")
|
||||
(~v 'south)
|
||||
(~v #"east")
|
||||
|
@ -141,7 +140,7 @@ marker is @racket["..."].
|
|||
|
||||
Use @racket[~v] to produce text that talks about Racket values.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(let ([nums (for/list ([i 10]) i)])
|
||||
(~a "The even numbers in " (~v nums)
|
||||
" are " (~v (filter even? nums)) "."))
|
||||
|
@ -165,7 +164,7 @@ Like @racket[~a], but each value is converted like @racket[(format
|
|||
"~s" v)], the default separator is @racket[" "], and the default limit
|
||||
marker is @racket["..."].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~s "north")
|
||||
(~s 'south)
|
||||
(~s #"east")
|
||||
|
@ -192,7 +191,7 @@ Like @racket[~a], but each value is converted like @racket[(format
|
|||
"~e" v)], the default separator is @racket[" "], and the default limit
|
||||
marker is @racket["..."].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~e "north")
|
||||
(~e 'south)
|
||||
(~e #"east")
|
||||
|
@ -241,7 +240,7 @@ The optional arguments control number formatting:
|
|||
in positional or exponential notation. If @racket[notation] is a
|
||||
function, it is applied to @racket[x] to get the notation to be used.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~r 12345)
|
||||
(~r 12345 #:notation 'exponential)
|
||||
(let ([pick-notation
|
||||
|
@ -266,7 +265,7 @@ point are dropped the decimal point is also dropped. If @racket[precision] is
|
|||
@racket[(list '= _digits)], then exactly @racket[_digits] digits after the
|
||||
decimal point are used, and the decimal point is never dropped.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~r pi)
|
||||
(~r pi #:precision 4)
|
||||
(~r pi #:precision 0)
|
||||
|
@ -282,7 +281,7 @@ with fewer than @racket[min-width] digits (including the decimal
|
|||
point but not including the sign indicator), the digits are left-padded
|
||||
using @racket[pad-string].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~r 17)
|
||||
(~r 17 #:min-width 4)
|
||||
(~r -42 #:min-width 4)
|
||||
|
@ -298,7 +297,7 @@ number to at least @racket[min-width] characters (not including the
|
|||
sign indicator). The padding is placed between the sign and the normal
|
||||
digits of @racket[x].
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~r 17 #:min-width 4 #:pad-string "0")
|
||||
(~r -42 #:min-width 4 #:pad-string "0")
|
||||
]}
|
||||
|
@ -311,7 +310,7 @@ indicated:
|
|||
generated if @racket[x] is either positive or zero, and a minus sign is
|
||||
prefixed if @racket[x] is negative.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(for/list ([x '(17 0 -42)]) (~r x))
|
||||
]}
|
||||
|
||||
|
@ -319,14 +318,14 @@ indicated:
|
|||
@racket[x] is zero, a plus sign is prefixed if @racket[x] is positive, and a
|
||||
minus sign is prefixed if @racket[x] is negative.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(for/list ([x '(17 0 -42)]) (~r x #:sign '+))
|
||||
]}
|
||||
|
||||
@item{If @racket[sign] is @racket['++], a plus sign is prefixed if @racket[x]
|
||||
is zero or positive, and a minus sign is prefixed if @racket[x] is negative.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(for/list ([x '(17 0 -42)]) (~r x #:sign '++))
|
||||
]}
|
||||
|
||||
|
@ -334,7 +333,7 @@ indicated:
|
|||
@racket[x] is zero or positive, and the number is enclosed in parentheses if
|
||||
@racket[x] is negative.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(for/list ([x '(17 0 -42)]) (~r x #:sign 'parens))
|
||||
]}
|
||||
|
||||
|
@ -344,7 +343,7 @@ indicated:
|
|||
either a string to be used as a prefix or a list containing two strings: a
|
||||
prefix and a suffix.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(let ([sign-table '(("" " up") "an even " ("" " down"))])
|
||||
(for/list ([x '(17 0 -42)]) (~r x #:sign sign-table)))
|
||||
]
|
||||
|
@ -359,7 +358,7 @@ indicated:
|
|||
used. If @racket[base] is @racket[(list 'up _base*)] and @racket[_base*] is
|
||||
greater than @racket[10], then upper-case letters are used.
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(~r 100 #:base 7)
|
||||
(~r 4.5 #:base 2)
|
||||
(~r 3735928559 #:base 16)
|
||||
|
@ -374,7 +373,7 @@ explicit sign (as with a @racket[sign] of @racket['++]) and at least two
|
|||
digits, separated from the significand by the ``exponent marker''
|
||||
@racket[format-exponent]:
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:label #f #:eval the-eval
|
||||
(~r 1234 #:notation 'exponential #:format-exponent "E")
|
||||
]
|
||||
|
||||
|
@ -382,7 +381,7 @@ If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is
|
|||
@racket["e"] if @racket[base] is @racket[10] and a string involving
|
||||
@racket[base] otherwise:
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:label #f #:eval the-eval
|
||||
(~r 1234 #:notation 'exponential)
|
||||
(~r 1234 #:notation 'exponential #:base 8)
|
||||
]
|
||||
|
@ -390,7 +389,7 @@ If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is
|
|||
If @racket[format-exponent] is a procedure, it is applied to the exponent and
|
||||
the resulting string is appended to the significand:
|
||||
|
||||
@interaction[#:eval the-eval
|
||||
@examples[#:label #f #:eval the-eval
|
||||
(~r 1234 #:notation 'exponential
|
||||
#:format-exponent (lambda (e) (format "E~a" e)))
|
||||
]}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt" (for-label racket/future))
|
||||
|
||||
@(define future-eval (make-base-eval))
|
||||
@(interaction-eval #:eval future-eval (require racket/future))
|
||||
@examples[#:hidden #:eval future-eval (require racket/future)]
|
||||
|
||||
@(define time-id @racketidfont{time})
|
||||
|
||||
|
@ -67,7 +67,7 @@ execute through a call to @racket[touch], however.
|
|||
future, the given @racket[thunk] may run speculatively in parallel to
|
||||
other computations, as described above.
|
||||
|
||||
@interaction[
|
||||
@examples[
|
||||
#:eval future-eval
|
||||
(let ([f (future (lambda () (+ 1 2)))])
|
||||
(list (+ 3 4) (touch f)))
|
||||
|
|
|
@ -132,7 +132,7 @@ method} called @racket[name] that does not support the @techlink{generic
|
|||
instance} @racket[v].
|
||||
|
||||
@examples[#:eval evaluator
|
||||
(raise-support-error 'some-method-name '("arbitrary" "instance" "value"))
|
||||
(eval:error (raise-support-error 'some-method-name '("arbitrary" "instance" "value")))
|
||||
]
|
||||
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ syntax error.}
|
|||
make-num)
|
||||
|
||||
(define z (make-num-contracted 10))
|
||||
(gen-print* z #:width "not a number" #:height 5)
|
||||
(eval:error (gen-print* z #:width "not a number" #:height 5))
|
||||
]
|
||||
|
||||
@defform[(generic-instance/c gen-id [method-id method-ctc] ...)
|
||||
|
|
|
@ -546,7 +546,7 @@ key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value
|
|||
@racket[v0] already exists, it is replaced with a mapping from @racket[k] to
|
||||
@racket[(combine/key k v0 v)].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval the-eval
|
||||
(hash-union (make-immutable-hash '([1 . one]))
|
||||
(make-immutable-hash '([2 . two]))
|
||||
|
@ -574,7 +574,7 @@ key @racket[k] and value @racket[v], if a mapping from @racket[k] to some value
|
|||
@racket[v0] already exists, it is replaced with a mapping from @racket[k] to
|
||||
@racket[(combine/key k v0 v)].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval the-eval
|
||||
(define h (make-hash))
|
||||
h
|
||||
|
|
|
@ -324,8 +324,8 @@ argument list takes precedence.}
|
|||
@note-lib[racket/logging]
|
||||
@(require (for-label racket/logging))
|
||||
@(define log-eval (make-base-eval))
|
||||
@(interaction-eval #:eval log-eval
|
||||
(require racket/logging))
|
||||
@examples[#:hidden #:eval log-eval
|
||||
(require racket/logging)]
|
||||
|
||||
@defproc[(log-level/c [v any/c])
|
||||
boolean?]{
|
||||
|
@ -353,7 +353,7 @@ Runs @racket[proc], calling @racket[interceptor] on any log event that would
|
|||
be received by @racket[(make-log-receiver (current-logger) level topic ... ...)].
|
||||
Returns whatever @racket[proc] returns.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval log-eval
|
||||
(let ([warning-counter 0])
|
||||
(with-intercepted-logging
|
||||
|
@ -381,7 +381,7 @@ Runs @racket[proc], outputting any logging that would be received by
|
|||
@racket[(make-log-receiver (current-logger) level topic ... ...)] to @racket[port].
|
||||
Returns whatever @racket[proc] returns.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval log-eval
|
||||
(let ([my-log (open-output-string)])
|
||||
(with-logging-to-port my-log
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
@(require "mz.rkt" "match-grammar.rkt" racket/match)
|
||||
|
||||
@(define match-eval (make-base-eval))
|
||||
@(interaction-eval #:eval match-eval (require racket/match racket/list))
|
||||
@(interaction-eval #:eval match-eval (require (for-syntax racket/base)))
|
||||
@examples[#:hidden #:eval match-eval (require racket/match racket/list)]
|
||||
@examples[#:hidden #:eval match-eval (require (for-syntax racket/base))]
|
||||
|
||||
@title[#:tag "match"]{Pattern Matching}
|
||||
|
||||
|
@ -239,9 +239,9 @@ In more detail, patterns match as follows:
|
|||
@racket[struct] declaration can provide the structure type
|
||||
information.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval match-eval
|
||||
(define-struct tree (val left right))
|
||||
(eval:no-prompt (define-struct tree (val left right)))
|
||||
(match (make-tree 0 (make-tree 1 #f #f) #f)
|
||||
[(tree a (tree b _ _) _) (list a b)])
|
||||
]}
|
||||
|
@ -430,27 +430,30 @@ many values to expect from @racket[expr].
|
|||
The arguments are ordered as they appear in the function header for
|
||||
matching purposes.
|
||||
|
||||
@defexamples[#:eval match-eval
|
||||
(define/match (fact n)
|
||||
[(0) 1]
|
||||
[(n) (* n (fact (sub1 n)))])
|
||||
@examples[#:eval match-eval
|
||||
(eval:no-prompt
|
||||
(define/match (fact n)
|
||||
[(0) 1]
|
||||
[(n) (* n (fact (sub1 n)))]))
|
||||
(fact 5)
|
||||
]
|
||||
|
||||
The function header may also contain optional or keyword arguments,
|
||||
may have curried arguments, and may also contain a rest argument.
|
||||
|
||||
@defexamples[#:eval match-eval
|
||||
(define/match ((f x) #:y [y '(1 2 3)])
|
||||
[((regexp #rx"p+") `(,a 2 3)) a]
|
||||
[(_ _) #f])
|
||||
@examples[#:eval match-eval
|
||||
(eval:no-prompt
|
||||
(define/match ((f x) #:y [y '(1 2 3)])
|
||||
[((regexp #rx"p+") `(,a 2 3)) a]
|
||||
[(_ _) #f]))
|
||||
((f "ape") #:y '(5 2 3))
|
||||
((f "dog"))
|
||||
|
||||
(define/match (g x y . rst)
|
||||
[(0 0 '()) #t]
|
||||
[(5 5 '(5 5)) #t]
|
||||
[(_ _ _) #f])
|
||||
(eval:no-prompt
|
||||
(define/match (g x y . rst)
|
||||
[(0 0 '()) #t]
|
||||
[(5 5 '(5 5)) #t]
|
||||
[(_ _ _) #f]))
|
||||
(g 0 0)
|
||||
(g 5 5 5 5)
|
||||
(g 1 2)
|
||||
|
@ -586,9 +589,10 @@ are used as binding identifiers (like any other identifier) when they appear
|
|||
anywhere except the first position in a sequence.
|
||||
|
||||
For example, to extend the pattern matcher and destructure syntax lists,
|
||||
@defs+int[
|
||||
@examples[#:label #f
|
||||
#:eval match-eval
|
||||
((define (syntax-list? x)
|
||||
(eval:no-prompt
|
||||
(define (syntax-list? x)
|
||||
(and (syntax? x)
|
||||
(list? (syntax->list x))))
|
||||
(define-match-expander syntax-list
|
||||
|
@ -602,8 +606,7 @@ For example, to extend the pattern matcher and destructure syntax lists,
|
|||
(and (identifier? stx)
|
||||
(free-identifier=? stx keyword))))
|
||||
(define or-keyword? (make-keyword-predicate #'or))
|
||||
(define and-keyword? (make-keyword-predicate #'and))
|
||||
)
|
||||
(define and-keyword? (make-keyword-predicate #'and)))
|
||||
|
||||
(match #'(or 3 4)
|
||||
[(syntax-list (? or-keyword?) b c)
|
||||
|
@ -622,9 +625,10 @@ And here is an example showing how
|
|||
@racket[define-match-expander]-bound identifiers are
|
||||
not treated specially unless they appear
|
||||
in the first position of pattern sequence.
|
||||
@defs+int[
|
||||
@examples[#:label #f
|
||||
#:eval match-eval
|
||||
((define-match-expander nil
|
||||
(eval:no-prompt
|
||||
(define-match-expander nil
|
||||
(λ (stx) #''())
|
||||
(λ (stx) #''()))
|
||||
(define (len l)
|
||||
|
@ -728,9 +732,10 @@ not provided, it defaults to @racket[equal?].
|
|||
Any field of @racket[struct-id] may be omitted, and such fields can
|
||||
occur in any order.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval match-eval
|
||||
(define-struct tree (val left right))
|
||||
(eval:no-prompt
|
||||
(define-struct tree (val left right)))
|
||||
(match (make-tree 0 (make-tree 1 #f #f) #f)
|
||||
[(struct* tree ([val a]
|
||||
[left (struct* tree ([right #f] [val b]))]))
|
||||
|
|
|
@ -199,7 +199,12 @@ execution. Otherwise, @racket[#f] is returned.}
|
|||
@section[#:tag "garbagecollection"]{Garbage Collection}
|
||||
|
||||
Set the @as-index{@envvar{PLTDISABLEGC}} environment variable (to any
|
||||
value) before Racket starts to disable @tech{garbage collection}.
|
||||
value) before Racket starts to disable @tech{garbage collection}. Set
|
||||
the @as-index{@envvar{PLT_INCREMENTAL_GC}} environment variable
|
||||
to a value that starts with @litchar{1}, @litchar{y}, or @litchar{Y} to
|
||||
request incremental mode at all times, but calling
|
||||
@racket[(collect-garbage 'incremental)] in a program with a periodic
|
||||
task is generally a better mechanism for requesting incremental mode.
|
||||
|
||||
In Racket 3m (the main variant of Racket), each garbage collection
|
||||
logs a message (see @secref["logging"]) at the @racket['debug] level with topic @racket['GC].
|
||||
|
@ -209,18 +214,28 @@ versions of Racket may use a @racket[gc-info] @tech{prefab} structure
|
|||
with additional fields:
|
||||
|
||||
@racketblock[
|
||||
(struct gc-info (major? pre-amount pre-admin-amount code-amount
|
||||
post-amount post-admin-amount
|
||||
start-process-time end-process-time
|
||||
start-time end-time)
|
||||
(struct gc-info (mode pre-amount pre-admin-amount code-amount
|
||||
post-amount post-admin-amount
|
||||
start-process-time end-process-time
|
||||
start-time end-time)
|
||||
#:prefab)
|
||||
]
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{The @racket[major?] field indicates whether the collection was
|
||||
a ``major'' collection that inspects all memory or a ``minor''
|
||||
collection that mostly inspects just recent allocations.}
|
||||
@item{The @racket[mode] field is a symbol @racket['major],
|
||||
@racket['minor], or @racket['incremental]; @racket['major]
|
||||
indicates a collection that inspects all memory,
|
||||
@racket['minor] indicates collection that mostly inspects just
|
||||
recent allocations, and @racket['incremental] indicates a minor
|
||||
collection that performs extra work toward the next major
|
||||
collection.
|
||||
|
||||
@history[#:changed "6.3.0.7" @elem{Changed first field from a
|
||||
boolean (@racket[#t] for
|
||||
@racket['major], @racket[#f]
|
||||
for @racket['minor]) to a
|
||||
mode symbol.}]}
|
||||
|
||||
@item{The @racket[pre-amount] field reports place-local memory use
|
||||
(i.e., not counting the memory use of child places) in bytes at
|
||||
|
@ -286,6 +301,8 @@ collection mode, the text has the format
|
|||
@elem{Processor time since startup of garbage collection's start}))
|
||||
]}
|
||||
|
||||
@history[#:changed "6.3.0.7" @elem{Added @envvar{PLT_INCREMENTAL_GC}.}]
|
||||
|
||||
|
||||
@defproc[(collect-garbage [request (or/c 'major 'minor 'incremental) 'major]) void?]{
|
||||
|
||||
|
@ -314,13 +331,18 @@ garbage-collection mode, depending on @racket[request]:
|
|||
major collections any sooner than they would occur otherwise.}
|
||||
|
||||
@item{@racket['incremental] --- Requests that each minor
|
||||
collection performs incremental work toward a major collection.
|
||||
collection performs incremental work toward a major collection
|
||||
(but does not request an immediate minor collection).
|
||||
This incremental-mode request expires at the next major
|
||||
collection.
|
||||
|
||||
The intent of incremental mode is to significantly reduce pause
|
||||
times due to major collections, but incremental mode typically
|
||||
implies longer minor-collection times and higher memory use.}
|
||||
implies longer minor-collection times and higher memory use.
|
||||
|
||||
If the @envvar{PLT_INCREMENTAL_GC} environment variable's value
|
||||
starts with @litchar{0}, @litchar{n}, or @litchar{N} on
|
||||
start-up, then incremental-mode requests are ignored.}
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
(require scribble/struct
|
||||
scribble/manual
|
||||
scribble/eval
|
||||
scribble/examples
|
||||
scribble/decode
|
||||
racket/contract
|
||||
"../icons.rkt")
|
||||
|
||||
(provide (all-from-out scribble/manual)
|
||||
(all-from-out scribble/eval)
|
||||
(all-from-out scribble/examples)
|
||||
(all-from-out racket/contract))
|
||||
|
||||
(require (for-label racket))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
racket/random))
|
||||
|
||||
@(define math-eval (make-base-eval))
|
||||
@(interaction-eval #:eval math-eval (require racket/math))
|
||||
@examples[#:hidden #:eval math-eval (require racket/math)]
|
||||
|
||||
@title[#:tag "numbers" #:style '(toc)]{Numbers}
|
||||
|
||||
|
@ -193,12 +193,12 @@ number, @racket[#f] otherwise.}
|
|||
@defproc[(even? [n integer?]) boolean?]{ Returns @racket[(zero? (modulo
|
||||
n 2))].
|
||||
|
||||
@mz-examples[(even? 10.0) (even? 11) (even? +inf.0)]}
|
||||
@mz-examples[(even? 10.0) (even? 11) (eval:error (even? +inf.0))]}
|
||||
|
||||
|
||||
@defproc[(odd? [n integer?]) boolean?]{ Returns @racket[(not (even? n))].
|
||||
|
||||
@mz-examples[(odd? 10.0) (odd? 11) (odd? +inf.0)]}
|
||||
@mz-examples[(odd? 10.0) (odd? 11) (eval:error (odd? +inf.0))]}
|
||||
|
||||
|
||||
@defproc[(exact? [z number?]) boolean?]{ Returns @racket[#t] if @racket[z]
|
||||
|
@ -289,7 +289,7 @@ If @racket[z] is exact @racket[0] and no @racket[w] is exact
|
|||
|
||||
Returns @racket[(truncate (/ n m))].
|
||||
|
||||
@mz-examples[(quotient 10 3) (quotient -10.0 3) (quotient +inf.0 3)]}
|
||||
@mz-examples[(quotient 10 3) (quotient -10.0 3) (eval:error (quotient +inf.0 3))]}
|
||||
|
||||
|
||||
@defproc[(remainder [n integer?] [m integer?]) integer?]{
|
||||
|
@ -307,7 +307,7 @@ Returns @racket[_q] with the same sign as @racket[n] such that
|
|||
If @racket[m] is exact @racket[0], the
|
||||
@exnraise[exn:fail:contract:divide-by-zero].
|
||||
|
||||
@mz-examples[(remainder 10 3) (remainder -10.0 3) (remainder 10.0 -3) (remainder -10 -3) (remainder +inf.0 3)]}
|
||||
@mz-examples[(remainder 10 3) (remainder -10.0 3) (remainder 10.0 -3) (remainder -10 -3) (eval:error (remainder +inf.0 3))]}
|
||||
|
||||
|
||||
@defproc[(quotient/remainder [n integer?] [m integer?]) (values integer? integer?)]{
|
||||
|
@ -336,7 +336,7 @@ Returns @racket[_q] with the same sign as @racket[m] where
|
|||
If @racket[m] is exact @racket[0], the
|
||||
@exnraise[exn:fail:contract:divide-by-zero].
|
||||
|
||||
@mz-examples[(modulo 10 3) (modulo -10.0 3) (modulo 10.0 -3) (modulo -10 -3) (modulo +inf.0 3)]}
|
||||
@mz-examples[(modulo 10 3) (modulo -10.0 3) (modulo 10.0 -3) (modulo -10 -3) (eval:error (modulo +inf.0 3))]}
|
||||
|
||||
|
||||
@defproc[(add1 [z number?]) number?]{ Returns @racket[(+ z 1)].}
|
||||
|
@ -842,13 +842,22 @@ both in binary and as integers.
|
|||
[rand-gen pseudo-random-generator?
|
||||
(current-pseudo-random-generator)])
|
||||
exact-nonnegative-integer?]
|
||||
[(random [min (integer-in 1 4294967087)]
|
||||
[max (integer-in 1 4294967087)]
|
||||
[rand-gen pseudo-random-generator?
|
||||
(current-pseudo-random-generator)])
|
||||
exact-nonnegative-integer?]
|
||||
[(random [rand-gen pseudo-random-generator?
|
||||
(current-pseudo-random-generator)])
|
||||
(and/c real? inexact? (>/c 0) (</c 1))])]{
|
||||
|
||||
When called with an integer argument @racket[k], returns a random
|
||||
exact integer in the range @racket[0] to @math{@racket[k]-1}. When
|
||||
called with zero arguments, returns a random inexact number between
|
||||
exact integer in the range @racket[0] to @math{@racket[k]-1}.
|
||||
|
||||
When called with two integer arguments @racket[min] and @racket[max], returns a
|
||||
random exact integer in the range @racket[min] to @math{@racket[max]-1}.
|
||||
|
||||
When called with zero arguments, returns a random inexact number between
|
||||
@racket[0] and @racket[1], exclusive.
|
||||
|
||||
In each case, the number is provided by the given pseudo-random number
|
||||
|
@ -856,7 +865,10 @@ generator (which defaults to the current one, as produced by
|
|||
@racket[current-pseudo-random-generator]). The generator maintains an
|
||||
internal state for generating numbers. The random number generator
|
||||
uses a 54-bit version of L'Ecuyer's MRG32k3a algorithm
|
||||
@cite["L'Ecuyer02"].}
|
||||
@cite["L'Ecuyer02"].
|
||||
|
||||
@history[#:changed "6.4"]{Added support for ranges.}}
|
||||
|
||||
|
||||
@defproc[(random-seed [k (integer-in 1 (sub1 (expt 2 31)))])
|
||||
void?]{
|
||||
|
@ -927,16 +939,17 @@ three integers is non-zero. Otherwise, the result is @racket[#f].}
|
|||
|
||||
@; ------------------------------------------------------------------------
|
||||
|
||||
@subsection{System-Provided Randomness}
|
||||
@subsection{Other Randomness Utilities}
|
||||
|
||||
@defmodule[racket/random]{The @racketmodname[racket/random] module
|
||||
provides an interface to randomness from the underlying operating
|
||||
system. Use @racket[crypto-random-bytes]
|
||||
instead of @racket[random] wherever security is a concern.}
|
||||
@defmodule[racket/random]{}
|
||||
|
||||
@defproc[(crypto-random-bytes [n exact-positive-integer?])
|
||||
bytes?]{
|
||||
|
||||
Provides an interface to randomness from the underlying operating system. Use
|
||||
@racket[crypto-random-bytes] instead of @racket[random] wherever security is a
|
||||
concern.
|
||||
|
||||
Returns @racket[n] random bytes. On Unix systems, the bytes are
|
||||
obtained from @filepath{/dev/urandom}, while Windows uses
|
||||
the @tt{RtlGenRand} system function.
|
||||
|
@ -947,6 +960,34 @@ the @tt{RtlGenRand} system function.
|
|||
|
||||
@history[#:added "6.3"]}
|
||||
|
||||
@defproc[(random-ref [seq sequence?]
|
||||
[rand-gen pseudo-random-generator?
|
||||
(current-pseudo-random-generator)])
|
||||
any/c]{
|
||||
|
||||
Returns a random element of the sequence. Like @racket[sequence-length], does
|
||||
not terminate on infinite sequences, and evaluates the entire sequence.
|
||||
|
||||
@history[#:added "6.4"]}
|
||||
|
||||
@defproc[(random-sample [seq sequence?]
|
||||
[n exact-positive-integer?]
|
||||
[rand-gen pseudo-random-generator?
|
||||
(current-pseudo-random-generator)]
|
||||
[#:replacement? replacement? any/c #t])
|
||||
(listof any/c)]{
|
||||
|
||||
Returns a list of @racket[n] elements of @racket[seq], picked at random, listed
|
||||
in any order.
|
||||
If @racket[replacement?] is non-false, elements are drawn with replacement,
|
||||
which allows for duplicates.
|
||||
|
||||
Like @racket[sequence-length], does not terminate on infinite sequences, and
|
||||
evaluates the entire sequence.
|
||||
|
||||
@history[#:added "6.4"]}
|
||||
|
||||
|
||||
@; ------------------------------------------------------------------------
|
||||
@subsection{Number--String Conversions}
|
||||
|
||||
|
|
|
@ -249,7 +249,8 @@ merely start with a chain of at least @racket[(add1 pos)] pairs.
|
|||
(list-ref (list 'a 'b 'c) 0)
|
||||
(list-ref (list 'a 'b 'c) 1)
|
||||
(list-ref (list 'a 'b 'c) 2)
|
||||
(list-ref (cons 1 2) 0)]}
|
||||
(list-ref (cons 1 2) 0)
|
||||
(eval:error (list-ref (cons 1 2) 1))]}
|
||||
|
||||
|
||||
@defproc[(list-tail [lst any/c] [pos exact-nonnegative-integer?])
|
||||
|
@ -264,8 +265,9 @@ must merely start with a chain of at least @racket[pos] pairs.
|
|||
|
||||
@mz-examples[
|
||||
(list-tail (list 1 2 3 4) 2)
|
||||
(list-ref (cons 1 2) 1)
|
||||
(list-ref 'not-a-pair 0)]}
|
||||
(list-tail (cons 1 2) 1)
|
||||
(eval:error (list-tail (cons 1 2) 2))
|
||||
(list-tail 'not-a-pair 0)]}
|
||||
|
||||
|
||||
@defproc*[([(append [lst list?] ...) list?]
|
||||
|
@ -342,7 +344,7 @@ If the @racket[lst]s are empty, then @racket[#t] is returned.
|
|||
|
||||
@mz-examples[
|
||||
(andmap positive? '(1 2 3))
|
||||
(andmap positive? '(1 2 a))
|
||||
(eval:error (andmap positive? '(1 2 a)))
|
||||
(andmap positive? '(1 -2 a))
|
||||
(andmap + '(1 2 3) '(4 5 6))]}
|
||||
|
||||
|
@ -711,8 +713,8 @@ Like @racket[assoc], but finds an element using the predicate
|
|||
|
||||
@note-lib[racket/list]
|
||||
@(define list-eval (make-base-eval))
|
||||
@(interaction-eval #:eval list-eval
|
||||
(require racket/list (only-in racket/function negate)))
|
||||
@examples[#:hidden #:eval list-eval
|
||||
(require racket/list (only-in racket/function negate))]
|
||||
|
||||
|
||||
@defthing[empty null?]{
|
||||
|
@ -1250,9 +1252,34 @@ returns @racket[#f].
|
|||
Returns a list with all elements from @racket[lst], randomly shuffled.
|
||||
|
||||
@mz-examples[#:eval list-eval
|
||||
(shuffle '(1 2 3 4 5 6))
|
||||
(shuffle '(1 2 3 4 5 6))
|
||||
(shuffle '(1 2 3 4 5 6))]}
|
||||
|
||||
|
||||
@defproc*[([(combinations [lst list?]) list?]
|
||||
[(combinations [lst list?] [size exact-nonnegative-integer?]) list?])]{
|
||||
@margin-note{Wikipedia @hyperlink["https://en.wikipedia.org/wiki/Combination"]{combinations}}
|
||||
Return a list of all combinations of elements in the input list
|
||||
(aka the @index["powerset"]{powerset} of @racket[lst]).
|
||||
If @racket[size] is given, limit results to combinations of @racket[size] elements.
|
||||
|
||||
@mz-examples[#:eval list-eval
|
||||
(combinations '(1 2 3))
|
||||
(combinations '(1 2 3) 2)]}
|
||||
|
||||
|
||||
@defproc*[([(in-combinations [lst list?]) list?]
|
||||
[(in-combinations [lst list?] [size exact-nonnegative-integer?]) sequence?])]{
|
||||
@index["in-powerset"]{Returns} a sequence of all combinations of elements in the input list,
|
||||
or all combinations of length @racket[size] if @racket[size] is given.
|
||||
Builds combinations one-by-one instead of all at once.
|
||||
|
||||
@mz-examples[#:eval list-eval
|
||||
(time (begin (combinations (range 15)) (void)))
|
||||
(time (begin (in-combinations (range 15)) (void)))]}
|
||||
|
||||
|
||||
@defproc[(permutations [lst list?])
|
||||
list?]{
|
||||
|
||||
|
@ -1329,7 +1356,7 @@ Computes the n-ary cartesian product of the given lists.
|
|||
Returns a list that is like @racket[lst], omitting the first element of @racket[lst]
|
||||
for which @racket[pred] produces a true value.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval list-eval
|
||||
(remf negative? '(1 -2 3 4 -5))
|
||||
]
|
||||
|
@ -1342,7 +1369,7 @@ for which @racket[pred] produces a true value.
|
|||
Like @racket[remf], but removes all the elements for which @racket[pred]
|
||||
produces a true value.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval list-eval
|
||||
(remf* negative? '(1 -2 3 4 -5))
|
||||
]
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
@section{Port String and List Conversions}
|
||||
@(define port-eval (make-base-eval))
|
||||
@(interaction-eval #:eval port-eval (require racket/port))
|
||||
@examples[#:hidden #:eval port-eval (require racket/port)]
|
||||
|
||||
@defproc[(port->list [r (input-port? . -> . any/c) read] [in input-port? (current-input-port)])
|
||||
(listof any/c)]{
|
||||
|
|
|
@ -288,7 +288,7 @@ all @tech{quotable}, then the vector @racket[print]s as
|
|||
and a closing @litchar{)}. A vector is @tech{quotable} when all of
|
||||
its elements are @tech{quotable}.
|
||||
|
||||
In @racket[write] or @racket[display] mode, an @tech{flvector} prints
|
||||
In @racket[write] or @racket[display] mode, a @tech{flvector} prints
|
||||
like a @tech{vector}, but with a @litchar{#fl} prefix instead of
|
||||
@litchar{#}. A @tech{fxvector} similarly prints with a @litchar{#fx}
|
||||
prefix instead of @litchar{#}. The @racket[print-vector-length]
|
||||
|
|
|
@ -123,9 +123,10 @@ not require any other keywords, and it must accept as many by-position
|
|||
arguments as supplied via the @racket[v]s and @racket[lst]; otherwise,
|
||||
the @exnraise[exn:fail:contract].
|
||||
|
||||
@defexamples[
|
||||
(define (f x #:y y #:z [z 10])
|
||||
(list x y z))
|
||||
@examples[
|
||||
(eval:no-prompt
|
||||
(define (f x #:y y #:z [z 10])
|
||||
(list x y z)))
|
||||
(keyword-apply f '(#:y) '(2) '(1))
|
||||
(keyword-apply f '(#:y #:z) '(2 3) '(1))
|
||||
(keyword-apply f #:z 7 '(#:y) '(2) '(1))
|
||||
|
@ -207,7 +208,7 @@ arity-reduced procedure) or @racket[arity] must be the empty list
|
|||
@examples[
|
||||
(define my+ (procedure-reduce-arity + 2))
|
||||
(my+ 1 2)
|
||||
(my+ 1 2 3)
|
||||
(eval:error (my+ 1 2 3))
|
||||
]}
|
||||
|
||||
@defproc[(procedure-keywords [proc procedure?])
|
||||
|
@ -256,19 +257,21 @@ The result of @racket[procedure-arity] and @racket[object-name] on the
|
|||
new procedure is the same as for @racket[plain-proc]. See also
|
||||
@racket[procedure-reduce-keyword-arity] and @racket[procedure-rename].
|
||||
|
||||
@defexamples[
|
||||
(define show
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest))))
|
||||
@examples[
|
||||
(eval:no-prompt
|
||||
(define show
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest)))))
|
||||
|
||||
(show 1)
|
||||
(show #:init 0 1 2 3 #:extra 4)
|
||||
|
||||
(define show2
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest))
|
||||
(lambda args
|
||||
(list->vector args))))
|
||||
(eval:no-prompt
|
||||
(define show2
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest))
|
||||
(lambda args
|
||||
(list->vector args)))))
|
||||
(show2 1)
|
||||
(show2 #:init 0 1 2 3 #:extra 4)
|
||||
]}
|
||||
|
@ -291,15 +294,16 @@ must require no more keywords than the ones listed in
|
|||
@racket[allowed-kws] (or it must allow all keywords if
|
||||
@racket[allowed-kws] is @racket[#f]).
|
||||
|
||||
@defexamples[
|
||||
(define orig-show
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest))))
|
||||
(define show (procedure-reduce-keyword-arity
|
||||
orig-show 3 '(#:init) '(#:extra #:init)))
|
||||
@examples[
|
||||
(eval:no-prompt
|
||||
(define orig-show
|
||||
(make-keyword-procedure (lambda (kws kw-args . rest)
|
||||
(list kws kw-args rest))))
|
||||
(define show (procedure-reduce-keyword-arity
|
||||
orig-show 3 '(#:init) '(#:extra #:init))))
|
||||
(show #:init 0 1 2 3 #:extra 4)
|
||||
(show 1)
|
||||
(show #:init 0 1 2 3 #:extra 4 #:more 7)
|
||||
(eval:error (show 1))
|
||||
(eval:error (show #:init 0 1 2 3 #:extra 4 #:more 7))
|
||||
]}
|
||||
|
||||
@defstruct[arity-at-least ([value exact-nonnegative-integer?])]{
|
||||
|
@ -452,7 +456,7 @@ property is not associated with a procedure structure type.
|
|||
(apply pairs more))])))
|
||||
|
||||
(pairs 1 2 3 4)
|
||||
(pairs 5)]}
|
||||
(eval:error (pairs 5))]}
|
||||
|
||||
|
||||
@defthing[prop:checked-procedure struct-type-property?]{
|
||||
|
@ -483,6 +487,21 @@ field of @racket[v] applied to @racket[v1] and @racket[v2] produces
|
|||
and @racket[v2], and its result is returned by
|
||||
@racket[checked-procedure-check-and-extract].}
|
||||
|
||||
|
||||
@defproc[(procedure-specialize [proc procedure?])
|
||||
procedure?]{
|
||||
|
||||
Returns @racket[proc] or its equivalent, but provides a hint to the
|
||||
run-time system that it should spend extra time and memory to
|
||||
specialize the implementation of @racket[proc].
|
||||
|
||||
The hint is currently used when @racket[proc] is the value of a
|
||||
@racket[lambda] or @racket[case-lambda] form that references variables
|
||||
bound outside of the @racket[lambda] or @racket[case-lambda], and when
|
||||
@racket[proc] has not been previously applied.
|
||||
|
||||
@history[#:added "6.3.0.10"]}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Reflecting on Primitives}
|
||||
|
@ -517,7 +536,7 @@ applied.}
|
|||
|
||||
@note-lib[racket/function]
|
||||
@(define fun-eval (make-base-eval))
|
||||
@(interaction-eval #:eval fun-eval (require racket/function))
|
||||
@examples[#:hidden #:eval fun-eval (require racket/function)]
|
||||
|
||||
@defproc[(identity [v any/c]) any/c]{
|
||||
Returns @racket[v].
|
||||
|
@ -540,13 +559,15 @@ The @racket[thunk] form creates a nullary function that evaluates the
|
|||
given body. The @racket[thunk*] form is similar, except that the
|
||||
resulting function accepts any arguments (including keyword arguments).
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval fun-eval
|
||||
(define th1 (thunk (define x 1) (printf "~a\n" x)))
|
||||
(eval:no-prompt
|
||||
(define th1 (thunk (define x 1) (printf "~a\n" x))))
|
||||
(th1)
|
||||
(th1 'x)
|
||||
(th1 #:y 'z)
|
||||
(define th2 (thunk* (define x 1) (printf "~a\n" x)))
|
||||
(eval:error (th1 'x))
|
||||
(eval:error (th1 #:y 'z))
|
||||
(eval:no-prompt
|
||||
(define th2 (thunk* (define x 1) (printf "~a\n" x))))
|
||||
(th2)
|
||||
(th2 'x)
|
||||
(th2 #:y 'z)
|
||||
|
@ -567,9 +588,10 @@ returns the @racket[not] of @racket[proc]'s result.
|
|||
Combines calls to each function with @racket[and]. Equivalent to
|
||||
@racket[(and (f x ...) ...)]
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval fun-eval
|
||||
(define f (conjoin exact? integer?))
|
||||
(eval:no-prompt
|
||||
(define f (conjoin exact? integer?)))
|
||||
(f 1)
|
||||
(f 1.0)
|
||||
(f 1/2)
|
||||
|
@ -583,9 +605,10 @@ Combines calls to each function with @racket[and]. Equivalent to
|
|||
Combines calls to each function with @racket[or]. Equivalent to
|
||||
@racket[(or (f x ...) ...)]
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval fun-eval
|
||||
(define f (disjoin exact? integer?))
|
||||
(eval:no-prompt
|
||||
(define f (disjoin exact? integer?)))
|
||||
(f 1)
|
||||
(f 1.0)
|
||||
(f 1/2)
|
||||
|
@ -708,7 +731,6 @@ and @racket[(equal? (normalize-arity a) (normalize-arity b))].
|
|||
(arity=? 1 (list 1))
|
||||
(arity=? 1 (arity-at-least 1))
|
||||
(arity=? (arity-at-least 1) 1)
|
||||
(arity=? 1 (arity-at-least 1))
|
||||
(arity=? (arity-at-least 1) (list 1 (arity-at-least 2)))
|
||||
(arity=? (list 1 (arity-at-least 2)) (arity-at-least 1))
|
||||
(arity=? (arity-at-least 1) (list 1 (arity-at-least 3)))
|
||||
|
@ -732,7 +754,6 @@ arguments that procedures with arity @racket[b] accept.
|
|||
(arity-includes? 1 (list 1))
|
||||
(arity-includes? 1 (arity-at-least 1))
|
||||
(arity-includes? (arity-at-least 1) 1)
|
||||
(arity-includes? 1 (arity-at-least 1))
|
||||
(arity-includes? (arity-at-least 1) (list 1 (arity-at-least 2)))
|
||||
(arity-includes? (list 1 (arity-at-least 2)) (arity-at-least 1))
|
||||
(arity-includes? (arity-at-least 1) (list 1 (arity-at-least 3)))
|
||||
|
|
|
@ -156,8 +156,10 @@ interpretation of results is up to external tools, such as DrRacket (see
|
|||
If no information is available for a given key, the result should be
|
||||
the second argument.
|
||||
@mz-examples[
|
||||
((read-language (open-input-string "#lang algol60")) 'color-lexer #f)
|
||||
((read-language (open-input-string "#lang algol60")) 'something-else #f)
|
||||
(define scribble-manual-info
|
||||
(read-language (open-input-string "#lang scribble/manual")))
|
||||
(scribble-manual-info 'color-lexer #f)
|
||||
(scribble-manual-info 'something-else #f)
|
||||
]
|
||||
|
||||
The @racketidfont{get-info} function itself is applied to five
|
||||
|
@ -217,6 +219,23 @@ A @tech{parameter} that controls whether @litchar["{"] and @litchar["}"]
|
|||
are treated as parentheses. See @secref["parse-pair"] for more
|
||||
information.}
|
||||
|
||||
@defboolparam[read-square-bracket-with-tag on?]{
|
||||
|
||||
A @tech{parameter} that controls whether @litchar{[} and @litchar{]}
|
||||
are treated as parentheses, but the resulting list tagged with
|
||||
@racket[#%brackets]. See @secref["parse-pair"] for more information.
|
||||
|
||||
@history[#:added "6.3.0.5"]}
|
||||
|
||||
@defboolparam[read-curly-brace-with-tag on?]{
|
||||
|
||||
A @tech{parameter} that controls whether @litchar["{"] and
|
||||
@litchar["}"] are treated as parentheses, but the resulting list
|
||||
tagged with @racket[#%braces]. See @secref["parse-pair"] for more
|
||||
information.
|
||||
|
||||
@history[#:added "6.3.0.5"]}
|
||||
|
||||
@defboolparam[read-accept-box on?]{
|
||||
|
||||
A @tech{parameter} that controls parsing @litchar{#&} input. See
|
||||
|
@ -256,6 +275,14 @@ information.}
|
|||
A @tech{parameter} that controls parsing input with two dots to trigger infix
|
||||
conversion. See @secref["parse-pair"] for more information.}
|
||||
|
||||
@defboolparam[read-cdot on?]{
|
||||
|
||||
A @tech{parameter} that controls parsing input with a dot, in a C
|
||||
structure accessor style. See @secref["parse-cdot"] for more
|
||||
information.
|
||||
|
||||
@history[#:added "6.3.0.5"]}
|
||||
|
||||
@defboolparam[read-accept-quasiquote on?]{
|
||||
|
||||
A @tech{parameter} that controls parsing input with @litchar{`} or
|
||||
|
|
|
@ -388,13 +388,21 @@ elements are themselves in @racket[read-syntax] mode, so that the
|
|||
result is a list or pair of syntax objects that is itself wrapped as a
|
||||
syntax object. If the reader constructs nested pairs because the input
|
||||
included a single delimited @litchar{.}, then only the innermost pair
|
||||
and outermost pair are wrapped as syntax objects. Whether wrapping a
|
||||
pair or list, if the pair or list was formed with @litchar{[} and
|
||||
@litchar{]}, then a @indexed-racket['paren-shape] property is attached
|
||||
to the result with the value @racket[#\[]; if the list or pair was
|
||||
formed with @litchar["{"] and @litchar["}"], then a
|
||||
@racket['paren-shape] property is attached to the result with the
|
||||
value @racket[#\{].
|
||||
and outermost pair are wrapped as syntax objects.
|
||||
|
||||
Whether wrapping a pair or list, if the pair or list was formed with
|
||||
@litchar{[} and @litchar{]}, then a @indexed-racket['paren-shape]
|
||||
property is attached to the result with the value @racket[#\[]. If the
|
||||
@racket[read-square-bracket-with-tag] @tech{parameter} is set to
|
||||
@racket[#t], then the resulting pair or list is wrapped by the
|
||||
equivalent of @racket[(cons '#%brackets _pair-or-list)].
|
||||
|
||||
Similarly, if the list or pair was formed with @litchar["{"] and
|
||||
@litchar["}"], then a @racket['paren-shape] property is attached to
|
||||
the result with the value @racket[#\{]. If the
|
||||
@racket[read-curly-brace-with-tag] @tech{parameter} is set to
|
||||
@racket[#t], then the resulting pair or list is wrapped by the
|
||||
equivalent of @racket[(cons '#%braces _pair-or-list)].
|
||||
|
||||
If a delimited @litchar{.} appears in any other configuration, then
|
||||
the @exnraise[exn:fail:read]. Similarly, if the reader encounters a
|
||||
|
@ -412,12 +420,14 @@ being parsed, then the @exnraise[exn:fail:read].
|
|||
"(1 . 2 . 3)"
|
||||
]
|
||||
|
||||
If the @racket[read-square-bracket-as-paren] @tech{parameter} is set to
|
||||
If the @racket[read-square-bracket-as-paren] and
|
||||
@racket[read-square-bracket-with-tag] @tech{parameter}s are set to
|
||||
@racket[#f], then when the reader encounters @litchar{[} and
|
||||
@litchar{]}, the @exnraise{exn:fail:read}. Similarly, if the
|
||||
@racket[read-curly-brace-as-paren] @tech{parameter} is set to @racket[#f],
|
||||
then when the reader encounters @litchar["{"] and @litchar["}"], the
|
||||
@exnraise{exn:fail:read}.
|
||||
@racket[read-curly-brace-as-paren] and
|
||||
@racket[read-curly-brace-with-tag] @tech{parameter}s are set to
|
||||
@racket[#f], then when the reader encounters @litchar["{"] and
|
||||
@litchar["}"], the @exnraise{exn:fail:read}.
|
||||
|
||||
If the @racket[read-accept-dot] @tech{parameter} is set to
|
||||
@racket[#f], then a delimited @litchar{.} triggers an
|
||||
|
@ -631,7 +641,7 @@ The elements of the vector are recursively read until a matching
|
|||
lists (see @secref["parse-pair"]). A delimited @litchar{.} is not
|
||||
allowed among the vector elements. In the case of @tech{flvectors},
|
||||
the recursive read for element is implicitly prefixed with @litchar{#i}
|
||||
and must produce a @tech{flonum}. In the case of @tech{flvectors},
|
||||
and must produce a @tech{flonum}. In the case of @tech{fxvectors},
|
||||
the recursive read for element is implicitly prefixed with @litchar{#e}
|
||||
and must produce a @tech{fixnum}.
|
||||
|
||||
|
@ -931,6 +941,30 @@ If the @racket[read-accept-reader] or @racket[read-accept-lang]
|
|||
@tech{parameter} is set to @racket[#f], then if the reader encounters
|
||||
@litchar{#lang} or equivalent @litchar{#!}, the @exnraise[exn:fail:read].
|
||||
|
||||
@section[#:tag "parse-cdot"]{Reading with C-style infix dot notation}
|
||||
|
||||
When the @racket[read-cdot] @tech{parameter} is set to @racket[#t],
|
||||
then a variety of changes occur in the reader.
|
||||
|
||||
First, symbols can no longer include the character @litchar{.}, unless
|
||||
the entire symbol is quoted with @litchar{|}.
|
||||
|
||||
Second, numbers can no longer include the character @litchar{.},
|
||||
unless the number is prefixed with @litchar{#e} or @litchar{#i}, or an
|
||||
equivalent prefix as discussed in @secref["parse-number"]. If these
|
||||
numbers are followed by a @litchar{.} intended to be read as a C-style
|
||||
infix dot, then there must be separating whitespace.
|
||||
|
||||
Finally, after reading any value, @racket[_x], the reader will seek
|
||||
over whitespace until it reaches a non-whitespace character. If the
|
||||
character is not @litchar{.}, then the value, @racket[_x], is returned
|
||||
as usual. If the character is @litchar{.}, then another value,
|
||||
@racket[_y], is read and the result @racket[(list '#%dot _x _y)] is
|
||||
returned. In @racket[read-syntax] mode, the @racket['#%dot] symbol has
|
||||
the source location information of the @litchar{.} character and the
|
||||
entire list has the source location information spanning from the
|
||||
start of @racket[_x] to the end of @racket[_y].
|
||||
|
||||
@subsection{S-Expression Reader Language}
|
||||
|
||||
@defmodulelang[s-exp]
|
||||
|
|
|
@ -67,7 +67,7 @@ otherwise.
|
|||
|
||||
}
|
||||
|
||||
@defproc[(make-readtable [readtable readtable?]
|
||||
@defproc[(make-readtable [readtable (or/c readtable? #f)]
|
||||
[key (or/c char? #f)]
|
||||
[mode (or/c (or/c 'terminating-macro
|
||||
'non-terminating-macro
|
||||
|
|
|
@ -32,7 +32,7 @@ friendlier (though less precise and less complete) overview of the
|
|||
language.
|
||||
|
||||
@margin-note{The source of this manual is available on
|
||||
@hyperlink["https://github.com/plt/racket/tree/master/pkgs/racket-doc/scribblings/reference"]{GitHub}.}
|
||||
@hyperlink["https://github.com/racket/racket/tree/master/pkgs/racket-doc/scribblings/reference"]{GitHub}.}
|
||||
|
||||
@defmodulelang*[(racket/base racket)
|
||||
;; Use sources for overlap with `scheme' and `mzscheme':
|
||||
|
|
|
@ -240,7 +240,7 @@ returns the source byte string for a @tech{regexp value}.
|
|||
@examples[
|
||||
(byte-regexp #"ap*le")
|
||||
(object-name #rx#"ap*le")
|
||||
(byte-regexp "ap*le")
|
||||
(eval:error (byte-regexp "ap*le"))
|
||||
]}
|
||||
|
||||
@defproc[(byte-pregexp [bstr bytes?]) byte-pregexp?]{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
racket/gui/dynamic))
|
||||
|
||||
@(define box-eval (make-base-eval))
|
||||
@(interaction-eval #:eval box-eval (require racket/sandbox))
|
||||
@examples[#:hidden #:eval box-eval (require racket/sandbox)]
|
||||
|
||||
@title{Sandboxed Evaluation}
|
||||
|
||||
|
@ -147,11 +147,12 @@ The following examples illustrate the difference between an evaluator
|
|||
that puts the program in a module and one that merely initializes a
|
||||
top-level namespace:
|
||||
|
||||
@interaction[
|
||||
@examples[#:label #f
|
||||
#:eval box-eval
|
||||
(define base-module-eval
|
||||
(code:comment @#,t{a module cannot have free variables...})
|
||||
(make-evaluator 'racket/base '(define (f) later)))
|
||||
(eval:error
|
||||
(define base-module-eval
|
||||
(code:comment @#,t{a module cannot have free variables...})
|
||||
(make-evaluator 'racket/base '(define (f) later))))
|
||||
(define base-module-eval
|
||||
(make-evaluator 'racket/base '(define (f) later)
|
||||
'(define later 5)))
|
||||
|
@ -229,9 +230,10 @@ of communication makes it impossible to have nested (or concurrent)
|
|||
calls to a single evaluator. Usually this is not a problem, but in
|
||||
some cases you can get the evaluator function available inside the
|
||||
sandboxed code, for example:
|
||||
@interaction[#:eval box-eval
|
||||
(let ([e (make-evaluator 'racket/base)])
|
||||
(e `(,e 1)))
|
||||
@examples[#:label #f #:eval box-eval
|
||||
(eval:error
|
||||
(let ([e (make-evaluator 'racket/base)])
|
||||
(e `(,e 1))))
|
||||
]
|
||||
An error will be signaled in such cases.
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ vice-versa.
|
|||
@(define sequence-evaluator
|
||||
(let ([evaluator (make-base-eval)])
|
||||
(evaluator '(require racket/generic racket/list racket/stream racket/sequence
|
||||
racket/contract))
|
||||
racket/contract racket/dict))
|
||||
evaluator))
|
||||
|
||||
@guideintro["sequences"]{sequences}
|
||||
|
@ -152,7 +152,7 @@ each element in the sequence.
|
|||
Returns @racket[#t] if @racket[v] can be used as a @tech{sequence},
|
||||
@racket[#f] otherwise.
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(sequence? 42)
|
||||
(sequence? '(a b c))
|
||||
(sequence? "word")
|
||||
|
@ -169,12 +169,12 @@ each element in the sequence.
|
|||
@racket[step] is non-negative, or less or equal to @racket[end] if
|
||||
@racket[step] is negative. @speed[in-range "number"]
|
||||
|
||||
Example: gaussian sum
|
||||
@interaction[#:eval sequence-evaluator
|
||||
|
||||
@examples[#:label "Example: gaussian sum" #:eval sequence-evaluator
|
||||
(for/sum ([x (in-range 10)]) x)]
|
||||
|
||||
Example: sum of even numbers
|
||||
@interaction[#:eval sequence-evaluator
|
||||
|
||||
@examples[#:label "Example: sum of even numbers" #:eval sequence-evaluator
|
||||
(for/sum ([x (in-range 0 100 2)]) x)]
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ each element in the sequence.
|
|||
integers starting with @racket[start], where each element is one
|
||||
more than the preceding element. @speed[in-naturals "integer"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(for/list ([k (in-naturals)]
|
||||
[x (in-range 10)])
|
||||
(list k x))]
|
||||
|
@ -197,7 +197,7 @@ each element in the sequence.
|
|||
@info-on-seq["pairs" "lists"]
|
||||
@speed[in-list "list"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(for/list ([x (in-list '(3 1 4))])
|
||||
`(,x ,(* x x)))]
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ each element in the sequence.
|
|||
@info-on-seq["mpairs" "mutable lists"]
|
||||
@speed[in-mlist "mutable list"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(for/list ([x (in-mlist (mcons "RACKET" (mcons "LANG" '())))])
|
||||
(string-length x))]
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ each element in the sequence.
|
|||
|
||||
@speed[in-vector "vector"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(define (histogram vector-of-words)
|
||||
(define a-hash (make-hash))
|
||||
(for ([word (in-vector vector-of-words)])
|
||||
|
@ -266,7 +266,7 @@ each element in the sequence.
|
|||
|
||||
@speed[in-string "string"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(define (line-count str)
|
||||
(for/sum ([ch (in-string str)])
|
||||
(if (char=? #\newline ch) 1 0)))
|
||||
|
@ -288,7 +288,7 @@ each element in the sequence.
|
|||
|
||||
@speed[in-bytes "byte string"]
|
||||
|
||||
@interaction[#:eval sequence-evaluator
|
||||
@examples[#:eval sequence-evaluator
|
||||
(define (has-eof? bs)
|
||||
(for/or ([ch (in-bytes bs)])
|
||||
(= ch 0)))
|
||||
|
@ -384,6 +384,48 @@ each element in the sequence.
|
|||
content of a directory, use the result of @racket[directory-list] as
|
||||
a sequence.
|
||||
|
||||
@examples[
|
||||
(code:comment @#,t{Given a directory tree:})
|
||||
(code:comment @#,t{})
|
||||
(code:comment @#,t{ /example})
|
||||
(code:comment @#,t{ ├── a})
|
||||
(code:comment @#,t{ │ ├── alpha})
|
||||
(code:comment @#,t{ │ └── apple})
|
||||
(code:comment @#,t{ ├── b})
|
||||
(code:comment @#,t{ │ └── beta})
|
||||
(code:comment @#,t{ └── c})
|
||||
(code:comment @#,t{})
|
||||
(eval:alts
|
||||
(parameterize ([current-directory "/example"])
|
||||
(for ([p (in-directory)])
|
||||
(printf "~a\n" p)))
|
||||
(for ([p (in-list '("a"
|
||||
"a/alpha"
|
||||
"a/apple"
|
||||
"b"
|
||||
"b/beta"
|
||||
"c"))])
|
||||
(printf "~a\n" p)))
|
||||
(eval:alts
|
||||
(for ([p (in-directory "/example")])
|
||||
(printf "~a\n" p))
|
||||
(for ([p (in-list '("/example/a"
|
||||
"/example/a/alpha"
|
||||
"/example/a/apple"
|
||||
"/example/b"
|
||||
"/example/b/beta"
|
||||
"/example/c"))])
|
||||
(printf "~a\n" p)))
|
||||
(eval:alts
|
||||
(let ([f (lambda (path) (regexp-match? #rx"/example/b.*" path))])
|
||||
(for ([p (in-directory "/example" f)])
|
||||
(printf "~a\n" p)))
|
||||
(for ([p (in-list '("/example/a"
|
||||
"/example/b"
|
||||
"/example/b/beta"
|
||||
"/example/c"))])
|
||||
(printf "~a\n" p)))]
|
||||
|
||||
@history[#:changed "6.0.0.1" @elem{Added @racket[use-dir?] argument.}]}
|
||||
|
||||
|
||||
|
@ -755,27 +797,30 @@ for instance, a wrapped list is not guaranteed to satisfy @racket[list?].
|
|||
|
||||
If @racket[min-count] is a number, the stream is required to have at least that many elements in it.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
#:eval sequence-evaluator
|
||||
(define/contract predicates
|
||||
(sequence/c (-> any/c boolean?))
|
||||
(in-list (list integer?
|
||||
string->symbol)))
|
||||
(for ([P predicates])
|
||||
(printf "~s\n" (P "cat")))
|
||||
(eval:error
|
||||
(for ([P predicates])
|
||||
(printf "~s\n" (P "cat"))))
|
||||
(define/contract numbers&strings
|
||||
(sequence/c number? string?)
|
||||
(in-dict (list (cons 1 "one")
|
||||
(cons 2 "two")
|
||||
(cons 3 'three))))
|
||||
(for ([(N S) numbers&strings])
|
||||
(printf "~s: ~a\n" N S))
|
||||
(eval:error
|
||||
(for ([(N S) numbers&strings])
|
||||
(printf "~s: ~a\n" N S)))
|
||||
(define/contract a-sequence
|
||||
(sequence/c #:min-count 2 char?)
|
||||
"x")
|
||||
(for ([x a-sequence]
|
||||
[i (in-naturals)])
|
||||
(printf "~a is ~a\n" i x))
|
||||
(eval:error
|
||||
(for ([x a-sequence]
|
||||
[i (in-naturals)])
|
||||
(printf "~a is ~a\n" i x)))
|
||||
]
|
||||
|
||||
}
|
||||
|
@ -1160,11 +1205,12 @@ values from the generator.
|
|||
literal, exact, non-negative integer.
|
||||
|
||||
@examples[#:eval generator-eval
|
||||
(let ([g (in-generator
|
||||
(let loop ([n 3])
|
||||
(unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))])
|
||||
(let-values ([(not-empty? next) (sequence-generate g)])
|
||||
(let loop () (when (not-empty?) (next) (loop))) 'done))
|
||||
(eval:error
|
||||
(let ([g (in-generator
|
||||
(let loop ([n 3])
|
||||
(unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))])
|
||||
(let-values ([(not-empty? next) (sequence-generate g)])
|
||||
(let loop () (when (not-empty?) (next) (loop))) 'done)))
|
||||
(let ([g (in-generator #:arity 2
|
||||
(let loop ([n 3])
|
||||
(unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))])
|
||||
|
@ -1174,7 +1220,7 @@ values from the generator.
|
|||
To use an existing generator as a sequence, use @racket[in-producer]
|
||||
with a stop-value known for the generator:
|
||||
|
||||
@interaction[#:eval generator-eval
|
||||
@examples[#:label #f #:eval generator-eval
|
||||
(define abc-generator (generator ()
|
||||
(for ([x '(a b c)])
|
||||
(yield x))))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt" racket/serialize (for-label racket/serialize racket/fasl))
|
||||
|
||||
@(define ser-eval (make-base-eval))
|
||||
@(interaction-eval #:eval ser-eval (require racket/serialize))
|
||||
@examples[#:hidden #:eval ser-eval (require racket/serialize)]
|
||||
|
||||
@title[#:tag "serialization"]{Serialization}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
@title[#:tag "sets"]{Sets}
|
||||
@(define set-eval (make-base-eval))
|
||||
@(interaction-eval #:eval set-eval (require racket/set))
|
||||
@examples[#:hidden #:eval set-eval (require racket/set)]
|
||||
|
||||
A @deftech{set} represents a collection of distinct elements. The following
|
||||
datatypes are all sets:
|
||||
|
@ -203,17 +203,21 @@ named by the @racket[sym]s.
|
|||
'dont-care]
|
||||
[#:kind kind
|
||||
(or/c 'dont-care 'immutable 'mutable 'weak 'mutable-or-weak)
|
||||
'immutable])
|
||||
'immutable]
|
||||
[#:lazy? lazy? any/c
|
||||
(not (and (equal? kind 'immutable)
|
||||
(flat-contract? elem/c)))]
|
||||
[#:equal-key/c equal-key/c contract? any/c])
|
||||
contract?]{
|
||||
|
||||
Constructs a contract that recognizes sets whose elements match
|
||||
@racket[contract].
|
||||
@racket[elem/c].
|
||||
|
||||
If @racket[kind] is @racket['immutable], @racket['mutable], or
|
||||
@racket['weak], the resulting contract accepts only @tech{hash sets} that
|
||||
are respectively immutable, mutable with strongly-held keys, or mutable with
|
||||
weakly-held keys. If @racket[kind] is @racket['mutable-or-weak], the
|
||||
resulting contract accepts any mutable @racket{hash sets}, regardless of
|
||||
resulting contract accepts any mutable @tech{hash sets}, regardless of
|
||||
key-holding strength.
|
||||
|
||||
If @racket[cmp] is @racket['equal], @racket['eqv], or @racket['eq], the
|
||||
|
@ -221,12 +225,34 @@ named by the @racket[sym]s.
|
|||
using @racket[equal?], @racket[eqv?], or @racket[eq?], respectively.
|
||||
|
||||
If @racket[cmp] is @racket['eqv] or @racket['eq], then @racket[elem/c] must
|
||||
be a flat contract.
|
||||
be a @tech{flat contract}.
|
||||
|
||||
If @racket[cmp] and @racket[kind] are both @racket['dont-care], then the
|
||||
resulting contract will accept any kind of set, not just @tech{hash
|
||||
sets}.
|
||||
|
||||
If @racket[lazy?] is not @racket[#f], then the elements of the set are not checked
|
||||
immediately by the contract and only the set itself is checked (according to the
|
||||
@racket[cmp] and @racket[kind] arguments). If @racket[lazy?] is
|
||||
@racket[#f], then the elements are checked immediately by the contract.
|
||||
The @racket[lazy?] argument is ignored when the set contract accepts generic sets
|
||||
(i.e., when @racket[cmp] and @racket[kind] are both @racket['dont-care]); in that
|
||||
case, the value being checked in that case is a @racket[list?], then the contract
|
||||
is not lazy otherwise the contract is lazy.
|
||||
|
||||
If @racket[kind] allows mutable sets (i.e., is @racket['dont-care],
|
||||
@racket['mutable], @racket['weak], or
|
||||
@racket['mutable-or-weak]) and @racket[lazy?] is @racket[#f], then the elements
|
||||
are checked both immediately and when they are accessed from the set.
|
||||
|
||||
The @racket[equal-key/c] contract is used when values are passed to the comparison
|
||||
and hashing functions used internally.
|
||||
|
||||
The result contract will be a @tech{flat contract} when @racket[elem/c]
|
||||
and @racket[equal-key/c] are both @tech{flat contracts},
|
||||
@racket[lazy?] is @racket[#f], and @racket[kind] is @racket['immutable].
|
||||
The result will be a @tech{chaperone contract} when @racket[elem/c] is a
|
||||
@tech{chaperone contract}.
|
||||
}
|
||||
|
||||
@section{Generic Set Interface}
|
||||
|
@ -446,7 +472,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-add] and @supp
|
|||
(set-union (seteq))
|
||||
(set-union (set 1 2) (set 2 3))
|
||||
(set-union (list 1 2) (list 2 3))
|
||||
(set-union (set 1 2) (seteq 2 3)) (code:comment "Sets of different types cannot be unioned.")
|
||||
(eval:error (set-union (set 1 2) (seteq 2 3))) (code:comment "Sets of different types cannot be unioned")
|
||||
]}
|
||||
|
||||
@defproc[(set-union! [st0 generic-set?] [st generic-set?] ...) void?]{
|
||||
|
@ -518,7 +544,7 @@ both @racket[set-clear] and @racket[set-add], and @supp{supports} @racket[set->s
|
|||
|
||||
}
|
||||
|
||||
@defproc[(set-subtract! [st0 generic-set?] [st generic-set?] ...) generic-set?]{
|
||||
@defproc[(set-subtract! [st0 generic-set?] [st generic-set?] ...) void?]{
|
||||
|
||||
Removes every element from @racket[st0] that is contained by any of the
|
||||
@racket[st]s.
|
||||
|
@ -557,7 +583,7 @@ Supported for any @racket[st] that @impl{implements} @racket[set-remove] or both
|
|||
|
||||
}
|
||||
|
||||
@defproc[(set-symmetric-difference! [st0 generic-set?] [st generic-set?] ...) generic-set?]{
|
||||
@defproc[(set-symmetric-difference! [st0 generic-set?] [st generic-set?] ...) void?]{
|
||||
|
||||
Adds and removes elements of @racket[st0] so that it includes all of the
|
||||
elements contained an odd number of times in the @racket[st]s and the
|
||||
|
@ -598,8 +624,7 @@ Supported for any @racket[st] and @racket[st2] that both @supp{support}
|
|||
(set=? (set 1 2 3) (set 1))
|
||||
(set=? (set 1 2 3) (set 1 2 3))
|
||||
(set=? (seteq 1 2) (mutable-seteq 2 1))
|
||||
(set=? (seteq 1 2) (seteqv 1 2)) (code:comment "Sets of different types cannot
|
||||
be compared.")
|
||||
(eval:error (set=? (seteq 1 2) (seteqv 1 2))) (code:comment "Sets of different types cannot be compared")
|
||||
]
|
||||
|
||||
}
|
||||
|
@ -696,6 +721,77 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream].
|
|||
|
||||
}
|
||||
|
||||
@defproc[(impersonate-hash-set [st (or/c mutable-set? weak-set?)]
|
||||
[inject-proc (or/c #f (-> set? any/c any/c))]
|
||||
[add-proc (or/c #f (-> set? any/c any/c))]
|
||||
[shrink-proc (or/c #f (-> set? any/c any/c))]
|
||||
[extract-proc (or/c #f (-> set? any/c any/c))]
|
||||
[clear-proc (or/c #f (-> set? any)) #f]
|
||||
[equal-key-proc (or/c #f (-> set? any/c any/c)) #f]
|
||||
[prop impersonator-property?]
|
||||
[prop-val any/c] ... ...)
|
||||
(and/c (or/c mutable-set? weak-set?) impersonator?)]{
|
||||
Impersonates @racket[st], redirecting various set operations via the given procedures.
|
||||
|
||||
The @racket[inject-proc] procedure
|
||||
is called whenever an element is temporarily put into the set for the purposes
|
||||
of comparing it with other elements that may already be in the set. For example,
|
||||
when evaluating @racket[(set-member? s e)], @racket[e] will be passed to the
|
||||
@racket[inject-proc] before comparing it with other elements of @racket[s].
|
||||
|
||||
The @racket[add-proc] procedure is called when adding an element to a set, e.g.,
|
||||
via @racket[set-add] or @racket[set-add!]. The result of the @racket[add-proc] is
|
||||
stored in the set.
|
||||
|
||||
The @racket[shrink-proc] procedure is called when building a new set with
|
||||
one fewer element. For example, when evaluating @racket[(set-remove s e)]
|
||||
or @racket[(set-remove! s e)],
|
||||
an element is removed from a set, e.g.,
|
||||
via @racket[set-remove] or @racket[set-remove!]. The result of the @racket[shrink-proc]
|
||||
is the element actually removed from the set.
|
||||
|
||||
The @racket[extract-proc] procedure is called when an element is pulled out of
|
||||
a set, e.g., by @racket[set-first]. The result of the @racket[extract-proc] is
|
||||
the element actually produced by from the set.
|
||||
|
||||
The @racket[clear-proc] is called by @racket[set-clear] and @racket[set-clear!]
|
||||
and if it returns (as opposed to escaping, perhaps via raising an exception),
|
||||
the clearing operation is permitted. Its result is ignored. If @racket[clear-proc]
|
||||
is @racket[#f], then clearing is done element by element (via calls into the other
|
||||
supplied procedures).
|
||||
|
||||
The @racket[equal-key-proc] is called when an element's hash code is needed of when an
|
||||
element is supplied to the underlying equality in the set. The result of
|
||||
@racket[equal-key-proc] is used when computing the hash or comparing for equality.
|
||||
|
||||
If any of the @racket[inject-proc], @racket[add-proc], @racket[shrink-proc], or
|
||||
@racket[extract-proc] arguments are @racket[#f], then they all must be @racket[#f],
|
||||
the @racket[clear-proc] and @racket[equal-key-proc] must also be @racket[#f],
|
||||
and there must be at least one property supplied.
|
||||
|
||||
Pairs of @racket[prop] and @racket[prop-val] (the number of arguments to
|
||||
@racket[impersonate-hash-set] must be odd) add @tech{impersonator properties} or
|
||||
override impersonator property values of @racket[st].
|
||||
}
|
||||
|
||||
@defproc[(chaperone-hash-set [st (or/c set? mutable-set? weak-set?)]
|
||||
[inject-proc (or/c #f (-> set? any/c any/c))]
|
||||
[add-proc (or/c #f (-> set? any/c any/c))]
|
||||
[shrink-proc (or/c #f (-> set? any/c any/c))]
|
||||
[extract-proc (or/c #f (-> set? any/c any/c))]
|
||||
[clear-proc (or/c #f (-> set? any)) #f]
|
||||
[equal-key-proc (or/c #f (-> set? any/c any/c)) #f]
|
||||
[prop impersonator-property?]
|
||||
[prop-val any/c] ... ...)
|
||||
(and/c (or/c set? mutable-set? weak-set?) chaperone?)]{
|
||||
Chaperones @racket[st]. Like @racket[impersonate-hash-set] but with
|
||||
the constraints that the results of the @racket[inject-proc],
|
||||
@racket[add-proc], @racket[shrink-proc], @racket[extract-proc], and
|
||||
@racket[equal-key-proc] must be
|
||||
@racket[chaperone-of?] their second arguments. Also, the input
|
||||
may be an @racket[immutable?] set.
|
||||
}
|
||||
|
||||
@section{Custom Hash Sets}
|
||||
|
||||
@defform[(define-custom-set-types name
|
||||
|
@ -710,7 +806,7 @@ Supported for any @racket[st] that @supp{supports} @racket[set->stream].
|
|||
(code:line hash1-expr)
|
||||
(code:line hash1-expr hash2-expr)])]{
|
||||
|
||||
Creates a new set type based on the given comparison @racket[comparison-expr],
|
||||
Creates a new hash set type based on the given comparison @racket[comparison-expr],
|
||||
hash functions @racket[hash1-expr] and @racket[hash2-expr], and element
|
||||
predicate @racket[predicate-expr]; the interfaces for these functions are the
|
||||
same as in @racket[make-custom-set-types]. The new set type has three
|
||||
|
@ -750,6 +846,8 @@ initial elements.
|
|||
(make-mutable-string-set '("apple" "banana")))
|
||||
(generic-set? imm)
|
||||
(generic-set? mut)
|
||||
(set? imm)
|
||||
(generic-set? imm)
|
||||
(string-set? imm)
|
||||
(string-set? mut)
|
||||
(immutable-string-set? imm)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
@(define shared-eval (make-base-eval))
|
||||
@(interaction-eval #:eval shared-eval (require racket/shared))
|
||||
@examples[#:hidden #:eval shared-eval (require racket/shared)]
|
||||
|
||||
@(define maker
|
||||
(make-element #f (list
|
||||
|
@ -125,11 +125,11 @@ that can be created via mutation).
|
|||
(shared ([a (cons 1 b)]
|
||||
[b 7])
|
||||
a)
|
||||
(shared ([a a]) (code:comment @#,t{no indirection...})
|
||||
a)
|
||||
(shared ([a (cons 1 b)] (code:comment @#,t{@racket[b] is early...})
|
||||
[b a])
|
||||
a)
|
||||
(eval:error (shared ([a a]) (code:comment @#,t{no indirection...})
|
||||
a))
|
||||
(eval:error (shared ([a (cons 1 b)] (code:comment @#,t{@racket[b] is early...})
|
||||
[b a])
|
||||
a))
|
||||
(shared ([a (mcons 1 b)] (code:comment @#,t{@racket[b] is patchable...})
|
||||
[b a])
|
||||
a)
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
@(require "mz.rkt" (for-label racket/splicing racket/stxparam racket/local))
|
||||
|
||||
@(define splice-eval (make-base-eval))
|
||||
@interaction-eval[#:eval splice-eval (require racket/splicing
|
||||
racket/stxparam
|
||||
(for-syntax racket/base))]
|
||||
@examples[#:hidden #:eval splice-eval (require racket/splicing
|
||||
racket/stxparam
|
||||
(for-syntax racket/base))]
|
||||
|
||||
@title[#:tag "splicing"]{Local Binding with Splicing Body}
|
||||
|
||||
|
@ -35,7 +35,7 @@ definition context (in the same way as for @racket[begin]).
|
|||
(splicing-let-syntax ([one (lambda (stx) #'1)])
|
||||
(define o one))
|
||||
o
|
||||
one
|
||||
(eval:error one)
|
||||
]
|
||||
|
||||
When a splicing binding form occurs in a @tech{top-level context} or
|
||||
|
@ -46,9 +46,10 @@ once during compilation as in @racket[let-syntax], etc.
|
|||
|
||||
@examples[
|
||||
#:eval splice-eval
|
||||
(splicing-letrec ([x bad]
|
||||
[bad 1])
|
||||
x)]
|
||||
(eval:error
|
||||
(splicing-letrec ([x bad]
|
||||
[bad 1])
|
||||
x))]
|
||||
|
||||
If a definition within a splicing form is intended to be local to the
|
||||
splicing body, then the identifier should have a true value for the
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt")
|
||||
|
||||
@(define sp-eval (make-base-eval))
|
||||
@(interaction-eval #:eval sp-eval (require racket/list))
|
||||
@examples[#:hidden #:eval sp-eval (require racket/list)]
|
||||
|
||||
@title[#:tag "stringport"]{String Ports}
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ allocated string).}
|
|||
|
||||
@note-lib[racket/string]
|
||||
@(define string-eval (make-base-eval))
|
||||
@(interaction-eval #:eval string-eval (require racket/string racket/list))
|
||||
@examples[#:hidden #:eval string-eval (require racket/string racket/list)]
|
||||
|
||||
@defproc[(string-append* [str string?] ... [strs (listof string?)]) string?]{
|
||||
@; Note: this is exactly the same description as the one for append*
|
||||
|
|
|
@ -197,52 +197,52 @@ The result of @racket[make-struct-type] is five values:
|
|||
|
||||
@examples[
|
||||
#:eval struct-eval
|
||||
(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))
|
||||
|
||||
(eval:no-prompt
|
||||
(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)
|
||||
]
|
||||
|
||||
@interaction[
|
||||
#:eval struct-eval
|
||||
(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))
|
||||
(eval:no-prompt
|
||||
(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)
|
||||
]
|
||||
|
||||
@interaction[
|
||||
#:eval struct-eval
|
||||
(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)
|
||||
(eval:no-prompt
|
||||
(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)))))
|
||||
|
||||
(eval:error (make-c 'x 'y 'z))
|
||||
(define a-c (make-c 'x 2 'z))
|
||||
(a-ref a-c 1)
|
||||
]}
|
||||
|
||||
@interaction[
|
||||
#:eval struct-eval
|
||||
(define p1 #s(p a b c))
|
||||
(define-values (struct:p make-p p? p-ref p-set!)
|
||||
(make-struct-type 'p #f 3 0 #f null 'prefab #f '(0 1 2)))
|
||||
(eval:no-prompt
|
||||
(define p1 #s(p a b c))
|
||||
(define-values (struct:p make-p p? p-ref p-set!)
|
||||
(make-struct-type 'p #f 3 0 #f null 'prefab #f '(0 1 2))))
|
||||
|
||||
(p? p1)
|
||||
(p-ref p1 0)
|
||||
(make-p 'x 'y 'z)
|
||||
]
|
||||
]}
|
||||
|
||||
@defproc[(make-struct-field-accessor [accessor-proc struct-accessor-procedure?]
|
||||
[field-pos exact-nonnegative-integer?]
|
||||
|
@ -667,7 +667,7 @@ the inaccessible fields are omitted from the list.
|
|||
(struct->list (make-open 'a 'b))
|
||||
(struct->list #s(pre 1 2 3))
|
||||
(define-struct (secret open) (x y))
|
||||
(struct->list (make-secret 0 1 17 22))
|
||||
(eval:error (struct->list (make-secret 0 1 17 22)))
|
||||
(struct->list (make-secret 0 1 17 22) #:on-opaque 'return-false)
|
||||
(struct->list (make-secret 0 1 17 22) #:on-opaque 'skip)
|
||||
(struct->list 'not-a-struct #:on-opaque 'return-false)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require "mz.rkt")
|
||||
|
||||
@(define stx-eval (make-base-eval))
|
||||
@(interaction-eval #:eval stx-eval (require (for-syntax racket/base)))
|
||||
@examples[#:hidden #:eval stx-eval (require (for-syntax racket/base))]
|
||||
|
||||
@title[#:tag "stxcmp"]{Syntax Object Bindings}
|
||||
|
||||
|
|
|
@ -105,6 +105,14 @@ to the syntax object:
|
|||
list of @tech{module path index}es (or symbols) representing the
|
||||
modules explicitly for-template imported into the module.}
|
||||
|
||||
@item{@indexed-racket['module-direct-for-meta-requires] --- a list of
|
||||
lists: each list is an integer or @racket[#f] representing a
|
||||
@tech{phase level} followed by a list of @tech{module path index}es
|
||||
(or symbols) representing the modules explicitly imported into the
|
||||
module at the corresponding phase.
|
||||
|
||||
@history[#:added "6.4.0.1"]}
|
||||
|
||||
@item{@indexed-racket['module-variable-provides] --- a list of
|
||||
provided items, where each item is one of the following:
|
||||
|
||||
|
@ -138,5 +146,35 @@ to the syntax object:
|
|||
be exported indirectly through macro expansions. Definitions of
|
||||
macro-generated identifiers create uninterned symbols in this list.}
|
||||
|
||||
@item{@indexed-racket['module-body-context] --- a syntax
|
||||
object whose @tech{lexical information} corresponds to the inside of
|
||||
the module, so it includes the expansion's @tech{outside-edge scope}
|
||||
and its @tech{inside-edge scope}; that is, the syntax object
|
||||
simulates an identifier that is present in the original module body
|
||||
and inaccessible to manipulation by any macro, so that its lexical
|
||||
information includes bindings for the module's imports and
|
||||
definitions.
|
||||
|
||||
@history[#:added "6.4.0.1"]}
|
||||
|
||||
@item{@indexed-racket['module-body-inside-context] --- a syntax
|
||||
object whose @tech{lexical information} corresponds to an identifier
|
||||
that starts with no lexical context and is moved into the macro, so
|
||||
that it includes only the expansions's @tech{inside-edge scope}.
|
||||
|
||||
@history[#:added "6.4.0.1"]}
|
||||
|
||||
@item{@indexed-racket['module-body-context-simple?] --- a boolean,
|
||||
where @racket[#t] indicates that the bindings of the module's body
|
||||
(as recorded in the @tech{lexical information} of the value of the
|
||||
@racket['module-body-inside-context] property) can be directly
|
||||
reconstructed from the values of @racket['module-direct-requires],
|
||||
@racket['module-direct-for-syntax-requires],
|
||||
@racket['module-direct-for-template-requires], and
|
||||
@racket['module-direct-for-meta-requires].
|
||||
|
||||
@history[#:added "6.4.0.1"]}
|
||||
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt" scribble/eval)
|
||||
@(require "mz.rkt")
|
||||
|
||||
@(define stx-eval (make-base-eval))
|
||||
@(stx-eval '(require (for-syntax racket/base)))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt"
|
||||
scribble/eval
|
||||
(for-label racket/stxparam racket/stxparam-exptime racket/splicing))
|
||||
|
||||
@(define the-eval (make-base-eval))
|
||||
|
@ -30,7 +29,7 @@ used as a macro that expands to a use of the target identifier, but
|
|||
@racket[syntax-local-value] of @racket[id] does not produce
|
||||
the target's value.
|
||||
|
||||
@defexamples[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(define-syntax-parameter current-class #f)
|
||||
(define-syntax-parameter yield (make-rename-transformer #'abort))
|
||||
(define-syntax-parameter define/public
|
||||
|
@ -59,7 +58,7 @@ used as a macro that expands to a use of the target identifier, but
|
|||
@racket[syntax-local-value] of @racket[id] does not produce
|
||||
the target's value.
|
||||
|
||||
@defexamples[#:eval the-eval
|
||||
@examples[#:eval the-eval
|
||||
(define-syntax-parameter abort (syntax-rules ()))
|
||||
|
||||
(define-syntax forever
|
||||
|
@ -80,6 +79,34 @@ the target's value.
|
|||
(if t then else)))]))
|
||||
]}
|
||||
|
||||
@defform[(define-rename-transformer-parameter id expr)]{
|
||||
|
||||
Binds @racket[id] as syntax to a @tech{syntax parameter} that must
|
||||
be bound to a @racket[make-rename-transformer] result and, unlike
|
||||
@racket[define-syntax-parameter], @racket[syntax-local-value] of
|
||||
@racket[id] @emph{does} produce the target's value, including inside
|
||||
of @racket[syntax-parameterize].
|
||||
|
||||
@examples[#:eval the-eval #:escape UNSYNTAX
|
||||
(define-syntax (test stx)
|
||||
(syntax-case stx ()
|
||||
[(_ t)
|
||||
#`#,(syntax-local-value #'t)]))
|
||||
(define-syntax one 1)
|
||||
(define-syntax two 2)
|
||||
(define-syntax-parameter not-num
|
||||
(make-rename-transformer #'one))
|
||||
(test not-num)
|
||||
|
||||
(define-rename-transformer-parameter num
|
||||
(make-rename-transformer #'one))
|
||||
(test num)
|
||||
(syntax-parameterize ([num (make-rename-transformer #'two)])
|
||||
(test num))
|
||||
]
|
||||
|
||||
@history[#:added "6.3.0.14"]}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Syntax Parameter Inspection}
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
racket/require-syntax
|
||||
racket/provide-transform
|
||||
racket/provide-syntax
|
||||
racket/keyword-transform))
|
||||
racket/keyword-transform
|
||||
syntax/intdef))
|
||||
|
||||
@(define stx-eval (make-base-eval))
|
||||
@(interaction-eval #:eval stx-eval (require (for-syntax racket/base)))
|
||||
@examples[#:hidden #:eval stx-eval (require (for-syntax racket/base))]
|
||||
|
||||
@(define (transform-time) @t{This procedure must be called during the
|
||||
dynamic extent of a @tech{syntax transformer} application by the
|
||||
|
@ -197,10 +198,12 @@ the target identifier is extracted from the structure instance; if the
|
|||
field value is not an identifier, then an identifier @racketidfont{?}
|
||||
with an empty context is used, instead.
|
||||
|
||||
If the property value is a procedure that takes one argument, then the procedure
|
||||
is called to obtain the identifier that the rename transformer will use
|
||||
as a target identifier. If the procedure returns any value that is not
|
||||
an identifier, the @racket[exn:fail:contract] exception is raised.
|
||||
If the property value is a procedure that takes one argument, then the
|
||||
procedure is called to obtain the identifier that the rename
|
||||
transformer will use as a target identifier. The returned identifier
|
||||
should probably have the @racket['not-free-identifier=?] syntax
|
||||
property. If the procedure returns any value that is not an
|
||||
identifier, the @racket[exn:fail:contract] exception is raised.
|
||||
|
||||
@examples[#:eval stx-eval #:escape UNSYNTAX
|
||||
(code:comment "Example of a procedure argument for prop:rename-transformer")
|
||||
|
@ -298,6 +301,13 @@ context is meant to splice into an immediately enclosing context, then
|
|||
when @racket[syntax-local-context] produces a list, @racket[cons] the
|
||||
generated value onto that list.
|
||||
|
||||
When expressions are expanded via @racket[local-expand] with an
|
||||
internal-definition context @racket[intdef-ctx], and when the expanded
|
||||
expressions are incorporated into an overall form @racket[_new-stx],
|
||||
then typically @racket[internal-definition-context-track] should be
|
||||
applied to @racket[intdef-ctx] and @racket[_new-stx] to provide
|
||||
expansion history to external tools.
|
||||
|
||||
@transform-time[]
|
||||
|
||||
@examples[#:eval stx-eval
|
||||
|
@ -456,6 +466,18 @@ match the number of identifiers, otherwise the
|
|||
@transform-time[]}
|
||||
|
||||
|
||||
@defproc[(internal-definition-context-binding-identifiers
|
||||
[intdef-ctx internal-definition-context?])
|
||||
(listof identifier?)]{
|
||||
|
||||
Returns a list of all binding identifiers registered for
|
||||
@racket[intdef-ctx] through @racket[syntax-local-bind-syntaxes]. Each
|
||||
identifier in the returned list includes the @tech{internal-definition
|
||||
context}'s @tech{scope}.
|
||||
|
||||
@history[#:added "6.3.0.4"]}
|
||||
|
||||
|
||||
@defproc[(internal-definition-context-introduce [intdef-ctx internal-definition-context?]
|
||||
[stx syntax?]
|
||||
[mode (or/c 'flip 'add 'remove) 'flip])
|
||||
|
@ -489,6 +511,8 @@ provided for backward compatibility; the more general
|
|||
@history[#:changed "6.3" @elem{Simplified the operation to @tech{scope} removal.}]}
|
||||
|
||||
|
||||
|
||||
|
||||
@defthing[prop:expansion-contexts struct-type-property?]{
|
||||
|
||||
A @tech{structure type property} to constrain the use of macro
|
||||
|
@ -570,7 +594,7 @@ if not @racket[#f]. If @racket[failure-thunk] is @racket[false], the
|
|||
@examples[#:eval stx-eval
|
||||
(define-syntax (transformer-2 stx)
|
||||
(syntax-local-value #'something-else (λ () (error "no binding"))))
|
||||
(transformer-2)
|
||||
(eval:error (transformer-2))
|
||||
]
|
||||
@examples[#:eval stx-eval
|
||||
(define-syntax nachos #'(printf "nachos~n"))
|
||||
|
@ -629,7 +653,9 @@ Other syntactic forms can capture lifts by using
|
|||
@racket[local-expand/capture-lifts] or
|
||||
@racket[local-transformer-expand/capture-lifts].
|
||||
|
||||
@transform-time[]}
|
||||
@transform-time[] In addition, this procedure can be called only when
|
||||
a lift target is available, as indicated by
|
||||
@racket[syntax-transforming-with-lifts?].}
|
||||
|
||||
@defproc[(syntax-local-lift-values-expression [n exact-nonnegative-integer?] [stx syntax?])
|
||||
(listof identifier?)]{
|
||||
|
@ -855,6 +881,21 @@ transformer} application by the expander and while a module is being
|
|||
@tech{visit}ed, @racket[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(syntax-transforming-with-lifts?) boolean?]{
|
||||
|
||||
Returns @racket[#t] if @racket[(syntax-transforming?)] produces
|
||||
@racket[#t] and a target context is available for lifting expressions
|
||||
(via @racket[syntax-local-lift-expression]), @racket[#f] otherwise.
|
||||
|
||||
For example, during an immedate macro expansion triggered by
|
||||
@racket[local-expand], as opposed to
|
||||
@racket[local-expand/capture-lifts], @racket[(syntax-transforming?)]
|
||||
produces @racket[#t] while @racket[(syntax-transforming-with-lifts?)]
|
||||
produces @racket[#f].
|
||||
|
||||
@history[#:added "6.3.0.9"]}
|
||||
|
||||
|
||||
@defproc[(syntax-transforming-module-expression?) boolean?]{
|
||||
|
||||
Returns @racket[#t] during the dynamic extent of a @tech{syntax
|
||||
|
@ -916,7 +957,7 @@ and different result procedures use distinct scopes.
|
|||
added the optional operation argument
|
||||
in the result procedure.}]}
|
||||
|
||||
@defproc[(make-syntax-delta-introducer [ext-stx syntax?]
|
||||
@defproc[(make-syntax-delta-introducer [ext-stx identifier?]
|
||||
[base-stx (or/c syntax? #f)]
|
||||
[phase-level (or/c #f exact-integer?)
|
||||
(syntax-local-phase-level)])
|
||||
|
@ -925,8 +966,10 @@ and different result procedures use distinct scopes.
|
|||
Produces a procedure that behaves like the result of
|
||||
@racket[make-syntax-introducer], but using the @tech{scopes} of
|
||||
@racket[ext-stx] that are not shared with @racket[base-stx].
|
||||
A @racket[#f] value for @racket[base-stx] is equivalent to a syntax
|
||||
object with no @tech{scopes}.
|
||||
|
||||
This procedure is potentially useful when @racket[_m-id] has a
|
||||
This procedure is potentially useful when some @racket[_m-id] has a
|
||||
transformer binding that records some @racket[_orig-id], and a use of
|
||||
@racket[_m-id] introduces a binding of @racket[_orig-id]. In that
|
||||
case, the @tech{scopes} one the use of @racket[_m-id] added since the
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@(require scribble/struct "mz.rkt" (for-syntax mzscheme))
|
||||
|
||||
@(define racket-eval (make-base-eval))
|
||||
@(interaction-eval #:eval racket-eval (require (for-syntax racket/base)))
|
||||
@examples[#:hidden #:eval racket-eval (require (for-syntax racket/base))]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@title[#:tag "syntax-model"]{Syntax Model}
|
||||
|
@ -742,9 +742,7 @@ internal-definition context are equivalent to local binding via
|
|||
@racket[letrec-syntaxes+values]; macro expansion converts internal
|
||||
definitions to a @racket[letrec-syntaxes+values] form.
|
||||
|
||||
Expansion of an internal-definition context begins with the
|
||||
introduction of a fresh @tech{scope} for the context. Thereafter,
|
||||
expansion relies on @tech{partial expansion} of each @racket[_body] in
|
||||
Expansion relies on @tech{partial expansion} of each @racket[_body] in
|
||||
an internal-definition sequence. Partial expansion of each
|
||||
@racket[_body] produces a form matching one of the following cases:
|
||||
|
||||
|
@ -782,8 +780,25 @@ are then converted to bindings in a @racket[letrec-syntaxes+values]
|
|||
form, and all expressions after the last definition become the body of
|
||||
the @racket[letrec-syntaxes+values] form.
|
||||
|
||||
Before partial expansion begins, expansion of an internal-definition
|
||||
context begins with the introduction of a fresh @deftech{outside-edge
|
||||
scope} on the content of the internal-definition context. This
|
||||
outside-edge scope effectively identifies syntax objects that are
|
||||
present in the original form. An @deftech{inside-edge scope} is also
|
||||
created and added to the original content; furthermore, the
|
||||
inside-edge scope is added to the result of any partial expansion.
|
||||
This inside-edge scope ensures that all bindings introduced by the
|
||||
internal-definition context have a particular scope in common.
|
||||
|
||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@subsection[#:tag "mod-parse"]{Module Phases and Visits}
|
||||
@subsection[#:tag "mod-parse"]{Module Expansion, Phases, and Visits}
|
||||
|
||||
Expansion of a @racket[module] form proceeds in a similar way to
|
||||
@seclink["intdef-body"]{expansion of an internal-definition context}:
|
||||
an @tech{outside-edge scope} is created for the original module
|
||||
content, and an @tech{inside-edge scope} is added to both the original
|
||||
module and any form that appears during a partial expansion of the
|
||||
module's top-level forms to uncover definitions and imports.
|
||||
|
||||
A @racket[require] form not only introduces @tech{bindings} at
|
||||
expansion time, but also @deftech{visits} the referenced module when
|
||||
|
@ -893,7 +908,7 @@ bucket-2
|
|||
(define (odd x) (if (zero? x) #f (even (sub1 x))))
|
||||
(define (even x) (if (zero? x) #t (odd (sub1 x))))
|
||||
(odd 17))]))
|
||||
(defs-and-uses/fail)
|
||||
(eval:error (defs-and-uses/fail))
|
||||
|
||||
(define-syntax defs-and-uses
|
||||
(syntax-rules ()
|
||||
|
|
|
@ -36,13 +36,13 @@ in the argument list are automatically converted to symbols.
|
|||
[(make-pred name)
|
||||
(format-id #'name "~a?" (syntax-e #'name))]))
|
||||
(make-pred pair)
|
||||
(make-pred none-such)
|
||||
(eval:error (make-pred none-such))
|
||||
(define-syntax (better-make-pred stx)
|
||||
(syntax-case stx ()
|
||||
[(better-make-pred name)
|
||||
(format-id #'name #:source #'name
|
||||
"~a?" (syntax-e #'name))]))
|
||||
(better-make-pred none-such)
|
||||
(eval:error (better-make-pred none-such))
|
||||
]
|
||||
|
||||
(Scribble doesn't show it, but the DrRacket pinpoints the location of
|
||||
|
@ -108,9 +108,10 @@ is prefixed with the special form name as described under
|
|||
@racket[current-syntax-context].
|
||||
|
||||
@examples[#:eval the-eval
|
||||
(wrong-syntax #'here "expected ~s" 'there)
|
||||
(parameterize ([current-syntax-context #'(look over here)])
|
||||
(wrong-syntax #'here "expected ~s" 'there))
|
||||
(eval:error (wrong-syntax #'here "expected ~s" 'there))
|
||||
(eval:error
|
||||
(parameterize ([current-syntax-context #'(look over here)])
|
||||
(wrong-syntax #'here "expected ~s" 'there)))
|
||||
]
|
||||
|
||||
A macro using @racket[wrong-syntax] might set the syntax context at the very
|
||||
|
|
|
@ -282,7 +282,7 @@ form. See also @racket[module-compiled-language-info],
|
|||
|
||||
See also @secref["module-eval-model"] and @secref["mod-parse"].
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module duck racket/base
|
||||
(provide num-eggs quack)
|
||||
(define num-eggs 2)
|
||||
|
@ -510,13 +510,13 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
is not in the set that @racket[require-spec] describes, a syntax
|
||||
error is reported.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(require (only-in racket/tcp
|
||||
tcp-listen
|
||||
[tcp-accept my-accept]))
|
||||
tcp-listen
|
||||
my-accept
|
||||
tcp-accept
|
||||
(eval:error tcp-accept)
|
||||
]}
|
||||
|
||||
@defsubform[(except-in require-spec id ...)]{ Like
|
||||
|
@ -525,11 +525,11 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
in the set that @racket[require-spec] describes, a syntax error is
|
||||
reported.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(require (except-in racket/tcp
|
||||
tcp-listen))
|
||||
tcp-accept
|
||||
tcp-listen
|
||||
(eval:error tcp-listen)
|
||||
]}
|
||||
|
||||
@defsubform[(prefix-in prefix-id require-spec)]{ Like
|
||||
|
@ -538,7 +538,7 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
@racket[prefix-id] is ignored, and instead preserved from the
|
||||
identifiers before prefixing.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(require (prefix-in tcp: racket/tcp))
|
||||
tcp:tcp-accept
|
||||
tcp:tcp-listen
|
||||
|
@ -550,7 +550,7 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
@racket[orig-id] is not in the set that @racket[require-spec]
|
||||
describes, a syntax error is reported.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(require (rename-in racket/tcp
|
||||
(tcp-accept accept)
|
||||
(tcp-listen listen)))
|
||||
|
@ -563,7 +563,7 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
@racket[require-spec]s have the same identifier name but they do not refer to
|
||||
the same original binding, a syntax error is reported.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(require (combine-in (only-in racket/tcp tcp-accept)
|
||||
(only-in racket/tcp tcp-listen)))
|
||||
tcp-accept
|
||||
|
@ -588,7 +588,7 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
The following example imports bindings only at @tech{phase level} 1,
|
||||
the transform phase:
|
||||
|
||||
@interaction[#:eval meta-in-eval
|
||||
@examples[#:label #f #:eval meta-in-eval
|
||||
(module nest racket
|
||||
(provide (for-syntax meta-eggs)
|
||||
(for-meta 1 meta-chicks)
|
||||
|
@ -604,13 +604,13 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
#'(void))
|
||||
|
||||
(desc)
|
||||
num-eggs
|
||||
(eval:error num-eggs)
|
||||
]
|
||||
|
||||
The following example imports only bindings at @tech{phase level} 0, the
|
||||
normal phase.
|
||||
|
||||
@interaction[#:eval meta-in-eval
|
||||
@examples[#:label #f #:eval meta-in-eval
|
||||
(require (only-meta-in 0 'nest))
|
||||
num-eggs
|
||||
]}
|
||||
|
@ -622,7 +622,7 @@ bindings of each @racket[require-spec] are visible for expanding later
|
|||
@tech{label phase level} corresponds to @racket[#f], and a shifting
|
||||
combination that involves @racket[#f] produces @racket[#f].
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide num-eggs)
|
||||
(define num-eggs 2))
|
||||
|
@ -894,7 +894,7 @@ level} 0 are imported.
|
|||
(let ()
|
||||
(local-require racket/control)
|
||||
fcontrol)
|
||||
fcontrol
|
||||
(eval:error fcontrol)
|
||||
]}
|
||||
|
||||
|
||||
|
@ -944,7 +944,7 @@ as follows.
|
|||
identifier must match (otherwise, the external name could be
|
||||
ambiguous).
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide num-eggs)
|
||||
(define num-eggs 2))
|
||||
|
@ -968,7 +968,7 @@ as follows.
|
|||
macro-introduced imports are not re-exported, unless the
|
||||
@racket[(all-defined-out)] form was introduced at the same time.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (all-defined-out))
|
||||
(define num-eggs 2))
|
||||
|
@ -987,7 +987,7 @@ as follows.
|
|||
macro-introduced imports are not re-exported, unless the
|
||||
@racket[module-path] was introduced at the same time.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide num-eggs)
|
||||
(define num-eggs 2))
|
||||
|
@ -1003,13 +1003,13 @@ as follows.
|
|||
the relevant @tech{phase level}. The symbolic name for each export is
|
||||
@racket[export-id] instead @racket[orig-d].
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (rename-out [count num-eggs]))
|
||||
(define count 2))
|
||||
(require 'nest)
|
||||
num-eggs
|
||||
count
|
||||
(eval:error count)
|
||||
]}
|
||||
|
||||
@defsubform[(except-out provide-spec provide-spec ...)]{ Like the
|
||||
|
@ -1019,7 +1019,7 @@ as follows.
|
|||
reported. The symbolic export name information in the latter
|
||||
@racket[provide-spec]s is ignored; only the bindings are used.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (except-out (all-defined-out)
|
||||
num-chicks))
|
||||
|
@ -1027,14 +1027,14 @@ as follows.
|
|||
(define num-chicks 3))
|
||||
(require 'nest)
|
||||
num-eggs
|
||||
num-chicks
|
||||
(eval:error num-chicks)
|
||||
]}
|
||||
|
||||
@defsubform[(prefix-out prefix-id provide-spec)]{
|
||||
Like @racket[provide-spec], but with each symbolic export name from
|
||||
@racket[provide-spec] prefixed with @racket[prefix-id].
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (prefix-out chicken: num-eggs))
|
||||
(define num-eggs 2))
|
||||
|
@ -1055,7 +1055,7 @@ as follows.
|
|||
accessor and mutator bindings of the super-type are @italic{not}
|
||||
included by @racket[struct-out] for export.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (struct-out egg))
|
||||
(struct egg (color wt)))
|
||||
|
@ -1066,7 +1066,7 @@ as follows.
|
|||
@defsubform[(combine-out provide-spec ...)]{ The union of the
|
||||
@racket[provide-spec]s.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide (combine-out num-eggs num-chicks))
|
||||
(define num-eggs 2)
|
||||
|
@ -1084,7 +1084,7 @@ as follows.
|
|||
For more details, see @secref["modprotect"]. The @racket[provide-spec] must specify only
|
||||
bindings that are defined within the exporting module.
|
||||
|
||||
@examples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(provide num-eggs (protect-out num-chicks))
|
||||
(define num-eggs 2)
|
||||
|
@ -1102,7 +1102,7 @@ as follows.
|
|||
(require 'nest)
|
||||
(list num-eggs num-chicks)
|
||||
(weak-eval 'num-eggs)
|
||||
(weak-eval 'num-chicks)
|
||||
(eval:error (weak-eval 'num-chicks))
|
||||
]}
|
||||
|
||||
@specsubform[#:literals (for-meta)
|
||||
|
@ -1118,7 +1118,7 @@ as follows.
|
|||
@racket[all-from-out] exports bindings imported with a shift by
|
||||
@racket[phase-level].
|
||||
|
||||
@examples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module nest racket
|
||||
(begin-for-syntax
|
||||
(define eggs 2))
|
||||
|
@ -1132,11 +1132,12 @@ as follows.
|
|||
(test-eggs)
|
||||
chickens
|
||||
|
||||
(module broken-nest racket
|
||||
(define eggs 2)
|
||||
(define chickens 3)
|
||||
(provide (for-syntax eggs)
|
||||
chickens))
|
||||
(eval:error
|
||||
(module broken-nest racket
|
||||
(define eggs 2)
|
||||
(define chickens 3)
|
||||
(provide (for-syntax eggs)
|
||||
chickens)))
|
||||
|
||||
(module nest2 racket
|
||||
(begin-for-syntax
|
||||
|
@ -1309,7 +1310,7 @@ Like @racket[require-spec], but including only imports whose names
|
|||
match @racket[regexp]. The @racket[regexp] must be a literal regular
|
||||
expression (see @secref["regexp"]).
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module zoo racket/base
|
||||
(provide tunafish swordfish blowfish
|
||||
monkey lizard ant)
|
||||
|
@ -1324,7 +1325,7 @@ Like @racket[require-spec], but including only imports whose names
|
|||
tunafish
|
||||
swordfish
|
||||
blowfish
|
||||
monkey
|
||||
(eval:error monkey)
|
||||
]}
|
||||
|
||||
@defform[(subtract-in require-spec subtracted-spec ...)]{
|
||||
|
@ -1332,7 +1333,7 @@ monkey
|
|||
Like @racket[require-spec], but omitting those imports that would be
|
||||
imported by one of the @racket[subtracted-spec]s.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(module earth racket
|
||||
(provide land sea air)
|
||||
(define land 1)
|
||||
|
@ -1350,7 +1351,7 @@ Like @racket[require-spec], but omitting those imports that would be
|
|||
|
||||
(require racket/require)
|
||||
(require (subtract-in 'solar-system 'earth))
|
||||
land
|
||||
(eval:error land)
|
||||
aliens
|
||||
]}
|
||||
|
||||
|
@ -1517,7 +1518,7 @@ introduces @racketidfont{#%datum} identifiers.
|
|||
@mz-examples[
|
||||
(#%datum . 10)
|
||||
(#%datum . x)
|
||||
(#%datum . #:x)
|
||||
(eval:error (#%datum . #:x))
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1532,14 +1533,14 @@ expression.
|
|||
|
||||
@mz-examples[
|
||||
(#%expression (+ 1 2))
|
||||
(#%expression (define x 10))
|
||||
(eval:error (#%expression (define x 10)))
|
||||
]
|
||||
|
||||
The @racket[#%expression] form is helpful in recursive definition contexts
|
||||
where expanding a subsequent definition can provide compile-time information
|
||||
for the current expression. For example, consider a @racket[define-sym-case]
|
||||
macro that simply records some symbols at compile-time in a given identifier.
|
||||
@interaction/no-prompt[#:eval meta-in-eval
|
||||
@examples[#:label #f #:no-prompt #:eval meta-in-eval
|
||||
(define-syntax (define-sym-case stx)
|
||||
(syntax-case stx ()
|
||||
[(_ id sym ...)
|
||||
|
@ -1548,7 +1549,7 @@ macro that simply records some symbols at compile-time in a given identifier.
|
|||
'(sym ...))]))]
|
||||
and then a variant of @racket[case] that checks to make sure the symbols
|
||||
used in the expression match those given in the earlier definition:
|
||||
@interaction/no-prompt[#:eval meta-in-eval
|
||||
@examples[#:label #f #:no-prompt #:eval meta-in-eval
|
||||
(define-syntax (sym-case stx)
|
||||
(syntax-case stx ()
|
||||
[(_ id val-expr [(sym) expr] ...)
|
||||
|
@ -1575,18 +1576,19 @@ If the definition follows the use like this, then
|
|||
the @racket[define-sym-case] macro does not have
|
||||
a chance to bind @racket[id] and the @racket[sym-case]
|
||||
macro signals an error:
|
||||
@interaction[#:eval meta-in-eval
|
||||
(let ()
|
||||
(sym-case land-creatures 'bear
|
||||
[(bear) 1]
|
||||
[(fox) 2])
|
||||
(define-sym-case land-creatures bear fox))
|
||||
@examples[#:label #f #:eval meta-in-eval
|
||||
(eval:error
|
||||
(let ()
|
||||
(sym-case land-creatures 'bear
|
||||
[(bear) 1]
|
||||
[(fox) 2])
|
||||
(define-sym-case land-creatures bear fox)))
|
||||
]
|
||||
But if the @racket[sym-case] is wrapped in an @racket[#%expression],
|
||||
then the expander does not need to expand it to know it is
|
||||
an expression and it moves on to the @racket[define-sym-case]
|
||||
expression.
|
||||
@interaction[#:eval meta-in-eval
|
||||
@examples[#:label #f #:eval meta-in-eval
|
||||
(let ()
|
||||
(#%expression (sym-case sea-creatures 'whale
|
||||
[(whale) 1]
|
||||
|
@ -1740,7 +1742,7 @@ expander introduces @racketidfont{#%app} identifiers.
|
|||
@mz-examples[
|
||||
(#%app + 1 2)
|
||||
(#%app (lambda (x #:arg y) (list y x)) #:arg 2 1)
|
||||
(#%app cons)
|
||||
(eval:error (#%app cons))
|
||||
]}
|
||||
|
||||
@defform*[[(#%plain-app proc-expr arg-expr ...)
|
||||
|
@ -2342,13 +2344,14 @@ in @math{O(log N)} time for @math{N} @racket[datum]s.
|
|||
(case (list 'quote 'x)
|
||||
[(x) "ex"]
|
||||
[('x) "quoted ex"])
|
||||
]
|
||||
@def+int[
|
||||
(define (classify c)
|
||||
(case (char-general-category c)
|
||||
[(ll lu lt ln lo) "letter"]
|
||||
[(nd nl no) "number"]
|
||||
[else "other"]))
|
||||
|
||||
(eval:no-prompt
|
||||
(define (classify c)
|
||||
(case (char-general-category c)
|
||||
[(ll lu lt ln lo) "letter"]
|
||||
[(nd nl no) "number"]
|
||||
[else "other"])))
|
||||
|
||||
(classify #\A)
|
||||
(classify #\1)
|
||||
(classify #\!)
|
||||
|
@ -2394,19 +2397,20 @@ In a context that allows @tech{liberal expansion} of @racket[define],
|
|||
@racket[lambda] form with keyword arguments or @racket[args] include
|
||||
keyword arguments.
|
||||
|
||||
@defexamples[
|
||||
(define x 10)
|
||||
@examples[
|
||||
(eval:no-prompt (define x 10))
|
||||
x
|
||||
]
|
||||
@def+int[
|
||||
(define (f x)
|
||||
(+ x 1))
|
||||
(f 10)
|
||||
]
|
||||
|
||||
@def+int[
|
||||
(define ((f x) [y 20])
|
||||
(+ x y))
|
||||
(eval:no-prompt
|
||||
(define (f x)
|
||||
(+ x 1)))
|
||||
|
||||
(f 10)
|
||||
|
||||
(eval:no-prompt
|
||||
(define ((f x) [y 20])
|
||||
(+ x y)))
|
||||
|
||||
((f 10) 30)
|
||||
((f 10))
|
||||
]
|
||||
|
@ -2427,7 +2431,7 @@ and the top-level mapping of each @racket[id] (in the
|
|||
@techlink{namespace} linked with the compiled definition) is set to
|
||||
the binding at the same time.
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
(define-values () (values))
|
||||
(define-values (x y z) (values 1 2 3))
|
||||
z
|
||||
|
@ -2459,7 +2463,7 @@ expands to a definition of the first form where the @racket[expr] is a
|
|||
In an @tech{internal-definition context} (see @secref["intdef-body"]),
|
||||
a @racket[define-syntax] form introduces a local binding.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(define-syntax foo
|
||||
(syntax-rules ()
|
||||
((_ a ...)
|
||||
|
@ -2490,7 +2494,7 @@ binding; see @secref["macro-introduced-bindings"].
|
|||
In an @tech{internal-definition context} (see @secref["intdef-body"]),
|
||||
a @racket[define-syntaxes] form introduces local bindings.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(define-syntaxes (foo1 foo2 foo3)
|
||||
(let ([transformer1 (lambda (syntax-object)
|
||||
(syntax-case syntax-object ()
|
||||
|
@ -2526,14 +2530,14 @@ form must be expanded before the use is expanded). In particular,
|
|||
mutually recursive functions bound by @racket[define-for-syntax] must
|
||||
be defined by the same @racket[define-for-syntax] form.
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(define-for-syntax helper 2)
|
||||
(define-syntax (make-two syntax-object)
|
||||
(printf "helper is ~a\n" helper)
|
||||
#'2)
|
||||
(make-two)
|
||||
(code:comment @#,t{`helper' is not bound in the runtime phase})
|
||||
helper
|
||||
(eval:error helper)
|
||||
|
||||
(define-for-syntax (filter-ids ids)
|
||||
(filter identifier? ids))
|
||||
|
@ -2552,7 +2556,7 @@ Like @racket[define-for-syntax], but @racket[expr] must produce as
|
|||
many values as supplied @racket[id]s, and all of the @racket[id]s are
|
||||
bound (at @tech{phase level} 1).}
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
@examples[#:eval (syntax-eval) #:once
|
||||
(define-values-for-syntax (foo1 foo2) (values 1 2))
|
||||
(define-syntax (bar syntax-object)
|
||||
(printf "foo1 is ~a foo2 is ~a\n" foo1 foo2)
|
||||
|
@ -2768,14 +2772,14 @@ variable} that has not been defined, the @exnraise[exn:fail:contract].
|
|||
|
||||
See also @racket[compile-allow-set!-undefined].
|
||||
|
||||
@defexamples[
|
||||
@examples[
|
||||
(define x 12)
|
||||
(set! x (add1 x))
|
||||
x
|
||||
(let ([x 5])
|
||||
(set! x (add1 x))
|
||||
x)
|
||||
(set! i-am-not-defined 10)
|
||||
(eval:error (set! i-am-not-defined 10))
|
||||
]}
|
||||
|
||||
@defform[(set!-values (id ...) expr)]{
|
||||
|
@ -2859,7 +2863,7 @@ other way than as @racket[(#,unquote-id _expr)] or
|
|||
(eval:alts (#,(racket quasiquote) (0 1 2)) `(0 1 2))
|
||||
(eval:alts (#,(racket quasiquote) (0 (#,unquote-id (+ 1 2)) 4)) `(0 ,(+ 1 2) 4))
|
||||
(eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id (list 1 2)) 4)) `(0 ,@(list 1 2) 4))
|
||||
(eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4))
|
||||
(eval:error (eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1) 4)) `(0 ,@1 4)))
|
||||
(eval:alts (#,(racket quasiquote) (0 (#,unquote-splicing-id 1))) `(0 ,@1))
|
||||
]
|
||||
|
||||
|
@ -2922,8 +2926,8 @@ Similar to @racket[quote], but produces a @tech{syntax object}
|
|||
that preserves the @tech{lexical information} and source-location
|
||||
information attached to @racket[datum] at expansion time.
|
||||
|
||||
When @racket[#:local] is specified, than all @tech{scopes} in the
|
||||
syntax object's @tech{lexical information} is preserved. When
|
||||
When @racket[#:local] is specified, then all @tech{scopes} in the
|
||||
syntax object's @tech{lexical information} are preserved. When
|
||||
@racket[#:local] is omitted, then the @tech{scope sets} within
|
||||
@racket[datum] are pruned to omit the @tech{scope} for any binding
|
||||
form that appears between the @racket[quote-syntax] form and the
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt" (for-label racket/trace)
|
||||
scribble/eval)
|
||||
@(require "mz.rkt" (for-label racket/trace))
|
||||
|
||||
@(begin (define ev (make-base-eval))
|
||||
(ev '(require racket/trace))
|
||||
|
|
|
@ -31,5 +31,5 @@ the @racket[call-with-values] call.
|
|||
|
||||
@examples[
|
||||
(call-with-values (lambda () (values 1 2)) +)
|
||||
(call-with-values (lambda () 1) (lambda (x y) (+ x y)))
|
||||
(eval:error (call-with-values (lambda () 1) (lambda (x y) (+ x y))))
|
||||
]}
|
||||
|
|
|
@ -151,8 +151,8 @@ _i)] is the value produced by @racket[(proc _i)].
|
|||
|
||||
@note-lib[racket/vector]
|
||||
@(define vec-eval (make-base-eval))
|
||||
@(interaction-eval #:eval vec-eval
|
||||
(require racket/vector))
|
||||
@examples[#:hidden #:eval vec-eval
|
||||
(require racket/vector)]
|
||||
|
||||
@defproc[(vector-set*! [vec (and/c vector? (not/c immutable?))]
|
||||
[pos exact-nonnegative-integer?]
|
||||
|
|
|
@ -16,7 +16,7 @@ Most of our collections come with test suites. These tests suites tend to
|
|||
Run the test suites before you commit. To facilitate testing, we urge you
|
||||
to add a @tt{TESTME.txt} file to your collections. Ideally, you may also
|
||||
wish to have a file in this directory that runs the basic tests. See the
|
||||
@hyperlink["https://github.com/plt/racket/tree/master/collects/2htdp/"]{2htdp},
|
||||
@hyperlink["https://github.com/racket/racket/tree/master/collects/2htdp/"]{2htdp},
|
||||
which is one of the collections with its own testing style. The file should
|
||||
describe where the tests are located, how to run these tests, and what to
|
||||
look for in terms of successes and failures. These files are necessary
|
||||
|
@ -30,7 +30,7 @@ After you commit, watch for and read(!)
|
|||
parts: @tt{success} and @tt{failure}. The former is for tests that should
|
||||
succeed now, and the latter is for tests that are currently expected to
|
||||
fail. See the
|
||||
@hyperlink["https://github.com/plt/racket/tree/master/collects/tests/typed-scheme"]{Typed
|
||||
@hyperlink["https://github.com/racket/racket/tree/master/collects/tests/typed-scheme"]{Typed
|
||||
Racket testing arrangement} for an example. When you create such
|
||||
@tt{failure} tests, you may wish to disable DrDr's checking like this:
|
||||
@verbatim[#:indent 2]{
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
@defmodule[syntax/free-vars]
|
||||
|
||||
@defproc[(free-vars [expr-stx syntax?] [insp inspector? _mod-decl-insp])
|
||||
@defproc[(free-vars [expr-stx syntax?]
|
||||
[insp inspector? _mod-decl-insp]
|
||||
[#:module-bound? module-bound? any/c #f])
|
||||
(listof identifier?)]{
|
||||
|
||||
Returns a list of free @racket[lambda]- and @racket[let]-bound
|
||||
|
@ -18,3 +20,6 @@ The inspector @racket[insp] is used to disarm @racket[expr-stx] and
|
|||
sub-expressions before extracting identifiers. The default
|
||||
@racket[insp] is the declaration-time inspector of the
|
||||
@racketmodname[syntax/free-vars] module.}
|
||||
|
||||
If @racket[module-bound?] is non-false, the list of free variables also
|
||||
includes free module-bound identifiers.
|
||||
|
|
|
@ -118,6 +118,16 @@ the @racket[failure] argument is applied if it is a procedure, or
|
|||
simply returned otherwise.
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-ref! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[failure any/c])
|
||||
any]{
|
||||
|
||||
Like @racket[hash-ref!].
|
||||
|
||||
@history[#:added "6.3.0.6"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-set! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
|
@ -134,6 +144,26 @@ Like @racket[hash-set!].
|
|||
Like @racket[hash-set].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-set*! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c] ...)
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-set*!].
|
||||
|
||||
@history[#:added "6.3.0.6"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-set* [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c] ...)
|
||||
immutable-free-id-table?]{
|
||||
|
||||
Like @racket[hash-set*].
|
||||
|
||||
@history[#:added "6.3.0.6"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-remove! [table mutable-free-id-table?]
|
||||
[id identifier?])
|
||||
void?]{
|
||||
|
@ -148,6 +178,30 @@ Like @racket[hash-remove!].
|
|||
Like @racket[hash-remove].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-update! [table mutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[updater (any/c . -> . any/c)]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
void?]{
|
||||
|
||||
Like @racket[hash-update!].
|
||||
|
||||
@history[#:added "6.3.0.6"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-update [table immutable-free-id-table?]
|
||||
[id identifier?]
|
||||
[updater (any/c . -> . any/c)]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
immutable-free-id-table?]{
|
||||
|
||||
Like @racket[hash-update].
|
||||
|
||||
@history[#:added "6.3.0.6"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-map [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
list?]{
|
||||
|
@ -155,6 +209,30 @@ Like @racket[hash-remove].
|
|||
Like @racket[hash-map].
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-keys [table free-id-table?])
|
||||
(listof identifier?)]{
|
||||
|
||||
Like @racket[hash-keys].
|
||||
|
||||
@history[#:added "6.3.0.3"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-values [table free-id-table?])
|
||||
(listof any/c)]{
|
||||
|
||||
Like @racket[hash-values].
|
||||
|
||||
@history[#:added "6.3.0.3"]
|
||||
}
|
||||
|
||||
@defproc[(in-free-id-table [table free-id-table?])
|
||||
sequence?]{
|
||||
|
||||
Like @racket[in-hash].
|
||||
|
||||
@history[#:added "6.3.0.3"]
|
||||
}
|
||||
|
||||
@defproc[(free-id-table-for-each [table free-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
void?]{
|
||||
|
@ -230,6 +308,10 @@ etc) can be used on bound-identifier tables.
|
|||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
any]
|
||||
@defproc[(bound-id-table-ref! [table mutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[failure any/c])
|
||||
any]
|
||||
@defproc[(bound-id-table-set! [table mutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c])
|
||||
|
@ -238,15 +320,41 @@ etc) can be used on bound-identifier tables.
|
|||
[id identifier?]
|
||||
[v any/c])
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-set*! [table mutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c] ...)
|
||||
void?]
|
||||
@defproc[(bound-id-table-set* [table immutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[v any/c] ...)
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-remove! [table mutable-bound-id-table?]
|
||||
[id identifier?])
|
||||
void?]
|
||||
@defproc[(bound-id-table-remove [table immutable-bound-id-table?]
|
||||
[id identifier?])
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-update! [table mutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[updater (any/c . -> . any/c)]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
void?]
|
||||
@defproc[(bound-id-table-update [table immutable-bound-id-table?]
|
||||
[id identifier?]
|
||||
[updater (any/c . -> . any/c)]
|
||||
[failure any/c
|
||||
(lambda () (raise (make-exn:fail .....)))])
|
||||
immutable-bound-id-table?]
|
||||
@defproc[(bound-id-table-map [table bound-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
list?]
|
||||
@defproc[(bound-id-table-keys [table bound-id-table?])
|
||||
(listof identifier?)]
|
||||
@defproc[(bound-id-table-values [table bound-id-table?])
|
||||
(listof any/c)]
|
||||
@defproc[(in-bound-id-table [table bound-id-table?])
|
||||
sequence?]
|
||||
@defproc[(bound-id-table-for-each [table bound-id-table?]
|
||||
[proc (-> identifier? any/c any)])
|
||||
void?]
|
||||
|
@ -273,6 +381,11 @@ Like the procedures for free-identifier tables
|
|||
(@racket[make-free-id-table], @racket[free-id-table-ref], etc), but
|
||||
for bound-identifier tables, which use @racket[bound-identifier=?] to
|
||||
compare keys.
|
||||
|
||||
@history[#:changed "6.3.0.3" "Added bound-id-table-keys, bound-id-table-values, in-bound-id-table."
|
||||
#:changed "6.3.0.6"
|
||||
@string-append{Added bound-id-table-ref!, bound-id-table-set*,
|
||||
bound-id-table-set*!, bound-id-table-update!, and bound-id-table-update}]
|
||||
}
|
||||
|
||||
@close-eval[id-table-eval]
|
||||
@close-eval[id-table-eval]
|
||||
|
|
22
pkgs/racket-doc/syntax/scribblings/intdef.scrbl
Normal file
22
pkgs/racket-doc/syntax/scribblings/intdef.scrbl
Normal file
|
@ -0,0 +1,22 @@
|
|||
#lang scribble/doc
|
||||
@(require "common.rkt" (for-label syntax/intdef))
|
||||
|
||||
@title[#:tag "intdef"]{Internal-Definition Context Helpers}
|
||||
|
||||
@defmodule[syntax/intdef]
|
||||
|
||||
@history[#:added "6.3.0.4"]
|
||||
|
||||
@defproc[(internal-definition-context-track
|
||||
[intdef-ctx internal-definition-context?]
|
||||
[stx syntax?])
|
||||
syntax?]{
|
||||
|
||||
Adjusts the @tech[#:doc refman]{syntax properties} of @racket[stx] to
|
||||
record that parts of @racket[stx] were expanded via
|
||||
@racket[intdef-ctx].
|
||||
|
||||
Specifically, the identifiers produced by
|
||||
@racket[(internal-definition-context-binding-identifiers intdef-ctx)]
|
||||
are added to the @racket['disappeared-bindings] property of
|
||||
@racket[stx].}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user