Merge branch 'master' of github.com:racket/racket

This commit is contained in:
Georges Dupéron 2016-01-15 01:03:24 +01:00
commit 37beaf7813
390 changed files with 16197 additions and 7103 deletions

7
.gitignore vendored
View File

@ -24,3 +24,10 @@ compiled/
.DS_Store
*.bak
TAGS
# generated by patch
*.orig
*.rej
# coredumps
*.core

View File

@ -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

View File

@ -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

View File

@ -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":

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]))

View File

@ -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

View File

@ -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[(

View File

@ -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.}]}

View File

@ -6,7 +6,7 @@
"base"
"net-lib"
"sandbox-lib"
"scribble-lib"
["scribble-lib" #:version "1.14"]
"racket-index"))
(define build-deps '("rackunit-doc"
"compatibility"

View File

@ -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]

View File

@ -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"]

View 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.

View File

@ -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).

View File

@ -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

View File

@ -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,

View File

@ -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}

View File

@ -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].}]}
@; ------------------------------------------------------------

View File

@ -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])

View File

@ -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[]

View File

@ -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[

View File

@ -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)))

View File

@ -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

View File

@ -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[]
@;------------------------------------------------------------------------

View File

@ -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.

View File

@ -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))

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]}

View File

@ -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")))

View File

@ -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[

View File

@ -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"]

View File

@ -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.}

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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*

View File

@ -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)

View File

@ -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]))))
]}

View File

@ -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?])

View File

@ -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

View File

@ -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")))

View File

@ -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))
]}
@; ----------------------------------------

View File

@ -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)
]}

View File

@ -1,6 +1,5 @@
#lang scribble/doc
@(require scribble/struct
scribble/eval
"mz.rkt"
(for-label racket/async-channel))

View File

@ -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))
]}

View File

@ -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.}
@; ------------------------------------------------------------------------

View File

@ -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}

View File

@ -27,8 +27,8 @@
(delete-file i)))))
(clean)
(begin0
(defexamples #:eval my-eval
expr ...)
(examples #:eval my-eval
expr ...)
(clean)))]))
"")

View File

@ -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)

View File

@ -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.}

View File

@ -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.}

View File

@ -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)))]

View File

@ -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)))
]}

View File

@ -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)))

View File

@ -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] ...)

View File

@ -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

View File

@ -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

View File

@ -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]))]))

View File

@ -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.}
]

View File

@ -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))

View File

@ -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}

View File

@ -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))
]

View File

@ -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)]{

View File

@ -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]

View File

@ -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)))

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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':

View File

@ -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?]{

View File

@ -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.

View File

@ -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))))

View File

@ -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}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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}

View File

@ -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*

View File

@ -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)

View File

@ -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}

View File

@ -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"]}
]

View File

@ -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)))

View File

@ -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}

View File

@ -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

View File

@ -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 ()

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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))))
]}

View File

@ -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?]

View File

@ -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]{

View File

@ -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.

View File

@ -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]

View 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