diff --git a/csug10.0/bibliography.html b/csug10.0/bibliography.html new file mode 100644 index 000000000..577965e65 --- /dev/null +++ b/csug10.0/bibliography.html @@ -0,0 +1,253 @@ + + + + +
++
[1] +Michael Adams and R. Kent Dybvig. +Efficient nondestructive equality checking for trees and graphs. +In Proceedings of the 13th ACM SIGPLAN International + Conference on Functional Programming, 179-188, September 2008. + +
+
[2] +J. Michael Ashley and R. Kent Dybvig. +An efficient implementation of multiple return values in Scheme. +In Proceedings of the 1994 ACM Conference on Lisp and + Functional Programming, 140-149, June 1994. + +
+
[3] +Carl Bruggeman, Oscar Waddell, and R. Kent Dybvig. +Representing control in the presence of one-shot continuations. +In Proceedings of the SIGPLAN '96 Conference on Programming + Language Design and Implementation, 99-107, May 1996. + +
+
[4] +Robert G. Burger and R. Kent Dybvig. +Printing floating-point numbers quickly and accurately. +In Proceedings of the SIGPLAN '96 Conference on Programming + Language Design and Implementation, 108-116, May 1996. + +
+
[5] +Robert G. Burger and R. Kent Dybvig. +An infrastructure for profile-driven dynamic recompilation. +In Proceedings of the IEEE Computer Society 1998 + International Conference on Computer Languages, 240-251, May 1998. + +
+
[6] +Robert G. Burger, Oscar Waddell, and R. Kent Dybvig. +Register allocation using lazy saves, eager restores, and greedy + shuffling. +In Proceedings of the ACM SIGPLAN '95 Conference on Programming + Language Design and Implementation, 130-138, June 1995. + +
+
[7] +R. Kent Dybvig. +Three Implementation Models for Scheme. +PhD thesis, University of North Carolina, Chapel Hill, April 1987. + +
+
[8] +R. Kent Dybvig. +Writing hygienic macros in scheme with syntax-case. +Technical Report 356, Indiana Computer Science Department, June 1992. + +
+
[9] +R. Kent Dybvig. +The development of Chez Scheme. +In Proceedings of the Eleventh ACM SIGPLAN International + Conference on Functional Programming, 1-12, September 2006. + +
+
[10] +R. Kent Dybvig. +A Scheme for native threads. +In Symposium in Honor of Mitchell Wand, August 2009. + https://web.archive.org/web/20170626072601/http://www.ccs.neu.edu/events/wand-symposium/talks/mitchfest-09-dybvig.pdf. +
[11] +R. Kent Dybvig. +The Scheme Programming Language, 4th edition. +MIT Press, 2009. + +
+
[12] +R. Kent Dybvig, Carl Bruggeman, and David Eby. +Guardians in a generation-based garbage collector. +In Proceedings of the SIGPLAN '93 Conference on Programming + Language Design and Implementation, 207-216, June 1993. + +
+
[13] +R. Kent Dybvig, David Eby, and Carl Bruggeman. +Don't stop the BiBOP: Flexible and efficient storage management for + dynamically-typed languages. +Technical Report 400, Indiana Computer Science Department, March + 1994. + +
+
[14] +R. Kent Dybvig, Daniel P. Friedman, and Christopher T. Haynes. +Expansion-passing style: A general macro mechanism. +Lisp and Symbolic Computation, 1(1):53-75, 1988. + +
+
[15] +R. Kent Dybvig and Robert Hieb. +Engines from continuations. +Computer Languages, 14(2):109-123, 1989. + +
+
[16] +R. Kent Dybvig and Robert Hieb. +A new approach to procedures with variable arity. +Lisp and Symbolic Computation, 3(3):229-244, September + 1990. + +
+
[17] +R. Kent Dybvig, Robert Hieb, and Carl Bruggeman. +Syntactic abstraction in Scheme. +Lisp and Symbolic Computation, 5(4):295-326, 1993. + +
+
[18] +R. Kent Dybvig, Robert Hieb, and Tom Butler. +Destination-driven code generation. +Technical Report 302, Indiana Computer Science Department, February + 1990. + +
+
[19] +Abdulaziz Ghuloum. +Implicit phasing for library dependencies. +PhD thesis, Indiana University, Indianapolis, IN, USA, 2008. +Adviser-Dybvig, R. Kent. + +
+
[20] +Abdulaziz Ghuloum and R. Kent Dybvig. +Generation-friendly eq hash tables. +In 2007 Workshop on Scheme and Functional Programming, + 27-35, 2007. + http://sfp2007.ift.ulaval.ca/programme.html. +
[21] +Abdulaziz Ghuloum and R. Kent Dybvig. +Implicit phasing for R6RS libraries. +In Proceedings of the 12th ACM SIGPLAN International + Conference on Functional Programming, 303-314, 2007. + http://doi.acm.org/10.1145/1291220.1291197. +
[22] +Abdulaziz Ghuloum and R. Kent Dybvig. +Fixing letrec (reloaded). +In 2009 Workshop on Scheme and Functional Programming, August + 2009. + http://www.schemeworkshop.org/2009/. +
[23] +Barry Hayes. +Ephemerons: a new finalization mechanism. +In Proceedings of the 12th ACM SIGPLAN Conference on + Object-Oriented Languages, Programming, Systems, and Applications, + 176-183, 1997. + https://doi.org/10.1145/263700.263733. +
[24] +Christopher T. Haynes and Daniel P. Friedman. +Abstracting timed preemption with engines. +Computer Languages, 12(2):109-121, 1987. + +
+
[25] +Robert Hieb, R. Kent Dybvig, and Carl Bruggeman. +Representing control in the presence of first-class continuations. +In Proceedings of the SIGPLAN '90 Conference on Programming + Language Design and Implementation, 66-77, June 1990. + +
+
[26] +IEEE Computer Society. +IEEE Standard for the Scheme Programming Language, May + 1991. +IEEE Std 1178-1990. + +
+
[27] +Eugene Kohlbecker. +Syntactic Extensions in the Programming Language Lisp. +PhD thesis, Indiana University, Bloomington, August 1986. + +
+
[28] +Michael Sperber, R. Kent Dybvig, Matthew Flatt, and Anton van Straaten (eds.). +Revised6 report on the algorithmic language Scheme, September + 2007. + http://www.r6rs.org/. +
[29] +Michael Sperber, R. Kent Dybvig, Matthew Flatt, and Anton van Straaten (eds.). +Revised6 report on the algorithmic language + Scheme---non-normative appendices, September 2007. + http://www.r6rs.org/. +
[30] +Guy L. Steele Jr. +Common Lisp, the Language, second edition. +Digital Press, 1990. + +
+
[31] +Oscar Waddell and R. Kent Dybvig. +Fast and effective procedure inlining. +In Fourth International Symposium on Static Analysis, volume + 1302 of Springer-Verlag Lecture Notes in Computer Science, 35-52. + Springer-Verlag, 1997. + +
+
[32] +Oscar Waddell and R. Kent Dybvig. +Extending the scope of syntactic abstraction. +In Conference Record of the 26th Annual ACM Symposium on + Principles of Programming Languages, 203-213, January 1999. + +
+
[33] +Oscar Waddell, Dipanwita Sarkar, and R. Kent Dybvig. +Fixing letrec: A faithful yet efficient implementation of Scheme's + recursive binding construct. +Higher-order and symbolic computation, 18(3/4):299-326, 2005. + +
+ + + + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/binding.html b/csug10.0/binding.html
new file mode 100644
index 000000000..ce6397717
--- /dev/null
+++ b/csug10.0/binding.html
@@ -0,0 +1,714 @@
+
+
+
+
+
+This chapter describes Chez Scheme extensions to the set of Revised6 +Report binding forms. +See Chapter 4 of The Scheme Programming Language, 4th Edition or the Revised6 Report +for a description of standard binding forms. + +
+ +
+A definition in Revised6 Report Scheme is a +variable definition, +keyword +definition, or derived definition, i.e., a syntactic extension that +expands into a definition. +In addition, the forms within a +begin +expression appearing after a sequence +of definitions is spliced onto the end of the sequence of definitions +so that definitions at the front of the begin expression +are treated as if they were part of the outer sequence of definitions. +A let-syntax or +letrec-syntax form +is treated similarly, so that definitions at the front of the body +are treated as if they were part of the outer sequence of definitions, +albeit scoped where the bindings of the let-syntax or +letrec-syntax form are visible. + +
+Chez Scheme extends the set of definitions to include +module forms, +import forms, +import-only forms, +meta definitions, and +alias forms, although the +module, import, import-only, +meta, and alias keywords are not available +in a library or RNRS top-level program unless the +scheme library is included in the library or +top-level programs imports. +These forms are described in Chapter 11. + +
+In Revised6 Report Scheme, definitions can appear at the front of +a lambda or similar body (e.g., a let or letrec +body), at the front of a library body, or intermixed with expressions +within an RNRS top-level program body. +In Chez Scheme, definitions may also be used in the +interactive top-level, i.e., they can be intermixed with expressions in +the REPL or in program text to be loaded from a file +via load (Section 12.4). +The Revised6 Report does not mandate the existence nor specify the +semantics of an interactive top-level, nor of a load +procedure. + +
+The macro expander uses the same two-pass algorithm for expanding +top-level begin expressions as it uses for a lambda, +library, or top-level program body. +(This algorithm is described in Section 8.1 of +The Scheme Programming Language, 4th Edition.) As a result, + +
+ +
(begin
+
+ (define-syntax a (identifier-syntax 3))
+
+ (define x a))
+
and + +
+ +
(begin
+
+ (define x a)
+
+ (define-syntax a (identifier-syntax 3)))
+
both result in the giving x the value 3, +even though an unbound variable reference to a would result if +the two forms within the latter begin expression were run +independently at top level. + +
+Similarly, the begin form produced by a use of + +
+ +
(define-syntax define-constant
+
+ (syntax-rules ()
+
+ [(_ x e)
+
+ (begin
+
+ (define t e)
+
+ (define-syntax x (identifier-syntax t)))]))
+
and the begin form produced by a use of + +
+ +
(define-syntax define-constant
+
+ (syntax-rules ()
+
+ [(_ x e)
+
+ (begin
+
+ (define-syntax x (identifier-syntax t))
+
+ (define t e))]))
+
are equivalent. + +
+The Revised6 Report specifies that internal variable definitions be +treated like letrec*, while earlier reports required internal +variable definitions to be treated like letrec. +By default, Chez Scheme implements the Revised6 Report semantics for +internal variable definitions, as for all other things, but this behavior +may be overridden via the internal-defines-as-letrec* parameter. + +
+thread parameter: internal-defines-as-letrec*
+
+libraries: (chezscheme)
+
+
When this parameter is set to #t (the default), internal variable +definitions are evaluated using letrec* semantics. +It may be set to #f to revert to the letrec semantics +for internal variable definitions, for backward compatibility. + + +
+ +
+syntax: (define-values formals expr)
+
+libraries: (chezscheme)
+
+
A define-values form is a definition and can appear anywhere +other definitions can appear. +It is like a define form but permits an arbitrary formals list +(like lambda) on the left-hand side. +It evaluates expr and binds the variables appearing in formals +to the resulting values, in the same manner as the formal parameters of a +procedure are bound to its arguments. + +
+ +
(let ()
+
+ (define-values (x y) (values 1 2))
+
+ (list x y)) (1 2)
+
+(let ()
+
+ (define-values (x y . z) (values 1 2 3 4))
+
+ (list x y z)) (1 2 (3 4))
+
A define-values form expands into a sequence of definitions, the +first for a hidden temporary bound to a data structure holding the values +returned by expr and the remainder binding each of the formals to +the corresponding value or list of values, extracted from the data +structure via a reference to the temporary. +Because the temporary must be defined before the other variables are +defined, this works for internal define-values forms only if +internal-defines-as-letrec* is set to the default value +#t. + + +
+ +
+syntax: (rec var expr)
+
+returns: value of expr
+
+libraries: (chezscheme)
+
+
The syntactic form rec creates a recursive object from expr by +establishing a binding of var within expr to the value of expr. +In essence, it is a special case of letrec for self-recursive objects. + +
+This form is useful for creating recursive objects (especially procedures) +that do not depend on external variables for the recursion, which are +sometimes undesirable because the external bindings can change. +For example, a recursive procedure defined at top level depends on the value +of the top-level variable given as its name. +If the value of this variable should change, the meaning of the procedure +itself would change. +If the procedure is defined instead with rec, its meaning is independent +of the variable to which it is bound. + +
+ +
(map (rec sum
+
+ (lambda (x)
+
+ (if (= x 0)
+
+ 0
+
+ (+ x (sum (- x 1))))))
+
+ '(0 1 2 3 4 5)) (0 1 3 6 10 15)
+
+
+(define cycle
+
+ (rec self
+
+ (list (lambda () self))))
+
+
+(eq? ((car cycle)) cycle) #t
+
The definition below expands rec in terms of letrec. + +
+ +
(define-syntax rec
+
+ (syntax-rules ()
+
+ [(_ x e) (letrec ((x e)) x)]))
+
+
+syntax: (fluid-let ((var expr) ...) body1 body2 ...)
+
+returns: the values of the body body1 body2 ...
+
+libraries: (chezscheme)
+
+
The syntactic form fluid-let +provides a way to temporarily assign values to a set of variables. +The new values are in effect only during the evaluation of the +body of the fluid-let expression. +The scopes of the variables are not determined by fluid-let; as with +set!, the variables must be bound at top level or by an enclosing +lambda or other binding form. +It is possible, therefore, to control the scope of a variable with +lambda or let while establishing a temporary +value with fluid-let. + +
+Although it is similar in appearance to let, its operation is more +like that of set!. +Each var is assigned, as with set!, to the value of the +corresponding expr within the body body1 body2 .... +Should the body +exit normally or by invoking a continuation made outside of the body +(see call/cc), the values in effect before the bindings were changed +are restored. +Should control return back to the body by the invocation of a continuation +created within the body, the bindings are changed once again to the values +in effect when the body last exited. + +
+Fluid bindings are most useful for +maintaining variables that must be shared by a group of procedures. +Upon entry to the group of procedures, the shared variables are fluidly +bound to a new set of initial values so that on exit the original values +are restored automatically. +In this way, the group of procedures itself can be reentrant; it may call +itself directly or indirectly without affecting the values of its shared +variables. + +
+Fluid bindings are similar to +special bindings in Common Lisp [30], except that +(1) there is a single namespace for both lexical and fluid bindings, and +(2) the scope of a fluidly bound variable is not necessarily global. + +
+ +
(let ([x 3])
+
+ (+ (fluid-let ([x 5])
+
+ x)
+
+ x)) 8
+
+
+(let ([x 'a])
+
+ (letrec ([f (lambda (y) (cons x y))])
+
+ (fluid-let ([x 'b])
+
+ (f 'c)))) (b . c)
+
+
+(let ([x 'a])
+
+ (call/cc
+
+ (lambda (k)
+
+ (fluid-let ([x 'b])
+
+ (letrec ([f (lambda (y) (k '*))])
+
+ (f '*)))))
+
+ x) a
+
fluid-let may be defined in terms of dynamic-wind as follows. + +
+ +
(define-syntax fluid-let
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(_ () b1 b2 ...) #'(let () b1 b2 ...)]
+
+ [(_ ((x e) ...) b1 b2 ...)
+
+ (andmap identifier? #'(x ...))
+
+ (with-syntax ([(y ...) (generate-temporaries #'(x ...))])
+
+ #'(let ([y e] ...)
+
+ (let ([swap (lambda ()
+
+ (let ([t x]) (set! x y) (set! y t))
+
+ ...)])
+
+ (dynamic-wind swap (lambda () b1 b2 ...) swap))))])))
+
+
+The procedures described in this section allow the direct manipulation +of top-level bindings for variables +and keywords. +They are intended primarily to support the definition of interpreters +or compilers for Scheme in Scheme but may be used to access or alter +top-level bindings anywhere within a program whether at top level or not. + +
+procedure: (define-top-level-value symbol obj)
+
procedure: (define-top-level-value symbol obj env)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
define-top-level-value is used to establish a binding +for the variable named by symbol to the value obj +in the environment env. +If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+An exception is raised with condition type &assertion if +env is not mutable. + +
+A call to define-top-level-value is similar to a top-level +define form, except that a call to +define-top-level-value need not occur at top-level and +the variable for which the binding is to be established can be +determined at run time, as can the environment. + +
+ +
(begin
+
+ (define-top-level-value 'xyz "hi")
+
+ xyz) "hi"
+
+
+(let ([var 'xyz])
+
+ (define-top-level-value var "mom")
+
+ (list var xyz)) (xyz "mom")
+
procedure: (set-top-level-value! symbol obj)
+
procedure: (set-top-level-value! symbol obj env)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
set-top-level-value! assigns +the variable named by symbol to the value obj +in the environment env. +If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+An exception is raised with condition type &assertion if the +identifier named by symbol is not defined as a variable in env +or if the variable or environment is not mutable. + +
+set-top-level-value! is similar to +set! when set! +is used on top-level variables except that the variable to be assigned +can be determined at run time, as can the environment. + +
+ +
(let ([v (let ([cons list])
+
+ (set-top-level-value! 'cons +)
+
+ (cons 3 4))])
+
+ (list v (cons 3 4))) ((3 4) 7)
+
procedure: (top-level-value symbol)
+
procedure: (top-level-value symbol env)
+
+returns: the top-level value of the variable named by symbol in env
+
+libraries: (chezscheme)
+
+
If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+An exception is raised with condition type &assertion if the +identifier named by symbol is not defined as a variable in env. + +
+top-level-value is similar to a top-level variable reference +except that the variable to be referenced can be determined at run time, +as can the environment. + +
+ +
(let ([cons +])
+
+ (list (cons 3 4)
+
+ ((top-level-value 'cons) 3 4))) (7 (3 . 4))
+
+
+(define e (copy-environment (scheme-environment)))
+
+(define-top-level-value 'pi 3.14 e)
+
+(top-level-value 'pi e) 3.14
+
+(set-top-level-value! 'pi 3.1416 e)
+
+(top-level-value 'pi e) 3.1416
+
procedure: (top-level-bound? symbol)
+
procedure: (top-level-bound? symbol env)
+
+returns: #t if symbol is defined as a variable in env, #f otherwise
+
+libraries: (chezscheme)
+
+
If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+This predicate is useful in an interpreter to check for the existence of +a top-level binding before requesting the value with +top-level-value. + +
+ +
(top-level-bound? 'xyz) #f
+
+
+(begin
+
+ (define-top-level-value 'xyz 3)
+
+ (top-level-bound? 'xyz)) #t
+
+
+(define e (copy-environment (interaction-environment)))
+
+(define-top-level-value 'pi 3.14 e)
+
+(top-level-bound? 'pi) #f
+
+(top-level-bound? 'pi e) #t
+
procedure: (top-level-mutable? symbol)
+
procedure: (top-level-mutable? symbol env)
+
+returns: #t if symbol is mutable in env, #f otherwise
+
+libraries: (chezscheme)
+
+
If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+This predicate is useful in an interpreter to check whether a variable +can be assigned before assigning it with +set-top-level-value!. + +
+ +
(define xyz 3)
+
+(top-level-mutable? 'xyz) #t
+
+(set-top-level-value! 'xyz 4)
+
+(top-level-value 'xyz) 4
+
+
+(define e (copy-environment (interaction-environment) #f))
+
+(top-level-mutable? 'xyz e) #f
+
+(set-top-level-value! 'xyz e) exception: xyz is immutable
+
procedure: (define-top-level-syntax symbol obj)
+
procedure: (define-top-level-syntax symbol obj env)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
define-top-level-syntax is used to establish a top-level binding +for the identifier named by symbol to the value of obj +in the environment env. +The value must be a procedure, the result of a call to +make-variable-transformer, or the result of a call to +top-level-syntax. +If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+An exception is raised with condition type &assertion if +env is not mutable. + +
+A call to define-top-level-syntax is similar to a top-level +define-syntax form, except that a call to +define-top-level-syntax need not occur at top-level and +the identifier for which the binding is to be established can be +determined at run time, as can the environment. + +
+ +
(define-top-level-syntax 'let1
+
+ (syntax-rules ()
+
+ [(_ x e b1 b2 ...) (let ([x e]) b1 b2 ...)]))
+
+(let1 a 3 (+ a 1)) 4
+
define-top-level-syntax can also be used to attach +to an identifier arbitrary compile-time bindings obtained +via top-level-syntax. + +
+procedure: (top-level-syntax symbol)
+
procedure: (top-level-syntax symbol env)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
top-level-syntax is used to retrieve the transformer, compile-time +value, or other compile-time binding to which +the identifier named by symbol is bound in the environment env. +If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). +All identifiers bound in an environment have compile-time bindings, including +variables. + +
+An exception is raised with condition type &assertion if the +identifier named by symbol is not defined as a keyword in env. + +
+ +
(define-top-level-syntax 'also-let (top-level-syntax 'let))
+
+(also-let ([x 3] [y 4]) (+ x y)) 7
+
+
+(define foo 17)
+
+(define-top-level-syntax 'also-foo (top-level-syntax 'foo))
+
+also-foo 17
+
+(set! also-foo 23)
+
+also-foo 23
+
+foo 23
+
The effect of the last example can be had more clearly with alias: + +
+ +
(define foo 17)
+
+(alias also-foo foo)
+
+also-foo 17
+
+(set! also-foo 23)
+
+also-foo 23
+
+foo 23
+
procedure: (top-level-syntax? symbol)
+
procedure: (top-level-syntax? symbol env)
+
+returns: #t if symbol is bound as a keyword in env, #f otherwise
+
+libraries: (chezscheme)
+
+
If env is not provided, it defaults to the +value of interaction-environment, i.e., the +top-level evaluation environment +(Section 12.3). + +
+All identifiers bound in an environment have compile-time bindings, including +variables, so this predicate amounts to a bound check, but is more general +than top-level-bound?, which returns true only for bound variables. + +
+ +
(define xyz 'hello)
+
+(top-level-syntax? 'cons) #t
+
+(top-level-syntax? 'lambda) #t
+
+(top-level-syntax? 'hello) #t
+
+
+(top-level-syntax? 'cons (scheme-environment)) #t
+
+(top-level-syntax? 'lambda (scheme-environment)) #t
+
+(top-level-syntax? 'hello (scheme-environment)) #f
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/canned/about.html b/csug10.0/canned/about.html
new file mode 100644
index 000000000..e1f3f4e7e
--- /dev/null
+++ b/csug10.0/canned/about.html
@@ -0,0 +1,37 @@
+
+
+The printed version of this book was created with LaTeX from extended +LaTeX sources with the help of a preprocessor written in Scheme. +The preprocessor handles extensions for incorporating arbitrary +verbatim Scheme code and various other features not directly supported +by LaTeX. +
+ ++The HTML version was created from the preprocessed sources for the +printed version by a separate Scheme program that performs a LaTeX to +HTML conversion. +In addition to the extended LaTeX source files, this program takes as +input the .aux and .bbl files produced by a complete LaTeX/BibTeX run +of the document in order to support labels and page references in the +text, summary of forms, and index. +As it runs, the program produces a .haux file containing urls for the +labels, bibliographic entries, and index entries; as with LaTeX, a +second run of the program is needed to achieve proper +cross-referencing. +
+ ++Most of the images and certain mathematical formulas included in the +HTML version were produced with the help of LaTeX, dvips, ghostscript, +and various programs from the netpbm library. +
+ + + diff --git a/csug10.0/canned/cisco-logo-large.png b/csug10.0/canned/cisco-logo-large.png new file mode 100644 index 000000000..47c6b3de1 Binary files /dev/null and b/csug10.0/canned/cisco-logo-large.png differ diff --git a/csug10.0/canned/cisco-logo-orig.png b/csug10.0/canned/cisco-logo-orig.png new file mode 100644 index 000000000..3a058ca3b Binary files /dev/null and b/csug10.0/canned/cisco-logo-orig.png differ diff --git a/csug10.0/canned/cisco-logo.png b/csug10.0/canned/cisco-logo.png new file mode 100644 index 000000000..52bfb8939 Binary files /dev/null and b/csug10.0/canned/cisco-logo.png differ diff --git a/csug10.0/canned/copyright.html b/csug10.0/canned/copyright.html new file mode 100644 index 000000000..8328131fb --- /dev/null +++ b/csug10.0/canned/copyright.html @@ -0,0 +1,25 @@ + + +
+© 2005-2015 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0.
+Revised April 2016 for Chez Scheme Version 9.3.4.
+
+Cisco and the Cisco logo are trademarks or registered trademarks +of Cisco and/or its affiliates in the U.S. and other countries. To +view a list of Cisco trademarks, go to this URL: +http://www.cisco.com/go/trademarks. Third-party trademarks mentioned +are the property of their respective owners. The use of the word +partner does not imply a partnership relationship between Cisco and +any other company. (1110R) +
+ + + diff --git a/csug10.0/canned/csug.css b/csug10.0/canned/csug.css new file mode 100644 index 000000000..083ce260b --- /dev/null +++ b/csug10.0/canned/csug.css @@ -0,0 +1,35 @@ +BODY {background-color: #FFFFFF} + +a:link, a:active, a:visited { color:#005568; text-decoration:underline } +a:hover { color:white; text-decoration:underline; background:#005568 } + +a.plain:link, a.plain:active, a.plain:visited { color:#005568; text-decoration:none } +a.plain:hover { color:white; text-decoration:none; background:#005568 } + +a.toc:link, a.toc:active, a.toc:visited {font-family: sans-serif; color:#005568; text-decoration:none} +a.toc:hover {font-family: sans-serif; color:white; text-decoration:none; background:#005568} + +a.image:link, a.image:active, a.image:visited, a.image:hover { + color: #005568; + background: #FFFFFF; +} + +ul.tocchapter { list-style: none; } +ul.tocsection { list-style: circle; color: #C41230 } + +hr.copyright { width: 50% } + +input.default { background: #ffffff; color: #000000; vertical-align: middle} + +h1, h2, h3, h4 {font-family: sans-serif; color: #005568} +h1 {font-size: 2em} +h2 {margin-top: 30px; font-size: 1.5em} +h3 {margin-top: 30px; font-size: 1.17em} +h1, h2, h3, h4 {font-weight: bold} + +.title { font-family: sans-serif; font-weight: bold; font-size: 2.5em; color: #005568; white-space: nowrap} + +.formdef { color: #005568 } + +table.indent {margin-left: 20px} + diff --git a/csug10.0/canned/fatfibhtml-orig.png b/csug10.0/canned/fatfibhtml-orig.png new file mode 100644 index 000000000..e64615805 Binary files /dev/null and b/csug10.0/canned/fatfibhtml-orig.png differ diff --git a/csug10.0/canned/fatfibhtml.png b/csug10.0/canned/fatfibhtml.png new file mode 100644 index 000000000..e64615805 Binary files /dev/null and b/csug10.0/canned/fatfibhtml.png differ diff --git a/csug10.0/canned/profilehtml-orig.png b/csug10.0/canned/profilehtml-orig.png new file mode 100644 index 000000000..e4806107a Binary files /dev/null and b/csug10.0/canned/profilehtml-orig.png differ diff --git a/csug10.0/canned/profilehtml.png b/csug10.0/canned/profilehtml.png new file mode 100644 index 000000000..e4806107a Binary files /dev/null and b/csug10.0/canned/profilehtml.png differ diff --git a/csug10.0/canned/profview.png b/csug10.0/canned/profview.png new file mode 100644 index 000000000..562b78b1b Binary files /dev/null and b/csug10.0/canned/profview.png differ diff --git a/csug10.0/compat.html b/csug10.0/compat.html new file mode 100644 index 000000000..e086ab829 --- /dev/null +++ b/csug10.0/compat.html @@ -0,0 +1,1039 @@ + + + + + ++This chapter describes several items that are included with current +versions of Chez Scheme primarily for compatibility with older +versions of the system. + +
+Section 16.1 describes a hash-table interface +that has since been replaced by the R6RS hashtable interface. +Section 16.2 +describes extend-syntax macros. +These features are supported directly by current versions of Chez Scheme, +but support may be dropped in future versions. +New programs should use the standard mechanisms described +in The Scheme Programming Language, 4th Edition [11] +instead. + +
+Section 16.3 describes a mechanism for defining +record-like structures as vectors instead of new unique types. +New programs should use define-record, which is described +in Section 7.17, instead. + +
+Section 16.4 +describes a compatibility file distributed with +Chez Scheme that contains definitions for forms and procedures no +longer supported directly by Chez Scheme. + + + +
+ +
+The hash table procedures here are obviated by the new hash table procedures +listed in Section 7.14. + +
+procedure: (make-hash-table)
+
procedure: (make-hash-table weak?)
+
+returns: a new hash table
+
+libraries: (chezscheme)
+
+
If weak? is provided and is non-false, the hash +table is a weak hash table, which means that it does not protect +keys from the garbage collector. +Keys reclaimed by the garbage collector are removed from the table, +and their associated values are dropped the next time the table +is modified, if not sooner. + +
+procedure: (hash-table? obj)
+
+returns: #t if obj is a hash table, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (put-hash-table! ht k v)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
ht must be a hash table. +k and v may be any Scheme values. + +
+put-hash-table! associates the value +v with the key k in ht. + +
+procedure: (get-hash-table ht k d)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
get-hash-table returns the value +associated with k in ht. +If no value is associated with k in ht, +get-hash-table returns d. + +
+Key comparisons are performed with eq?. + +
+Because objects may be moved by the garbage collector, get-hash-table +may need to rehash some objects and therefore cause side effects in the +hash table. +Thus, it is not safe to perform concurrent accesses of the same hash table +from multiple threads using get-hash-table. + +
+procedure: (remove-hash-table! ht k)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
remove-hash-table! drops any association +for k from ht. + +
+procedure: (hash-table-map ht p)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
hash-table-map applies p to each key, value association +in ht, in no particular order, and returns a list of the resulting +values, again in no particular order. +p should accept two arguments, a key and a value. + + +
+procedure: (hash-table-for-each ht p)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hash-table-for-each applies p to each key, value +association in ht, in no particular order. +Unlike hash-table-map, it does not create a list of the values; +instead, it's value is unspecified. +p should accept two arguments, a key and a value. + + +
+ +
+This section describes extend-syntax, a powerful yet easy to use +syntactic extension facility based on +pattern matching [27]. +Syntactic transformations written using +extend-syntax are similar to those written using a +define-syntax with syntax-case, except that the +transformations produced by extend-syntax do not automatically +respect lexical scoping. + +
+It is not typically possible to mix syntactic abstractions written using +syntax-case with those written using extend-syntax +seamlessly; it is generally preferable to use one or the other wherever +possible. +Support for extend-syntax within the syntax-case expander +is provided only as an aid to migrating to syntax-case. + + +
+syntax: (extend-syntax (name key ...) (pat fender template) ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The identifier name is the name, or syntax keyword, for the +syntactic extension to be defined. +When the system expander processes any list expression whose car is +name, the syntactic transformation procedure generated by +extend-syntax is invoked on this expression. +The remaining identifiers key ... are additional keywords to +be recognized within input expressions during expansion (such as +else in cond or case). + +
+Each clause after the list of keys consists of a pattern pat, an +optional fender, +and a template. +The optional fender is omitted more often than not. +The pat specifies the syntax the input expression must have +for the clause to be chosen. +Identifiers within the pattern that are not keywords +(pattern variables) are bound to corresponding pieces of the input expression. +If present, the fender is a Scheme expression that specifies +additional constraints on the input expression (accessed through the +pattern variables) that must be satisfied in order for the clause to +be chosen. +The template specifies what form the output takes, usually in +terms of the pattern variables. + +
+During expansion, the transformation procedure extend-syntax +generates attempts to match the input expression against each +pattern in the order the clauses are given. +If the input expression matches the pattern, the pattern variables are +bound to the corresponding pieces of the input expression and the +fender for the clause, if any, is evaluated. +If the fender returns a true value, the given expansion is performed. +If input does not match the pattern or if the fender returns a false +value, the transformation procedure tries the next clause. +An exception is raised with condition type &assertion if no clause can be chosen. + +
+Within the pattern, +ellipsis +(...) may be +used to specify zero or more occurrences +of the preceding pattern fragment, or prototype. +Similarly, ellipses may be used in the output to specify the construction +of zero or more expansion prototypes. +In this case, the expansion prototype must contain part of an input pattern +prototype. +The use of patterns, templates, ellipses within patterns and templates, +and fenders is illustrated in the following sequence of examples. + +
+The first example, defining rec, uses a single keyword, a single +clause with no fender, and no ellipses. + +
+ +
(extend-syntax (rec)
+
+ [(rec id val)
+
+ (let ([id #f])
+
+ (set! id val)
+
+ id)])
+
The second example, defining when, shows +the use of ellipses. + +
+ +
(extend-syntax (when)
+
+ [(when test exp1 exp2 ...)
+
+ (if test (begin exp1 exp2 ...) #f)])
+
The next example shows the definition of +let. +The definition of let shows the use of multiple ellipses, employing +one for the identifier/value pairs and one for the expressions in the body. +It also shows that the prototype need not be a single identifier, and that +pieces of the prototype may be separated from one another in the template. + +
+ +
(extend-syntax (let)
+
+ [(let ([x e] ...) b1 b2 ...)
+
+ ((lambda (x ...) b1 b2 ...) e ...)])
+
The next example shows let*, whose syntax is the same as for +let, but which is defined recursively in terms of let with +two clauses (one for the base case, one for the recursion step) since +it must produce a nested structure. + +
+ +
(extend-syntax (let*)
+
+ [(let* () b1 b2 ...)
+
+ (let () b1 b2 ...)]
+
+ [(let* ([x e] more ...) b1 b2 ...)
+
+ (let ([x e]) (let* (more ...) b1 b2 ...))])
+
The first pattern/template pair matches any let* expression with no +identifier/value pairs and maps it into the equivalent begin expression. +This is the base case. +The second pattern/template pair matches any let* expression with one +or more identifier/value pairs and transforms it into a let expression +binding the first pair whose body is a let* expression binding the +remaining pairs. +This is the recursion step, which will eventually lead us to the base case +because we remove one identifier/value pair at each step. +Notice that the second pattern uses the pattern variable more for the +second and later identifier/value pairs; this makes the pattern and template +less cluttered and makes it clear that only the first identifier/value pair +is dealt with explicitly. + +
+The definition for and requires three clauses. +The first clause is necessary to recognize (and), and the second +two define all other and forms recursively. + +
+ +
(extend-syntax (and)
+
+ [(and) #t]
+
+ [(and x) x]
+
+ [(and x y ...) (if x (and y ...) #f)])
+
The definition for cond requires four clauses. +As with let*, cond must be described recursively, partly because +it produces nested if expressions, and partly because one +ellipsis prototype would not be sufficient to describe all possible +cond clauses. +The definition of cond also requires that we specify else as a +keyword, in addition to cond. +Here is the definition: + +
+ +
(extend-syntax (cond else)
+
+ [(cond) #f]
+
+ [(cond (else e1 e2 ...))
+
+ (begin e1 e2 ...)]
+
+ [(cond (test) more ...)
+
+ (or test (cond more ...))]
+
+ [(cond (test e1 e2 ...) more ...)
+
+ (if test
+
+ (begin e1 e2 ...)
+
+ (cond more ...))])
+
Two of the clauses are base cases and two are recursion steps. +The first base case is an empty cond. +The value of cond in this case is unspecified, so the choice of +#f is somewhat arbitrary. +The second base case is a cond containing only an else clause; +this is transformed to the equivalent begin expression. +The two recursion steps differ in the number of expressions in the cond +clause. +The value of cond when the first true clause contains only the test +expression is the value of the test. +This is similar to what or does, so we expand the cond clause +into an or expression. +On the other hand, when there are expressions following the test expression, +the value of the last expression is returned, so we use if and +begin. + +
+To be absolutely correct about the syntax of let, we actually +must require that the bound identifiers in the input are symbols. +If we typed something like (let ([3 x]) x) we would not get an +error from let because it does not check to verify that the +objects in the identifier positions are symbols. +Instead, lambda may complain, or perhaps the system evaluator +long after expansion is complete. +This is where fenders +are useful. + +
+ +
(extend-syntax (let)
+
+ [(let ([x e] ...) b1 b2 ...)
+
+ (andmap symbol? '(x ...))
+
+ ((lambda (x ...) b1 b2 ...) e ...)])
+
The andmap of symbol? +over '(x ...) assures that each +bound identifier is a symbol. +A fender is simply a Scheme expression. +Within that expression, any quoted object is first expanded by the same +rules as the template part of the clause. +In this case, '(x ...) is expanded to the list of identifiers from +the identifier/value pairs. + +
+extend-syntax typically handles everything you need it for, but +some syntactic extension definitions require the ability to include the +result of evaluating an arbitrary Scheme expression. +This ability is provided by with. + + +
+syntax: (with ((pat expr) ...) template)
+
+returns: processed template
+
+
+ +
with is valid only within an template inside of extend-syntax. +with patterns are the same as extend-syntax patterns, with +expressions are the same as extend-syntax fenders, and with +templates are the same as extend-syntax templates. + +
+with can be used to introduce new pattern identifiers bound to +expressions produced by arbitrary Scheme expressions within +extend-syntax templates. +That is, with allows an escape from the declarative style of +extend-syntax into the procedural style of full Scheme. + +
+One common use of with is the introduction of a temporary +identifier or list of temporary identifiers into a template. +with is also used to perform complex transformations that might +be clumsy or inefficient if performed within the extend-syntax +framework. + +
+For example, or requires the use of a temporary identifier. +We could define or as follows. + +
+ +
(extend-syntax (or)
+
+ [(or) #f]
+
+ [(or x) x]
+
+ [(or x y ...)
+
+ (let ([temp x])
+
+ (if temp temp (or y ...)))])
+
This would work until we placed an or expression within the scope +of an occurrence of temp, in which case strange things could happen, +since extend-syntax does not respect lexical scoping. +(This is one of the reasons that define-syntax is preferable to +extend-syntax.) + +
+ +
(let ([temp #t])
+
+ (or #f temp)) #f
+
One solution is to use +gensym and with to +create a temporary identifier, as follows. + +
+ +
(extend-syntax (or)
+
+ [(or) #f]
+
+ [(or x) x]
+
+ [(or x y ...)
+
+ (with ([temp (gensym)])
+
+ (let ([temp x])
+
+ (if temp temp (or y ...))))])
+
Also, with can be used to combine elements of the input pattern +in ways not possible directly with extend-syntax, such as the +following folding-plus example. + +
+ +
(extend-syntax (folding-plus)
+
+ [(folding-plus x y)
+
+ (and (number? 'x) (number? 'y))
+
+ (with ([val (+ 'x 'y)])
+
+ val)]
+
+ [(folding-plus x y) (+ x y)])
+
folding-plus collapses into the value of (+ x y) if both +x and y are numeric constants. +Otherwise, folding-plus is transformed into (+ x y) for +later evaluation. +The fender checks that the operands are numbers at expansion time, and +the with performs the evaluation. +As with fenders, expansion is performed only within a quoted expressions, +since quote sets the data apart from the remainder of the Scheme +expression. + +
+The example below binds a list of pattern variables to a list of +temporary symbols, taking advantage of the fact that with allows +us to bind patterns to expressions. +This list of temporaries helps us to implement the sigma syntactic +extension. +sigma is similar to lambda, except it assigns the identifiers +in the identifier list instead of creating new bindings. +It may be used to perform a series of assignments in parallel. + +
+ +
(extend-syntax (sigma)
+
+ [(sigma (x ...) e1 e2 ...)
+
+ (with ([(t ...) (map (lambda (x) (gensym)) '(x ...))])
+
+ (lambda (t ...)
+
+ (set! x t) ...
+
+ e1 e2 ...))])
+
+
+(let ([x 'a] [y 'b])
+
+ ((sigma (x y) (list x y)) y x)) (b a)
+
The final example below uses extend-syntax to implement +define-structure, following a similar example using +syntax-case in Section 8.4 of +The Scheme Programming Language, 4th Edition. + +
+The definition of define-structure makes use of two pattern/template +clauses. +Two clauses are needed to handle the optionality of the second subexpression. +The first clause matches the form without the second subexpression and +merely converts it into the equivalent form with the second subexpression +present, but empty. + +
+The definition also makes heavy use of with to evaluate Scheme +expressions at expansion time. +The first four with clauses are used to manufacture the identifiers +that name the automatically defined procedures. +(The procedure format is particularly useful here, but it could be +replaced with string-append!, using symbol->string as needed.) +The first two clauses yield single identifiers (for the constructor and +predicate), while the next two yield lists of identifiers (for the field +access and assignment procedures). +The fifth with clause (the final clause in the outer with) +is used to count the total length vector needed for each instance of +the structure, which must include room for the name and all of the fields. +The final with clause (the only clause in the inner with) +is used to create a list of vector indexes, one for each field (starting at +1, since the structure name occupies position 0). + +
+ +
(extend-syntax (define-structure)
+
+ [(define-structure (name id1 ...))
+
+ (define-structure (name id1 ...) ())]
+
+ [(define-structure (name id1 ...) ([id2 val] ...))
+
+ (with ([constructor
+
+ (string->symbol (format "make-~a" 'name))]
+
+ [predicate
+
+ (string->symbol (format "~a?" 'name))]
+
+ [(access ...)
+
+ (map (lambda (x)
+
+ (string->symbol
+
+ (format "~a-~a" 'name x)))
+
+ '(id1 ... id2 ...))]
+
+ [(assign ...)
+
+ (map (lambda (x)
+
+ (string->symbol
+
+ (format "set-~a-~a!" 'name x)))
+
+ '(id1 ... id2 ...))]
+
+ [count (length '(name id1 ... id2 ...))])
+
+ (with ([(index ...)
+
+ (let f ([i 1])
+
+ (if (= i 'count)
+
+ '()
+
+ (cons i (f (+ i 1)))))])
+
+ (begin
+
+ (define constructor
+
+ (lambda (id1 ...)
+
+ (let* ([id2 val] ...)
+
+ (vector 'name id1 ... id2 ...))))
+
+ (define predicate
+
+ (lambda (obj)
+
+ (and (vector? obj)
+
+ (= (vector-length obj) count)
+
+ (eq? (vector-ref obj 0) 'name))))
+
+ (define access
+
+ (lambda (obj)
+
+ (vector-ref obj index)))
+
+ ...
+
+ (define assign
+
+ (lambda (obj newval)
+
+ (vector-set! obj index newval)))
+
+ ...)))])
+
+
+This section describes a mechanism, similar +to the record-defining mechanisms of Section 7.17, +that permits the creation of data structures +with fixed sets of named fields. +Unlike record types, structure types are not unique types, but are +instead implemented as vectors. +Specifically, a structure is implemented as a vector whose length is +one more than the number of fields and whose first element contains +the symbolic name of the structure. + +
+The representation of structures as vectors +simplifies reading and printing of structures somewhat as well +as extension of the structure definition facility. +It does, however, have some drawbacks. +One is that structures may be treated as ordinary vectors by mistake in +situations where doing so is inappropriate. +When dealing with both structures and vectors in a program, care must +be taken to look for the more specific structure type before checking +for the more generic vector type, e.g., in a series of cond +clauses. +A similar drawback is that structure instances are easily "forged," either +intentionally or by accident. +It is also impossible to control how structures are printed and read. + +
+Structures are created via define-structure. +Each structure definition defines a constructor +procedure, a type predicate, an access procedure for each of its fields, +and an assignment procedure for each of its fields. +define-structure allows the programmer to control which fields +are arguments to the generated constructor procedure and which fields +are explicitly initialized by the constructor procedure. + +
+define-structure is simple +yet powerful enough for most applications, and it is easily +extended to handle many applications for which it is not sufficient. +The definition of define-structure given at the end of +this section can serve as a starting point for more complicated +variants. + +
+syntax: (define-structure (name id1 ...) ((id2 expr) ...))
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A define-structure form is a definition and may appear anywhere +and only where other definitions may appear. + +
+define-structure defines a new data structure, name, and +creates a set of procedures for creating and manipulating instances of +the structure. +The identifiers id1 ... and id2 ... +name the fields of the data structure. + +
+The following procedures are defined by define-structure: + +
+
+
+
+
+ +
+The fields named by the identifiers id1 ... are +initialized by the arguments to the constructor procedure. +The fields named by the identifiers id2 ... are initialized +explicitly to the values of the expressions expr .... +Each expression is evaluated within the scope of the identifiers +id1 ... (bound to the corresponding field values) and any +of the identifiers id2 ... (bound to the corresponding field +values) appearing before it (as if within a let*). + +
+To clarify, the constructor behaves as if defined as + +
+ +
(define make-name
+
+ (lambda (id1 ...)
+
+ (let* ([id2 expr] ...)
+
+ body)))
+
where body builds the structure from the values of the identifiers +id1 ... and id2 .... + +
+If no fields other than those initialized by the arguments to the +constructor procedure are needed, the second subexpression, +((id2 expr) ...), may be omitted. + +
+The following simple example +demonstrates how pairs might be defined in Scheme if they did not +already exist. +Both fields are initialized by the arguments to the constructor +procedure. + +
+ +
(define-structure (pare car cdr))
+
+(define p (make-pare 'a 'b))
+
+
+(pare? p) #t
+
+(pair? p) #f
+
+(pare? '(a . b)) #f
+
+
+(pare-car p) a
+
+(pare-cdr p) b
+
+
+(set-pare-cdr! p (make-pare 'b 'c))
+
+
+(pare-car (pare-cdr p)) b
+
+(pare-cdr (pare-cdr p)) c
+
The following example defines a handy string data structure, called a +stretch-string, that grows as needed. +This example uses a field explicitly initialized to a value that +depends on the value of the constructor argument fields. + +
+ +
(define-structure (stretch-string length fill)
+
+ ([string (make-string length fill)]))
+
+
+(define stretch-string-ref
+
+ (lambda (s i)
+
+ (let ([n (stretch-string-length s)])
+
+ (when (>= i n) (stretch-stretch-string! s (+ i 1) n))
+
+ (string-ref (stretch-string-string s) i))))
+
+
+(define stretch-string-set!
+
+ (lambda (s i c)
+
+ (let ([n (stretch-string-length s)])
+
+ (when (>= i n) (stretch-stretch-string! s (+ i 1) n))
+
+ (string-set! (stretch-string-string s) i c))))
+
+
+(define stretch-string-fill!
+
+ (lambda (s c)
+
+ (string-fill! (stretch-string-string s) c)
+
+ (set-stretch-string-fill! s c)))
+
+
+(define stretch-stretch-string!
+
+ (lambda (s i n)
+
+ (set-stretch-string-length! s i)
+
+ (let ([str (stretch-string-string s)]
+
+ [fill (stretch-string-fill s)])
+
+ (let ([xtra (make-string (- i n) fill)])
+
+ (set-stretch-string-string! s
+
+ (string-append str xtra))))))
+
As often happens, most of the procedures defined automatically are +used only to define more specialized procedures, in this case the procedures +stretch-string-ref and stretch-string-set!. +stretch-string-length and stretch-string-string are +the only automatically defined procedures that are likely to be +called directly in code that uses stretch strings. + +
+ +
(define ss (make-stretch-string 2 #\X))
+
+
+(stretch-string-string ss) "XX"
+
+(stretch-string-ref ss 3) #\X
+
+(stretch-string-length ss) 4
+
+(stretch-string-string ss) "XXXX"
+
+
+(stretch-string-fill! ss #\@)
+
+(stretch-string-string ss) "@@@@"
+
+(stretch-string-ref ss 5) #\@
+
+(stretch-string-string ss) "@@@@@@"
+
+
+(stretch-string-set! ss 7 #\=)
+
+(stretch-string-length ss) 8
+
+(stretch-string-string ss) "@@@@@@@="
+
Section 8.4 of The Scheme Programming Language, 4th Edition defines a simplified +variant of define-structure as an example of the use of +syntax-case. +The definition given below implements the complete version. + +
+define-structure expands into a series of definitions for names +generated from the structure name and field names. +The generated identifiers are created with +datum->syntax to +make the identifiers visible where the define-structure +form appears. +Since a define-structure form expands into a begin +containing definitions, it is itself a definition and can be used +wherever definitions are valid. + +
+ +
(define-syntax define-structure
+
+ (lambda (x)
+
+ (define gen-id
+
+ (lambda (template-id . args)
+
+ (datum->syntax template-id
+
+ (string->symbol
+
+ (apply string-append
+
+ (map (lambda (x)
+
+ (if (string? x)
+
+ x
+
+ (symbol->string
+
+ (syntax->datum x))))
+
+ args))))))
+
+ (syntax-case x ()
+
+ ((_ (name field1 ...))
+
+ (andmap identifier? #'(name field1 ...))
+
+ #'(define-structure (name field1 ...) ()))
+
+ ((_ (name field1 ...) ((field2 init) ...))
+
+ (andmap identifier? #'(name field1 ... field2 ...))
+
+ (with-syntax
+
+ ((constructor (gen-id #'name "make-" #'name))
+
+ (predicate (gen-id #'name #'name "?"))
+
+ ((access ...)
+
+ (map (lambda (x) (gen-id x #'name "-" x))
+
+ #'(field1 ... field2 ...)))
+
+ ((assign ...)
+
+ (map (lambda (x) (gen-id x "set-" #'name "-" x "!"))
+
+ #'(field1 ... field2 ...)))
+
+ (structure-length
+
+ (+ (length #'(field1 ... field2 ...)) 1))
+
+ ((index ...)
+
+ (let f ([i 1] [ids #'(field1 ... field2 ...)])
+
+ (if (null? ids)
+
+ '()
+
+ (cons i (f (+ i 1) (cdr ids)))))))
+
+ #'(begin
+
+ (define constructor
+
+ (lambda (field1 ...)
+
+ (let* ([field2 init] ...)
+
+ (vector 'name field1 ... field2 ...))))
+
+ (define predicate
+
+ (lambda (x)
+
+ (and (vector? x)
+
+ (#3%fx= (vector-length x) structure-length)
+
+ (eq? (vector-ref x 0) 'name))))
+
+ (define access (lambda (x) (vector-ref x index)))
+
+ ...
+
+ (define assign
+
+ (lambda (x update) (vector-set! x index update)))
+
+ ...))))))
+
+
+Current versions of Chez Scheme are distributed with a compatibility +file containing definitions of various syntactic forms and procedures +supported by earlier versions of Chez Scheme for which support has +since been dropped. +This file, compat.ss, is typically installed in the library +subdirectory of the Chez Scheme installation directory. + +
+In some cases, the forms and procedures found in compat.ss +have been dropped because they were infrequently used and easily +written directly in Scheme. +In other cases, the forms and procedures have been rendered obsolete by +improvements in the system. +In such cases, new code should be written to use the newer features, +and older code should be rewritten if possible to use the newer +features as well. + + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/control.html b/csug10.0/control.html
new file mode 100644
index 000000000..010243396
--- /dev/null
+++ b/csug10.0/control.html
@@ -0,0 +1,1196 @@
+
+
+
+
+
+This chapter describes Chez Scheme extensions to the set of standard +control structures. +See Chapter 5 of The Scheme Programming Language, 4th Edition or the Revised6 Report +on Scheme for a description of standard control structures. + + +
+ +
+syntax: (exclusive-cond clause1 clause2 ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
exclusive-cond is a version of cond +(Section 5.3 of TSPLFOUR) that differs +from cond in that the tests embedded within the clauses +are assumed to be exclusive in the sense that if one of the tests +is true, the others are not. +This allows the implementation to reorder clauses when profiling +information is available at expansion time (Section 12.7). + +
+The (test) form of clause is not supported. +The order chosen when profiling information is available is based +on the relative numbers of times the RHS of each clause is executed, +and (test) has no RHS. +(test => values) is equivalent, albeit less concise. + +
+syntax: (case expr0 clause1 clause2 ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
Each clause but the last must take one of the forms: + +
+ +
((key ...) expr1 expr2 ...)
+
+(key expr1 expr2 ...)
+
where each key is a datum distinct from the other keys. +The last clause may be in the above form or it may be an +else clause of the form + +
+ +
(else expr1 expr2 ...) +
expr0 is evaluated and the result is compared +(using equal?) against the keys of each clause in order. +If a clause containing a matching key is found, the +expressions expr1 expr2 ... are evaluated in sequence +and the values of the last expression are returned. + +
+If none of the clauses contains a matching key and an else clause +is present, the expressions expr1 expr2 ... of the +else clause are evaluated in sequence and the values of the last +expression are returned. + +
+If none of the clauses contains a matching key and no else clause +is present, the value or values are unspecified. + +
+The Revised6 Report version of case does not support singleton +keys (the second of the first two clause forms above) and uses +eqv? rather than equal? as the comparison procedure. +Both versions are defined in terms of exclusive-cond so that +if profiling information is available at expansion time, the clauses will +be reordered to put those that are most frequently executed first. + +
+ +
(let ([ls '(ii iv)])
+
+ (case (car ls)
+
+ [i 1]
+
+ [ii 2]
+
+ [iii 3]
+
+ [(iiii iv) 4]
+
+ [else 'out-of-range])) 2
+
+
+(define p
+
+ (lambda (x)
+
+ (case x
+
+ [("abc" "def") 'one]
+
+ [((a b c)) 'two]
+
+ [else #f])))
+
+
+(p (string #\d #\e #\f)) one
+
+(p '(a b c)) two
+
syntax: (record-case expr clause1 clause2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
record-case is a restricted form of case that supports the +destructuring of records, or tagged lists. +A record has as its first element a tag that determines what "type" +of record it is; the remaining elements are the fields of the record. + +
+Each clause but the last must take the form + +
+ +
((key ...) formals body1 body2 ...) +
where each key is a datum distinct from the other keys. +The last clause may be in the above form or it may be an +else clause of the form + +
+ +
(else body1 body2 ...) +
expr must evaluate to a pair. +expr is evaluated and the car of its value is compared +(using eqv?) against the keys of each clause in order. +If a clause containing a matching key is found, the variables in +formals are bound to the remaining elements +of the list and the expressions +body1 body2 ... are evaluated in sequence. +The value of the last expression is returned. +The effect is identical to the application of + +
+ +
(lambda formals body1 body2 ...) +
to the cdr of the list. + +
+If none of the clauses contains a matching key and an else clause +is present, the expressions body1 body2 ... of the +else clause are evaluated in sequence and the value of the last +expression is returned. + +
+If none of the clauses contains a matching key and no else clause +is present, the value is unspecified. + + +
+ +
(define calc
+
+ (lambda (x)
+
+ (record-case x
+
+ [(add) (x y) (+ x y)]
+
+ [(sub) (x y) (- x y)]
+
+ [(mul) (x y) (* x y)]
+
+ [(div) (x y) (/ x y)]
+
+ [else (assertion-violationf 'calc "invalid expression ~s" x)])))
+
+
+(calc '(add 3 4)) 7
+
+(calc '(div 3 4)) 3/4
+
+
+procedure: (ormap procedure list1 list2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
ormap is identical to the Revised6 Report exists. + +
+procedure: (andmap procedure list1 list2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
andmap is identical to the Revised6 Report for-all. + + +
+ +
+Chez Scheme supports one-shot continuations as well as the standard +multi-shot continuations obtainable via call/cc. +One-shot continuations are continuations that may be invoked at most +once, whether explicitly or implicitly. +They are obtained with call/1cc. + +
+Continuation marks support efficient annotation of continuations +and inspection of those annotations. Each continuation has a table of +marks, where each mark is a key-value pair. This table is updated using +the with-continuation-mark form to associate a key with a value, +replacing any existing association for that key. Although each +continuation has a single immediate table of marks, a continuation may +extend another continuation that has its own marks. The +current-continuation-marks function captures the sequence of mark +tables for a continuation and all continuations that it extends. Functions such as +continuation-marks-first, +continuation-marks->list, and +continuation-marks->iterator can be used to inspect mark +sequences. When a continuation is captured with call/cc, only the +marks of the rest of the continuation are captured, and +continuation-next-marks returns the captured marks. + +
+procedure: (call/1cc procedure)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
call/1cc obtains its continuation and passes it to procedure, +which should accept one argument. +The continuation itself is represented by a procedure. +This procedure normally takes one argument but may take an arbitrary +number of arguments depending upon whether the context of the call +to call/1cc +expects multiple return values or not. +When this procedure is applied to a value or values, it returns the values +to the continuation of the call/1cc application. + +
+The continuation obtained by call/1cc is a +"one-shot continuation." +A one-shot continuation should not be returned to multiple times, either +by invoking the continuation or returning normally from procedure more +than once. +A one-shot continuation is "promoted" into a normal (multishot) +continuation, however, if it is +still active when a +normal continuation is obtained by call/cc. +After a one-shot continuation is promoted into a multishot continuation, +it behaves exactly as if it had been obtained via call/cc. +This allows call/cc and call/1cc to be used together +transparently in many applications. + +
+One-shot continuations may be more efficient for some applications than +multishot continuations. +See the paper "Representing control in the presence of one-shot +continuations" [3] for more information about +one-shot continuations, including how they are implemented in +Chez Scheme. + +
+The following examples highlight the similarities and differences +between one-shot and normal continuations. + +
+ +
(define prod
+
+ ; compute the product of the elements of ls, bugging out
+
+ ; with no multiplications if a zero element is found
+
+ (lambda (ls)
+
+ (lambda (k)
+
+ (if (null? ls)
+
+ 1
+
+ (if (= (car ls) 0)
+
+ (k 0)
+
+ (* (car ls) ((prod (cdr ls)) k)))))))
+
+
+(call/cc (prod '(1 2 3 4))) 24
+
+(call/1cc (prod '(1 2 3 4))) 24
+
+
+(call/cc (prod '(1 2 3 4 0))) 0
+
+(call/1cc (prod '(1 2 3 4 0))) 0
+
+
+(let ([k (call/cc (lambda (x) x))])
+
+ (k (lambda (x) 0))) 0
+
+
+(let ([k (call/1cc (lambda (x) x))])
+
+ (k (lambda (x) 0))) exception
+
+procedure: (dynamic-wind in body out)
+
procedure: (dynamic-wind critical? in body out)
+
+returns: values resulting from the application of body
+
+libraries: (chezscheme)
+
+
The first form is identical to the Revised6 Report dynamic-wind. +When the optional critical? argument is present and non-false, +the in thunk is invoked in a critical section along with the code +that records that the body has been entered, and the out thunk is +invoked in a critical section along with the code that records +that the body has been exited. +Extreme caution must be taken with this form of dynamic-wind, +since an error or long-running computation can leave interrupts +and automatic garbage collection disabled. + +
+
+syntax: (with-continuation-mark key val body)
+
+returns: the value of the body expression
+
+libraries: (chezscheme)
+
+
with-continuation-mark updates the table of marks +on the current continuation to map the result of the key +expression to the result of the val expression. If the current +continuation's table of marks already has a mapping for key +(based on eq? comparison), then the mark's value is replaced +with val, otherwise a mapping from key to val is +added to the table. + +
+ +
(with-continuation-mark
+
+ 'key "val"
+
+ "hello") ; => "hello"
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (continuation-marks-first (current-continuation-marks)
+
+ 'key)) ; => "val"
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (continuation-marks-first (current-continuation-marks)
+
+ 'other-key)) ; => #f
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (continuation-marks-first (current-continuation-marks)
+
+ 'key))) ; => "val2"
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (continuation-marks->list (current-continuation-marks)
+
+ 'key))) ; => ("val2")
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (values
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (continuation-marks->list (current-continuation-marks)
+
+ 'key)))) ; => ("val2" "val")
+
procedure: (continuation-marks? obj)
+
+returns: boolean
+
+libraries: (chezscheme)
+
+
A predicate that recognizes a continuation mark sequence, which +can be produced by the functions current-continuation-marks and +continuation-next-marks. + +
+procedure: (current-continuation-marks)
+
procedure: (continuation-next-marks cont)
+
+returns: a continuation mark sequence
+
+libraries: (chezscheme)
+
+
Returns a captured sequence of mark tables, either the +current continuation's marks in the case of +current-continuation-marks or the marks of the rest of +cont in the case of continuation-next-marks. In the +latter case, cont must be a continuation. + +
+This function takes constant time. The size of the resulting mark sequence +is proportional to the number of distinct key-value mappings in the +overall mark-table sequence; that size is bounded by the length of the +continuation times the number of distinct values used as keys, but +since many continuations have no keys or fewer than all possible keys +in their tables, the size tends to be much less than the bound. + +
+ +
(continuation-marks? (current-continuation-marks)) ; => #t
+
+(continuation-marks? (continuation-next-marks
+
+ (call/cc (lambda (k) k)))) ; => #t
+
procedure: (continuation-marks-first marks key)
+
procedure: (continuation-marks-first marks key none-val)
+
+returns: the value for key in marks or none-val
+
+libraries: (chezscheme)
+
+
Extracts the first value found for key in +marks, checking the mark table of a continuation before +checking the table of the continuation that it extends (if any). Keys are +compared using eq?. If no mark for key is found, +none-val is returned; if none-val is not provided, it +defaults to #f. + +
+This function takes amortized time proportional to the number of +distinct values used as keys in marks. Typically the number of +keys used in an application is bounded, which makes the computation +amortized constant-time for those applications. + +
+ +
(with-continuation-mark
+
+ 'key "val"
+
+ (values
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (continuation-marks-first (current-continuation-marks)
+
+ 'key)))) ; => "val2"
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (continuation-marks-first (current-continuation-marks)
+
+ 'other
+
+ "nope")) ; => "nope"
+
procedure: (continuation-marks->list marks key)
+
+returns: a list
+
+libraries: (chezscheme)
+
+
Returns the list of all values associated with key in +marks, with the value from a continuation's mark +table appearing before the values from the mark tables of any other +continuation that it extends. Keys are compared using +eq?. + +
+This function takes time proportional to the size of the captured mark +sequence. + +
+ +
(with-continuation-mark
+
+ 'key "val"
+
+ (values
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (continuation-marks->list (current-continuation-marks)
+
+ 'key)))) ; => ("val2" "val")
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (continuation-marks->list (current-continuation-marks)
+
+ 'other)) ; => ()
+
procedure: (continuation-marks->iterator marks key-vector)
+
procedure: (continuation-marks->iterator marks key-vector none-val)
+
+returns: a procedure
+
+libraries: (chezscheme)
+
+
Generalizes the mark sequence traversal of +continuation-marks->list to a functional iterator. The +marks argument must be a continuation mark sequence, and the +key-vector argument must be a vector of values to be used as +keys. The result is an iterator procedure of zero arguments. + +
+Calling the result iterator procedure (with no arguments) returns two values: + +
+
+
+
+
+ +
+Obtaining an iterator from continuation-marks->iterator takes +constant time. Each call to an iterator takes time proportional to the +size of continuation mark tables that are traversed to find one of the +keys in key-vector. + +
+ +
(with-continuation-mark
+
+ 'key "val"
+
+ (with-continuation-mark
+
+ 'other "also"
+
+ (values
+
+ (with-continuation-mark
+
+ 'key "val2"
+
+ (let loop ([iter (continuation-marks->iterator
+
+ (current-continuation-marks)
+
+ '#(key other))])
+
+ (let-values ([(vec iter) (iter)])
+
+ (if vec
+
+ (cons vec (loop iter))
+
+ '()))))))) ; => (#("val2" #f) #("val" "also"))
+
procedure: (call-with-immediate-continuation-mark key proc)
+
procedure: (call-with-immediate-continuation-mark key none-val proc)
+
+returns: the value produced by calling proc
+
+libraries: (chezscheme)
+
+
Similar to + +
(continuation-marks-first (current-continuation-marks) key none-val) +
but only the immediate continuation's mark table is checked, and the result is +delivered to proc instead of returned. The proc, which must be +a procedure that accepts one argument, is called +in tail position, so its continuation is the same as the one whose +table is checked. + +
+ +
(with-continuation-mark
+
+ 'key "val"
+
+ (call-with-immediate-continuation-mark 'key list)) ; => ("val")
+
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (vector (call-with-immediate-continuation-mark 'key list))) ; => #((#f))
+
+(with-continuation-mark
+
+ 'key "val"
+
+ (vector (call-with-immediate-continuation-mark 'key 'no list))) ; => #((no))
+
procedure: (call-in-continuation continuation procedure)
+
procedure: (call-in-continuation continuation marks procedure)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
continuation must be a continuation, +procedure must be a procedure that accepts zero arguments, and +marks (if provided) must be a continuation mark sequence. + +
+Applies procedure to zero arguments with continuation as +the continuation of the call, escaping from the current continuation. +This operation is similar to applying continuation to values, +except that the values delivered to the continuation are the ones +produced by procedure as it runs within the applied +continuation. + +
+If marks is not provided, then procedure starts with no +immediate mark table. Otherwise, marks must be +consistent with the result of continuation-next-marks on +continuation: either the same content or one additional mark +table, and the additional mark table becomes the immediate mark table +when calling procedure. + + +
+ +
+Engines are a high-level process abstraction supporting +timed preemption [15,24]. +Engines may be used to simulate multiprocessing, implement operating +system kernels, and perform nondeterministic computations. + +
+procedure: (make-engine thunk)
+
+returns: an engine
+
+libraries: (chezscheme)
+
+
An engine is created by passing a thunk (no argument procedure) +to make-engine. +The body of the thunk is the computation to be performed by the engine. +An engine itself is a procedure of three arguments: + +
+
+
+
+When an engine is applied to its arguments, it sets up a timer +to fire in ticks time units. +(See set-timer on page 359.) +If the engine computation completes before the timer expires, the +system invokes complete, passing +it the number of ticks left over and +the values produced by the computation. +If, on the other hand, the timer goes off before the engine computation +completes, the system creates a new engine from the continuation of +the interrupted computation and passes this engine to expire. +complete and expire are invoked in the continuation +of the engine invocation. + +
+An implementation of engines is given +in Section 12.11. +of The Scheme Programming Language, 4th Edition. + +
+Do not use the timer interrupt (see set-timer) and engines +at the same time, since engines are implemented in terms of the timer. + +
+The following example creates an engine from a trivial computation, +3, and gives the engine 10 ticks. + +
+ +
(define eng
+
+ (make-engine
+
+ (lambda () 3)))
+
+
+(eng 10
+
+ (lambda (ticks value) value)
+
+ (lambda (x) x)) 3
+
It is often useful to pass list as the complete +procedure to an engine, causing an engine that completes to return a +list whose first element is the ticks remaining and whose remaining elements +are the values returned by the computation. + +
+ +
(define eng
+
+ (make-engine
+
+ (lambda () 3)))
+
+
+(eng 10
+
+ list
+
+ (lambda (x) x)) (9 3)
+
In the example above, the value is 3 and there are 9 ticks left over, +i.e., it takes one unit of fuel to evaluate 3. +(The fuel amounts given here are for illustration only. +Your mileage may vary.) + +
+Typically, the engine computation does not finish in one try. +The following example displays the use of an engine to +compute the 10th Fibonacci number in steps. + +
+ +
(define fibonacci
+
+ (lambda (n)
+
+ (let fib ([i n])
+
+ (cond
+
+ [(= i 0) 0]
+
+ [(= i 1) 1]
+
+ [else (+ (fib (- i 1))
+
+ (fib (- i 2)))]))))
+
+
+(define eng
+
+ (make-engine
+
+ (lambda ()
+
+ (fibonacci 10))))
+
+
+(eng 50
+
+ list
+
+ (lambda (new-eng)
+
+ (set! eng new-eng)
+
+ "expired")) "expired"
+
+
+(eng 50
+
+ list
+
+ (lambda (new-eng)
+
+ (set! eng new-eng)
+
+ "expired")) "expired"
+
+
+(eng 50
+
+ list
+
+ (lambda (new-eng)
+
+ (set! eng new-eng)
+
+ "expired")) "expired"
+
+
+(eng 50
+
+ list
+
+ (lambda (new-eng)
+
+ (set! eng new-eng)
+
+ "expired")) (21 55)
+
Each time the engine's fuel runs out, the expire procedure assigns +eng to the new engine. +The entire computation requires four blocks of 50 ticks to complete; of the +last 50 it uses all but 21. +Thus, the total amount of fuel used is 179 ticks. +This leads to the following procedure, mileage, which "times" a +computation using engines: + +
+ +
(define mileage
+
+ (lambda (thunk)
+
+ (let loop ([eng (make-engine thunk)] [total-ticks 0])
+
+ (eng 50
+
+ (lambda (ticks . values)
+
+ (+ total-ticks (- 50 ticks)))
+
+ (lambda (new-eng)
+
+ (loop new-eng
+
+ (+ total-ticks 50)))))))
+
+
+(mileage (lambda () (fibonacci 10))) 179
+
The choice of 50 for the number of ticks to use each time is +arbitrary, of course. +It might make more sense to pass a much larger number, say 10000, +in order to reduce the number of times the computation is interrupted. + +
+The next procedure is similar to mileage, but it returns a list +of engines, one for each tick it takes to complete the computation. +Each of the engines in the list represents a "snapshot" of the +computation, analogous to a single frame of a moving picture. +snapshot might be useful for "single stepping" a computation. + +
+ +
(define snapshot
+
+ (lambda (thunk)
+
+ (let again ([eng (make-engine thunk)])
+
+ (cons eng
+
+ (eng 1 (lambda (t . v) '()) again)))))
+
The recursion embedded in this procedure is rather strange. +The complete procedure performs the base case, returning the empty +list, and the expire procedure performs the recursion. + +
+The next procedure, round-robin, could be the basis for a simple +time-sharing operating system. +round-robin maintains a queue of processes (a list of engines), +cycling through the queue in a round-robin fashion, allowing each +process to run for a set amount of time. +round-robin returns a list of the values returned by the engine +computations in the order that the computations complete. +Each computation is assumed to produce exactly one value. + +
+ +
(define round-robin
+
+ (lambda (engs)
+
+ (if (null? engs)
+
+ '()
+
+ ((car engs)
+
+ 1
+
+ (lambda (ticks value)
+
+ (cons value (round-robin (cdr engs))))
+
+ (lambda (eng)
+
+ (round-robin
+
+ (append (cdr engs) (list eng))))))))
+
Since the amount of fuel supplied each time, one tick, is constant, +the effect of round-robin is to return a list of the values sorted +from the quickest to complete to the slowest to complete. +Thus, when we call round-robin on a list of engines, each computing +one of the Fibonacci numbers, the output list is sorted with the earlier +Fibonacci numbers first, regardless of the order of the input list. + +
+ +
(round-robin
+
+ (map (lambda (x)
+
+ (make-engine
+
+ (lambda ()
+
+ (fibonacci x))))
+
+ '(4 5 2 8 3 7 6 2))) (1 1 2 3 5 8 13 21)
+
More interesting things can happen if the amount of fuel varies +each time through the loop. +In this case, the computation would +be nondeterministic, i.e., the results would vary from call to call. + +
+The following syntactic form, por (parallel-or), returns the +first of its expressions to complete with a true value. +por is implemented with the procedure first-true, which is +similar to round-robin but quits when any of the engines +completes with a true value. +If all of the engines complete, but none with a true value, +first-true (and hence por) returns #f. +Also, although first-true passes a fixed amount of fuel to each +engine, it chooses the next engine to run at random, and is thus +nondeterministic. + +
+ +
(define-syntax por
+
+ (syntax-rules ()
+
+ [(_ x ...)
+
+ (first-true
+
+ (list (make-engine (lambda () x)) ...))]))
+
+
+(define first-true
+
+ (let ([pick
+
+ (lambda (ls)
+
+ (list-ref ls (random (length ls))))])
+
+ (lambda (engs)
+
+ (if (null? engs)
+
+ #f
+
+ (let ([eng (pick engs)])
+
+ (eng 1
+
+ (lambda (ticks value)
+
+ (or value
+
+ (first-true
+
+ (remq eng engs))))
+
+ (lambda (new-eng)
+
+ (first-true
+
+ (cons new-eng
+
+ (remq eng engs))))))))))
+
The list of engines is maintained with pick, which randomly +chooses an element of the list, and remq, which removes the +chosen engine from the list. +Since por is nondeterministic, subsequent uses with the same +expressions may not return the same values. + +
+ +
(por 1 2 3) 2
+
+(por 1 2 3) 3
+
+(por 1 2 3) 2
+
+(por 1 2 3) 1
+
Furthermore, even if one of the expressions is an infinite loop, +por still finishes as long as one of the other expressions +completes and returns a true value. + +
+ +
(por (let loop () (loop)) 2) 2 +
With engine-return and engine-block, it is possible to +terminate an engine explicitly. +engine-return causes the engine to complete, as if the +computation had finished. +Its arguments are passed to the complete procedure along with the +number of ticks remaining. +It is essentially a nonlocal exit from the engine. +Similarly, engine-block causes the engine to expire, as if the +timer had run out. +A new engine is made from the continuation of the call to engine-block +and passed to the expire procedure. + + +
+procedure: (engine-block)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
This causes a running engine to stop, create a new engine capable +of continuing the computation, and pass the new engine to the original +engine's third argument +(the expire procedure). +Any remaining fuel is forfeited. + +
+ +
(define eng
+
+ (make-engine
+
+ (lambda ()
+
+ (engine-block)
+
+ "completed")))
+
+
+(eng 100
+
+ (lambda (ticks value) value)
+
+ (lambda (x)
+
+ (set! eng x)
+
+ "expired")) "expired"
+
+
+(eng 100
+
+ (lambda (ticks value) value)
+
+ (lambda (x)
+
+ (set! eng x)
+
+ "expired")) "completed"
+
procedure: (engine-return obj ...)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
This causes a running engine to stop and pass control to the +engine's complete argument. +The first argument passed to the complete procedure is the amount of +fuel remaining, as usual, and +the remaining arguments are the objects obj ... +passed to engine-return. + +
+ +
(define eng
+
+ (make-engine
+
+ (lambda ()
+
+ (reverse (engine-return 'a 'b 'c)))))
+
+
+(eng 100
+
+ (lambda (ticks . values) values)
+
+ (lambda (new-eng) "expired")) (a b c)
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/csug.css b/csug10.0/csug.css
new file mode 100644
index 000000000..083ce260b
--- /dev/null
+++ b/csug10.0/csug.css
@@ -0,0 +1,35 @@
+BODY {background-color: #FFFFFF}
+
+a:link, a:active, a:visited { color:#005568; text-decoration:underline }
+a:hover { color:white; text-decoration:underline; background:#005568 }
+
+a.plain:link, a.plain:active, a.plain:visited { color:#005568; text-decoration:none }
+a.plain:hover { color:white; text-decoration:none; background:#005568 }
+
+a.toc:link, a.toc:active, a.toc:visited {font-family: sans-serif; color:#005568; text-decoration:none}
+a.toc:hover {font-family: sans-serif; color:white; text-decoration:none; background:#005568}
+
+a.image:link, a.image:active, a.image:visited, a.image:hover {
+ color: #005568;
+ background: #FFFFFF;
+}
+
+ul.tocchapter { list-style: none; }
+ul.tocsection { list-style: circle; color: #C41230 }
+
+hr.copyright { width: 50% }
+
+input.default { background: #ffffff; color: #000000; vertical-align: middle}
+
+h1, h2, h3, h4 {font-family: sans-serif; color: #005568}
+h1 {font-size: 2em}
+h2 {margin-top: 30px; font-size: 1.5em}
+h3 {margin-top: 30px; font-size: 1.17em}
+h1, h2, h3, h4 {font-weight: bold}
+
+.title { font-family: sans-serif; font-weight: bold; font-size: 2.5em; color: #005568; white-space: nowrap}
+
+.formdef { color: #005568 }
+
+table.indent {margin-left: 20px}
+
diff --git a/csug10.0/csug.html b/csug10.0/csug.html
new file mode 100644
index 000000000..6c8c76372
--- /dev/null
+++ b/csug10.0/csug.html
@@ -0,0 +1,417 @@
+
+
+
+
+
+ + +
+
Chez Scheme Version 10 User's Guide |
+
+ + + + + + + + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
+
+ + diff --git a/csug10.0/csug10.0.pdf b/csug10.0/csug10.0.pdf new file mode 100644 index 000000000..042556c2b Binary files /dev/null and b/csug10.0/csug10.0.pdf differ diff --git a/csug10.0/csug_1.html b/csug10.0/csug_1.html new file mode 100644 index 000000000..a85fdd70d --- /dev/null +++ b/csug10.0/csug_1.html @@ -0,0 +1,2480 @@ + + + + +
++This index is a unified index for this book and +The +Scheme Programming Language, 4th Edition (TSPL4). +Page numbers prefixed by "t" refer the latter document. +Italicized page numbers refer to the primary description of a syntactic +form or procedure. + +
+All page numbers appearing here refer to the printed version of these +books and also serve as hypertext links to the corresponding locations +in the electronic versions of these books. + +
+ + + + + + +
+! (exclamation point), t8
+
" (double quote), t216
+
#!r6rs, t456
+
#n# (graph reference), 3, 280
+
#% ($primitive), 3, 390
+
#2% ($primitive), 390
+
#3% ($primitive), 390
+
#& (box prefix), 3, 168
+
#' (syntax), t300
+
#( (vector prefix), 3, 153
+
#n( (vector prefix), 3, 153
+
#, (unsyntax), t305
+
#,@ (unsyntax-splicing), t305
+
#: (gensym prefix), 2, 170, 171, 282
+
#; (datum comment), t455
+
#n= (graph mark), 3, 280
+
#[ (record prefix), 3
+
#\, t211
+
#\alarm, 3
+
#\backspace, 3
+
#\bel, 3
+
#\delete, 3
+
#\esc, 3
+
#\linefeed, 3
+
#\ls, 3
+
#\nel, 3
+
#\newline, 3
+
#\nul, 3
+
#\page, 3
+
#\return, 3
+
#\rubout, 3
+
#{ (gensym prefix), 2, 170, 171, 282
+
#\space, 3
+
#\tab, 3
+
#\vt, 3
+
#` (quasisyntax), t305
+
#|...|# (block comment), t455
+
#b (binary), t169
+
#d (decimal), t169
+
#f, t7, t36, t143
+
#false, 4
+
#o (octal), t169
+
#nr (radix prefix), 3
+
#t, t7, t36, t143
+
#true, 4
+
#nvfl( (flvector prefix), 158
+
#vfl( (flvector prefix), 158
+
#nvfx( (fxvector prefix), 155
+
#vfx( (fxvector prefix), 155
+
#nvs( (stencil vector prefix), 165
+
#x (hexadecimal), t169
+
$primitive ( #% ), 390
+
$primitive ( #2% ), 390
+
$primitive ( #3% ), 390
+
$system, 339
+
$system module, 339
+
&assertion, t366
+
&condition, t362
+
&continuation, 355
+
&error, t367
+
&format, 354
+
&i/o, t371
+
&i/o-decoding, t375
+
&i/o-encoding, t376
+
&i/o-file-already-exists, t374
+
&i/o-file-does-not-exist, t374
+
&i/o-file-is-read-only, t374
+
&i/o-file-protection, t373
+
&i/o-filename, t373
+
&i/o-invalid-position, t372
+
&i/o-port, t375
+
&i/o-read, t372
+
&i/o-write, t372
+
&implementation-restriction, t369
+
&irritants, t368
+
&lexical, t370
+
&message, t368
+
&no-infinities, t376
+
&no-nans, t377
+
&non-continuable, t369
+
&serious, t366
+
&source, 354
+
&syntax, t370
+
&undefined, t371
+
&violation, t366
+
&warning, t367
+
&who, t369
+
' (quote), t17, t22, t59, t141
+
(), t7, t19
+
(chezscheme csv7) library, 304
+
(chezscheme) library, 304
+
(scheme csv7) library, 304
+
(scheme) library, 304
+
*, t16, t172
+
+, t16, t171
+
, (unquote), t142
+
,@ (unquote-splicing), t142
+
-, t16, t172
+
-- command-line option, 30
+
--boot command-line option, 30, 30, 376
+
--compact command-line option, 30
+
--compile-imported-libraries command-line option, 30, 316
+
--debug-on-exception command-line option, 10, 30, 41, 356, 356
+
--disable-library-timestamps command-line option, 318
+
--eedisable command-line-option, 30
+
--eehistory command-line-option, 30, 462
+
--enable-object-counts command-line-option, 30
+
--heap command-line option, 30
+
--help command-line option, 30
+
--import-notify command-line option, 18, 30
+
--libdirs command-line option, 21, 30, 316
+
--libexts command-line option, 21, 30, 316
+
--optimize-level command-line option, 23, 30, 389
+
--program command-line option, 10, 21, 30, 41, 305, 371, 390, 411
+
--quiet command-line option, 30
+
--retain-static-relocation command-line option, 30, 53, 54
+
--saveheap command-line option, 30
+
--script command-line option, 10, 20, 30, 41, 371, 411, 412
+
--verbose command-line option, 30
+
--version command-line option, 30
+
->, t8
+
-1+, 235
+
-b command-line option, 30, 30, 376
+
-c command-line option, 30
+
-h command-line option, 30
+
-q command-line option, 30
+
-s command-line option, 30
+
. (dot), t19, t460
+
... (ellipses), 281, 483
+
... (ellipsis), t61, t294, t297
+
/, t16, t172
+
; (comment), t7, t455
+
<, 235, t170
+
<=, 235, t170
+
=, 235, t170
+
=>, t111, t112
+
>, 235, t170
+
>=, 235, t170
+
? (question mark), t8, t37
+
[, 273
+
], 273
+
_ (underscore), t61, t296, t315
+
_ (underscore), t294, t297
+
` (quasiquote), t142
+
1+, 235
+
1-, 235
+
abort, 410
+
abort-handler, 410
+
abs, t34, t178, t183
+
abstract objects, t53, t408
+
acos, t185
+
acosh, 238
+
actual parameters, t27, t92
+
add-duration, 416
+
add-duration!, 416
+
add-prefix, 338
+
add1, 235
+
Algol 60, t6
+
alias, 117, 338, 342
+
and, 484, t37, t62, t110
+
andmap, 129, 485
+
angle, t183
+
annotation-expression, 345
+
annotation-option-set, 346
+
annotation-options, 348
+
annotation-source, 346
+
annotation-stripped, 346
+
annotation?, 345
+
annotations, 343
+
append, t46, t160
+
append!, 147
+
applications, 24
+
apply, t107
+
apropos, 364
+
apropos-list, 363
+
arbitrary precision, t167
+
ash, 228
+
asin, t185
+
asinh, 238
+
assert, t359
+
assert-unreachable, 357
+
assertion-violation, t358
+
assertion-violation?, t366
+
assertion-violationf, 354
+
assignable variables, 41
+
assignment, t102
+
assignments, 120, 122, t47, t102
+
assoc, t165
+
association list, t165, t166, t243, t404
+
assp, t166
+
assq, t165
+
assv, t165
+
atan, t185
+
atanh, 238
+
atom?, 143, t41
+
auxiliary keywords, 17, t61, t294
+
base case, t41
+
base-exception-handler, 11, 356
+
be-like-begin, t313
+
begin, 117, t51, t60, t101, t108
+
bignum, 213, 214
+
bignum?, 214
+
binary port, t257
+
binary trees, t155
+
binary-port-input-buffer, 246
+
binary-port-input-count, 247
+
binary-port-input-index, 246
+
binary-port-input-size, 246
+
binary-port-output-buffer, 247
+
binary-port-output-count, 248
+
binary-port-output-index, 247
+
binary-port-output-size, 247
+
binary-port?, t270
+
binding, t4
+
bitwise-and, t186
+
bitwise-arithmetic-shift, t190
+
bitwise-arithmetic-shift-left, t189
+
bitwise-arithmetic-shift-right, t189
+
bitwise-bit-count, t187
+
bitwise-bit-field, t189
+
bitwise-bit-set?, t188
+
bitwise-copy-bit, t188
+
bitwise-copy-bit-field, t189
+
bitwise-first-bit-set, t187
+
bitwise-if, t186
+
bitwise-ior, t186
+
bitwise-length, t187
+
bitwise-not, t186
+
bitwise-reverse-bit-field, t191
+
bitwise-rotate-bit-field, t190
+
bitwise-xor, t186
+
block buffering, t258
+
block comment ( #|...|# ), t455
+
block profiling, 397
+
block structure, t4
+
block-read, 262
+
block-write, 269
+
boolean, 63, 66
+
boolean syntax, t457
+
boolean values, t7
+
boolean=?, t243
+
boolean?, t150
+
boot files, 28, 31
+
bound-identifier=?, t302
+
box, 168
+
box-cas!, 169
+
box-immobile, 452
+
box-immutable, 168, 170
+
box?, 168
+
boxes, 168
+
brackets ( [ ] ), t7, t155
+
break, 358, t308
+
break-handler, 358
+
broadcast streams, 239
+
buffer modes, t258
+
buffer-mode, t261
+
buffer-mode?, t262
+
bwp-object?, 445
+
bytes-allocated, 422
+
bytes-deallocated, 422
+
bytes-finalized, 422
+
bytevector, 161
+
bytevector syntax, t461
+
bytevector->immutable-bytevector, 161, 164
+
bytevector->s8-list, 161
+
bytevector->sint-list, t238
+
bytevector->string, t286
+
bytevector->u8-list, t232
+
bytevector->uint-list, t238
+
bytevector-compress, 164
+
bytevector-copy, t229
+
bytevector-copy!, t230
+
bytevector-fill!, t229
+
bytevector-ieee-double-native-ref, t239
+
bytevector-ieee-double-native-set!, t239
+
bytevector-ieee-double-ref, t240
+
bytevector-ieee-double-set!, t240
+
bytevector-ieee-single-native-ref, t239
+
bytevector-ieee-single-native-set!, t239
+
bytevector-ieee-single-ref, t240
+
bytevector-ieee-single-set!, t240
+
bytevector-length, t229
+
bytevector-reference*-ref, 92
+
bytevector-reference-ref, 91
+
bytevector-reference-set!, 91
+
bytevector-s16-native-ref, t232
+
bytevector-s16-native-set!, t233
+
bytevector-s16-ref, t235
+
bytevector-s16-set!, t236
+
bytevector-s24-ref, 163
+
bytevector-s24-set!, 163
+
bytevector-s32-native-ref, t232
+
bytevector-s32-native-set!, t233
+
bytevector-s32-ref, t235
+
bytevector-s32-set!, t236
+
bytevector-s40-ref, 163
+
bytevector-s40-set!, 163
+
bytevector-s48-ref, 163
+
bytevector-s48-set!, 163
+
bytevector-s56-ref, 163
+
bytevector-s56-set!, 163
+
bytevector-s64-native-ref, t232
+
bytevector-s64-native-set!, t233
+
bytevector-s64-ref, t235
+
bytevector-s64-set!, t236
+
bytevector-s8-ref, t231
+
bytevector-s8-set!, t231
+
bytevector-sint-ref, t237
+
bytevector-sint-set!, t238
+
bytevector-truncate!, 162
+
bytevector-u16-native-ref, t232
+
bytevector-u16-native-set!, t233
+
bytevector-u16-ref, t235
+
bytevector-u16-set!, t236
+
bytevector-u24-ref, 163
+
bytevector-u24-set!, 163
+
bytevector-u32-native-ref, t232
+
bytevector-u32-native-set!, t233
+
bytevector-u32-ref, t235
+
bytevector-u32-set!, t236
+
bytevector-u40-ref, 163
+
bytevector-u40-set!, 163
+
bytevector-u48-ref, 163
+
bytevector-u48-set!, 163
+
bytevector-u56-ref, 163
+
bytevector-u56-set!, 163
+
bytevector-u64-native-ref, t232
+
bytevector-u64-native-set!, t233
+
bytevector-u64-ref, t235
+
bytevector-u64-set!, t236
+
bytevector-u8-ref, t230
+
bytevector-u8-set!, t231
+
bytevector-uint-ref, t237
+
bytevector-uint-set!, t238
+
bytevector-uncompress, 164
+
bytevector=?, t229
+
bytevector?, t155
+
C, t393
+
C (programming language), 57, 59, 95, 97
+
C preprocessor macros, 97
+
C-callable library functions, 97
+
caaaar, t157
+
caaadr, t157
+
caaar, t157
+
caadar, t157
+
caaddr, t157
+
caadr, t157
+
caar, t157
+
caar, cadr, ..., cddddr, t34
+
cadaar, t157
+
cadadr, t157
+
cadar, t157
+
caddar, t157
+
cadddr, t157
+
caddr, t157
+
cadr, t31, t32, t34, t157
+
café, 407
+
call-by-name, t408
+
call-by-reference, 168
+
call-by-value, t407
+
call-in-continuation, 135
+
call-with-bytevector-output-port, t266
+
call-with-current-continuation, t123, t426
+
call-with-immediate-continuation-mark, 135
+
call-with-input-file, 258, t281
+
call-with-output-file, 266, t282
+
call-with-port, t272
+
call-with-string-output-port, t267
+
call-with-values, t130, t131
+
call/1cc, 130
+
call/cc, t74, t122, t123, t126, t133, t425, t426
+
car, t18, t155, t156
+
case, 127, t55, t113, t306
+
case-lambda, 34, 429, t94
+
case-sensitive, 279
+
cd, 288
+
cdaaar, t157
+
cdaadr, t157
+
cdaar, t157
+
cdadar, t157
+
cdaddr, t157
+
cdadr, t157
+
cdar, t157
+
cddaar, t157
+
cddadr, t157
+
cddar, t157
+
cdddar, t157
+
cddddr, t157
+
cdddr, t157
+
cddr, t31, t34, t157
+
cdr, t18, t38, t155, t156
+
ceiling, t177
+
cfl*, 223
+
cfl+, 223
+
cfl-, 223
+
cfl-conjugate, 223
+
cfl-imag-part, 222
+
cfl-magnitude-squared, 224
+
cfl-real-part, 222
+
cfl/, 223
+
cfl=, 223
+
cflonum, 214
+
cflonum?, 215
+
cflonums, 222
+
char, 63, 66
+
char-, 148
+
char->integer, t215
+
char-alphabetic?, t213
+
char-ci<=?, 148, t212
+
char-ci<?, 148, t212
+
char-ci=?, 148, t212
+
char-ci>=?, 148, t212
+
char-ci>?, 148, t212
+
char-downcase, t214
+
char-extended-pictographic?, 150
+
char-foldcase, t215
+
char-general-category, t214
+
char-grapheme-break-property, 149
+
char-grapheme-step, 149
+
char-lower-case?, t213
+
char-name, 148, 278
+
char-numeric?, t213
+
char-ready?, 262
+
char-title-case?, t213
+
char-titlecase, t214
+
char-upcase, t214
+
char-upper-case?, t213
+
char-whitespace?, t213
+
char<=?, 148, t212
+
char<?, 148, t212
+
char=?, 148, t212
+
char>=?, 148, t212
+
char>?, 148, t212
+
char?, t154
+
character syntax, t457
+
characters, t211
+
Chez Scheme, tix, t42
+
CHEZSCHEMELIBDIRS, 22
+
CHEZSCHEMELIBEXTS, 22
+
child type, t325
+
chmod, 291
+
circular lists, t156
+
clear-input-port, 252
+
clear-output-port, 253
+
close-input-port, t285
+
close-output-port, t285
+
close-port, t270
+
codec, t257
+
collect, 437, 439
+
collect-generation-radix, 438, 440
+
collect-maximum-generation, 437, 441
+
collect-maximum-generation-threshold-factor, 438, 440
+
collect-notify, 440
+
collect-rendezvous, 440
+
collect-request-handler, 437, 441, 450
+
collect-trip-bytes, 437, 440
+
collections, 423
+
command-line, 411, 412, t350
+
command-line options, 30
+
command-line-arguments, 411, 412
+
comments, t7, t455
+
Common Lisp, t6
+
commonization-level, 395
+
compilation, 369
+
compile, 365, 391
+
compile-file, 10, 26, 369, 389
+
compile-file-message, 393
+
compile-imported-libraries, 18, 19, 316
+
compile-interpret-simple, 391
+
compile-library, 19, 23, 26, 367, 371
+
compile-library-handler, 372
+
compile-omit-concatenate-support, 388
+
compile-port, 374
+
compile-procedure-realm, 378
+
compile-profile, 398, 401
+
compile-program, 19, 20, 23, 26, 306, 367, 371
+
compile-program-handler, 372
+
compile-script, 21, 26, 370
+
compile-time-value-value, 330
+
compile-time-value?, 330
+
compile-to-file, 372, 376
+
compile-to-port, 375
+
compile-whole-library, 367, 374
+
compile-whole-program, 28, 367, 373, 392
+
compiler, t4
+
complete, see engines
+
complex numbers, 222, t167, t412
+
complex?, t151, t167
+
compose, t34
+
compound condition, t362
+
compress-format, 164, 242, 253, 266, 288
+
compress-level, 164, 242, 253, 254, 266, 288
+
compute-composition, 55
+
compute-size, 42, 54
+
compute-size-increments, 56
+
concatenate-object-files, 376
+
concatenated streams, 239
+
cond, 484, t39, t44, t111, t304
+
condition, t362
+
condition object, t361
+
condition type, t361
+
condition-accessor, t365
+
condition-broadcast, 471
+
condition-continuation, 355
+
condition-irritants, t368
+
condition-message, t368
+
condition-name, 471
+
condition-predicate, t365
+
condition-signal, 471
+
condition-wait, 470
+
condition-who, t369
+
condition?, t362
+
conditionals, t109
+
conditions, t357
+
conjugate, 223, 237
+
cons, t19, t156
+
cons cell, t155
+
cons*, t158
+
consing, t19
+
console-error-port, 265
+
console-input-port, 256, 408
+
console-output-port, 264, 408
+
constant, t141
+
constants, t21, t141
+
constructor, 199
+
continuation-condition?, 355
+
continuation-marks->iterator, 134
+
continuation-marks->list, 133
+
continuation-marks-first, 133
+
continuation-marks?, 132
+
continuation-next-marks, 132
+
continuation-passing style, t78, t418
+
continuations, t5, t73, t124, t421
+
control structures, t107
+
copy propagation, 22
+
copy-environment, 363
+
copy-time, 416
+
core syntactic forms, t4, t22, t59, t404
+
cos, t185
+
cosh, 238
+
cost-center-allocation-count, 428
+
cost-center-instruction-count, 428
+
cost-center-time, 428
+
cost-center?, 428
+
cp0-effort-limit, 393
+
cp0-outer-unroll-limit, 393
+
cp0-score-limit, 393
+
CPS, t78
+
cpu-time, 421
+
create-exception-state, 357
+
creating subprocesses, 57
+
critical-section, 360
+
current exception handler, t357
+
current-continuation-marks, 132
+
current-date, 417
+
current-directory, 288
+
current-error-port, 265, t263
+
current-eval, 365
+
current-exception-state, 356
+
current-expand, 379
+
current-generate-id, 386
+
current-input-port, 257, t263
+
current-locate-source-object-source, 349
+
current-make-source-object, 347
+
current-memory-bytes, 422
+
current-output-port, 264, t263
+
current-time, 414
+
current-transcoder, 244
+
custom-port-buffer-size, 256
+
customization, 24
+
cyclic lists, t56
+
d (double), t169
+
data, t141
+
date->time-utc, 420
+
date-and-time, 420
+
date-day, 418
+
date-dst?, 419
+
date-hour, 418
+
date-minute, 418
+
date-month, 418
+
date-nanosecond, 418
+
date-second, 418
+
date-week-day, 419
+
date-year, 418
+
date-year-day, 419
+
date-zone-name, 419
+
date-zone-offset, 418
+
date?, 418
+
datum, 325
+
datum comment ( #; ), t455
+
datum syntax, t455, t456
+
datum->syntax, 491, t308, t317, t320
+
datum->syntax-object, 325
+
debug, 41
+
debug-condition, 356
+
debug-level, 390
+
debug-on-exception, 10, 356
+
debugger, 358
+
decode-float, 221
+
default protocol, t327
+
default-exception-handler, 355
+
default-library-search-handler, 317
+
default-prompt-and-read, 409
+
default-record-equal-procedure, 188, 191
+
default-record-hash-procedure, 189, 192
+
define, 117, 121, t30, t81, t100
+
define-condition-type, t364
+
define-enumeration, t250
+
define-ftype, 77
+
define-integrable, 322, t315
+
define-object, t408
+
define-property, 330
+
define-record, 192, 195
+
define-record-type, 187, 188, t323, t328
+
define-structure, 489, t318
+
define-syntax, 117, 123, t61, t291, t292, t389
+
define-top-level-syntax, 123
+
define-top-level-value, 121
+
define-values, 118
+
defining syntactic extensions, t60
+
definitions, 117
+
defun syntax, t33, t60
+
delay, t128
+
delayed evaluation, t408
+
delete-directory, 291
+
delete-file, 290, t286
+
delq!, t54
+
denominator, t181
+
describe-segment, t132
+
directory-list, 288
+
directory-separator, 292
+
directory-separator?, 292
+
disable-interrupts, 359, 440
+
display, t285, t397
+
display-condition, 355
+
display-statistics, 421
+
display-string, 269
+
distributing applications, 24
+
div, t175
+
div-and-mod, t175
+
div0, t176
+
div0-and-mod0, t176
+
divisors, t115, t116
+
do, 35, t115, t312
+
dot ( . ), t19, t460
+
dotted pair, t20, t155
+
double, 63, 65, 66, t27, t33
+
double quotes, t216
+
double-any, t30
+
double-cons, t27, t33
+
double-float, 61, 65
+
doubler, t33
+
doubly recursive, t70
+
drop-prefix, 338
+
dxdy, t131
+
dynamic allocation, t3
+
dynamic-wind, 131, t124
+
echo streams, 239
+
ee-accept, 463
+
ee-auto-indent, 455, 458
+
ee-auto-paren-balance, 456, 458
+
ee-backward-char, 458
+
ee-backward-delete-char, 460
+
ee-backward-delete-sexp, 461
+
ee-backward-page, 460
+
ee-backward-sexp, 460
+
ee-backward-word, 460
+
ee-beginning-of-entry, 459
+
ee-beginning-of-line, 459
+
ee-bind-key, 457
+
ee-command-repeat, 464
+
ee-common-identifiers, 456, 462
+
ee-compose, 457, 465
+
ee-default-repeat, 456, 464
+
ee-delete-between-point-and-mark, 461
+
ee-delete-char, 460
+
ee-delete-entry, 461
+
ee-delete-line, 460
+
ee-delete-sexp, 461
+
ee-delete-to-eol, 461
+
ee-end-of-entry, 459
+
ee-end-of-line, 459
+
ee-eof, 463
+
ee-eof/delete-char, 464
+
ee-exchange-point-and-mark, 459
+
ee-flash-matching-delimiter, 459
+
ee-flash-parens, 456, 458
+
ee-forward-char, 458
+
ee-forward-page, 460
+
ee-forward-sexp, 460
+
ee-forward-word, 460
+
ee-goto-matching-delimiter, 459
+
ee-history-bwd, 459, 462
+
ee-history-bwd-contains, 463
+
ee-history-bwd-prefix, 462
+
ee-history-fwd, 459, 462
+
ee-history-fwd-contains, 463
+
ee-history-fwd-prefix, 462
+
ee-history-limit, 456
+
ee-id-completion, 461
+
ee-id-completion/indent, 461, 464
+
ee-indent, 463
+
ee-indent-all, 463
+
ee-insert-paren, 458
+
ee-insert-self, 457
+
ee-newline, 458
+
ee-newline/accept, 464
+
ee-next-id-completion, 462
+
ee-next-id-completion/indent, 462, 464
+
ee-next-line, 459
+
ee-noisy, 456
+
ee-open-line, 458
+
ee-paren-flash-delay, 456, 458, 459
+
ee-previous-line, 459
+
ee-redisplay, 463
+
ee-reset-entry, 461
+
ee-set-mark, 464
+
ee-standard-indent, 455
+
ee-string-macro, 457, 465
+
ee-suspend-process, 464
+
ee-yank-kill-buffer, 458
+
ee-yank-selection, 458
+
ellipses ( ... ), 281, 483
+
ellipsis ( ... ), t61, t294
+
else, 127, 128, t111, t112, t113
+
empty list, t7, t19
+
enable-arithmetic-left-associative, 392
+
enable-cross-library-optimization, 392
+
enable-error-source-expression, 392
+
enable-interrupts, 359
+
enable-object-backreferences, 426
+
enable-object-counts, 425
+
enable-type-recovery, 395
+
enable-unsafe-application, 392
+
enable-unsafe-variable-reference, 392
+
endianness, t228
+
engine-block, 140
+
engine-return, 141
+
engines, 135, 136, t421
+
enum-set->list, t252
+
enum-set-complement, t254
+
enum-set-constructor, t251
+
enum-set-difference, t253
+
enum-set-indexer, t254
+
enum-set-intersection, t253
+
enum-set-member?, t253
+
enum-set-projection, t254
+
enum-set-subset?, t252
+
enum-set-union, t253
+
enum-set-universe, t252
+
enum-set=?, t252
+
enum-set?, 143
+
enumerate, 145
+
environment, t137
+
environment, t404
+
environment-mutable?, 361
+
environment-symbols, 363
+
environment?, 361
+
eof object, t257
+
eof-object, t273
+
eof-object?, t257, t273
+
eol style, t257
+
eol-style, t259
+
ephemeron pairs, 443
+
ephemeron-cons, 444
+
ephemeron-pair?, 445
+
eq-hashtable-cell, 183
+
eq-hashtable-contains?, 182
+
eq-hashtable-delete!, 184
+
eq-hashtable-ephemeron?, 181
+
eq-hashtable-ref, 181
+
eq-hashtable-ref-cell, 183
+
eq-hashtable-set!, 181
+
eq-hashtable-try-atomic-cell, 183
+
eq-hashtable-update!, 182
+
eq-hashtable-weak?, 181
+
eq-hashtable?, 181
+
eq?, t143
+
equal-hash, 188, t245
+
equal-hash on records, 188
+
equal?, 188, t148
+
equal? on records, 188
+
equivalence predicates, t143
+
eqv?, t38, t146
+
error, t358
+
error handling mode, t258
+
error-handling-mode, t260
+
error?, t367
+
errorf, 354
+
eval, 364, 365, t136
+
eval-syntax-expanders-when, 385
+
eval-when, 381, 389
+
even?, t47, t66, t81, t174
+
exact, 219, t180
+
exact complexnum, 213
+
exact->inexact, t181
+
exact-integer-sqrt, t184
+
exact?, t167, t170
+
exactness, t167, t180
+
exactness preserving, t167
+
except, 338
+
except import set, t346
+
exception handling, 353
+
exceptions, 4, t9, t357
+
exclamation point ( ! ), t8
+
exclusive-cond, 127
+
exists, t119
+
exit, 410, t350
+
exit-handler, 410
+
exp, t184
+
expand, 379, 396, 408
+
expand-omit-library-invocations, 387
+
expand-output, 379, 396
+
expand-time generativity, 193
+
expand/optimize, 380, 394, 396
+
expand/optimize-output, 380, 396
+
expansion, t59
+
expire, see engines
+
export, 312, t345
+
export level, t345
+
expression-editor, 455
+
expressions, t7
+
expt, t179
+
expt-mod, 236
+
extend-syntax, 483
+
extended examples, t381
+
f (single), t169
+
factor, t71, t72, t73
+
factorial, t68, t75, t116
+
false, t7, t36
+
fasl-compressed, 288
+
fasl-file, 288
+
fasl-read, 287
+
fasl-strip-options, 377
+
fasl-write, 286
+
fast Fourier transform (FFT), t412
+
fast loading format, 286
+
fenders, 483, 485, t299, t301
+
fibonacci, 137, t69, t102, t116, t422
+
Fibonacci numbers, t69, t102
+
fields, t331
+
file, t257
+
file-access-time, 290
+
file-buffer-size, 256
+
file-change-time, 290
+
file-directory?, 289
+
file-exists?, 289, t286
+
file-length, 250
+
file-modification-time, 290
+
file-options, t261
+
file-port?, 256
+
file-position, 252
+
file-regular?, 289
+
file-symbolic-link?, 289
+
filter, t164
+
find, t165
+
finite?, t174
+
first-class data values, t3
+
first-class procedures, t5
+
fixnum, 63
+
fixnum, 213, 214, t192
+
fixnum->flonum, t211
+
fixnum-width, t193
+
fixnum?, t193
+
fl*, t207
+
fl+, t206
+
fl-, t206
+
fl-make-rectangular, 222
+
fl/, t207
+
fl<, 220
+
fl<=, 220
+
fl<=?, t203
+
fl<?, t203
+
fl=, 220
+
fl=?, t203
+
fl>, 220
+
fl>=, 220
+
fl>=?, t203
+
fl>?, t203
+
flabs, t209
+
flacos, t210
+
flasin, t210
+
flatan, t210
+
flceiling, t208
+
flcos, t210
+
fldenominator, t209
+
fldiv, t207
+
fldiv-and-mod, t207
+
fldiv0, t208
+
fldiv0-and-mod0, t208
+
fleven?, t205
+
flexp, t209
+
flexpt, t210
+
flfinite?, t205
+
flfloor, t208
+
flinfinite?, t205
+
flinteger?, t204
+
flip-flop, t102
+
fllog, t209
+
fllp, 221
+
flmax, t205
+
flmin, t205
+
flmod, t207
+
flmod0, t208
+
flnan?, t205
+
flnegative?, t204
+
flnonnegative?, 220
+
flnonpositive?, 220
+
flnumerator, t209
+
float, 63, 65, 67
+
floating
+point, t167
+
flodd?, t205
+
flonum, 213, 214, t202
+
flonum->fixnum, 219
+
flonum?, t203
+
floor, t177
+
flpositive?, t204
+
flround, t208
+
flsin, t210
+
flsingle, 221
+
flsqrt, t210
+
fltan, t210
+
fltruncate, t208
+
fluid binding, 120, t125
+
fluid-let, 120
+
fluid-let-syntax, 321, 323
+
flush-output-port, 253, t280
+
flvector, 158
+
flvector->list, 160
+
flvector-copy, 160
+
flvector-fill!, 160
+
flvector-length, 159
+
flvector-ref, 159
+
flvector-set!, 159
+
flvector?, 158
+
flvectors, 158
+
flzero?, t204
+
fold-left, t120
+
fold-right, t121
+
folding, t120, t121
+
for-all, t119
+
for-each, t118
+
force, t128
+
foreign entry, 59
+
foreign types, 77
+
foreign-address-name, 94
+
foreign-alignof, 77
+
foreign-alloc, 75
+
foreign-callable, 70, 83
+
foreign-callable-code-object, 73
+
foreign-callable-entry-point, 71, 73
+
foreign-entry, 93
+
foreign-entry?, 93, 97
+
foreign-free, 75
+
foreign-procedure, 59, 69, 88
+
foreign-procedure interface, 59
+
foreign-ref, 75
+
foreign-set!, 77
+
foreign-sizeof, 77
+
fork-thread, 468
+
formal parameters, t26, t29, t92
+
format, 275, 487
+
format-condition?, 354
+
formatted error messages, 354
+
formatted output, 275, t401
+
fprintf, 277, t401
+
Fred, 174
+
free variable, t28
+
free-identifier=?, 17, t302
+
frequency, t393
+
fresh-line, 270
+
ftype, 64, 68
+
ftype subtyping, 82
+
ftype-&ref, 85
+
ftype-guardian, 450, 451, 473, 474
+
ftype-init-lock!, 472
+
ftype-lock!, 472
+
ftype-locked-decr!, 473, 474
+
ftype-locked-incr!, 473, 474
+
ftype-pointer->sexpr, 89
+
ftype-pointer-address, 84
+
ftype-pointer-ftype, 88
+
ftype-pointer-null?, 85
+
ftype-pointer=?, 85
+
ftype-pointer?, 84
+
ftype-ref, 86
+
ftype-set!, 86
+
ftype-sizeof, 82
+
ftype-spin-lock!, 472
+
ftype-unlock!, 472
+
ftypes, 77
+
function ftype, 78, 83, 84, 88
+
fx*, 217, t195
+
fx*/carry, t197
+
fx*/wraparound, 218
+
fx+, 216, t195
+
fx+/carry, t197
+
fx+/wraparound, 218
+
fx-, 217, t195
+
fx-/carry, t197
+
fx-/wraparound, 218
+
fx/, 217
+
fx<, 215
+
fx<=, 215
+
fx<=?, t193
+
fx<?, t193
+
fx=, 215
+
fx=?, t193
+
fx>, 215
+
fx>=, 215
+
fx>=?, t193
+
fx>?, t193
+
fx1+, 218
+
fx1-, 218
+
fxabs, 219
+
fxand, t197
+
fxarithmetic-shift, t201
+
fxarithmetic-shift-left, t201
+
fxarithmetic-shift-right, t201
+
fxbit-count, t198
+
fxbit-field, t200
+
fxbit-set?, t199
+
fxcopy-bit, t200
+
fxcopy-bit-field, t200
+
fxdiv, t196
+
fxdiv-and-mod, t196
+
fxdiv0, t196
+
fxdiv0-and-mod0, t196
+
fxeven?, t194
+
fxfirst-bit-set, t199
+
fxif, t198
+
fxior, t197
+
fxlength, t198
+
fxlogand, 228
+
fxlogbit?, 230
+
fxlogbit0, 231
+
fxlogbit1, 231
+
fxlogior, 229
+
fxlognot, 229
+
fxlogor, 229
+
fxlogtest, 230
+
fxlogxor, 229
+
fxmax, t195
+
fxmin, t195
+
fxmod, t196
+
fxmod0, t196
+
fxmodulo, 219
+
fxnegative?, t194
+
fxnonnegative?, 216
+
fxnonpositive?, 216
+
fxnot, t197
+
fxodd?, t194
+
fxpopcount, 232
+
fxpopcount16, 232
+
fxpopcount32, 232
+
fxpositive?, t194
+
fxquotient, 218
+
fxremainder, 218
+
fxreverse-bit-field, t202
+
fxrotate-bit-field, t201
+
fxsll, 231
+
fxsll/wraparound, 218
+
fxsra, 232
+
fxsrl, 232
+
fxvector, 156
+
fxvector->list, 157
+
fxvector-copy, 158
+
fxvector-fill!, 157
+
fxvector-length, 156
+
fxvector-ref, 156
+
fxvector-set!, 157
+
fxvector?, 155
+
fxvectors, 155
+
fxxor, t197
+
fxzero?, t194
+
garbage collector, 437, t3
+
gcd, t179
+
generate-allocation-counts, 427
+
generate-covin-files, 349, 397, 402
+
generate-inspector-information, 27, 391
+
generate-instruction-counts, 427
+
generate-interrupt-trap, 390
+
generate-procedure-source-information, 391
+
generate-profile-forms, 402
+
generate-temporaries, t310
+
generate-wpo-files, 373, 392
+
generated symbols, 170
+
generative, t324
+
generativity of record definitions, 193
+
generic port, 239, 245
+
gensym, 170, 172, 282, 486
+
gensym->unique-string, 172
+
gensym-count, 172
+
gensym-prefix, 172
+
gensym?, 172
+
gensyms, 170
+
get-bytevector-all, t275
+
get-bytevector-n, t274
+
get-bytevector-n!, t274
+
get-bytevector-some, t275
+
get-bytevector-some!, 260
+
get-char, t275
+
get-datum, t278
+
get-datum/annotations, 344, 348
+
get-hash-table, 482
+
get-initial-thread, 468
+
get-line, t277
+
get-mode, 291
+
get-output-string, 255
+
get-process-id, 434, 468
+
get-property, 331
+
get-registry, 434
+
get-source-table!, 349, 351, 402
+
get-string-all, t277
+
get-string-n, t276
+
get-string-n!, t276
+
get-string-some, 259
+
get-string-some!, 259
+
get-thread-id, 468
+
get-u8, t274
+
getenv, 434
+
getprop, 173
+
getq, t54
+
goodbye, t41
+
greatest-fixnum, t193
+
guard, t361
+
guardian?, 450, 474
+
guardians, 443
+
half, 33
+
hare and tortoise, t56, t66
+
hash-table-for-each, 482
+
hash-table-map, 482
+
hash-table?, 481
+
hashtable-cell, 176
+
hashtable-cells, 179
+
hashtable-clear!, t249
+
hashtable-contains?, t246
+
hashtable-copy, t248
+
hashtable-delete!, t248
+
hashtable-entries, 178, t250
+
hashtable-ephemeron?, 180
+
hashtable-equivalence-function, t245
+
hashtable-hash-function, t245
+
hashtable-keys, 177, t249
+
hashtable-mutable?, t245
+
hashtable-ref, t246
+
hashtable-ref-cell, 177
+
hashtable-set!, t246
+
hashtable-size, t248
+
hashtable-update!, t247
+
hashtable-values, 178
+
hashtable-weak?, 180
+
hashtable?, t155
+
hashtables, t243
+
heap files, 31
+
heap-reserve-ratio, 442
+
i/o-decoding-error?, t375
+
i/o-encoding-error-char, t376
+
i/o-encoding-error?, t376
+
i/o-error-filename, t373
+
i/o-error-port, t375
+
i/o-error-position, t372
+
i/o-error?, t371
+
i/o-file-already-exists-error?, t374
+
i/o-file-does-not-exist-error?, t374
+
i/o-file-is-read-only-error?, t374
+
i/o-file-protection-error?, t373
+
i/o-filename-error?, t373
+
i/o-invalid-position-error?, t372
+
i/o-port-error?, t375
+
i/o-read-error?, t372
+
i/o-write-error?, t372
+
iconv-codec, 244, 271
+
identifier-syntax, t291, t297, t307, t316, t317
+
identifier?, t301
+
identifiers, t6
+
ieee, 339
+
ieee module, 339
+
ieee-environment, 339, 362
+
if, t35, t36, t39, t51, t59, t109
+
imag-part, t182
+
imaginary numbers, 222
+
immutability of exports, t349
+
immutable, t331
+
immutable, 199
+
immutable boxes, 168, 170
+
immutable bytevectors, 161, 164
+
immutable strings, 150, 152
+
immutable vectors, 153, 155
+
immutable-box?, 169
+
immutable-bytevector?, 164
+
immutable-string?, 152
+
immutable-vector?, 154
+
implementation-restriction-violation?, t369
+
implicit begin, t109
+
implicit-exports, 314
+
import, 117, 303, 308, 315, t345
+
import level, t345
+
import spec, t345, t346
+
import-notify, 18, 317
+
import-only, 117, 308
+
improper list, t19, t155
+
in-place-minimum-generation, 442
+
include, 316, 326, t309
+
indirect exports, t349
+
indirect-export, 313
+
inexact, t180
+
inexact complexnum, 213
+
inexact->exact, t181
+
inexact?, t167, t170
+
infinite?, t174
+
inheritance, t412
+
inheritance in records, 193, 196, t325
+
initial-bytes-allocated, 422
+
INITLOCK, 109
+
inlining, 22
+
input port, t257
+
input-port-ready?, 58, 261
+
input-port?, t270
+
inspect, 42
+
inspect/object, 47
+
inspector, 41
+
int, 62, 66
+
integer->char, t215
+
integer-16, 61, 65
+
integer-32, 61, 65
+
integer-64, 61, 65
+
integer-8, 61, 65
+
integer-divide, t79
+
integer-length, 236
+
integer-valued?, t153
+
integer?, t151, t167
+
integers, t167
+
integrable procedures, 322, t315
+
interaction environment, 14
+
interaction-environment, 15, 362
+
interactive top level, 14
+
interactive?, 433
+
internal definitions, t81, t92
+
internal state, t49
+
internal-defines-as-letrec*, 118
+
interpret, 365, t404
+
interpreter, t4, t404
+
interrupts, 357
+
intraline whitespace, t455
+
invoke-library, 315
+
iota, 145
+
iptr, 62, 66
+
irritants-condition?, t368
+
isqrt, 236
+
iteration, t5, t45, t68, t114, t115, t117, t118, t120, t121, t122
+
keep-live, 442
+
kernel, 24
+
keyboard-interrupt-handler, 358
+
keyword definition, 117
+
keywords, t4, t61, t291
+
l (long), t169
+
lambda, 33, t26, t29, t59, t92, t93
+
lambda*, t94
+
last-pair, 144
+
latin-1, t257
+
latin-1-codec, t259
+
lazy, t51
+
lazy evaluation, t51, t127
+
lcm, t179
+
least-fixnum, t193
+
length, t42, t159
+
let, 34, 484, t23, t28, t65, t95, t114
+
let*, 484, t64, t96
+
let*-values, t99, t134
+
let-bound variables, t23
+
let-syntax, 117, t291, t293, t314
+
let-values, t99, t134, t310
+
letrec, t65, t81, t97, t310
+
letrec*, t98
+
letrec-syntax, 117, t291, t293, t314
+
lexical scoping, t4, t5, t25, t63
+
lexical-violation?, t370
+
libraries, 17, 23, 303, t343
+
library, 306
+
library body, t348
+
library version, t344
+
library version reference, t347
+
library-directories, 18, 21, 316, 367
+
library-exports, 318
+
library-extensions, 18, 21, 316
+
library-list, 318
+
library-object-filename, 20, 318
+
library-requirements, 20, 318
+
library-requirements-options, 319
+
library-search-handler, 317
+
library-timestamp-mode, 317
+
library-version, 318
+
light-weight threads, t421
+
line buffering, t258
+
line ending, t455
+
Lisp, tix, t6
+
lisp-cdr, t38
+
list, t20, t31, t32, t158
+
list constants, t7
+
list syntax, t460
+
list*, 145
+
list->flvector, 160
+
list->fxvector, 157
+
list->string, t223
+
list->vector, t226
+
list-assuming-immutable?, 144
+
list-copy, 145, t43
+
list-head, 144
+
list-ref, t159
+
list-sort, t167, t387
+
list-tail, t160
+
list?, t56, t66, t67, t81, t158
+
lists, t17, t18, t155
+
literal-identifier=?, 328
+
literals, 323, t294
+
load, 10, 117, 366, 370, t13
+
load-compiled-from-port, 368
+
load-library, 306, 366
+
load-program, 305, 315, 367
+
load-shared-object, 94
+
local variable bindings, t95
+
locate-source, 348
+
locate-source-object-source, 349
+
lock-object, 71, 105, 451
+
locked-object?, 452
+
LOCKED_DECR, 109
+
LOCKED_INCR, 109, 474
+
locks, 471
+
log, t184
+
logand, 224
+
logbit?, 226
+
logbit0, 227
+
logbit1, 228
+
logior, 225
+
lognot, 226
+
logor, 225
+
logtest, 227
+
logxor, 225
+
long, 62, 66
+
long-long, 62, 66
+
lookahead-char, t275
+
lookahead-u8, t274
+
loop, t308
+
looping, t5
+
machine-type, 378
+
macros, t291
+
magnitude, 224, t178, t183
+
magnitude-squared, 224, 237
+
main.c, 24
+
make-annotation, 343, 345
+
make-arity-wrapper-procedure, 209
+
make-assertion-violation, t366
+
make-boot-file, 29, 376
+
make-boot-header, 377
+
make-bytevector, t228
+
make-codec-buffer, 245
+
make-compile-time-value, 328
+
make-condition, 470
+
make-continuation-condition, 355
+
make-cost-center, 428
+
make-counter, t50, t54
+
make-custom-binary-input-port, t267
+
make-custom-binary-input/output-port, t267
+
make-custom-binary-output-port, t267
+
make-custom-textual-input-port, t268
+
make-custom-textual-input/output-port, t268
+
make-custom-textual-output-port, t268
+
make-date, 417
+
make-engine, 136
+
make-enumeration, t251
+
make-ephemeron-eq-hashtable, 180
+
make-ephemeron-eqv-hashtable, 180
+
make-ephemeron-hashtable, 180
+
make-eq-hashtable, t243
+
make-eqv-hashtable, t244
+
make-error, t367
+
make-flvector, 159
+
make-format-condition, 354
+
make-ftype-pointer, 82
+
make-fxvector, 156
+
make-guardian, 446, 474
+
make-hash-table, 481
+
make-hashtable, t244
+
make-i/o-decoding-error, t375
+
make-i/o-encoding-error, t376
+
make-i/o-error, t371
+
make-i/o-file-already-exists-error, t374
+
make-i/o-file-does-not-exist-error, t374
+
make-i/o-file-is-read-only-error, t374
+
make-i/o-file-protection-error, t373
+
make-i/o-filename-error, t373
+
make-i/o-invalid-position-error, t372
+
make-i/o-port-error, t375
+
make-i/o-read-error, t372
+
make-i/o-write-error, t372
+
make-immobile-bytevector, 452
+
make-immobile-reference-bytevector, 91
+
make-immobile-vector, 452
+
make-implementation-restriction-violation, t369
+
make-input-port, 245
+
make-input/output-port, 245
+
make-irritants-condition, t368
+
make-lexical-violation, t370
+
make-list, 145, t46, t94
+
make-message-condition, t368
+
make-mutex, 469
+
make-no-infinities-violation, t376
+
make-no-nans-violation, t377
+
make-non-continuable-violation, t369
+
make-object-finder, 42, 53
+
make-output-port, 245
+
make-parameter, 429
+
make-pare, 489
+
make-phantom-bytevector, 453
+
make-polar, t183
+
make-promise, t129
+
make-pseudo-random-generator, 233
+
make-queue, t54
+
make-record-constructor-descriptor, t332
+
make-record-type, 192, 203
+
make-record-type-descriptor, 208, t323, t331
+
make-rectangular, t182
+
make-reference-bytevector, 91
+
make-serious-condition, t366
+
make-source-condition, 354
+
make-source-file-descriptor, 344, 347
+
make-source-object, 343, 346
+
make-source-table, 349
+
make-sstats, 424
+
make-stack, t52, t55
+
make-string, t218
+
make-syntax-violation, t370
+
make-thread-parameter, 476
+
make-time, 414
+
make-transcoder, t259
+
make-undefined-violation, t371
+
make-variable-transformer, t291, t298, t306
+
make-vector, t224
+
make-violation, t366
+
make-warning, t367
+
make-weak-eq-hashtable, 179
+
make-weak-eqv-hashtable, 179
+
make-weak-hashtable, 179
+
make-who-condition, t369
+
make-wrapper-procedure, 209
+
map, t45, t47, t117, t392
+
map1, t46
+
mapping, t45, t117, t118, t121, t122
+
mark-port-closed!, 249
+
matrix multiplication, t381
+
max, t178
+
maximum-memory-bytes, 423
+
maybe-compile-file, 372
+
maybe-compile-library, 372
+
maybe-compile-program, 372
+
member, t161
+
memory-order-acquire, 476
+
memory-order-release, 476
+
memp, t163
+
memq, t161
+
memv, t43, t161
+
merge, 176, t387
+
merge!, 176
+
message-condition?, t368
+
messages, t52, t408
+
meta, 117, 340
+
meta-circular interpreter, t404
+
meta-cond, 341
+
method, t317
+
min, t178
+
mkdir, 290
+
mod, t175
+
mod0, t176
+
module, 117, 333
+
modules, 117, 333
+
modulo, t175
+
most-negative-fixnum, 215
+
most-positive-fixnum, 215
+
mul, t382
+
multibyte->string, 271
+
multiple values, t9
+
multiprocessing, 135, t421
+
mutable, t331
+
mutable, 199
+
mutable boxes, 168, 170
+
mutable bytevectors, 161, 164
+
mutable strings, 150, 152
+
mutable vectors, 153, 155
+
mutable-box?, 169
+
mutable-bytevector?, 164
+
mutable-string?, 152
+
mutable-vector?, 154
+
mutex-acquire, 469
+
mutex-name, 470
+
mutex-release, 469
+
mutex?, 469
+
mutually recursive procedures, t66, t97
+
mvlet, 381
+
named let, t67, t71, t114
+
naming conventions, t8
+
nan?, t174
+
native-endianness, t228
+
native-eol-style, t260
+
native-transcoder, t259
+
negative?, t173
+
nested engines, t429
+
nested let expressions, t96
+
new-cafe, 407
+
newline, t285
+
no-infinities-violation?, t376
+
no-nans-violation?, t377
+
nodups?, 381
+
non-continuable-violation?, t369
+
nondeterministic computations, 135, 139, t421, t424
+
nongenerative, t331
+
nongenerative, t324
+
nongenerative record definitions, 194, 199
+
nonlocal exits, t123, t124
+
nonnegative?, 237
+
nonpositive?, 237
+
not, t36, t110
+
null-environment, 339, t137
+
null?, t37, t151
+
number syntax, t459
+
number->string, 238, t191
+
number?, t38, t151
+
numbers, t16, t167
+
numerator, t181
+
object identity, t144
+
object->reference-address, 92
+
object->string, t267
+
object-backreferences, 426
+
object-counts, 54, 425
+
object-oriented programming, t317, t408
+
objects, t3
+
oblist, 174
+
occur free, t28, t30
+
octet, t257
+
odd?, t47, t66, t81, t174
+
one-shot continuations, 130
+
only, 338
+
only import set, t346
+
opaque, t331
+
opaque record type, t330, t336
+
open-bytevector-input-port, t264
+
open-bytevector-output-port, t265
+
open-fd-input-port, 258
+
open-fd-input/output-port, 270
+
open-fd-output-port, 267
+
open-file-input-port, t262
+
open-file-input/output-port, t263
+
open-file-output-port, t262
+
open-input-file, 257, t280
+
open-input-output-file, 270
+
open-input-string, 254
+
open-output-file, 265, t281
+
open-output-string, 255
+
open-process-ports, 58
+
open-source-file, 345, 348
+
open-string-input-port, t265
+
open-string-output-port, t266
+
operating system, 138, t423, t429
+
operations on objects, t141
+
operator precedence, t16
+
optimization, 22
+
optimize-level, 23, 389
+
optional arguments, t93
+
or, t36, t63, t110
+
order of evaluation, t22, t107
+
ordinals, 204
+
ormap, 129
+
output port, t257
+
output-port-buffer-mode, t273
+
output-port?, t270
+
pair?, t38, t151
+
pairs, t19, t155
+
parameterize, 430
+
parameters, 5
+
parent, t331
+
parent type, t325
+
parent-rtd, t331
+
pares, 489
+
pariah, 397
+
partition, t164
+
path-absolute?, 292
+
path-build, 292
+
path-extension, 292
+
path-first, 292
+
path-last, 292
+
path-parent, 292
+
path-rest, 292
+
path-root, 292
+
pattern matching, 483
+
pattern variable, t294
+
pattern variables, t61, t299
+
patterns, t294
+
pbchunk-convert-file, 378
+
peek-char, t284
+
petite.boot, 24
+
petite?, 433
+
Petite Chez Scheme, 1, tix
+
phamtom bytevectors, 452
+
phantom-bytevector-length, 453
+
phantom-bytevector?, 453
+
pointer, 168
+
pointers, t4
+
por (parallel-or), 139, t424
+
port, t257
+
port-bol?, 249
+
port-closed?, 249
+
port-eof?, t278
+
port-file-compressed!, 253
+
port-file-descriptor, 256
+
port-handler, 245
+
port-has-port-length?, 250
+
port-has-port-nonblocking??, 251
+
port-has-port-position?, t271
+
port-has-set-port-length!?, 251
+
port-has-set-port-nonblocking!?, 251
+
port-has-set-port-position!?, t272
+
port-input-buffer, 246
+
port-input-count, 247
+
port-input-empty?, 247
+
port-input-index, 246
+
port-input-size, 246
+
port-length, 250
+
port-name, 250
+
port-nonblocking?, 251
+
port-output-buffer, 247
+
port-output-count, 248
+
port-output-full?, 248
+
port-output-index, 247
+
port-output-size, 247
+
port-position, t271
+
port-transcoder, t271
+
port?, t270
+
positive?, t173
+
predicate, 199
+
predicates, t8, t37, t143
+
prefix, 199
+
prefix import set, t346
+
prefix notation, t15, t16
+
pretty-file, 272
+
pretty-format, 272
+
pretty-initial-indent, 38, 274
+
pretty-line-length, 274
+
pretty-maximum-lines, 275
+
pretty-one-line-limit, 274
+
pretty-print, 271, 274, 282
+
pretty-standard-indent, 275
+
primitive procedures, t4
+
print-brackets, 282
+
print-char-name, 279
+
print-extended-identifiers, 4, 283
+
print-gensym, 171, 282
+
print-graph, 202, 280
+
print-length, 202, 280
+
print-level, 5, 280
+
print-positive-exponent-sign, 285
+
print-precision, 284
+
print-radix, 281
+
print-record, 203
+
print-select-flonum-exponential-format, 285
+
print-subnormal-precision, 284
+
print-unicode, 285
+
print-vector-length, 4, 284
+
printf, 277, t401
+
procedure application, t16, t17, t21, t27, t107
+
procedure definition, t5, t31, t100
+
procedure-arity-mask, 208
+
procedure-known-single-valued?, 211
+
procedure?, t155
+
procedures, t26, t91, t92
+
process, 57, 58
+
process ports, 298
+
product, t74, t80
+
profile, 402
+
profile-clear, 402, 403
+
profile-clear-database, 407
+
profile-dump, 398, 403, 404
+
profile-dump-data, 398, 404, 406
+
profile-dump-html, 398, 404
+
profile-dump-list, 398, 404, 405
+
profile-line-number-color, 405
+
profile-load-data, 398, 406
+
profile-palette, 404
+
profile-query-weight, 407
+
profile-release-counters, 402, 403
+
profiling, 23, 397
+
proper list, t19, t56, t155
+
property lists, 173
+
property-list, 174
+
protocol, t331
+
protocol for records, t326, t332
+
pseudo-random-generator->vector, 234
+
pseudo-random-generator-next!, 234
+
pseudo-random-generator-seed!, 234
+
pseudo-random-generator?, 233
+
ptr, 63, 67
+
ptrdiff_t, 62, 66
+
put-bytevector, t279
+
put-bytevector-some, 268
+
put-char, t279
+
put-datum, t279, t397
+
put-hash-table!, 482
+
put-registry!, 434
+
put-source-table, 349, 351
+
put-string, t279
+
put-string-some, 268
+
put-u8, t278
+
putenv, 434
+
putprop, 173
+
putq!, t54
+
quadratic-formula, t48
+
quasiquote ( ` ), t142
+
quasisyntax ( #` ), t305
+
question mark ( ? ), t8, t37
+
queue, t53
+
quote ( ' ), t17, t22, t59, t141
+
quotient, t175
+
r5rs, 339
+
r5rs module, 339
+
r5rs-syntax, 339
+
r5rs-syntax module, 339
+
raise, t357
+
raise-continuable, t357
+
random, 233
+
random number generator, 233
+
random-seed, 233
+
rational numbers, t167
+
rational-valued?, t153
+
rational?, t151, t167
+
rationalize, t181
+
ratnum, 213, 214
+
ratnum?, 215
+
rcd, t332
+
read, 280, t284
+
read-char, t284
+
read-token, 262
+
real numbers, t167
+
real->flonum, t211
+
real-part, t182
+
real-time, 421
+
real-valued?, t153
+
real?, t151, t167
+
rec, 119, 483, t311
+
reciprocal, t15, t37, t39, t80
+
record equality, 188
+
record field ordinals, 204
+
record generativity, 193, t324
+
record hashing, 188
+
record inheritance, 193, 196, t325
+
record uid, t325
+
record-accessor, t334
+
record-case, 128
+
record-constructor, 205, t333
+
record-constructor descriptor, t332
+
record-constructor-descriptor, t333
+
record-constructor-descriptor?, 143
+
record-equal-procedure, 188, 191
+
record-field-accessible?, 205
+
record-field-accessor, 205
+
record-field-mutable?, 206, t338
+
record-field-mutator, 205
+
record-hash-procedure, 188, 191
+
record-instance?, 207
+
record-mutator, t334
+
record-predicate, t333
+
record-reader, 200
+
record-rtd, t338
+
record-type descriptor, t331
+
record-type-descriptor, 208, t333
+
record-type-descriptor?, t332
+
record-type-equal-procedure, 188, 190
+
record-type-field-decls, 207
+
record-type-field-names, 206, t337
+
record-type-generative?, t337
+
record-type-has-named-fields?, 208
+
record-type-hash-procedure, 188, 191
+
record-type-name, 206, t336
+
record-type-opaque?, t337
+
record-type-parent, t336
+
record-type-sealed?, t337
+
record-type-symbol, 206
+
record-type-uid, t336
+
record-writer, 201
+
record?, 207, t338
+
records, 128, 192, t323
+
recursion, t5, t41, t65, t114
+
recursion step, t41
+
recursive object, 119
+
recursive procedure, t41
+
reference, 168
+
reference*-address->object, 92
+
reference-address->object, 92
+
reference-bytevector?, 91
+
register-signal-handler, 360
+
release-minimum-generation, 441
+
remainder, t175
+
remove, t163
+
remove!, 146
+
remove-foreign-entry, 96
+
remove-hash-table!, 482
+
remove-registry!, 434
+
remp, t163
+
remprop, 174
+
remq, t163
+
remq!, 146
+
remv, t44, t163
+
remv!, 146
+
rename, 338
+
rename import set, t346
+
rename-file, 291
+
require-nongenerative-clause, 187, 188
+
reset, 410
+
reset-cost-center!, 429
+
reset-handler, 11, 410
+
reset-maximum-memory-bytes!, 423
+
retry, t75, t80
+
reverse, t161
+
reverse!, 147
+
Revised Reports, tix, t3
+
revisit, 369
+
revisit-compiled-from-port, 368
+
round, t178
+
round-robin, 138, t423
+
rtd, t331
+
run-cp0, 393
+
run-time generativity, 194
+
s (short), t169
+
s8-list->bytevector, 162
+
Sactivate_thread, 109
+
safety, 23
+
Sbignump, 100
+
Sboolean, 103
+
Sboolean_value, 100
+
Sbooleanp, 100
+
Sbox, 104
+
Sboxp, 100
+
Sbuild_heap, 98
+
Sbwp_object, 103
+
Sbwp_objectp, 100
+
Sbytevector_data, 102
+
Sbytevector_length, 101
+
Sbytevector_u8_ref, 102
+
Sbytevector_u8_set, 102
+
Sbytevectorp, 100
+
sc-expand, 379
+
Scall, 107
+
Scall0, 107
+
Scall1, 107
+
Scall2, 107
+
Scall3, 107
+
Scar, 101
+
Scdr, 101
+
Schar, 103
+
Schar_value, 100
+
Scharp, 100
+
scheme, 339
+
scheme module, 339
+
Scheme shell scripts, 20
+
Scheme standard, tix
+
scheme-environment, 362
+
scheme-object, 60, 63, 65, 67
+
scheme-pre-release, 433
+
scheme-program, 411
+
scheme-report-environment, 339, t137
+
scheme-script, 305, 411
+
scheme-start, 27, 28, 411
+
scheme-version, 432
+
scheme-version-number, 433
+
scheme.boot, 24
+
SCHEMEHEAPDIRS, 31
+
Scompact_heap, 98, 105, 437
+
Scons, 104
+
scope, t25
+
scripting, 20
+
Sdeactivate_thread, 109
+
Sdestroy_thread, 109
+
sealed, t331
+
sealed record type, t330
+
segment-length, t132
+
segment-slope, t132
+
self-evaluating-vectors, 155
+
semicolon ( ; ), t7, t455
+
Senable_expeditor, 98
+
Seof_object, 103
+
Seof_objectp, 100
+
sequence, t313
+
sequencing, t108
+
serious-condition?, t366
+
set!, 122, t47, t59, t102
+
set-binary-port-input-buffer!, 246
+
set-binary-port-input-index!, 246
+
set-binary-port-input-size!, 246
+
set-binary-port-output-buffer!, 248
+
set-binary-port-output-index!, 248
+
set-binary-port-output-size!, 248
+
set-box!, 169
+
set-car!, t157
+
set-cdr!, t56, t157
+
set-of, t389
+
set-phantom-bytevector-length!, 453
+
set-port-bol!, 249
+
set-port-eof!, 249
+
set-port-input-buffer!, 246
+
set-port-input-index!, 246
+
set-port-input-size!, 246
+
set-port-length!, 251
+
set-port-name!, 250
+
set-port-nonblocking!, 251
+
set-port-output-buffer!, 248
+
set-port-output-index!, 248
+
set-port-output-size!, 248
+
set-port-position!, t272
+
set-sstats-bytes!, 424
+
set-sstats-cpu!, 424
+
set-sstats-gc-bytes!, 424
+
set-sstats-gc-count!, 424
+
set-sstats-gc-cpu!, 424
+
set-sstats-gc-real!, 424
+
set-sstats-real!, 424
+
set-textual-port-input-buffer!, 246
+
set-textual-port-input-index!, 246
+
set-textual-port-input-size!, 246
+
set-textual-port-output-buffer!, 248
+
set-textual-port-output-index!, 248
+
set-textual-port-output-size!, 248
+
set-time-nanosecond!, 415
+
set-time-second!, 415
+
set-time-type!, 415
+
set-timer, 136, 359
+
set-top-level-value!, 122
+
set-virtual-register!, 432
+
set-wrapper-procedure-data!, 210
+
set-wrapper-procedure-procedure!, 210
+
sets, t389
+
Sexactnump, 100
+
Sfalse, 103
+
Sfixnum, 103
+
Sfixnum_value, 100
+
Sfixnump, 100
+
Sflonum, 103
+
Sflonum_value, 100
+
Sflonump, 100
+
Sforeign_callable_code_object, 106
+
Sforeign_callable_entry_point, 106
+
Sforeign_symbol, 106
+
Sfxvector_length, 101
+
Sfxvector_ref, 102
+
Sfxvector_set, 102
+
Sfxvectorp, 100
+
Sgetenv, 104
+
shadowing, t4, t25, t31
+
shhh, t50
+
short, 62, 65
+
shorter, t41, t47
+
shorter?, t47
+
side effects, t8, t108
+
simple condition, t362
+
simple-conditions, t363
+
sin, t185
+
Sinexactnump, 100
+
single-float, 62, 65
+
sinh, 238
+
Sinitframe, 107
+
Sinputportp, 100
+
sint-list->bytevector, t239
+
Sinteger, 103
+
Sinteger_value, 101
+
Sinteger32, 104
+
Sinteger32_value, 101
+
Sinteger64, 104
+
Sinteger64_value, 101
+
size_t, 62, 66
+
Skernel_version, 98
+
sleep, 420
+
Slock_object, 105, 451
+
Slocked_objectp, 106
+
Smake_bytevector, 104
+
Smake_fxvector, 104
+
Smake_string, 104
+
Smake_uninitialized_string, 104
+
Smake_vector, 104
+
Snil, 103
+
Snullp, 100
+
sockets, 109, 298
+
sort, 176, t387
+
sort!, 176
+
source objects, 343
+
source profiling, 397
+
source-condition-form, 354
+
source-condition?, 354
+
source-directories, 18, 366, 367, 369, 388
+
source-file descriptors, 344
+
source-file-descriptor, 347
+
source-file-descriptor-checksum, 347
+
source-file-descriptor-path, 347
+
source-file-descriptor?, 347
+
source-object-bfp, 346
+
source-object-column, 347
+
source-object-efp, 346
+
source-object-line, 346
+
source-object-sfd, 346
+
source-object?, 346
+
source-table-cell, 350
+
source-table-contains?, 350
+
source-table-delete!, 350
+
source-table-dump, 404
+
source-table-ref, 349, 350
+
source-table-set!, 349, 350
+
source-table-size, 351
+
source-table?, 350
+
Soutputportp, 100
+
Spairp, 100
+
special bindings (in Lisp), 120
+
SPINLOCK, 109
+
split, t133
+
Sprocedurep, 100
+
Sput_arg, 107
+
sqrt, t183
+
square, t14
+
Sratnump, 100
+
Srecord_type, 102
+
Srecord_type_parent, 102
+
Srecord_type_size, 102
+
Srecord_type_uniformp, 102
+
Srecord_uniform_ref, 102
+
Srecordp, 100
+
Sregister_boot_file, 98
+
Sregister_boot_file_fd, 98
+
Sregister_boot_file_fd_segment, 98
+
Sregister_symbol, 106
+
Sretain_static_relocation, 98
+
Sscheme_deinit, 98
+
Sscheme_init, 98
+
Sscheme_program, 98
+
Sscheme_script, 98
+
Sscheme_start, 98
+
Sset_box, 102
+
Sset_car, 102
+
Sset_cdr, 102
+
Sset_top_level_value, 105
+
Sset_verbose, 98
+
ssize_t, 62, 66
+
sstats-bytes, 424
+
sstats-cpu, 424
+
sstats-difference, 425
+
sstats-gc-bytes, 424
+
sstats-gc-count, 424
+
sstats-gc-cpu, 424
+
sstats-gc-real, 424
+
sstats-print, 425
+
sstats-real, 424
+
sstats?, 424
+
Sstring, 103
+
Sstring_length, 101
+
Sstring_of_length, 103
+
Sstring_ref, 102
+
Sstring_set, 102
+
Sstring_to_symbol, 104
+
Sstring_utf8, 103
+
Sstringp, 100
+
Ssymbol_to_string, 101
+
Ssymbolp, 100
+
stack objects, t52
+
standard-error-port, 268, t264
+
standard-input-port, 259, t264
+
standard-output-port, 267, t264
+
static generation, 437
+
statistics, 423
+
stencil vectors, 165
+
stencil-vector, 165
+
stencil-vector-length, 166
+
stencil-vector-mask, 166
+
stencil-vector-mask-width, 165
+
stencil-vector-ref, 166
+
stencil-vector-set!, 166
+
stencil-vector-truncate!, 167
+
stencil-vector-update, 167
+
stencil-vector?, 165
+
Stop_level_value, 105
+
storage management, 437
+
streams, t128
+
stretch strings, 490
+
string, 60, 64, 68, t218
+
string input port, 254
+
string output port, 255
+
string streams, 239
+
string syntax, t458
+
string->bytevector, t287
+
string->immutable-string, 150, 152
+
string->list, t222
+
string->multibyte, 271
+
string->number, 238, t191
+
string->symbol, t242
+
string->uninterned-symbol, 172
+
string->utf16, t287
+
string->utf32, t287
+
string->utf8, t287
+
string-append, t219
+
string-append-immutable, 150, 152
+
string-ci-hash, t245
+
string-ci<=?, 150, t217
+
string-ci<?, 150, t217
+
string-ci=?, 150, t217
+
string-ci>=?, 150, t217
+
string-ci>?, 150, t217
+
string-copy, t219
+
string-copy!, 151
+
string-downcase, t221
+
string-fill!, t220
+
string-foldcase, t221
+
string-for-each, t122
+
string-grapheme-count, 153
+
string-grapheme-span, 152
+
string-hash, t245
+
string-length, t218
+
string-normalize-nfc, t222
+
string-normalize-nfd, t222
+
string-normalize-nfkc, t222
+
string-normalize-nfkd, t222
+
string-ref, t218
+
string-set!, t219
+
string-titlecase, t221
+
string-truncate!, 151
+
string-upcase, t221
+
string<=?, 150, t216
+
string<?, 150, t216
+
string=?, 150, t216
+
string>=?, 150, t216
+
string>?, 150, t216
+
string?, t38, t154
+
strings, t14, t216
+
strip-fasl-file, 27, 377
+
structured forms, t6
+
structures, 488, t318
+
Strue, 103
+
Stry_integer_value, 101
+
Stry_integer32_value, 101
+
Stry_integer64_value, 101
+
Stry_unsigned_value, 101
+
Stry_unsigned32_value, 101
+
Stry_unsigned64_value, 101
+
sub1, 235
+
subset-mode, 435
+
subst, 146
+
subst!, 146
+
substq, 146
+
substq!, 146
+
substring, t95, t220
+
substring-fill!, 151
+
substv, 146
+
substv!, 146
+
subtract-duration, 416
+
subtract-duration!, 416
+
sum, t65
+
Sunbox, 101
+
Sunlock_object, 106, 451
+
Sunsigned, 103
+
Sunsigned_value, 101
+
Sunsigned32, 104
+
Sunsigned32_value, 101
+
Sunsigned64, 104
+
Sunsigned64_value, 101
+
suppress-greeting, 412
+
Sutf8_to_wide, 105
+
Svector_length, 101
+
Svector_ref, 102
+
Svector_set, 102
+
Svectorp, 100
+
Svoid, 103
+
Swide_to_utf8, 105
+
symbol syntax, t458
+
symbol table, t241
+
symbol->string, t242
+
symbol-hash, t245
+
symbol-hashtable-cell, 186
+
symbol-hashtable-contains?, 185
+
symbol-hashtable-delete!, 187
+
symbol-hashtable-ref, 185
+
symbol-hashtable-ref-cell, 187
+
symbol-hashtable-set!, 184
+
symbol-hashtable-update!, 185
+
symbol-hashtable?, 184
+
symbol=?, t242
+
symbol?, t38, t154
+
symbols, t18, t241
+
synonym streams, 239
+
syntactic extensions, t5, t22, t59, t60, t291
+
syntactic forms, t18, t59, t291
+
syntax, t291
+
syntax ( #' ), t300
+
syntax object, t298
+
syntax violation, 4, t9
+
syntax->annotation, 345, 348
+
syntax->datum, t308
+
syntax->list, 323
+
syntax->vector, 324
+
syntax-case, 491, t291, t299
+
syntax-error, 327
+
syntax-object->datum, 324
+
syntax-rules, 323, t291, t294, t300, t389
+
syntax-violation, t359
+
syntax-violation-form, t370
+
syntax-violation-subform, t370
+
syntax-violation?, t370
+
system, 57
+
tagged lists, 128
+
tail call, t5, t68
+
tail recursion, t5, t68
+
tan, t185
+
tanh, 238
+
tconc, t53
+
tell, t50
+
templates, t295
+
textual port, t257
+
textual-port-input-buffer, 246
+
textual-port-input-count, 247
+
textual-port-input-index, 246
+
textual-port-input-size, 246
+
textual-port-output-buffer, 247
+
textual-port-output-count, 248
+
textual-port-output-index, 247
+
textual-port-output-size, 247
+
textual-port?, t270
+
The Scheme Programming Language, 4th Edition, ???, 1, 497
+
thread-condition?, 470
+
thread-join, 468
+
thread-preserve-ownership!, 468
+
thread-safe primitives, 467
+
thread?, 468
+
threaded?, 433
+
threads, 467, t421
+
thunk, t51, t124
+
ticks, see engines
+
time, 421
+
time-difference, 416
+
time-difference!, 416
+
time-nanosecond, 415
+
time-second, 415
+
time-type, 415
+
time-utc->date, 420
+
time<=?, 416
+
time<?, 416
+
time=?, 416
+
time>=?, 416
+
time>?, 416
+
time?, 415
+
timed preemption, 135, t421
+
timer interrupts, 359, t425
+
timer-interrupt-handler, 359
+
tokens, t455
+
top-level definitions, t30, t101
+
top-level programs, 14, 21, t343
+
top-level values, 121
+
top-level-bound?, 122
+
top-level-mutable?, 123
+
top-level-program, 306, 307
+
top-level-programs, 17, 23, 303, 307
+
top-level-syntax, 124
+
top-level-syntax?, 125
+
top-level-value, 122
+
trace, 36, t42
+
trace-case-lambda, 34
+
trace-define, 38
+
trace-define-syntax, 39
+
trace-do, 35
+
trace-lambda, 33
+
trace-let, 34
+
trace-output-port, 38
+
trace-print, 38
+
tracing, t42
+
transcoded-port, t271
+
transcoded-port-buffer-size, 244
+
transcoder, t257
+
transcoder-codec, t259
+
transcoder-eol-style, t259
+
transcoder-error-handling-mode, t259
+
transcoder?, 244
+
transcript, 412
+
transcript ports, 295
+
transcript-cafe, 413
+
transcript-off, 413
+
transcript-on, 413
+
transformer, t61
+
tree-copy, t44
+
true, t7, t36
+
truncate, t177
+
truncate-file, 269
+
truncate-port, 269
+
two-way ports, 294
+
two-way streams, 239
+
type predicates, t38
+
type-descriptor, 200
+
u16*, 60, 63, 67
+
u32*, 60, 63
+
u8*, 60, 63, 67
+
u8-list->bytevector, t232
+
uint-list->bytevector, t239
+
unbox, 168
+
undefined-variable-warnings, 396
+
undefined-violation?, t371
+
underscore ( _ ), t61, t296, t315
+
underscore (_), t294
+
unget-char, 260
+
unget-u8, 261
+
unification, t417
+
unify, t418
+
uninterned symbols, 171
+
uninterned-symbol?, 173
+
uninterned-symbol?, 171
+
Unix, 97
+
unless, t64, t112
+
UNLOCK, 109
+
unlock-object, 106, 451
+
unquote ( , ), t142
+
unquote-splicing ( ,@ ), t142
+
unread-char, 260
+
unregister-guardian, 450, 474
+
unsigned, 62, 66
+
unsigned long, 62, 66
+
unsigned short, 62, 65
+
unsigned-16, 61, 65
+
unsigned-32, 61, 65
+
unsigned-64, 61, 65
+
unsigned-8, 61, 65
+
unsigned-int, 62, 66
+
unsigned-long-long, 62, 66
+
unspecified, 4, t9
+
unsyntax ( #, ), t305
+
unsyntax-splicing ( #,@ ), t305
+
untrace, 37
+
unwind-protect (in Lisp), t124
+
uptr, 62, 66
+
utf-16, 60, 64, 67
+
utf-16, t257
+
utf-16-codec, 243, t259
+
utf-16be, 60, 64, 67
+
utf-16be-codec, 243
+
utf-16le, 60, 64, 67
+
utf-16le-codec, 243
+
utf-32, 60, 64, 68
+
utf-32be, 60, 64, 68
+
utf-32le, 60, 64, 68
+
utf-8, 60, 63, 67
+
utf-8, t257
+
utf-8-codec, t259
+
utf16->string, t288
+
utf32->string, t288
+
utf8->string, t287
+
values, t130, t131
+
variable binding, t23, t91
+
variable definition, 117
+
variable reference, t91
+
variables, t4, t18, t23, t30, t47
+
vector, t224
+
vector printing, 284
+
vector syntax, t461
+
vector->immutable-vector, 153, 155
+
vector->list, t225
+
vector->pseudo-random-generator, 234
+
vector->pseudo-random-generator!, 234
+
vector-cas!, 154
+
vector-copy, 153
+
vector-fill!, t225
+
vector-for-each, t122
+
vector-length, t224
+
vector-map, t121
+
vector-ref, t224
+
vector-set!, t225
+
vector-set-fixnum!, 154
+
vector-sort, t226
+
vector-sort!, t226
+
vector?, t154
+
vectors, t55, t223, t383
+
verify-loadability, 367
+
vfasl-convert-file, 378
+
violation?, t366
+
virtual-register, 432
+
virtual-register-count, 432
+
visit, 368
+
visit-compiled-from-port, 368
+
void, 4, 65, 175
+
void object, 4
+
void*, 62, 66
+
waiter, 407
+
waiter-prompt-and-read, 409
+
waiter-prompt-string, 408
+
waiter-write, 409
+
warning, 353
+
warning?, t367
+
warningf, 354
+
wchar, 63, 66
+
wchar_t, 63, 66
+
weak pairs, 443
+
weak pointers, 443
+
weak-cons, 443
+
weak-pair?, 444
+
when, 484, t64, t112
+
whitespace, t455
+
whitespace characters, t7
+
who-condition?, t369
+
winders, see dynamic-wind
+
with, 485, 487
+
with-continuation-mark, 131
+
with-cost-center, 428
+
with-exception-handler, t360
+
with-implicit, 325
+
with-input-from-file, 258, t283
+
with-input-from-string, 254
+
with-interrupts-disabled, 360, 440
+
with-mutex, 470
+
with-output-to-file, 267, t283
+
with-output-to-string, 255
+
with-profile-tracker, 349, 403, 404
+
with-source-path, 388
+
with-syntax, t304
+
wrapper-procedure-data, 210
+
wrapper-procedure-procedure, 210
+
wrapper-procedure?, 209
+
write, t284, t397
+
write-char, t285
+
wstring, 60, 64, 68
+
x++, t316
+
zero?, t173
+
+ +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/debug.html b/csug10.0/debug.html
new file mode 100644
index 000000000..37c6b460b
--- /dev/null
+++ b/csug10.0/debug.html
@@ -0,0 +1,2001 @@
+
+
+
+
+
+Chez Scheme has several features that support debugging. +In addition to providing error messages when fully type-checked code is +run, Chez Scheme also permits tracing of procedure calls, interruption +of any computation, redefinition of exception and interrupt handlers, +and inspection of any object, including the continuations of exceptions and +interrupts. + +
+Programmers new to Scheme or Chez Scheme, and even more experienced +Scheme programmers, might want to consult +the tutorial "How to Debug Chez Scheme Programs." +HTML and PDF versions +are available at +http://www.cs.indiana.edu/chezscheme/debug/. + + +
+ +
+Tracing is one of the most useful mechanisms for debugging Scheme programs. +Chez Scheme permits any primitive or user-defined procedure to be traced. +The trace package prints the arguments and return values for each +traced procedure with a compact indentation mechanism that shows the +nesting depth of calls. +The distinction between tail calls and nontail calls is reflected +properly by an increase in indentation for nontail calls only. +For nesting depths of 10 or greater, a number in brackets is used in +place of indentation to signify nesting depth. + +
+This section covers the mechanisms for tracing procedures and +controlling trace output. + +
+syntax: (trace-lambda name formals body1 body2 ...)
+
+returns: a traced procedure
+
+libraries: (chezscheme)
+
+
A trace-lambda expression is equivalent to a +lambda expression with the same formals and body +except that trace information is printed to the trace output port whenever +the procedure is invoked, using name to identify the procedure. +The trace information shows the value of the arguments passed to the +procedure and the values returned by the procedure, with indentation to +show the nesting of calls. + +
+The traced procedure half defined below +returns the integer quotient of its argument and 2. + +
+ +
(define half
+
+ (trace-lambda half (x)
+
+ (cond
+
+ [(zero? x) 0]
+
+ [(odd? x) (half (- x 1))]
+
+ [(even? x) (+ (half (- x 1)) 1)])))
+
A trace of the call (half 5), which returns 2, is shown below. + +
+ +
|(half 5)
+
+|(half 4)
+
+| (half 3)
+
+| (half 2)
+
+| |(half 1)
+
+| |(half 0)
+
+| |0
+
+| 1
+
+|2
+
This example highlights the proper treatment of tail and nontail calls +by the trace package. +Since half tail calls itself when its argument is odd, the call +(half 4) appears at the same level of indentation as the call +(half 5). +Furthermore, since the return values of (half 5) and +(half 4) are necessarily the same, only one return value is +shown for both calls. + +
+syntax: (trace-case-lambda name clause ...)
+
+returns: a traced procedure
+
+libraries: (chezscheme)
+
+
A trace-case-lambda expression is +equivalent to a case-lambda expression with the same clauses +except that trace information is printed to the trace output port whenever +the procedure is invoked, using name to identify the procedure. +The trace information shows the value of the arguments passed to the +procedure and the values returned by the procedure, with indentation to +show the nesting of calls. + + +
+syntax: (trace-let name ((var expr) ...) body1 body2 ...)
+
+returns: the values of the body body1 body2 ...
+
+libraries: (chezscheme)
+
+
A trace-let expression is equivalent to a +named let expression with the same name, bindings, and body +except that trace information is printed to the trace output port on +entry or reentry (via invocation of the procedure bound to name) +into the trace-let expression. + +
+A trace-let expression of the form + +
+ +
(trace-let name ([var expr] ...)
+
+ body1 body2 ...)
+
can be rewritten in terms of trace-lambda as follows: + +
+ +
((letrec ([name
+
+ (trace-lambda name (var ...)
+
+ body1 body2 ...)])
+
+ name)
+
+ expr ...)
+
trace-let may be used to trace ordinary let expressions +as well as let expressions as long as the name inserted along +with the trace-let keyword in place of let does not +appear free within the body of the let expression. +It is also sometimes useful to insert a trace-let expression +into a program simply to display the value of an arbitrary expression +at the current trace indentation. +For example, a call to the following variant of half + +
+ +
(define half
+
+ (trace-lambda half (x)
+
+ (cond
+
+ [(zero? x) 0]
+
+ [(odd? x) (half (trace-let decr-value () (- x 1)))]
+
+ [(even? x) (+ (half (- x 1)) 1)])))
+
with argument 5 results in the trace: + +
+ +
|(half 5)
+
+| (decr-value)
+
+| 4
+
+|(half 4)
+
+| (half 3)
+
+| |(decr-value)
+
+| |2
+
+| (half 2)
+
+| |(half 1)
+
+| | (decr-value)
+
+| | 0
+
+| |(half 0)
+
+| 1
+
+|2
+
syntax: (trace-do ((var init update) ...) (test result ...) expr ...)
+
+returns: the values of the last result expression
+
+libraries: (chezscheme)
+
+
A trace-do expression is equivalent to a +do expression with the same subforms, +except that trace information is printed to the trace output port, +showing the values of var ... and each iteration and +the final value of the loop on termination. +For example, the expression + +
+ +
(trace-do ([old '(a b c) (cdr old)]
+
+ [new '() (cons (car old) new)])
+
+ ((null? old) new))
+
produces the trace + +
+ +
|(do (a b c) ())
+
+|(do (b c) (a))
+
+|(do (c) (b a))
+
+|(do () (c b a))
+
+|(c b a)
+
and returns (c b a). + + +
+syntax: (trace var1 var2 ...)
+
+returns: a list of var1 var2 ...
+
syntax: (trace)
+
+returns: a list of all currently traced top-level variables
+
+libraries: (chezscheme)
+
+
In the first form, trace reassigns the top-level values of +var1 var2 ..., whose values must be procedures, +to equivalent procedures that display trace information in the manner +of trace-lambda. + +
+trace works by encapsulating the old value of each var in a +traced procedure. +It could be defined approximately as follows. (The actual version +records and returns information about traced variables.) + +
+ +
(define-syntax trace
+
+ (syntax-rules ()
+
+ [(_ var ...)
+
+ (begin
+
+ (set-top-level-value! 'var
+
+ (let ([p (top-level-value 'var)])
+
+ (trace-lambda var args (apply p args))))
+
+ ...)]))
+
Tracing for a procedure traced in this manner may be disabled via +untrace (see below), an assignment of the corresponding +variable to a different, untraced value, or a subsequent use of +trace for the same variable. +Because the value is traced and not the binding, however, a traced +value obtained before tracing is disabled and retained after tracing is +disabled will remain traced. + +
+trace without subexpressions evaluates to a list of all +currently traced variables. +A variable is currently traced if it has been traced and +not subsequently untraced or assigned to a different value. + +
+The following transcript demonstrates the use of trace in +an interactive session. + +
+ +
> (define half
+
+ (lambda (x)
+
+ (cond
+
+ [(zero? x) 0]
+
+ [(odd? x) (half (- x 1))]
+
+ [(even? x) (+ (half (- x 1)) 1)])))
+
+> (half 5)
+
+2
+
+> (trace half)
+
+(half)
+
+> (half 5)
+
+|(half 5)
+
+|(half 4)
+
+| (half 3)
+
+| (half 2)
+
+| |(half 1)
+
+| |(half 0)
+
+| |0
+
+| 1
+
+|2
+
+2
+
+> (define traced-half half)
+
+> (untrace half)
+
+(half)
+
+> (half 2)
+
+1
+
+> (traced-half 2)
+
+|(half 2)
+
+|1
+
+1
+
syntax: (untrace var1 var2 ...)
+
syntax: (untrace)
+
+returns: a list of untraced variables
+
+libraries: (chezscheme)
+
+
untrace restores the original (pre-trace) top-level values +of each currently traced variable in +var1 var2 ..., +effectively disabling the tracing of the values of these variables. +Any variable in var1 var2 ... that is not +currently traced is ignored. +If untrace is called without arguments, the values of all +currently traced variables are restored. + +
+The following transcript demonstrates the use of trace and +untrace in an interactive session to debug an incorrect +procedure definition. + +
+ +
> (define square-minus-one
+
+ (lambda (x)
+
+ (- (* x x) 2)))
+
+> (square-minus-one 3)
+
+7
+
+> (trace square-minus-one * -)
+
+(square-minus-one * -)
+
+> (square-minus-one 3)
+
+|(square-minus-one 3)
+
+| (* 3 3)
+
+| 9
+
+|(- 9 2)
+
+|7
+
+7
+
+> (define square-minus-one
+
+ (lambda (x)
+
+ (- (* x x) 1))) ; change the 2 to 1
+
+> (trace)
+
+(- *)
+
+> (square-minus-one 3)
+
+|(* 3 3)
+
+|9
+
+|(- 9 1)
+
+|8
+
+8
+
+> (untrace square-minus-one)
+
+()
+
+> (untrace * -)
+
+(- *)
+
+> (square-minus-one 3)
+
+8
+
The first call to square-minus-one indicates there is an error, +the second (traced) call indicates the step at which the error occurs, +the third call demonstrates that the fix works, +and the fourth call demonstrates that +untrace does not wipe out the fix. + + +
+thread parameter: trace-output-port
+
+libraries: (chezscheme)
+
+
trace-output-port is a parameter that determines the +output port to which tracing information is sent. +When called with no arguments, trace-output-port returns the +current trace output port. +When called with one argument, which must be a textual output port, +trace-output-port changes the value of the current +trace output port. + + +
+thread parameter: trace-print
+
+libraries: (chezscheme)
+
+
The value of trace-print must be a procedure of two arguments, +an object and an output port. +The trace package uses the value of trace-print to print the +arguments and return values for each call to a traced procedure. +trace-print is set to pretty-print by default. + +
+The trace package sets +pretty-initial-indent +to an appropriate value for the current nesting level before calling +the value of trace-print so that multiline output can be +indented properly. + + +
+syntax: (trace-define var expr)
+
syntax: (trace-define (var . idspec) body1 body2 ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
trace-define is a convenient shorthand for defining variables bound +to traced procedures of the same name. +The first form is equivalent to + +
+ +
(define var
+
+ (let ([x expr])
+
+ (trace-lambda var args
+
+ (apply x args))))
+
and the second is equivalent to + +
+ +
(define var
+
+ (trace-lambda var idspec
+
+ body1 body2 ...))
+
In the former case, expr must evaluate to a procedure. + +
+ +
> (let ()
+
+ (trace-define plus
+
+ (lambda (x y)
+
+ (+ x y)))
+
+ (list (plus 3 4) (+ 5 6)))
+
+|(plus 3 4)
+
+|7
+
+(7 11)
+
syntax: (trace-define-syntax keyword expr)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
trace-define-syntax traces the input and output to the +transformer value of expr, stripped of the contextual +information used by the expander to maintain lexical scoping. + +
+ +
> (trace-define-syntax let*
+
+ (syntax-rules ()
+
+ [(_ () b1 b2 ...)
+
+ (let () b1 b2 ...)]
+
+ [(_ ((x e) m ...) b1 b2 ...)
+
+ (let ((x e))
+
+ (let* (m ...) b1 b2 ...))]))
+
+> (let* ([x 3] [y (+ x x)]) (list x y))
+
+|(let* (let* [(x 3) (y (+ x x))] [list x y]))
+
+|(let ([x 3]) (let* ([y (+ x x)]) (list x y)))
+
+|(let* (let* [(y (+ x x))] [list x y]))
+
+|(let ([y (+ x x)]) (let* () (list x y)))
+
+|(let* (let* () [list x y]))
+
+|(let () (list x y))
+
+(3 6)
+
Without contextual information, the displayed forms are more readable +but less precise, since different identifiers with the same name are +indistinguishable, as shown in the example below. + +
+ +
> (let ([x 0])
+
+ (trace-define-syntax a
+
+ (syntax-rules ()
+
+ [(_ y) (eq? x y)]))
+
+ (let ([x 1])
+
+ (a x)))
+
+|(a (a x))
+
+|(eq? x x)
+
+#f
+
+
+The interactive debugger is entered as a result of +a call to the procedure debug after an exception is handled +by the default exception handler. +It can also be entered directly from the default exception handler, for +serious or non-warning conditions, if the parameter +debug-on-exception is true. + +
+Within the debugger, the command "?" lists the debugger command options. +These include commands to: + +
+
+ +
+The raise continuation is the continuation encapsulated within the +condition, if any. +The standard exception reporting procedures and forms assert, +assertion-violation, and error as well as the +Chez Scheme procedures assertion-violationf, errorf, +and syntax-error all raise exceptions with conditions that +encapsulate the continuations of their calls, allowing the programmer to +inspect the frames of pending calls at the point of a violation, error, or +failed assertion. + +
+A variant of the interactive debugger, the break handler, is entered as +the result of a keyboard interrupt handled by the default +keyboard-interrupt handler or an explicit call to the procedure +break handled by the default break handler. +Again, the command "?" lists the command options. +These include commands to: + +
+
+ +
+It is also usually possible to exit from the debugger or break handler by +typing the end-of-file character ("control-D" under Unix, "control-Z" +under Windows). + + + +
+procedure: (debug)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
When the default exception handler receives a serious or non-warning +condition, it displays the condition and resets to the current café. +Before it resets, it saves the condition in the parameter +debug-condition. +The debug procedure may be used to inspect the condition. +Whenever one of the built-in error-reporting mechanisms is used to +raise an exception, the continuation at the point where the +exception was raised can be inspected as well. +More generally, debug allows the continuation contained +within any continuation condition created by +make-continuation-condition to be inspected. + +
+If the parameter debug-on-exception is set to #t, +the default exception handler enters the debugger directly for all +serious and non-warning conditions, delaying its reset until after +the debugger exits. +The --debug-on-exception +command-line option may be used to set debug-on-exception to +#t from the command line, which is particularly useful when +debugging scripts or top-level programs run via the +--script or +--program +command-line options. + + + +
+ +
+The inspector may be called directly via the procedure inspect or +indirectly from the debugger. +It allows the programmer to examine circular objects, objects such as +ports and procedures that do not have a reader syntax, and objects such +as continuations and variables that are not directly accessible by the +programmer, as well as ordinary printable Scheme objects. + +
+The primary intent of the inspector is examination, not alteration, of +objects. +The values of assignable variables may be changed from within the +inspector, however. +Assignable variables are generally limited to those for which +assignments occur in the source program. +It is also possible to invoke arbitrary procedures +(including mutation procedures such as set-car!) on an object. +No mechanism is provided for altering objects that are inherently +immutable, e.g., nonassignable variables, procedures, and bignums, since +doing so can violate assumptions made by the compiler and run-time +system. + +
+The user is presented with a prompt line that includes a printed +representation of the current object, abbreviated if necessary to +fit on the line. +Various commands are provided for displaying objects and moving around +inside of objects. +On-line descriptions of the command options are provided. +The command "?" displays commands that apply specifically to the +current object. +The command "??" displays commands that are always applicable. +The command "h" provides a brief description of how to use the +inspector. +The end-of-file character or the command "q" exits the inspector. + +
+procedure: (inspect obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Invokes the inspector on obj, as described above. +The commands recognized by the inspector are listed below, categorized +by the type of the current object. + + +
+ + + +
+
Generally applicable commands
help or h displays a brief description of how to use the +inspector. + +
+
? displays commands applicable to the current type of +object. + +
+
?? displays the generally applicable commands. + +
+
print or p prints the current object (using pretty-print). + +
+
write or w writes the current object (using write). + +
+
size writes the size in bytes occupied by the current object +(determined via compute-size), +including any objects accessible from the current object except those +for which the size was previously requested during the same interactive +inspector session. + +
+
find expr [ g ] evaluates expr, which should evaluate +to a procedure of one argument, and searches +(via make-object-finder) +for the first occurrence +of an object within the current object for which the predicate returns +a true value, treating immediate values (e.g., fixnums), values in +generations older than g, and values already visited during the +search as leaves. +If g is not unspecified, it defaults to the current maximum +generation, i.e., the value of collect-maximum-generation. +If specified, g must be an exact nonnegative integer less than or +equal to the current maximum generation or the symbol static +representing the static generation. +If such an object is found, the inspector's focus moves to that object +as if through a series of steps that lead from the current object to the +located object, so that the up command can be used to determine +where the object was found relative to the original object. + +
+
find-next repeats the last find, locating an +occurrence not previously found, if any. + +
+
up or u n returns to the nth previous level. +Used to move outwards in the structure of the inspected object. +n defaults to 1. + +
+
top or t returns to the outermost level of the inspected +object. + +
+
forward or f moves to the nth next expression. +Used to move from one element to another of an object containing +a sequence of elements, such as a list, vector, record, frame, or closure. +n defaults to 1. + +
+
back or b moves to the nth previous expression. +Used to move from one element to another of an object containing +a sequence of elements, such as a list, vector, record, frame, or closure. +n defaults to 1. + +
+
=> expr sends the current object to the procedure value +of expr. +expr may begin on the current or following line and may +span multiple lines. + +
+
file path opens the source file at the specified path for +listing. +The parameter source-directories (Section 12.5) +determines the set of directories +searched for source files. + +
+
list line count lists count lines of the +current source file (see file) starting at line. +line defaults to the end of the previous set of lines listed and +count defaults to ten or the number of lines previously listed. +If line is negative, listing begins line lines before the +previous set of lines listed. + +
+
files shows the currently open source files. + +
+
mark or m m marks the current location with the +symbolic mark m. +If m is not specified, the current location is marked with +a unique default mark. + +
+
goto or g m returns to the location marked m. +If m is not specified, the inspector returns to the location +marked with the default mark. + +
+
new-cafe or n enters a new read-eval-print loop +(café), giving access to the normal top-level environment. + +
+
quit or q exits from the inspector. + +
+
reset or r resets to the current café. + +
+
abort or a x aborts from Scheme with exit +status x, which defaults to -1. + + +
+
Continuation commands
show-frames or sf shows the next n frames. +If n is not specified, all frames are displayed. + +
+
depth displays the number of frames in the continuation. + +
+
down or d n move to the nth frame down in the +continuation. +n defaults to 1. + +
+
show or s shows the continuation (next frame) and, +if available, the calling procedure source, the pending call source, +the closure, and the frame and free-variable values. +Source is available only if generation of inspector information +was enabled during compilation of the corresponding lambda +expression. + +
+
show-local or sl is like show or s +except that free variable values are not shown. (If present, free variable +values can be found by inspecting the closure.) + +
+
length or l displays the number of elements +in the topmost frame of the continuation. + +
+
ref or r moves to the nth or named +frame element. n defaults to 0. +If multiple elements have the same name, only one is +accessible by name, and the others must be accessed by number. + +
+
code or c moves to the source for the calling procedure. + +
+
call moves to the source for the pending call. + +
+
file opens the source file containing the pending call, +if known. +The parameter source-directories (Section 12.5) +determines the list of source directories searched for source files +identified by relative path names. + +
+For absolute pathnames starting with a / (or \ or a +directory specifier under Windows), the inspector tries the absolute +pathname first, then looks for the last (filename) component of the path in +the list of source directories. +For pathnames starting with ./ (or .\ under Windows) +or ../ (or ..\ under Windows), the inspector looks in +"." or ".." first, as appropriate, then for the entire +.- or ..-prefixed +pathname in the source directories, then for the last (filename) +component in the source directories. +For other (relative) pathnames, the inspector looks for the entire +relative pathname in the list of source directories, then the last +(filename) component in the list of source directories. + +
+If a file by the same name as but different contents from the original +source file is found during this process, it will be skipped over. +This typically happens because the file has been modified since it was +compiled. +Pass an explicit filename argument to force opening of a particular file +(see the generally applicable commands above). + + + +
+
eval or e expr evaluates the expression +expr in an environment containing bindings for the elements of +the frame. Within the evaluated expression, the value of each frame +element n is accessible via the variable %n. +Named elements are accessible via their names as well. Names are +available only if generation of inspector information was enabled +during compilation of the corresponding lambda expression. + +
+
set! or ! n e sets the value of the nth frame +element to e, if the frame element corresponds to +an assignable variable. +n defaults to 0. + + + +
+
Procedure commands
show or s shows the source and free variables of the +procedure. +Source is available only if generation of inspector information +was enabled during compilation of the corresponding lambda +expression. + +
+
code or c moves to the source for the procedure. + +
+
file opens the file containing the procedure's source code, +if known. +See the description of the continuation file entry above for more +information. + +
+
length or l displays the number of free variables +whose values are recorded in the procedure object. + +
+
ref or r moves to the nth or named +free variable. n defaults to 0. +If multiple free variables have the same name, only one is +accessible by name, and the others must be accessed by number. + +
+
set! or ! n e sets the value of the nth free variable +to e, if the variable is assignable. +n defaults to 0. + +
+
eval or e expr evaluates the expression +expr in an environment containing bindings for the free variables +of the procedure. +Within the evaluated expression, the value of each free variable +n is accessible via the variable %n. +Named free variables are accessible via their names as well. +Names are available only if generation of inspector information was +enabled during compilation of the corresponding lambda expression. + + +
+
Pair (list) commands
show or s n shows the first n elements of the list. +If n is not specified, all elements are displayed. + +
+
length or l displays the list length. + +
+
car moves to the object in the car of the current object. + +
+
cdr moves to the object in the cdr. + +
+
ref or r n moves to the nth element of the list. +n defaults to 0. + +
+
tail n moves to the nth cdr of the list. +n defaults to 1. + + +
+
Vector, Bytevector, and Fxvector commands
show or s n shows the first n elements of the vector. +If n is not specified, all elements are displayed. + +
+
length or l displays the vector length. + +
+
ref or r n moves to the nth element of the vector. +n defaults to 0. + + +
+
String commands
show or s n shows the first n elements of the string. +If n is not specified, all elements are displayed. + +
+
length or l displays the string length. + +
+
ref or r n moves to the nth element of the string. +n defaults to 0. + +
+
unicode n displays the first n elements of the string +as hexadecimal Unicode scalar values. + +
+
ascii n displays the first n elements of the string +as hexadecimal ASCII values, using -- to denote characters whose Unicode +scalar values are not in the ASCII range. + + +
+
Symbol commands
show or s shows the fields of the symbol. + +
+
value or v moves to the top-level value of the symbol. + +
+
name or n moves to the name of the symbol. + +
+
property-list or pl moves to the property list +of the symbol. + +
+
ref or r n moves to the nth field of the symbol. +Field 0 is the top-level value of the symbol, field 1 +is the symbol's name, and field 2 is its property list. +n defaults to 0. + + + + +
+
Character commands
unicode displays the hexadecimal Unicode scalar value for +the character. + +
+
ascii displays the hexadecimal ASCII code for the character, +using -- to denote characters whose Unicode scalar values are not +in the ASCII range. + + +
+
Box commands
show or s shows the contents of the box. + +
+
unbox or ref or r moves to the boxed object. + + +
+
Port commands
show or s shows the fields of the port, including +the input and output size, index, and buffer fields. + +
+
name moves to the port's name. + +
+
handler moves to the port's handler. + +
+
output-buffer or ob moves to the port's output buffer. + +
+
input-buffer or ib moves to the port's input buffer. + + + +
+
Record commands
show or s shows the contents of the record. + +
+
fields moves to the list of field names +of the record. + +
+
name moves to the name of the record. + +
+
rtd moves to the record-type descriptor of the record. + +
+
ref or r name moves to the named field of the +record, if accessible. + +
+
set! or ! name value sets the value +of the named field of the record, if mutable. + + +
+
Transport Link Cell (TLC) commands
show or s shows the fields of the TLC. + +
+
keyval moves to the keyval of the TLC. + +
+
tconc moves to the tconc of the TLC. + +
+
next moves to the next link of the TLC. + +
+
ref or r n moves to the nth field of the symbol. +Field 0 is the keyval, field 1 the tconc, and field 2 the next link. +n defaults to 0. + + +
+ +
+A facility for noninteractive inspection is also provided +to allow construction of different inspection interfaces. +Like the interactive facility, it allows objects to be examined in +ways not ordinarily possible. +The noninteractive system follows a simple, object-oriented protocol. +Ordinary Scheme objects are encapsulated in procedures, or inspector +objects, that take symbolic messages and return either information +about the encapsulated object or new inspector objects that encapsulate +pieces of the object. + +
+procedure: (inspect/object object)
+
+returns: an inspector object procedure
+
+libraries: (chezscheme)
+
+
inspect/object is used to turn an ordinary Scheme object into an +inspector object. +All inspector objects accept the messages type, print, +write, and size. +The type message returns a symbolic representation of the type of +the object. +The print and write messages must be accompanied by a port +parameter. +They cause a representation of the object to be written to the port, +using the Scheme procedures pretty-print and write. +The size message returns a fixnum representing the size +in bytes occupied by the object, including any objects accessible +from the current object except those for which the size was already +requested via an inspector object derived from the argument of the +same inspect/object call. + +
+All inspector objects except for variable inspector objects accept +the message value, which returns the actual object encapsulated +in the inspector object. + +
+ +
(define x (inspect/object '(1 2 3)))
+
+(x 'type) pair
+
+(define p (open-output-string))
+
+(x 'write p)
+
+(get-output-string p) "(1 2 3)"
+
+(x 'length) (proper 3)
+
+(define y (x 'car))
+
+(y 'type) simple
+
+(y 'value) 1
+
+ +
+ + +
+
Pair inspector objects. +Pair inspector objects contain Scheme pairs. + +
+
(pair-object 'type) +returns the symbol pair. + +
+
(pair-object 'car) +returns an inspector object containing the "car" field of the pair. + +
+
(pair-object 'cdr) +returns an inspector object containing the "cdr" field of the pair. + +
+
(pair-object 'length) +returns a list of the form (type count). +The type field contains the symbol proper, the symbol improper, or +the symbol circular, depending on the structure of the list. +The count field contains the number of distinct pairs in the list. + +
+
Box inspector objects. +Box inspector objects contain Chez Scheme boxes. + +
+
(box-object 'type) +returns the symbol box. + +
+
(box-object 'unbox) +returns an inspector object containing the contents of the box. + +
+
TLC inspector objects. +Box inspector objects contain Chez Scheme boxes. + +
+
(tlc-object 'type) +returns the symbol tlc. + +
+
(tlc-object 'keyval) +returns an inspector object containing the TLC's keyval. + +
+
(tlc-object 'tconc) +returns an inspector object containing the TLC's tconc. + +
+
(tlc-object 'next) +returns an inspector object containing the TLC's next link. + +
+
Vector, String, Bytevector, and Fxvector inspector objects. +Vector (bytevector, string, fxvector) inspector objects contain Scheme +vectors (bytevectors, strings, fxvectors). + +
+
(vector-object 'type) +returns the symbol vector (string, bytevector, fxvector). + +
+
(vector-object 'length) +returns the number of elements in the vector or string. + +
+
(vector-object 'ref n) +returns an inspector object containing the nth element of the +vector or string. + +
+
Simple inspector objects. +Simple inspector objects contain unstructured, unmodifiable objects. +These include numbers, booleans, the empty list, the end-of-file +object, and the void object. +They may be examined directly by asking for the value of the object. + +
+
(simple-object 'type) +returns the symbol simple. + +
+
Unbound inspector objects. +Although unbound objects are not normally accessible to Scheme programs, +they may be encountered when inspecting variables. + +
+
(unbound-object 'type) +returns the symbol unbound. + +
+
Procedure inspector objects. +Procedure inspector objects contain Scheme procedures. + +
+
(procedure-object 'type) +returns the symbol procedure. + +
+
(procedure-object 'length) +returns the number of free variables. + +
+
(procedure-object 'ref n) +returns an inspector object containing the nth free variable of the +procedure. +See the description below of variable inspector objects. +n must be nonnegative and less than the length of the procedure. + +
+
(procedure-object 'eval expr) +evaluates expr and returns its value. +The values of the procedure's free variables are bound within the +evaluated expression to +identifiers of the form %n, where n is the location number +displayed by the inspector. +The values of named variables are also bound to their names. + +
+
(procedure-object 'code) +returns an inspector object containing the procedure's code object. +See the description below of code inspector objects. + + +
+
Continuation inspector objects. +Continuations created by call/cc are actually +procedures. +However, when inspecting such a procedure the underlying data structure +that embodies the continuation may be exposed. +A continuation structure contains the location at which computation is +to resume, the variable values necessary to perform the computation, +and a link to the next continuation. + +
+
(continuation-object 'type) +returns the symbol continuation. + +
+
(continuation-object 'length) +returns the number of free variables. + +
+
(continuation-object 'ref n) +returns an inspector object containing the nth free variable of the +continuation. +See the description below of variable inspector objects. +n must be nonnegative and less than the length of the continuation. + +
+
(continuation-object 'eval expr) +evaluates expr and returns its value. +The values of frame locations are bound within the +evaluated expression to +identifiers of the form %n, where n is the location number +displayed by the inspector. +The values of named locations are also bound to their names. + +
+
(continuation-object 'code) +returns an inspector object containing the code object for the procedure +that was active when the current continuation frame was created. +See the description below of code inspector objects. + +
+
(continuation-object 'depth) +returns the number of frames in the continuation. + +
+
(continuation-object 'link) +returns an inspector object containing the next continuation frame. +The depth must be greater than 1. + +
+
(continuation-object 'link* n) +returns an inspector object containing the nth continuation link. +n must be less than the depth. + +
+
(continuation-object 'source) +returns an inspector object containing the source information attached +to the continuation (representing the source for the application that +resulted in the formation of the continuation) +or #f if no source information is attached. + +
+
(continuation-object 'source-object) +returns an inspector object containing the source object for the +procedure application that resulted in the formation of the continuation +or #f if no source object is attached. + +
+
(continuation-object 'source-path) +attempts to find the pathname of the file containing the source for +the procedure application that resulted in the formation of the continuation. +If successful, three values are returned to identify the file and position +of the application within the file: path, line, and char. +Two values, a file name and an absolute character position, are returned +if the file name is known but the named file cannot be found. +The search may be unsuccessful even if a file by the expected +name is found in the path if the file has been modified since the source +code was compiled. +If no file name is known, no values are returned. +The parameter source-directories (Section 12.5) +determines the set of directories +searched for source files identified by relative path names. + + +
+
Code inspector objects. +Code inspector objects contain Chez Scheme code objects. + +
+
(code-object 'type) +returns the symbol code. + +
+
(code-object 'name) +returns a string or #f. +The name associated with a code inspector object is the name of the +variable to which the procedure was originally bound or assigned. +Since the binding of a variable can be changed, this name association +may not always be accurate. +#f is returned if the inspector cannot determine a name for the +procedure. + +
+
(code-object 'realm) +returns a symbol or #f. The realm of a code object is determined +by the compile-procedure-realm parameter at the time that the code +object is compiled. + +
+
(code-object 'source) +returns an inspector object containing the source information attached +to the code object or #f if no source information is attached. + +
+
(continuation-object 'source-object) +returns an inspector object containing the source object for the +code object or #f if no source object is attached. + +
+
(code-object 'source-path) +attempts to find the pathname of the file containing the source for +the lambda expression that produced the code object. +If successful, three values are returned to identify the file and position +of the application within the file: path, line, and char. +Two values, a file name and an absolute character position, are returned +if the file name is known but the named file cannot be found. +The search may be unsuccessful even if a file by the expected +name is found in the path if the file has been modified since the source +code was compiled. +If no file name is known, no values are returned. +The parameter source-directories (Section 12.5) +determines the set of directories +searched for source files identified by relative path names. + +
+
(code-object 'free-count) +returns the number of free variables in any procedure for which this is +the corresponding code. + + +
+
Variable inspector objects. +Variable inspector objects encapsulate variable bindings. +Although the actual underlying representation varies, the variable +inspector object provides a uniform interface. + +
+
(variable-object 'type) +returns the symbol variable. + +
+
(variable-object 'name) +returns a symbol or #f. +#f is returned if the name is not available or if the variable is a +compiler-generated temporary variable. +Variable names are not retained when the parameter +generate-inspector-information +(page 12.6) +is false during compilation. + +
+
(variable-object 'ref) +returns an inspector object containing the current value of the +variable. + +
+
(variable-object 'set! e) +returns unspecified, after setting the current value of the +variable to e. +An exception is raised with condition type &assertion if the variable is not assignable. + + + +
+
Port inspector objects. +Port inspector objects contain ports. + +
+
(port-object 'type) +returns the symbol port. + +
+
(port-object 'input?) +returns #t if the port is an input port, #f otherwise. + +
+
(port-object 'output?) +returns #t if the port is an output port, #f otherwise. + +
+
(port-object 'binary?) +returns #t if the port is a binary port, #f otherwise. + +
+
(port-object 'closed?) +returns #t if the port is closed, #f if the port is open. + +
+
(port-object 'name) +returns an inspector object containing the port's name. + +
+
(port-object 'handler) +returns a procedure inspector object encapsulating the port handler, +such as would be returned by port-handler. + +
+
(port-object 'output-size) +returns the output buffer size as a fixnum if the port is an +output port (otherwise the value is unspecified). + +
+
(port-object 'output-index) +returns the output buffer index as a fixnum if the port is an +output port (otherwise the value is unspecified). + +
+
(port-object 'output-buffer) +returns an inspector object containing the string used for buffered +output. + +
+
(port-object 'input-size) +returns the input buffer size as a fixnum if the port is an +input port (otherwise the value is unspecified). + +
+
(port-object 'input-index) +returns the input buffer index as a fixnum if the port is an +input port (otherwise the value is unspecified). + +
+
(port-object 'input-buffer) +returns an inspector object containing the string used for buffered +input. + + +
+
Symbol inspector objects. +Symbol inspector objects contain symbols. +These include gensyms. + +
+
(symbol-object 'type) +returns the symbol symbol. + +
+
(symbol-object 'name) +returns a string inspector object. +The string name associated with a symbol inspector object is the print +representation of a symbol, such as would be returned by the procedure +symbol->string. + +
+
(symbol-object 'gensym?) +returns #t if the symbol is a gensym, #f otherwise. +Gensyms are created by gensym. + +
+
(symbol-object 'top-level-value) +returns an inspector object containing the global value of the symbol. + +
+
(symbol-object 'property-list) +returns an inspector object containing the property list for the +symbol. + + + +
+
Record inspector objects. +Record inspector objects contain records. + +
+
(record-object 'type) +returns the symbol record. + +
+
(record-object 'name) +returns a string inspector object corresponding to the name of +the record type. + +
+
(record-object 'fields) +returns an inspector object containing a list of the field names of +the record type. + +
+
(record-object 'length) +returns the number of fields. + +
+
(record-object 'rtd) +returns an inspector object containing the record-type descriptor of the +record type. + +
+
(record-object 'accessible? name) +returns #t if the named field is accessible, #f otherwise. +A field may be inaccessible if optimized away by the compiler. + +
+
(record-object 'ref name) +returns an inspector object containing the value of the named field. +An exception is raised with condition type &assertion if the named field is not accessible. + +
+
(record-object 'mutable? name) +returns #t if the named field is mutable, #f otherwise. +A field is immutable if it is not declared mutable or if the compiler +optimizes away all assignments to the field. + +
+
(record-object 'set! name value) +sets the value of the named field to value. +An exception is raised with condition type &assertion if the named field is not assignable. + +
+ +
+procedure: (make-object-finder pred)
+
procedure: (make-object-finder pred g)
+
procedure: (make-object-finder pred x g)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
The procedure make-object-finder takes a predicate pred and two optional +arguments: a starting point x and a maximum generation g. +The starting point defaults to the value of the procedure oblist, +and the maximum generation defaults to the value of the parameter +collect-maximum-generation. +make-object-finder returns an object finder p that can be used to +search for objects satisfying pred within the starting-point object x. +Immediate objects and objects in generations older than g are treated +as leaves. +p is a procedure accepting no arguments. +If an object y satisfying pred can be found starting with x, +p returns a list whose first element is y and whose remaining +elements represent the path of objects from x to y, listed +in reverse order. +p can be invoked multiple times to find additional objects satisfying +the predicate, if any. +p returns #f if no more objects matching the predicate +can be found. + +
+p maintains internal state recording where it has been so it +can restart at the point of the last found object and not return +the same object twice. +The state can be several times the size of the starting-point object +x and all that is reachable from x. + +
+The interactive inspector provides a convenient interface to the object +finder in the form of find and find-next commands. + +
+Relocation tables for static code objects are discarded by default, which +prevents object finders from providing accurate results when static code +objects are involved. +That is, they will not find any objects pointed to directly from a code +object that has been promoted to the static generation. +If this is a problem, the command-line argument +--retain-static-relocation +can be used to prevent the relocation tables from being discarded. + + +
+ +
+The procedures compute-size and compute-composition can be +used to determine the size or composition of an object, including anything +reachable via pointers from the object. +Depending on the number of objects reachable from the object, the procedures +potentially allocate a large amount of memory. +In an application for which knowing the number, size, generation, and types +of all objects in the heap is sufficient, +object-counts is potentially much +more efficient. + +
+The procedure compute-size-increments is similar to +compute-size mapped over a list of elements, but it reports a +size for each later element without including the size of objects +reachable from ealier elements, and it treats weak and ephemeron pairs +differently. For a large number of reachable objects, +compute-size-increments uses much less memory than +compute-size. + +
+These procedures treat immediate objects such as fixnums, booleans, and +characters as zero-count, zero-byte leaves. + +
+By default, these procedures also treat static objects (those in the +initial heap) as zero-count, zero-byte leaves. +Both procedures accept an optional second argument that specifies the +maximum generation of interest, with the symbol static being +used to represent the static generation. + +
+Objects sometimes point to a great deal more than one might expect. +For example, if static data is included, the procedure value of +(lambda (x) x) points indirectly to the exception handling +subsystem (because of the argument-count check) and many other things +as a result of that. + +
+Relocation tables for static code objects are discarded by default, +which prevents these procedures from providing accurate results when +static code objects are involved. +That is, they will not find any objects pointed to directly from a code +object that has been promoted to the static generation. +If accurate sizes and compositions for static code objects are +required, the command-line argument +--retain-static-relocation +can be used to prevent the relocation tables from being discarded. + +
+procedure: (compute-size object)
+
procedure: (compute-size object generation)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
object can be any object. +generation must be a fixnum between 0 and the value of +collect-maximum-generation, inclusive, or the symbol +static. +If generation is not supplied, it defaults to the value of +collect-maximum-generation. + +
+compute-size returns the amount of memory, in bytes, occupied by +object and anything reachable from object in any generation +less than or equal to generation. +Immediate values such as fixnums, booleans, and characters have zero size. +Size computation for a thread is limited when the thread is still active, +since its full continuation cannot be inspected in that case, but the +full continuation is inspected if the thread is inactive (such as during +a garbage collection rendezvous when a different thread is selected by +the rendezvous). + +
+The following examples are valid for machines with 32-bit pointers. + +
+ +
(compute-size 0) 0
+
+(compute-size (cons 0 0)) 8
+
+(compute-size (cons (vector #t #f) 0)) 24
+
+
+(compute-size
+
+ (let ([x (cons 0 0)])
+
+ (set-car! x x)
+
+ (set-cdr! x x)
+
+ x)) 8
+
+
+(define-record-type frob (fields x))
+
+(collect 1 1) ; force rtd into generation 1
+
+(compute-size
+
+ (let ([x (make-frob 0)])
+
+ (cons x x))
+
+ 0) 16
+
procedure: (compute-composition object)
+
procedure: (compute-composition object generation)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
object can be any object. +generation must be a fixnum between 0 and the value of +collect-maximum-generation, inclusive, or the symbol +static. +If generation is not supplied, it defaults to the value of +collect-maximum-generation. + +
+compute-composition returns an association list representing +the composition of object, including anything reachable from it +in any generation less than or equal to generation. +The association list has the following structure: + +
+ +
((type count . bytes) ...) +
type is either the name of a primitive type, represented as a +symbol, e.g., pair, or a record-type descriptor (rtd). +count and bytes are nonnegative fixnums. + +
+Immediate values such as fixnums, booleans, and characters are not +included in the composition. + +
+The following examples are valid for machines with 32-bit pointers. + +
+ +
(compute-composition 0) ()
+
+(compute-composition (cons 0 0)) ((pair 1 . 8))
+
+(compute-composition
+
+ (cons (vector #t #f) 0)) ((pair 1 . 8) (vector 1 . 16))
+
+
+(compute-composition
+
+ (let ([x (cons 0 0)])
+
+ (set-car! x x)
+
+ (set-cdr! x x)
+
+ x)) ((pair 1 . 8)
+
+
+(define-record-type frob (fields x))
+
+(collect 1 1) ; force rtd into generation 1
+
+(compute-composition
+
+ (let ([x (make-frob 0)])
+
+ (cons x x))
+
+ 0) ((pair 1 . 8)
+
+ (#<record type frob> 1 . 8))
+
procedure: (compute-size-increments list)
+
procedure: (compute-size-increments list generation)
+
+returns: a list as described below
+
+libraries: (chezscheme)
+
+
list must be a list, but each element can be any object. +generation must be a fixnum between 0 and the value of +collect-maximum-generation, inclusive, or the symbol +static. +If generation is not supplied, it defaults to the value of +collect-maximum-generation. +In the threaded versions of Chez Scheme, the thread that invokes +compute-size-increments must be the only active thread. + +
+compute-size-increments is like mapping compute-size +over list, except that any object reachable from an earlier +element of list is not treated as reachable by a later element +of list. In addition, each immediate element of list is +not treated as reachable by earlier elements of list---although +other values reachable from later elements of list may be +considered reachable from earlier elements. + +
+Unlike compute-size, compute-size-increments does not +consider the car of a weak pair reachable from the weak pair. +It also does not consider the car or cdr of an +ephemeron pair to be reachable from the ephemeron pair, unless the +car is already determined to be reachable (perhaps from an +earlier element of list); if the car of an ephemeron +pair is discovered to be reachable later (perhaps from a later element +of list), then the cdr of the ephemeron pair is +considered to be reachable from the car, which has the effect +of charging the memory of the cdr to the same element of +list as the memory of the car. + +
+The following examples are valid for machines with 32-bit pointers. + +
+ +
(compute-size-increments (list 0)) (0)
+
+(compute-size-increments (list (cons 0 0))) (8)
+
+(compute-size-increments (list (cons 0 0) (cons 0 0))) (8 8)
+
+(compute-size-increments (let ([p (cons 0 0)])
+
+ (list p p))) (8 0)
+
+(compute-size-increments (let ([p (cons 0 0)])
+
+ (list (cons 1 p) (cons 1 p)))) (16 8)
+
+(compute-size-increments (list (ephemeron-cons 0 0))) (16)
+
+(compute-size-increments (let* ([p (cons 0 0)]
+
+ [e (ephemeron-cons p (cons 0 0))])
+
+ (list e p))) (16 16)
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/expeditor.html b/csug10.0/expeditor.html
new file mode 100644
index 000000000..a68dcd1aa
--- /dev/null
+++ b/csug10.0/expeditor.html
@@ -0,0 +1,827 @@
+
+
+
+
+
+When the expression editor (expeditor) is enabled as described in +Section 2.2, it allows the user to edit expressions +entered into the system and move backwards and forwards through +a history of entered expressions. +This chapter describes a set of parameters that may be used to +control various aspects of the expression editor's behavior +(Section 14.1), +a procedure for binding key sequences to editing commands +(Section 14.2), +the built-in editing commands +(Section 14.3), and mechanisms for creating new +editing commands (Section 14.4). + +
+These mechanisms are available through the expression-editor module. + +
+module: expression-editor
+
+libraries: (chezscheme)
+
+
The expression-editor module exports a set of bindings for +parameters and other procedures that can be used to modify how the +expression editor interacts with the user, including the particular keys +used to invoke the various editing commands. + +
+
Basic use of the expression editor is described in Section 2.2. + + + +
+ +
+global parameter: ee-auto-indent + +
+ +
The value of ee-auto-indent is a boolean value that determines +whether the expression editor indents expressions as they are entered. +Its default value is #t. + + +
+global parameter: ee-standard-indent + +
+ +
The value of ee-standard-indent is a nonnegative fixnum +value that determines the amount (in single spaces) by which each +expression is indented relative to the enclosing expression, if +not aligned otherwise by one of the indenter's other heuristics, +when ee-auto-indent is true or when one of the indentation +commands is invoked explicitly. +It's default value is 2. + + +
+global parameter: ee-auto-paren-balance + +
+ +
The value of ee-auto-paren-balance is a boolean value that determines +whether the expression editor automatically corrects a close +parenthesis or bracket, when typed, to match the corresponding open +parenthesis or bracket, if any. +Its default value is #t. + + +
+global parameter: ee-flash-parens + +
+ +
The value of ee-flash-parens is a boolean value that determines +whether the expression editor briefly moves the cursor when an open +or close parenthesis or bracket is typed to the +matching close or open parenthesis or bracket (if any). +Its default value is #t. + + +
+global parameter: ee-paren-flash-delay + +
+ +
The value of ee-paren-flash-delay is a nonnegative fixnum +value that determines the amount of time (in milliseconds) that the +expression editor pauses when the cursor is moved to the matching +parenthesis or bracket, if any, when a parenthesis or bracket is +entered. +The value is ignored if the ee-flash-parens is false. +Its default value is 100. + + +
+global parameter: ee-default-repeat + +
+ +
The value of ee-default-repeat is a nonnegative fixnum +value that determines the number of times the next command is +repeated after the ee-command-repeat editing command +(bound to Esc-^U by default) is used and not +followed by a sequence of digits. +It's default value is 4. + + +
+global parameter: ee-noisy + +
+ +
The value of ee-noisy is a boolean value that determines +whether the expression editor emits a beep (bell) when an error +occurs, such as an attempt to find the matching delimiter for a +non-delimiter character. +Its default value is #f. + + +
+global parameter: ee-history-limit + +
+ +
The value of ee-history-limit is a nonnegative fixnum value +that determines the number of history entries retained by the +expression editor during and across sessions. +Only the last (ee-history-limit) entries are retained. + + +
+global parameter: ee-common-identifiers + +
+ +
The value of ee-common-identifiers is list of symbols that +are considered common enough that they should appear early when +one of the incremental identifier-completion editing commands is +invoked. +Its default value contains a few dozen entries. +They are all more than a few characters long (under the theory that +users will most likely type short ones out fully) and all would +appear later than they likely should when incremental +identifier-completion is used. + + +
+ +
+Key bindings are established via ee-bind-key. +The default key bindings are described in Section 14.3. + +
+procedure: (ee-bind-key key procedure) + +
+
+returns: unspecified
+
+
The ee-bind-key procedure is used to add to or change the +set of key bindings recognized by the expression editor. + +
+The key must be a character or string; if it is a string, it +must have the following form. + +
+ + + +
+<key-string> | "<key-char>+" + |
+where + +
+ + + +
+<key-char> | \\e (specifying an escape character) | |
+ | | | ^x (specifying control-x) |
+ | | | \\^ (specifying caret) |
+ | | | \\\\ (specifying back slash) |
+ | | | plain char (any character other than \ or ^) + |
+Note that each double-backslash in the syntax actually denotes just +one backslash in the string. + +
+For example, the key "\\eX" represents the two-character +sequence Escape-x, i.e., the "escape" key followed by the (capital) +"X" key. +Similarly, they key "\\e^X" represents the two-character +sequence Escape-Control-x, i.e., the "escape" key followed by +Control-X. + +
+Character keys and string keys consisting of a single plain character +always represent a single keystroke. + +
+The procedure argument should normally be one of the built-in editing +commands described below. +It is also possible to define new editing commands with +ee-string-macro +and ee-compose. + + +
+ +
+ + +
+The editing commands are grouped into sections according to usage. +Each is listed along with the default character sequence or sequences by +which it may be invoked. + +
+
Insertion commands +
command: ee-insert-self
+
+ key(s): most printing characters
+
+Inserts the entered character into the entry. + +
command: ee-insert-paren
+
+ key(s): (, ), [, ]
+
+Inserts the entered parenthesis or bracket into the entry. + +
+If the parameter +ee-auto-paren-balance is +true, the editor corrects close delimiters if necessary to balance +existing open delimiters, when a matching open delimiter can be found. + +
+If the parameter ee-flash-parens +is true, the editor briefly moves the cursor to the matching delimiter, if +one can be found, pausing for an amount of time controlled by the +parameter ee-paren-flash-delay. +If the matching delimiter is not presently displayed, the cursor is flashed +to the upper-left or lower-left corner of the displayed portion of the +entry, as appropriate. + +
+The behavior of this command is undefined if used for something other +than a parenthesis or bracket. + +
command: ee-newline
+
+ key(s): none
+
+Inserts a newline at the cursor position, moves to the next line, and +indents that line if the parameter +ee-auto-indent is true. +Does nothing if the entry is empty. +See also ee-newline/accept. + +
command: ee-open-line
+
+ key(s): ^O
+
+Inserts a newline at the cursor position and indents the next line, +but does not move to the next line. + +
command: ee-yank-kill-buffer
+
+ key(s): ^Y
+
+Inserts the contents of the kill buffer, which is set by the deletion +commands described below. + +
command: ee-yank-selection
+
+ key(s): ^V
+
+Inserts the contents of the window system's current selection or paste +buffer. +When running in a shell window under X Windows, this command requires that +the DISPLAY environment variable be set to the appropriate display. + +
+
Cursor movement commands +
command: ee-backward-char
+
+ key(s): leftarrow, ^B
+
+Moves the cursor left one character. + +
command: ee-forward-char
+
+ key(s): rightarrow, ^F
+
+Moves the cursor right one character. + +
command: ee-next-line
+
+ key(s): downarrow, ^N
+
+Moves the cursor down one line (and to the left if necessary so that +the cursor does not sit beyond the last possible position). +If the cursor is at the end of the current entry, and the current +entry has not been modified, this command behaves like +ee-history-fwd. + +
command: ee-previous-line
+
+ key(s): uparrow, ^P
+
+Moves the cursor up one line (and to the left if necessary so that +the cursor does not sit beyond the last possible position). +If the cursor is at the top of the current entry, and the current +entry has not been modified, this command behaves like +ee-history-bwd. + +
command: ee-beginning-of-line
+
+ key(s): home, ^A
+
+Moves the cursor to the first character of the current line. + +
command: ee-end-of-line
+
+ key(s): end, ^E
+
+Moves the cursor to the right of the last character of the current line. + +
command: ee-beginning-of-entry
+
+ key(s): escape-<
+
+Moves the cursor to the first character of the entry. + +
command: ee-end-of-entry
+
+ key(s): escape->
+
+Moves the cursor to the right of the last character of the entry. + +
command: ee-goto-matching-delimiter
+
+ key(s): escape-]
+
+Moves the cursor to the matching delimiter. +Has no effect if the character under the cursor is not a parenthesis +or bracket or if no matching delimiter can be found. + +
command: ee-flash-matching-delimiter
+
+ key(s): ^]
+
+Moves the cursor briefly to the matching delimiter, if +one can be found, pausing for an amount of time controlled by the +parameter ee-paren-flash-delay. +If the matching delimiter is not presently displayed, the cursor is flashed +to the upper-left or lower-left corner of the displayed portion of the +entry, as appropriate. + +
command: ee-exchange-point-and-mark
+
+ key(s): ^X-^X
+
+Moves the cursor to the mark and leaves the mark at the old cursor +position. +(The mark can be set with ee-set-mark.) + +
command: ee-forward-sexp
+
+ key(s): escape-^F
+
+Moves the cursor to the start of the next expression. + +
command: ee-backward-sexp
+
+ key(s): escape-^B
+
+Moves the cursor to the start of the preceding expression. + +
command: ee-forward-word
+
+ key(s): escape-f, escape-F
+
+Moves the cursor to the end of the next word. + +
command: ee-backward-word
+
+ key(s): escape-b, escape-B
+
+Moves the cursor to the start of the preceding word. + +
command: ee-forward-page
+
+ key(s): pagedown, ^X-]
+
+Moves the cursor down one screen page. + +
command: ee-backward-page
+
+ key(s): pageup, ^X-[
+
+Moves the cursor up one screen page. + +
Deletion commands +
command: ee-delete-char
+
+ key(s): delete
+
+Deletes the character under the cursor. + +
+See also ee-eof/delete-char. + +
command: ee-backward-delete-char
+
+ key(s): backspace (rubout), ^H
+
+Deletes the character to the left of the cursor. + +
command: ee-delete-line
+
+ key(s): ^U
+
+Deletes the contents of the current line, leaving behind an empty line. +When used on the first line of a multiline entry of which only the first line +is displayed, i.e., immediately after history movement, ee-delete-line +deletes the contents of the entire entry, like ee-delete-entry +(described below). + +
command: ee-delete-to-eol
+
+ key(s): ^K, escape-K
+
+If the cursor is at the end of a line, joins the line with the next +line, otherwise deletes from the cursor position to the end of the line. + +
command: ee-delete-between-point-and-mark
+
+ key(s): ^W
+
+Deletes text between the current cursor position and the mark. +(The mark can be set with ee-set-mark.) + +
command: ee-delete-entry
+
+ key(s): ^G
+
+Deletes the contents of the current entry. + +
command: ee-reset-entry
+
+ key(s): ^C
+
+Deletes the contents of the current entry and moves to the end of the +history. + +
command: ee-delete-sexp
+
+ key(s): escape-^K, escape-delete
+
+Deletes the expression that starts under the cursor, or if +no expression starts under the cursor, deletes up to the next +expression. + +
command: ee-backward-delete-sexp
+
+ key(s): escape-backspace (escape-rubout), escape-^H
+
+Deletes the expression to the left of the cursor. + +
Identifier/filename completion commands +
These commands perform either identifier or filename completion. +Identifier completion is performed outside of a string constant, and filename +completion is performed within a string constant. +(In determining whether the cursor is within a string constant, the +expression editor looks only at the current line and so can be fooled +by string constants that span multiple lines.) + +
+
command: ee-id-completion
+
+ key(s): none
+
+Inserts the common prefix of possible completions of the identifier or +filename immediately to the left of the cursor. +Identifier completion is based on the identifiers +defined in the interaction environment. +When there is exactly one possible completion, the common prefix is the +completion. +This command has no effect if no filename or identifier prefix is +immediately the left of the cursor or if the possible completions have +no common prefix. +If run twice in succession, a list of possible completions is displayed. + +
+See also +ee-id-completion/indent. + +
command: ee-next-id-completion
+
+ key(s): ^R
+
+Inserts one of the possible completions of the identifier or filename +immediately to the left of the cursor. +Identifier completion is based on the identifiers +defined in the interaction environment. +If run twice or more in succession, this command cycles through all of +the possible completions. +The order is determined by the following heuristics: appearing first +are identifiers whose names appear in the list value of the parameter +ee-common-identifiers; +appearing second are identifiers bound in the interaction environment +but not bound in the scheme-environment (i.e., identifiers defined by +the user), and appearing last are those in the scheme environment. +Within the set of matches appearing in the ee-common-identifiers +list, those listed earliest are shown first; the order is alphabetical +within the other two sets. + +
+See also +ee-next-id-completion/indent. + +
History movement commands +
The expression editor maintains a history of entries during each session. +It also saves the history across sessions unless this behavior is +disabled via the command-line argument "--eehistory off." + +
+When moving from one history entry to another, only the first line of each +multi-line entry is displayed. +The redisplay command (which ^L is bound to by default) can be used +to display the entire entry. +It is also possible to move down one line at a time to expose just part of +the rest of the entry. + +
+
command: ee-history-bwd
+
+ key(s): escape-uparrow, escape-^P
+
+Moves to the preceding history entry +if the current entry is empty or has not been modified; +otherwise, has no effect. + +
+See also ee-previous-line. + +
command: ee-history-fwd
+
+ key(s): escape-downarrow, escape-^N
+
+Moves to the next history entry +if the current entry is empty or has not been modified; +otherwise, has no effect. + +
+See also ee-next-line. + +
command: ee-history-bwd-prefix
+
+ key(s): escape-p
+
+Moves to the closest previous history entry, if any, that starts with +the sequence of characters that makes up the current entry. +May be used multiple times to search for same prefix. + +
command: ee-history-fwd-prefix
+
+ key(s): escape-n
+
+Moves to the closest following history entry, if any, that starts with +the sequence of characters that makes up the current entry. +May be used multiple times to search for same prefix. + +
command: ee-history-bwd-contains
+
+ key(s): escape-P
+
+Moves to the closest previous history entry, if any, that contains within +it the sequence of characters that makes up the current entry. +May be used multiple times to search for same content. + +
command: ee-history-fwd-contains
+
+ key(s): escape-N
+
+Moves to the closest following history entry, if any, that contains within +it the sequence of characters that makes up the current entry. +May be used multiple times to search for same content. + +
Indentation commands +
command: ee-indent
+
+ key(s): escape-tab
+
+Re-indents the current line. + +
+See also ee-next-id-completion/indent. + +
command: ee-indent-all
+
+ key(s): escape-q, escape-Q, escape-^Q
+
+Re-indents each line of the entire entry. + +
Miscellaneous commands +
command: ee-accept
+
+ key(s): ^J
+
+Causes the expression editor to invoke the Scheme reader on the contents +of the entry. +If the read is successful, the expression is returned to the waiter; +otherwise, an error message is printed, the entry redisplayed, and the +cursor left (if possible) at the start of the invalid subform. + +
+See also ee-newline/accept. + +
command: ee-eof
+
+ key(s): none
+
+Causes end-of-file to be returned from the expression editor, +which in turn causes the waiter to exit. +Ignored unless entry is empty. + +
+See also ee-eof/delete-char. + +
command: ee-redisplay
+
+ key(s): ^L
+
+Redisplays the current expression. +If run twice in succession, clears the screen and redisplays the +expression at the top of the screen. + +
command: ee-suspend-process
+
+ key(s): ^Z
+
+Suspends the current process in shells that support job control. + +
command: ee-set-mark
+
+ key(s): ^@, ^space
+
+Sets the mark to the current cursor position. + +
command: ee-command-repeat
+
+ key(s): escape-^U
+
+Repeats the next command n times. +If the next character typed is a digit, n is determined by reading +up the sequence of the digits typed and treating it as a decimal +number. +Otherwise, n is the value of the parameter +ee-default-repeat. + +
Combination commands +
command: ee-newline/accept
+
+ key(s): enter, ^M
+
+Behaves like ee-accept if run at the end (not including +whitespace) of an entry that starts with a balanced expression; +otherwise, behaves like ee-newline. + +
command: ee-id-completion/indent
+
+ key(s): tab
+
+Behaves like ee-id-completion if an identifier (outside +a string constant) or filename (within a string constant) appears +just to the left of the cursor and the last character of that +identifier or filename was just entered; +otherwise, behaves like ee-indent. + +
+If an existing identifier or filename, i.e., not one just typed, appears to the left +of the cursor, the first use of this command behaves like +ee-newline, the second consecutive use behaves like +ee-id-completion, and the third behaves like a second consecutive +use of ee-id-completion. + +
command: ee-next-id-completion/indent
+
+ key(s): none
+
+Behaves like ee-next-id-completion if an identifier (outside +a string constant) or filename (within a string constant) +appears just to the left of the cursor and the last character of that +identifier or identifier was just entered; +otherwise, behaves like ee-indent. + +
command: ee-eof/delete-char
+
+ key(s): ^D
+
+Behaves like ee-delete-char if the entry is nonempty; +otherwise, behaves like ee-eof. +If the entry is nonempty and this command is run twice or more in +succession, it does nothing once the entry becomes empty. +This is to prevent accidental exit from the waiter in cases where +the command is run repeatedly (perhaps with the help of a keyboard's +auto-repeat feature) to delete all of the characters in an entry. + +
+
+procedure: (ee-string-macro string) + +
+
+returns: a new editing command
+
+
The new editing command produced inserts string before the current +cursor position. + +
+Two string macros are predefined: + +
+
+(ee-string-macro "(define ") | escape-d |
+(ee-string-macro "(lambda ") | escape-l + |
+procedure: (ee-compose ecmd ...) + +
+
+returns: a new editing command
+
+
Each ecmd must be an editing command. + +
+The new editing command runs each of the editing commands +ecmd ... in sequence. + + +
+For example, the following expression binds ^X-p to an editing +command that behaves like ee-history-bwd-prefix but leaves the +cursor at the end of the expression rather than at the end of the first +line, causing the entire entry to be displayed. + +
+ +
(let ()
+
+ (import expression-editor)
+
+ (ee-bind-key "^Xp"
+
+ (ee-compose ee-history-bwd ee-end-of-entry)))
+
A command such as ee-id-completion that performs a different +action when run twice in succession will not recognize that it has been +run twice in succession if run as part of a composite command. + + +
+ + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/foreign.html b/csug10.0/foreign.html
new file mode 100644
index 000000000..56b6fcbcc
--- /dev/null
+++ b/csug10.0/foreign.html
@@ -0,0 +1,4986 @@
+
+
+
+
+
+Chez Scheme provides two ways to interact with "foreign" code, +i.e., code written in other languages. +The first is via subprocess creation and communication, which is +discussed in the Section 4.1. +The second is via static or dynamic loading and invocation from Scheme +of procedures written in C and +invocation from C of procedures written in Scheme. +These mechanisms are discussed in Sections 4.2 +through 4.4. + +
+The method for static loading of C object code is dependent upon which +machine you are running; see the installation instructions distributed +with Chez Scheme. + + +
+ +
+Two procedures, system and process, are used to create +subprocesses. +Both procedures accept a single string argument and create a +subprocess to execute the shell command contained in the string. +The system procedure waits for the process to exit before +returning, however, +while the process procedure returns immediately without +waiting for the process to exit. +The standard input and output files of a subprocess created by system +may be used to communicate with the user's console. +The standard +input and output files of a subprocess created by process may be used +to communicate with the Scheme process. + +
+procedure: (system command)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
command must be a string. + +
+The system procedure creates a subprocess to perform the operation +specified by command. +The subprocess may communicate with the user through the same console +input and console output files used by the Scheme process. +After creating the subprocess, system waits for the process to exit +before returning. + +
+When the subprocess exits, system returns the exit code for the +subprocess, unless (on Unix-based systems) a signal caused the subprocess +to terminate, in which case system returns the negation of the +signal that caused the termination, e.g., -1 for SIGHUP. + + +
+procedure: (open-process-ports command)
+
procedure: (open-process-ports command b-mode)
+
procedure: (open-process-ports command b-mode ?transcoder)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
command must be a string. +If ?transcoder is present and not #f, it must be a +transcoder, and this procedure creates textual ports, each of whose +transcoder is ?transcoder. +Otherwise, this procedure returns binary ports. +b-mode specifies the buffer mode used by each of the ports +returned by this procedure and defaults to block. +Buffer modes are described in Section 7.2 of +The Scheme Programming Language, 4th Edition. + +
+open-process-ports creates a subprocess to perform the operation +specified by command. +Unlike system, process returns immediately after creating the +subprocess, i.e., without waiting for the subprocess to terminate. +It returns four values: + +
+
+ +
+If the process exits or closes its standard output file descriptor, any +procedure that reads input from from-stdout will return an +end-of-file object. +Similarly, if the process exits or closes its standard error file +descriptor, any procedure that reads input from from-stderr will +return an end-of-file object. + +
+The predicate input-port-ready? +may be used to detect whether input has been sent by the subprocess to +Scheme. + +
+It is sometimes necessary to force output to be sent immediately +to the subprocess by invoking flush-output-port on +to-stdin, since Chez Scheme buffers the output for efficiency. + +
+On UNIX systems, the process-id is the process identifier +for the shell created to execute command. +If command is used to invoke an executable file rather than +a shell command, it may be useful to prepend command with +the string "exec ", which causes the shell to load and execute +the named executable directly, without forking a new +process---the shell equivalent of a tail call. +This will reduce by one the number of subprocesses created and +cause process-id to reflect the process identifier for the +executable once the shell has transferred control. + + +
+procedure: (process command)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
command must be a string. + +
+process is similar to open-process-ports, but less +general. +It does not return a port from which the subprocess's standard error output +can be read, and it always creates textual ports. +It returns a list of three values rather than the four separate values +of open-process-ports. +The returned list contains, in order: from-stdout, +to-stdin, and process-id, which correspond to the second, +first, and fourth return values of open-process-ports. + + +
+ + +
+ +
+Chez Scheme's foreign-procedure interface allows a Scheme program +to invoke +procedures written in C or in languages that obey the same +calling conventions as C. +Two steps are necessary before foreign procedures can be invoked from Scheme. +First, the foreign procedure must be compiled and loaded, +either statically or dynamically, +as described in Section 4.7. +Then, access to the foreign procedure must be established in Scheme, +as described in this section. +Once access to a foreign procedure has been established it may be called as an +ordinary Scheme procedure. + +
+Since foreign procedures operate independently of the Scheme memory management +and exception handling system, great care must be taken when using them. +Although the foreign-procedure interface provides +type checking (at optimize levels less than 3) and +type conversion, the programmer must ensure that +the sharing of data between Scheme and foreign procedures is done safely by +specifying proper argument and result types. + +
+Scheme-callable wrappers for foreign procedures can also be created via +ftype-ref and function ftypes (Section 4.5). + + +
+syntax: (foreign-procedure conv ... entry-exp (param-type ...) res-type)
+
+returns: a procedure
+
+libraries: (chezscheme)
+
+
entry-exp must evaluate to a string representing a valid foreign +procedure entry point or an integer representing the address of the +foreign procedure. +The param-types and res-type must be symbols or +structured forms as described below. +When a foreign-procedure expression is evaluated, a Scheme procedure is +created that will invoke the foreign procedure specified by entry-exp. +When the procedure is called each argument is checked and converted according to +the specified param-type before it is passed to the foreign procedure. +The result of the foreign procedure call is converted as specified +by the res-type. +Multiple procedures may be created for the same foreign entry. + +
+Each conv adjusts the calling convention to be used. +A #f is allowed as conv to indicate the default calling convention +on the target machine (so the #f has no effect). +Three other conventions are currently supported under +Windows: __stdcall, __cdecl, and __com (32-bit only). +Since __cdecl is the default, specifying __cdecl is +equivalent to specifying #f or no convention. +Additionally, conv can be __collect_safe to indicate that garbage +collection is allowed concurrently with a call of the foreign procedure, or it +can be __varargs or (__varargs_after n) to indicate +that the procedure uses a convention that works with a variable number of arguments +after the first n (which may differ from the convention used for the +fixed-argument variant on some platforms and conventions). +__varargs is a shorthand for (__varargs_after 1). + +
+Use __stdcall to access most Windows API procedures. +Use __cdecl for Windows API varargs procedures, +for C library procedures, and for most other procedures. +Use __com to invoke COM interface methods; COM uses the +__stdcall convention but additionally performs the indirections +necessary to obtain the correct method from a COM instance. +The address of the COM instance must be passed as the first argument, +which should normally be declared as iptr. +For the __com interface only, entry-exp must evaluate +to the byte offset of the method in the COM vtable. +For example, + +
+ +
(foreign-procedure __com 12 (iptr double-float) integer-32) +
creates an interface to a COM method at offset 12 in the vtable +encapsulated within the COM instance passed as the first argument, +with the second argument being a double float and the return +value being an integer. + +
+Use __collect_safe to declare that garbage collection is +allowed concurrently with the foreign procedure. The +__collect_safe declaration allows concurrent collection by +deactivating the current thread (see fork-thread) when the +foreign procedure is called, and the thread is activated again when +the foreign procedure returns. The __collect_safe declaration +is useful, for example, when calling a blocking I/O call to allow +other Scheme threads to run normally. Refrain from passing collectable memory to a +__collect_safe foreign procedure, or use lock-object +to lock the memory in place; see also Sdeactivate_thread. The +__collect_safe declaration has no effect on a non-threaded +version of the system. + +
+For example, calling the C sleep function with the default +convention will block other Scheme threads from performing a garbage +collection, but adding the __collect_safe declaration avoids that +problem: + +
+ +
(define c-sleep
+
+ (foreign-procedure __collect_safe "sleep" (unsigned) unsigned))
+
+(c-sleep 10) ; sleeps for 10 seconds without blocking other threads
+
If a foreign procedure that is called with __collect_safe can +invoke callables, then each callable should also be declared with +__collect_safe so that the callable reactivates the thread. + + +
+Complete type checking and conversion is performed on the parameters +to a foreign procedure. +The types +scheme-object, +string, +wstring, +u8*, +u16*, +u32*, +utf-8, +utf-16, +utf-16le, +utf-16be, +utf-32, +utf-32le, +and +utf-32be, +must be used with caution, however, since they allow allocated +Scheme objects to be used in places the Scheme memory management system +cannot control. No problems will arise as long as such objects are not +retained in foreign variables or data structures while Scheme code is running, +and as long as they are not passed as arguments to a __collect_safe procedure, +since garbage collection can occur only while Scheme code is running +or when concurrent garbage collection is enabled. +Other parameter types are converted to equivalent foreign +representations and consequently they can be retained indefinitely in +foreign variables and data structures. + +
+For argument types string, wstring, +utf-8, +utf-16, +utf-16le, +utf-16be, +utf-32, +utf-32le, and +utf-32be, an argument is converted +to a fresh object that is passed to the foreign procedure. Since the +fresh object is not accessible for locking before the call, it can +never be treated correctly for a __collect_safe foreign +procedure, so those types are disallowed as argument types for +a __collect_safe foreign procedure. For analogous reasons, +those types are disallowed as the result of a __collect_safe +foreign callable. + +
+Following are the valid parameter types: + +
+
integer-8: Exact integers from -27 through +28 - 1 are valid. +Integers in the range 27 through 28 - 1 are treated as +two's complement representations of negative numbers, e.g., +#xff is treated as -1. +The argument is passed to C as an integer of the appropriate size +(usually signed char). + +
+
unsigned-8: Exact integers from -27 to +28 - 1 are valid. +Integers in the range -27 through -1 are treated as the +positive equivalents of their two's complement representation, +e.g., -1 is treated as #xff. +The argument is passed to C as an unsigned integer of the +appropriate size (usually unsigned char). + +
+
integer-16: Exact integers from -215 through +216 - 1 are valid. +Integers in the range 215 through 216 - 1 are treated as +two's complement representations of negative numbers, e.g., +#xffff is treated as -1. +The argument is passed to C as an integer of the appropriate size +(usually short). + +
+
unsigned-16: Exact integers from -215 to +216 - 1 are valid. +Integers in the range -215 through -1 are treated as the +positive equivalents of their two's complement representation, +e.g., -1 is treated as #xffff. +The argument is passed to C as an unsigned integer of the +appropriate size (usually unsigned short). + +
+
integer-32: Exact integers from -231 through +232 - 1 are valid. +Integers in the range 231 through 232 - 1 are treated as +two's complement representations of negative numbers, e.g., +#xffffffff is treated as -1. +The argument is passed to C as an integer of the appropriate size +(usually int). + +
+
unsigned-32: Exact integers from -231 to +232 - 1 are valid. +Integers in the range -231 through -1 are treated as the +positive equivalents of their two's complement representation, +e.g., -1 is treated as #xffffffff. +The argument is passed to C as an unsigned integer of the +appropriate size (usually unsigned int). + +
+
integer-64: Exact integers from -263 through +264 - 1 are valid. +Integers in the range 263 through 264 - 1 are treated as +two's complement representations of negative numbers. +The argument is passed to C as an integer of the appropriate +size (usually long long or, on many 64-bit platforms, +long). + +
+
unsigned-64: Exact integers from -263 through +264 - 1 are valid. +Integers in the range -263 through -1 are treated as the +positive equivalents of their two's complement representation, +The argument is passed to C as an integer of the appropriate +size (usually unsigned long long or, on many 64-bit +platforms, long). + +
+
double-float: Only Scheme flonums are valid---other +Scheme numeric types are not automatically converted. +The argument is passed to C as a double float. + +
+
single-float: Only Scheme flonums are valid---other +Scheme numeric types are not automatically converted. +The argument is passed to C as a single float. +Since Chez Scheme represents flonums in double-float format, the +parameter is first converted into single-float format. + +
+
short: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C short. + +
+
unsigned-short: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned short. + +
+
int: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C int. + +
+
unsigned: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned. + +
+
unsigned-int: This type is an alias unsigned. +fixed-size type above, depending on the size of a C unsigned. + +
+
long: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C long. + +
+
unsigned-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned long. + +
+
long-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of the nonstandard C type +long long. + +
+
unsigned-long-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of the nonstandard C type +unsigned long long. + +
+
ptrdiff_t: This type is an alias for the appropriate +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
size_t: This type is an alias for the appropriate unsigned +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
ssize_t: This type is an alias for the appropriate signed +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
iptr: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C pointer. + +
+
uptr: This type is an alias for the appropriate +(unsigned) fixed-size type above, depending on the size of a C pointer. + +
+
void*: This type is an alias for uptr. + +
+
fixnum: This type is equivalent to iptr, +except only values in the fixnum range are valid. +Transmission of fixnums is slightly faster than transmission of +iptr values, but the fixnum range is smaller, so some +iptr values do not have a fixnum representation. + +
+
boolean: Any Scheme object may be passed as a boolean. +#f is converted to 0; all other objects are converted to 1. +The argument is passed to C as an int. + +
+
char: Only Scheme characters with Unicode scalar values +in the range 0 through 255 are valid char parameters. +The character is converted to its Unicode scalar value, as with +char->integer, and passed to C as an unsigned char. + +
+
wchar_t: Only Scheme characters are valid wchar_t parameters. +Under Windows and any other system where wchar_t holds only +16-bit values rather than full Unicode scalar values, only characters with +16-bit Unicode scalar values are valid. +On systems where wchar_t is a full 32-bit value, any Scheme +character is valid. +The character is converted to its Unicode scalar value, as with +char->integer, and passed to C as a wchar_t. + +
+
wchar: This type is an alias for wchar_t. + +
+
double: This type is an alias for double-float. + +
+
float: This type is an alias for single-float. + +
+
scheme-object: The argument is passed directly to the +foreign procedure; no conversion or type checking is performed. +This form of parameter passing should be used with discretion. +Scheme objects should not be preserved in foreign variables or data structures +since the memory management system may relocate them between foreign procedure +calls. + +
+
ptr: This type is an alias for scheme-object. + +
+
u8*: The argument must be a Scheme bytevector or +#f. +For #f, the null pointer (0) is passed to the foreign procedure. +For a bytevector, a pointer to the first byte of the bytevector's data +is passed. +If the C routine to which the data is passed requires the input to be +null-terminated, a null (0) byte must be included explicitly in the +bytevector. +The bytevector should not be retained in foreign variables or data +structures, since the memory management system may relocate or discard +them between foreign procedure calls, and use their storage for some +other purpose. + +
+
u16*: Arguments of this type are treated just like +arguments of type u8*. +If the C routine to which the data is passed requires the input to be +null-terminated, two null (0) bytes must be included explicitly in the +bytevector, aligned on a 16-bit boundary. + +
+
u32*: Arguments of this type are treated just like +arguments of type u8*. +If the C routine to which the data is passed requires the input to be +null-terminated, four null (0) bytes must be included explicitly in the +bytevector, aligned on a 32-bit boundary. + +
+
utf-8: The argument must be a Scheme string or +#f. +For #f, the null pointer (0) is passed to the foreign procedure. +A string is converted into a bytevector, as if via string->utf8, +with an added null byte, and the address of the first byte of the +bytevector is passed to C. +The bytevector should not be retained in foreign variables or data +structures, since the memory management system may relocate or discard +them between foreign procedure calls and use their storage for some +other purpose. The utf-8 argument type is not allowed for a +__collect_safe foreign procedure. + +
+
utf-16: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf16 with endianness (native-endianness), and they are +extended by two null bytes rather than one. + +
+
utf-16le: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf16 with endianness little, and they are +extended by two null bytes rather than one. + +
+
utf-16be: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf16 with endianness big, and they are +extended by two null bytes rather than one. + +
+
utf-32: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf32 with endianness (native-endianness), and they are +extended by four null bytes rather than one. + +
+
utf-32le: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf32 with endianness little, and they are +extended by four null bytes rather than one. + +
+
utf-32be: Arguments of this type are treated like arguments +of type utf-8, except they are converted as if via +string->utf32 with endianness big, and they are +extended by four null bytes rather than one. + +
+
string: This type is an alias for utf-8. + +
+
wstring: This type is an alias for utf-16 +or utf-32 as +appropriate depending on the size of a C wchar_t. +For example, wstring is equivalent to utf-16 +under Windows running on Intel hardware. + +
+
(* ftype-name): This type allows a pointer to a foreign +type (ftype) to be passed. +The argument must be an ftype pointer of the type identified by +ftype-name, +and the actual argument is the address encapsulated in the +ftype pointer. +See Section 4.5 for a description of +foreign types. + +
+
(& ftype-name): This type allows a foreign +type (ftype) to be passed as a value, but represented +on the Scheme side as a pointer to the foreign-type data. +That is, a (& ftype-name) argument is represented on +the Scheme side the same as a (* ftype-name) argument, +but a (& ftype-name) argument is passed to the foreign procedure as the +content at the foreign pointer's address instead of as the +address. For example, if ftype-name identifies a struct type, +then (& ftype-name) passes a struct argument instead of +a struct-pointer argument. The ftype-name cannot refer to an array type. + +
+
The result types are similar to the parameter types with the addition of a +void type. +In general, the type conversions are the inverse of the parameter type +conversions. +No error checking is performed on return, since the system cannot determine +whether a foreign result is actually of the indicated type. +Particular caution should be exercised with the result types +scheme-object, +double-float, +double, +single-float, +float, +and the types that result in the construction of bytevectors or strings, +since invalid +return values may lead to invalid memory references as well as incorrect +computations. +Following are the valid result types: + +
+
void: The result of the foreign procedure call is +ignored and an unspecified Scheme object is returned. +void should be used when foreign procedures are called for effect only. + +
+
integer-8: The result is interpreted as a signed +8-bit integer and is converted to a Scheme exact integer. + +
+
unsigned-8: The result is interpreted as an unsigned +8-bit integer and is converted to a Scheme nonnegative exact integer. + +
+
integer-16: The result is interpreted as a signed +16-bit integer and is converted to a Scheme exact integer. + +
+
unsigned-16: The result is interpreted as an unsigned +16-bit integer and is converted to a Scheme nonnegative exact integer. + +
+
integer-32: The result is interpreted as a signed +32-bit integer and is converted to a Scheme exact integer. + +
+
unsigned-32: The result is interpreted as an unsigned +32-bit integer and is converted to a Scheme nonnegative exact integer. + +
+
integer-64: The result is interpreted as a signed +64-bit integer and is converted to a Scheme exact integer. + +
+
unsigned-64: The result is interpreted as an unsigned +64-bit integer and is converted to a Scheme nonnegative exact integer. + +
+
double-float: The result is interpreted as a double float +and is translated into a Chez Scheme flonum. + +
+
single-float: The result is interpreted as a single float +and is translated into a Chez Scheme flonum. +Since Chez Scheme represents flonums in double-float format, the +result is first converted into double-float format. + +
+
short: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C short. + +
+
unsigned-short: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned short. + +
+
int: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C int. + +
+
unsigned: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned. + +
+
unsigned-int: This type is an alias unsigned. +fixed-size type above, depending on the size of a C unsigned. + +
+
long: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C long. + +
+
unsigned-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C unsigned long. + +
+
long-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of the nonstandard C type +long long. + +
+
unsigned-long-long: This type is an alias for the appropriate +fixed-size type above, depending on the size of the nonstandard C type +unsigned long long. + +
+
ptrdiff_t: This type is an alias for the appropriate +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
size_t: This type is an alias for the appropriate unsigned +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
ssize_t: This type is an alias for the appropriate signed +fixed-size type above, depending on its definition in the host machine's +stddef.h include file. + +
+
iptr: This type is an alias for the appropriate +fixed-size type above, depending on the size of a C pointer. + +
+
uptr: This type is an alias for the appropriate +(unsigned) fixed-size type above, depending on the size of a C pointer. + +
+
void*: This type is an alias for uptr. + +
+
boolean: This type converts a C int return value +into a Scheme boolean. +0 is converted to #f; all other values are converted to #t. + +
+
char: This type converts a C unsigned char return value +into a Scheme character, as if via integer->char. + +
+
wchar_t: This type converts a C wchar_t return value +into a Scheme character, as if via integer->char. +The wchar_t value must be a valid Unicode scalar value. + +
+
wchar: This type is an alias for wchar_t. + +
+
double: This type is an alias for double-float. + +
+
float: This type is an alias for single-float. + +
+
scheme-object: The result is assumed to be a valid Scheme +object, and no conversion is performed. +This type is inherently dangerous, since an invalid Scheme object can corrupt +the memory management system with unpredictable (but always unpleasant) results. +Since Scheme objects are actually typed pointers, even integers cannot +safely be returned as type scheme-object unless they were created by +the Scheme system. + +
+
ptr: This type is an alias for scheme-object. + +
+
u8*: The result is interpreted as a pointer to a +null-terminated sequence of 8-bit unsigned integers (bytes). +If the result is a null pointer, #f is returned. +Otherwise, the sequence of bytes is stored in a freshly allocated +bytevector of the appropriate length, and the bytevector is returned to +Scheme. + +
+
u16*: The result is interpreted as a pointer to a +null-terminated sequence of 16-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of 16-bit integers is stored in a freshly allocated +bytevector of the appropriate length, and the bytevector is returned to +Scheme. +The null terminator must be a properly aligned 16-bit word, +i.e., two bytes of zero aligned on a 16-bit boundary. + +
+
u32*: The result is interpreted as a pointer to a +null-terminated sequence of 32-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of 16-bit integers is stored in a freshly allocated +bytevector of the appropriate length, and the bytevector is returned to +Scheme. +The null terminator must be a properly aligned 32-bit word, +i.e., four bytes of zero aligned on a 32-bit boundary. + +
+
utf-8: The result is interpreted as a pointer to a +null-terminated sequence of 8-bit unsigned character values. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of bytes is converted into a Scheme string, as if +via utf8->string, and the string is returned to Scheme. + +
+
utf-16: The result is interpreted as a pointer to a +null-terminated sequence of 16-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf16->string with endianness (native-endianness), +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
utf-16le: The result is interpreted as a pointer to a +null-terminated sequence of 16-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf16->string with endianness little, +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
utf-16be: The result is interpreted as a pointer to a +null-terminated sequence of 16-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf16->string with endianness big, +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
utf-32: The result is interpreted as a pointer to a +null-terminated sequence of 32-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf32->string with endianness (native-endianness), +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
utf-32le: The result is interpreted as a pointer to a +null-terminated sequence of 32-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf32->string with endianness little, +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
utf-32be: The result is interpreted as a pointer to a +null-terminated sequence of 32-bit unsigned integers. +If the result is a null pointer, #f is returned. +Otherwise, the sequence of integers is converted into a Scheme string, as if +via utf32->string with endianness big, +and the string is returned to Scheme. +A byte-order mark in the sequence of integers is treated as an ordinary +character value and does not affect the byte ordering. + +
+
string: This type is an alias for utf-8. + +
+
wstring: This type is an alias for utf-16 +or utf-32 as appropriate depending on the size of a C wchar_t. +For example, wstring is equivalent to utf-16 +under Windows running on Intel hardware. + +
+
(* ftype-name): The result is interpreted as the address of a foreign object +whose structure is described by the ftype identified by ftype-name, and a freshly allocated +ftype pointer encapsulating the address is returned. +See Section 4.5 for a description of +foreign types. + +
+
(& ftype-name): The result is interpreted as a foreign object +whose structure is described by the ftype identified by ftype-name, where the foreign +procedure returns a ftype-name result, but the caller +must provide an extra (* ftype-name) argument before +all other arguments to receive the result. An unspecified Scheme object +is returned when the foreign procedure is called, since the result +is instead written into storage referenced by the extra argument. + The ftype-name cannot refer to an array type. + +
+
Consider a C identity procedure: + +
int id(x) int x; { return x; } +
After a file containing this procedure has been compiled and loaded +(see Section 4.7) it can be accessed as follows: + +
+ +
(foreign-procedure "id"
+
+ (int) int) #<procedure>
+
+((foreign-procedure "id"
+
+ (int) int)
+
+ 1) 1
+
+(define int-id
+
+ (foreign-procedure "id"
+
+ (int) int))
+
+(int-id 1) 1
+
The "id" entry can also be interpreted as accepting and returning +a boolean: + +
+ +
(define bool-id
+
+ (foreign-procedure "id"
+
+ (boolean) boolean))
+
+(bool-id #f) #f
+
+(bool-id #t) #t
+
+(bool-id 1) #t
+
As the last example reveals, bool-id is actually a conversion procedure. +When a Scheme object is passed as type boolean it is converted to +0 or 1, and when it is returned it is converted to #f or #t. +As a result objects are converted to normalized boolean values. +The "id" entry can be used to create other conversion procedures by +varying the type specifications: + +
+ +
(define int->bool
+
+ (foreign-procedure "id"
+
+ (int) boolean))
+
+(int->bool 0) #f
+
+(int->bool 5) #t
+
+(map (foreign-procedure "id"
+
+ (boolean) int)
+
+ '(#t #f)) (1 0)
+
+(define void
+
+ (foreign-procedure "id"
+
+ (int) void))
+
+(void 10) unspecified
+
There are, of course, simpler and more efficient ways of accomplishing +these conversions directly in Scheme. + +
+A foreign entry is resolved when a +foreign-procedure expression +is evaluated, rather than either when the code is loaded or each time +the procedure is invoked. +Thus, the following definition is always valid since the +foreign-procedure expression is not immediately evaluated: + +
+ +
(define doit
+
+ (lambda ()
+
+ ((foreign-procedure "doit" () void))))
+
doit should not be invoked, however, before an entry for +"doit" has been provided. +Similarly, an entry for "doit" must exist before the following code +is evaluated: + +
+ +
(define doit
+
+ (foreign-procedure "doit" () void))
+
Although the second definition is more constraining on the load order +of foreign files, it is more efficient since the entry resolution need +be done only once. + +
+It is often useful to define a template to be used +in the creation of several foreign procedures with similar argument +types and return values. +For example, the following code creates two foreign procedures from +a single foreign procedure expression, by abstracting out the foreign +procedure name: + +
+ +
(define double->double
+
+ (lambda (proc-name)
+
+ (foreign-procedure proc-name
+
+ (double)
+
+ double)))
+
+
+(define log10 (double->double "log10"))
+
+(define gamma (double->double "gamma"))
+
Both "log10" and "gamma" must be available as foreign +entries (see Section 4.7) +before the corresponding definitions. +The use of foreign procedure templates can simplify the coding process +and reduce the amount of code generated when a large number of +foreign procedures are involved, e.g., when an entire library of +foreign procedures is imported into Scheme. + + +
+ +
+Section 4.2 describes the foreign-procedure +form, which permits Scheme code to invoke C or C-compatible foreign +procedures. +This section describes the foreign-callable form, which permits +C or C-compatible code to call Scheme procedures. +A more primitive mechanism for calling Scheme procedures from C is +described in Section 4.9. + +
+As when calling foreign procedures from Scheme, +great care must be taken when sharing data between Scheme and +foreign code that calls Scheme to avoid corrupting Scheme's memory +management system. + +
+A foreign-callable wrapper for a Scheme procedure can also be created by +passing the procedure to make-ftype-pointer with an appropriate +function ftype (Section 4.5). + + +
+syntax: (foreign-callable conv ... proc-exp (param-type ...) res-type)
+
+returns: a code object
+
+libraries: (chezscheme)
+
+
proc-exp must evaluate to a procedure, the Scheme procedure that +is to be invoked by foreign code. +The parameter and result types are as described for +foreign-procedure in Section 4.2, +except that the requirements and conversions are effectively reversed, +e.g., the conversions described for foreign-procedure +arguments are performed for foreign-callable return +values. +A (& ftype) argument to the callable refers to an address +that is valid only during the dynamic extent of the callback invocation. +A (& ftype) result type for a callable causes the Scheme +procedure to receive an extra (& ftype) argument before +all others; the Scheme procedure should write a result into the extra +argument, and the direct result of the Scheme procedure is ignored. +Type checking is performed for result values but not argument values, +since the parameter +values are provided by the foreign code and must be assumed to be +correct. + +
+Each conv adjusts the calling convention to be used. +foreign-callable supports the same conventions as +foreign-procedure with the exception of __com. +The __collect_safe convention for a callable activates a +calling thread if the thread is not already activated, and +the thread's activation state is reverted when the callable +returns. If a calling thread is not currently registered with +the Scheme system, then reverting the thread's activation state implies +destroying the thread's registration (see Sdestroy_thread). + + +
+The value produced by foreign-callable is a Scheme code object, +which contains some header information as well as code that performs +the call to the encapsulated Scheme procedure. +The code object may be converted into a foreign-callable address via +foreign-callable-entry-point, which returns an integer representing +the address of the entry point within the code object. +(The C-callable library function Sforeign_callable_entry_point, described in +Section 4.9, may be used to obtain the entry point +as well.) +This is an implicit pointer into an immobile Scheme object, so +it will not be relocated by the storage management system, but +it may be reclaimed if the code object becomes unreachable on the Scheme +side; lock the code object (using lock-object) +or otherwise retain it if the entry point is, for example, +registered as a callback and retained in the "C" side indefinitely. + + +
+The following code creates a foreign-callable code object, locks +the code object, and returns the entry point. + +
+ +
(let ([x (foreign-callable
+
+ (lambda (x y) (pretty-print (cons x (* y 2))))
+
+ (string integer-32)
+
+ void)])
+
+ (lock-object x)
+
+ (foreign-callable-entry-point x))
+
Unless the entry point is intended to be permanent, however, a pointer +to the code object returned by foreign-callable should be retained +(in which case locking is unnecessary, since the storage management system +will not move the code object as long as it remains reachable on the +Scheme side). + +
+Mixed use of foreign-callable and foreign-procedure +may result in nesting of foreign and Scheme calls, and this +results in some interesting considerations when continuations are +involved, directly or indirectly (as via the default exception handler). +See Section 4.4 for a discussion of the +interaction between foreign calls and continuations. + +
+The following example demonstrates how the "callback" functions +required by many windowing systems might be defined in Scheme with the +use of foreign-callable. +Assume that the following C code has been compiled and loaded +(see Section 4.7). + +
+ +
#include <stdio.h>
+
+
+typedef void (*CB)(char);
+
+
+CB callbacks[256];
+
+
+void cb_init(void) {
+
+ int i;
+
+
+ for (i = 0; i < 256; i += 1)
+
+ callbacks[i] = (CB)0;
+
+}
+
+
+void register_callback(char c, CB cb) {
+
+ callbacks[c] = cb;
+
+}
+
+
+void event_loop(void) {
+
+ CB f; char c;
+
+
+ for (;;) {
+
+ c = getchar();
+
+ if (c == EOF) break;
+
+ f = callbacks[c];
+
+ if (f != (CB)0) f(c);
+
+ }
+
+}
+
Interfaces to these functions may be defined in Scheme as follows. + +
+ +
(define cb-init
+
+ (foreign-procedure "cb_init" () void))
+
+(define register-callback
+
+ (foreign-procedure "register_callback" (char void*) void))
+
+(define event-loop
+
+ (foreign-procedure __collect_safe "event_loop" () void))
+
A callback for selected characters can then be defined. + +
+ +
(define callback
+
+ (lambda (p)
+
+ (let ([code (foreign-callable __collect_safe p (char) void)])
+
+ (lock-object code)
+
+ (foreign-callable-entry-point code))))
+
+(define ouch
+
+ (callback
+
+ (lambda (c)
+
+ (printf "Ouch! Hit by '~c'~%" c))))
+
+(define rats
+
+ (callback
+
+ (lambda (c)
+
+ (printf "Rats! Received '~c'~%" c))))
+
+
+(cb-init)
+
+(register-callback #\a ouch)
+
+(register-callback #\c rats)
+
+(register-callback #\e ouch)
+
This sets up the following interaction. + +
+ +
> (event-loop)
+
+a
+
+Ouch! Hit by 'a'
+
+b
+
+c
+
+Rats! Received 'c'
+
+d
+
+e
+
+Ouch! Hit by 'e'
+
The __collect_safe declarations in this example ensure that +other threads can continue working while event-loop +blocks waiting for input. +A more well-behaved version of the example would save each code object +returned by foreign-callable and unlock it when it is no longer +registered as a callback. + + +
+procedure: (foreign-callable-entry-point code)
+
+returns: the address of the foreign-callable entry point in code
+
+libraries: (chezscheme)
+
+
code should be a code object produced by foreign-callable. + + +
+procedure: (foreign-callable-code-object address)
+
+returns: the code object corresponding to the foreign-callable entry point address
+
+libraries: (chezscheme)
+
+
address must be an exact integer and should be the address of the +entry point of a code object produced by foreign-callable. + + +
+ +
+foreign-callable and foreign-procedure allow arbitrary +nesting of foreign and Scheme calls. +Because other languages do not support the fully general first-class +continuations of Scheme, the interaction between continuations and +nested calls among Scheme and foreign procedures is problematic. +Chez Scheme handles this interaction in a general manner by trapping +attempts to return to stale foreign contexts rather than by restricting +the use of continuations directly. +A foreign context is a foreign frame and return point corresponding to +a particular call from a foreign language, e.g., C, into Scheme. +A foreign context becomes stale after a normal return to the context or +after a return to some other foreign context beneath it on the control +stack. + +
+As a result of this treatment, Scheme continuations may be used to +throw control either upwards or downwards logically through any mix +of Scheme and foreign frames. +Furthermore, until some return to a foreign context is actually performed, +all return points remain valid. +In particular, this means that programs that use continuations +exclusively for nonlocal exits never attempt to return to a +stale foreign context. +(Nonlocal exits themselves are no problem and are implemented +by the C library function longjmp or the equivalent.) +Programs that use continuations more generally also function +properly as long as they never actually return to a stale foreign context, +even if control logically moves past stale foreign contexts via invocation +of continuations. + +
+One implication of this mechanism is that the C stack pointer is not +automatically restored to its base value when a continuation is used on +the Scheme side to perform a nonlocal exit. +If the program continues to run after the nonlocal exit, any further +build-up of the C stack will add to the existing build up, which might +result in a C stack overflow. +To avoid this situation, a program can arrange to set up a single C +call frame before obtaining the continuation and return to the C frame +after the nonlocal exit. +The procedure with-exit-proc below arranges to do this without +involving any C code. + +
+ +
(define with-exit-proc
+
+ (lambda (p)
+
+ (define th (lambda () (call/cc p)))
+
+ (define-ftype ->ptr (function () ptr))
+
+ (let ([fptr (make-ftype-pointer ->ptr th)])
+
+ (let ([v ((ftype-ref ->ptr () fptr))])
+
+ (unlock-object
+
+ (foreign-callable-code-object
+
+ (ftype-pointer-address fptr)))
+
+ v))))
+
with-exit-proc behaves like call/cc except it resets +the C stack when the continuation is invoked. +To do this, it creates an ftype-pointer representing a foreign-callable +entry point for th and creates a Scheme-callable procedure for +that entry point. +This creates a wrapper for th that involves a C call. +When a call to the wrapper returns, either by explicit invocation of the +continuation passed to p or by a normal return from p, +the C stack is reset to its original value. + +
+ +
+The procedures described in this section directly create and manipulate +foreign data, i.e., data that resides outside of the Scheme heap. +With the exception of foreign-alloc, foreign-sizeof, and foreign-alignof, +these procedures are inherently unsafe in the sense that they do not (and +cannot) check the validity of the addresses they are passed. +Improper use of these procedures can result in invalid memory references, +corrupted data, or system crashes. + +
+This section also describes a higher-level syntactic mechanism for +manipulating foreign data, including foreign structures, unions, +arrays, and bit fields. +The syntactic interface is safer than the procedural interface but +must still assume that the addresses it's given are appropriate for +the types of object being manipulated. + +
+procedure: (foreign-alloc n)
+
+returns: the address of a freshly allocated block of foreign data n bytes long
+
+libraries: (chezscheme)
+
+
n must be a positive fixnum. +The returned value is an exact integer and is guaranteed to be properly +aligned for any type of value according to the requirements of the +underlying hardware. +An exception is raised with condition type &assertion +if the block of foreign data cannot be allocated. + + +
+procedure: (foreign-free address)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure frees the block of storage to which address points. +address must be an exact integer in the range -2w-1 through +2w - 1, where w is the width in bits of a pointer, e.g., 64 for a +64-bit machine. +It should be an address returned by an earlier call to +foreign-alloc and not subsequently passed to +foreign-free. + +
+procedure: (foreign-ref type address offset)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
foreign-ref extracts the value of type type +from the memory location at offset bytes offset from +address. + +
+type must be a symbol identifying the type of value +to be extracted. +The following types have machine-dependent sizes and correspond to the +like-named C types: + +
+
+ +
+The types long-long and unsigned-long-long +correspond to the C types long long +and unsigned long long. +A value of type char is referenced as a single +byte and converted (as if via integer->char) +into a Scheme character. +A value of type wchar_t is converted (as if via +integer->char) into a Scheme character. +The value must be a valid Unicode scalar value. + +
+wchar is an alias for wchar_t. + +
+Several additional machine-dependent types are recognized: + +
+
+ +
+uptr is equivalent to void*; both are treated as +unsigned integers the size of a pointer. +iptr is treated as a signed integer the size of a pointer. +fixnum is treated as an iptr, but with a range limited +to the fixnum range. +boolean is treated as an int, with zero +converted to the Scheme value #f and all +other values converted to #t. + +
+Finally, several fixed-sized types are also supported: + +
+
+ +
+address must be an exact integer in the range -2w-1 through +2w - 1, where w is the width in bits of a pointer, e.g., 64 for a +64-bit machine. +offset must be an exact fixnum. +The sum of address and offset should address a readable block +of memory large enough to hold a value of type type, within a block +of storage previously returned by foreign-alloc and not +subsequently freed by foreign-free or within a block of storage +obtained via some other mechanism, e.g., a foreign call. +For multiple-byte values, the native endianness of the machine is assumed. + +
+procedure: (foreign-set! type address offset value)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
foreign-set! stores a representation of value as type +type offset bytes into the block of foreign data addressed by +address. + +
+type must be a symbol identifying the type of value +to be stored, one of those listed in the description of +foreign-ref above. +Scheme characters are converted to type char or wchar_t +as if via char->integer. +For type boolean, Scheme #f is converted to the +int 0, and any other Scheme object is converted to 1. + +
+address must be an exact integer in the range -2w-1 through +2w - 1, where w is the width in bits of a pointer, e.g., 64 for a +64-bit machine. +offset must be an exact fixnum. +The sum of address and offset should address a writable block +of memory large enough to hold a value of type type, within a block +of storage previously returned by foreign-alloc and not +subsequently freed by foreign-free or within a block of storage +obtained via some other mechanism, e.g., a foreign call. +value must be an appropriate value for type, e.g., +a floating-point number for the float types or an exact integer within +the appropriate range for the integer types. +For multiple-byte values, the native endianness of the machine is assumed. + +
+procedure: (foreign-sizeof type)
+
+returns: the size in bytes of type
+
+libraries: (chezscheme)
+
+
type must be one of the symbols listed in the description +of foreign-ref above. + + +
+procedure: (foreign-alignof type)
+
+returns: the alignment in bytes of type
+
+libraries: (chezscheme)
+
+
type must be one of the symbols listed in the description +of foreign-ref above. + + +
+
+syntax: (define-ftype ftype-name ftype)
+
syntax: (define-ftype (ftype-name ftype) ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A define-ftype form is a definition and can appear anywhere +other definitions can appear. +It establishes one or more foreign-type (ftype) bindings for the identifier +ftype-name or identifiers ftype-name ... +to the foreign type represented ftype or the foreign types +represented by ftype .... +Each ftype-name can be used to access foreign objects with the +declared shape, and each can be used in the formation of other ftypes. + +
+An ftype must take one of the following forms: + +
+ +
ftype-name
+
+(struct (field-name ftype) ...)
+
+(union (field-name ftype) ...)
+
+(array length ftype)
+
+(* ftype)
+
+(bits (field-name signedness bits) ...)
+
+(function conv ... (ftype ...) ftype)
+
+(packed ftype)
+
+(unpacked ftype)
+
+(endian endianness ftype)
+
where length is an exact nonnegative integer, +bits is an exact positive integer, +field-name is an identifier, +conv is #f or a string naming a valid convention +as described on page 4.2, +signedness is either signed or unsigned, and +endianness is one of native, swapped, big, or little. + +
+A restriction not reflected above is that +function ftypes cannot be used as the types of +field names or array elements. +That is, function ftypes are valid only at the +top level of an ftype, e.g,: + +
+ +
(define-ftype bvcopy_t (function (u8* u8* size_t) void)) +
or as the immediate sub-type of a pointer (*) ftype, as in the +following definitions, which are equivalent assuming the definition of +bvcopy_t above. + +
+ +
(define-ftype A
+
+ (struct
+
+ [x int]
+
+ [f (* (function (u8* u8* size_t) void))]))
+
+
+(define-ftype A
+
+ (struct
+
+ [x int]
+
+ [f (* bvcopy_t)]))
+
That is, a function cannot be embedded within a struct, union, +or array, but a pointer to a function can be so embedded. + +
+The following definitions establish ftype bindings for F, +A, and E. + +
+ +
(define-ftype F (function (wchar_t int) int))
+
+
+(define-ftype A (array 10 wchar_t))
+
+
+(define-ftype E
+
+ (struct
+
+ [a int]
+
+ [b double]
+
+ [c (array 25
+
+ (struct
+
+ [a short]
+
+ [_ long]
+
+ [b A]))]
+
+ [d (endian big
+
+ (union
+
+ [v1 unsigned-32]
+
+ [v2 (bits
+
+ [hi unsigned 12]
+
+ [lo unsigned 20])]))]
+
+ [e (* A)]
+
+ [f (* F)]))
+
The ftype F describes the type of a foreign function that +takes two arguments, a wide character and an integer, and returns an +integer. +The ftype A is simply an array of 10 wchar_t values, +and its size will be 10 times the size of a single wchar_t. +The ftype E is a structure with six fields: an integer +a, a double-float b, an array c, a +union d, a pointer e, and a pointer f. +The array c is an array of 25 structs, each of which +contains a short integer, a long integer, and a A array. +The size of the c array will be 25 times the size of a +single A array, plus 25 times the space needed to store +each of the short and long integers. +The union d is either a 32-bit unsigned integer or +a 32-bit unsigned integer split into high (12 bits) and low (20 bits) +components. +The fields of a union overlap so that writing to one effectively +overlaps the other. +Thus, one can use the d union type to split apart an +unsigned integer by writing the integer into v1 and reading +the pieces from hi and lo. +The pointer e points to an A array; it is not +itself an array, and its size is just the size of a single pointer. +Similarly, f points to a function, and its size is also +that of a single pointer. + +
+An underscore ( _ ) can be used as the field name for one or +more fields of a struct, union, or bits ftype. +Such fields are included in the layout but are considered unnamed and +cannot be accessed via the ftype operators described below. +Thus, in the example above, the long field within the +c array is inaccessible. + +
+Non-underscore field names are handled symbolically, i.e., +they are treated as symbols rather than identifiers. +Each symbol must be unique (as a symbol) with respect to the other +field names within a single struct, union, +or bits ftype but need not be +unique with respect to field names in other struct, +union, or bits ftypes within the same +ftype. + +
+Each ftype-name in an ftype must either +(a) have been defined previously by define-ftype, +(b) be defined by the current define-ftype, +or +(c) be a base-type name, i.e., one of the type names supported by +foreign-ref and foreign-set!. +In case (b), any reference within one ftype to the +ftype-name of one of the earlier bindings is permissible, +but a reference to the ftype-name of the current or a +subsequent binding can appear only within a pointer field. + +
+For example, in: + +
+ +
(define-ftype
+
+ [Qlist (struct
+
+ [head int]
+
+ [tail (* Qlist)])])
+
the reference to Qlist is permissible since it appears +within a pointer field. +Similarly, in: + +
+ +
(define-ftype
+
+ [Qfrob (struct
+
+ [head int]
+
+ [tail (* Qsnark)])]
+
+ [Qsnark (struct
+
+ [head int]
+
+ [xtra Qfrob]
+
+ [tail (* Qfrob)])])
+
the mutually recursive references to Qsnark and Qfrob +are permissible. +In the following, however: + +
+ +
(define-ftype
+
+ [Qfrob (struct
+
+ [head int]
+
+ [xtra Qfrob]
+
+ [tail (* Qsnark)])]
+
+ [Qsnark (struct
+
+ [head int]
+
+ [tail (* Qfrob)])])
+
the reference to Qfrob within the ftype for Qfrob +is invalid, and in: + +
+ +
(define-ftype
+
+ [Qfrob (struct
+
+ [head int]
+
+ [xtra Qsnark]
+
+ [tail (* Qsnark)])]
+
+ [Qsnark (struct
+
+ [head int]
+
+ [tail (* Qfrob)])])
+
the reference to Qsnark is similarly invalid. + +
+By default, padding is inserted where appropriate to maintain +proper alignment of multiple-byte scalar values in an attempt to +mirror the target machine's C struct layout conventions, where +such layouts are adequately documented. +For packed ftypes (ftypes wrapped in a packed form with +no closer enclosing unpacked form), this padding is not +inserted. + +
+Multiple-byte scalar values are stored in memory using the +target machine's native "endianness," e.g., little +on X86 and X86_64-based platforms and big on +Sparc-based platforms. +Big-endian or little-endian representation can be forced via +the endian ftype with a big or little +endianness specifier. +The native specifier can be used to force a return +back to native representation. +The swapped specifier can be used to swap the +representation relative to the default or enclosing representation. +Each endian form affects only ftypes nested syntactically +within it and not nested within a closer endian form. +The endianness of an ftype is fixed once it is defined. + +
+The total size n of the fields within an ftype bits form must +be 8, 16, 24, 32, 40, 48, 56, or 64. Padding must be added manually, if needed. +In little-endian representation, the first field occupies +the low-order bits of the containing 8, 16, 24, 32, 40, 48, 56, or 64-bit word, +with each subsequent field just above the preceding field. +In big-endian representation, the first field occupies the +high-order bits, with each subsequent field just below the +preceding field. For a machine type where endianness is not +known at compile time (such as the portable bytecode +virtual machine), a bit field must be specified explicitly +as big or little endian by an enclosing +declaration. + +
+Two ftypes are considered equivalent only if defined by the +same ftype binding. +If two ftype definitions look identical but appear in two +parts of the same program, the ftypes are not identical, +and attempts to access one using the name of the other via +the operators described below will fail with a run-time +exception. + +
+Array bounds must always be constant. +If an array's length cannot be known until run time, the array +can be placed at the end of the ftype (and any containing ftype) +and declared to have size zero, as illustrated by the example below. + +
+ +
(define-ftype Vec
+
+ (struct
+
+ [len int]
+
+ [data (array 0 double)]))
+
+(define make-Vec
+
+ (lambda (n)
+
+ (let ([fptr (make-ftype-pointer Vec
+
+ (foreign-alloc
+
+ (+ (ftype-sizeof Vec)
+
+ (* (ftype-sizeof double) n))))])
+
+ (ftype-set! Vec (len) fptr n)
+
+ fptr)))
+
+(define x (make-Vec 100))
+
+(/ (- (ftype-pointer-address (ftype-&ref Vec (data 10) x))
+
+ (ftype-pointer-address x) 10
+
+ (ftype-sizeof int))
+
+ (ftype-sizeof double))
+
+(foreign-free (ftype-pointer-address x))
+
No array bounds checks are performed for zero-length arrays. +Only one variable-sized array can appear +in a single foreign object, but one can work around this by +treating the object as multiple individual objects. + +
+To avoid specifying the constant length of an array in more than +one place, a macro that binds both a variable to the size as +well as an ftype name to the ftype can be used. +For example, + +
+ +
(define-syntax define-array
+
+ (syntax-rules ()
+
+ [(_ array-name type size-name size)
+
+ (begin
+
+ (define size-name size)
+
+ (define-ftype array-name
+
+ (array size type)))]))
+
+(define-array A int A-size 100)
+
+A-size 100
+
+(ftype-pointer-ftype
+
+ (make-ftype-pointer A
+
+ (foreign-alloc (ftype-sizeof A)))) (array 100 int)
+
This technique can be used to define arbitrary ftypes with +arbitrary numbers of array fields. + +
+A struct ftype is an implicit subtype of the type of the first field +of the struct. +Similarly, an array ftype is an implicit subtype of the type of its +elements. +Thus, the struct or array extends the type of first field or element +with additional fields or elements. +This allows an instance of the struct or array to be treated as an instance +of the type of its first field or element, without the need to use +ftype-&ref to allocate a new pointer to the field or element. + + +
+syntax: (ftype-sizeof ftype-name)
+
+returns: the size in bytes of the ftype identified by ftype-name
+
+libraries: (chezscheme)
+
+
The size includes the sizes of any ftypes directly embedded within the +identified ftype but excludes those indirectly embedded via a pointer +ftype. +In the latter case, the size of the pointer is included. + +
+ftype-name must not be defined as a function ftype, since the size +of a function cannot generally be determined. + +
+ +
(define-ftype B
+
+ (struct
+
+ [b1 integer-32]
+
+ [b2 (array 10 integer-32)]))
+
+(ftype-sizeof B) 44
+
+
+(define-ftype C (* B))
+
+(ftype-sizeof C) 4 ; on 32-bit machines
+
+(ftype-sizeof C) 8 ; on 64-bit machines
+
+
+(define-ftype BB
+
+ (struct
+
+ [bb1 B]
+
+ [bb2 (* B)]))
+
+(- (ftype-sizeof BB) (ftype-sizeof void*)) 44
+
+syntax: (make-ftype-pointer ftype-name expr)
+
+returns: an ftype-pointer object
+
+libraries: (chezscheme)
+
+
If ftype-name does not describe a function ftype, expr +must evaluate to an address represented as an exact integer in +the appropriate range for the target machine. + +
+The ftype-pointer object returned by this procedure encapsulates the +address and is tagged with a representation of the type identified by +ftype-name to enable various forms of checking to be done by the +access routines described below. + +
+ +
(make-ftype-pointer E #x80000000) #<ftype-pointer #x80000000> +
The address will not typically be a constant, as shown. +Instead, it might instead come from a call to foreign-alloc, e.g.: + +
+ +
(make-ftype-pointer E (foreign-alloc (ftype-sizeof E))) +
It might also come from source outside of Scheme such as from a C +routine called from Scheme via the foreign-procedure interface. + +
+If ftype-name describes a function ftype, +expr must evaluate to an address, procedure, or string. +If it evaluates to address, the call behaves like any other call to +make-ftype-pointer with an address argument. + +
+If it evaluates to a procedure, a foreign-callable code object is +created for the procedure, as if via +foreign-callable +(Section 4.3). +The address encapsulated in the resulting ftype-pointer object is the +address of the procedure's entry point. + +
+ +
(define fact
+
+ (lambda (n)
+
+ (if (= n 0) 1 (fact (- n 1)))))
+
+(define-ftype fact_t (function (int) int))
+
+(define fact-fptr (make-ftype-pointer fact_t fact))
+
The resulting ftype pointer can be passed to a C routine, +if the argument is declared to be a pointer to the same ftype, and +the C routine can invoke the function pointer it receives as it +would any other function pointer. +Thus, make-ftype-pointer with a function ftype is an alternative +to foreign-callable for creating C-callable wrappers for Scheme +procedures. + +
+Since the foreign-callable code object can be reclaimed by the garbage +collector if it is not otherwise referenced, the implicit foreign-callable's code object +is automatically locked, as if via lock-object, before it is +embedded in the ftype pointer. +The code object should be unlocked after its last use from C, +since locked objects take up space, cause fragmentation, and +increase the cost of collection. +Since the system cannot determine automatically when the last use +from C occurs, the program must explicitly unlock the code object, +which it can do by extracting the address from the ftype-pointer +converting the address (back) into a code object, and passing it +to unlock-object: + +
+ +
(unlock-object
+
+ (foreign-callable-code-object
+
+ (ftype-pointer-address fact-fptr)))
+
Even after the code object is unlocked, the code object will remain +immobile as long as a result of foreign-callable-code-object +is retained. However, if only the ftype pointer object is retained, +then the ftype pointer should not be used again unless +it is relocked, e.g., via: + +
+ +
(lock-object
+
+ (foreign-callable-code-object
+
+ (ftype-pointer-address fact-fptr)))
+
A program can determine whether an object is already locked via +the locked-object? predicate. + +
+A function ftype can be also used with +make-ftype-pointer to create an ftype-pointer to a C function, +either by providing the address of the C function or its name, represented +as a string. +For example, with the following definition of bvcopy_t, + +
+ +
(define-ftype bvcopy_t (function (u8* u8* size_t) void)) +
the two definitions of bvcopy-ftpr below are equivalent. + +
+ +
(define bvcopy-fptr (make-ftype-pointer bvcopy_t "memcpy"))
+
+(define bvcopy-fptr (make-ftype-pointer bvcopy_t (foreign-entry "memcpy")))
+
A library that defines memcpy must be loaded first via +load-shared-object, or memcpy must be registered +via one of the methods described in Section 4.7. + +
+syntax: (ftype-pointer? obj)
+
+returns: #t if obj is an ftype pointer, otherwise #f
+
syntax: (ftype-pointer? ftype-name obj)
+
+returns: #t if obj is an ftype-name, otherwise #f
+
+libraries: (chezscheme)
+
+
+
(define-ftype Widget1 (struct [x int] [y int]))
+
+(define-ftype Widget2 (struct [w Widget1] [b boolean]))
+
+
+(define x1 (make-ftype-pointer Widget1 #x80000000))
+
+(define x2 (make-ftype-pointer Widget2 #x80000000))
+
+
+(ftype-pointer? x1) #t
+
+(ftype-pointer? x2) #t
+
+
+(ftype-pointer? Widget1 x1) #t
+
+(ftype-pointer? Widget1 x2) #t
+
+
+(ftype-pointer? Widget2 x1) #f
+
+(ftype-pointer? Widget2 x2) #t
+
+
+(ftype-pointer? #x80000000) #f
+
+(ftype-pointer? Widget1 #x80000000) #f
+
procedure: (ftype-pointer-address fptr)
+
+returns: the address encapsulated within fptr
+
+libraries: (chezscheme)
+
+
fptr must be an ftype-pointer object. + +
+ +
(define x (make-ftype-pointer E #x80000000))
+
+(ftype-pointer-address x) #x80000000
+
syntax: (ftype-pointer=? fptr1 fptr2)
+
+returns: #t if fptr1 and fptr2 have the same address, otherwise #f
+
+libraries: (chezscheme)
+
+
fptr1 and fptr2 must be ftype-pointer objects. + +
+ftype-pointer=? might be defined as follows: + +
+ +
(define ftype-pointer=?
+
+ (lambda (fptr1 fptr2)
+
+ (= (ftype-pointer-address fptr1) (ftype-pointer-address fptr2))))
+
It is, however, guaranteed not to allocate bignums for the addresses +even if the addresses do not fit in fixnum range. + +
+syntax: (ftype-pointer-null? fptr)
+
+returns: #t if the address of fptr is 0, otherwise #f
+
+libraries: (chezscheme)
+
+
fptr must be an ftype-pointer object. + +
+ftype-pointer-null? might be defined as follows: + +
+ +
(define ftype-pointer-null?
+
+ (lambda (fptr)
+
+ (= (ftype-pointer-address fptr) 0)))
+
It is, however, guaranteed not to allocate a bignum for the address +even if the address does not fit in fixnum range. + +
+syntax: (ftype-&ref ftype-name (a ...) fptr-expr)
+
syntax: (ftype-&ref ftype-name (a ...) fptr-expr index)
+
+returns: an ftype-pointer object
+
+libraries: (chezscheme)
+
+
The ftype-pointer object returned by ftype-&ref +encapsulates the address of some object embedded directly or +indirectly within the foreign object pointed to by the value +of fptr-expr, offset by index, if present. +The value of fptr-expr must be +an ftype pointer (fptr) of the ftype identified by ftype-name, +and index must either be the identifier * or evaluate +to a fixnum, possibly negative. +The index is automatically scaled by the size of the ftype identified +by ftype-name, which allows the fptr to be treated as an array +of ftype-name objects and index as an index into that array. +An index of * or 0 is the same as no index. + +
+The sequence of accessors a ... must specify a +valid path through the identified ftype. +For struct, union, and bits ftypes, +an accessor must be a valid field name for the ftype, while for +pointer and array ftypes, an accessor must be the identifier +* or evaluate to a fixnum index. +For array ftypes, an index must be nonnegative, and for array ftypes +with nonzero length, an index must also be less than the length. + +
+The examples below assume the definitions of B and BB +shown above in the description of ftype-sizeof. +Fixed addresses are shown for illustrative purposes and are assumed +to be valid, although addresses are generally determined +at run time via foreign-alloc or some other mechanism. + +
+ +
(define x (make-ftype-pointer B #x80000000))
+
+(ftype-&ref B () x) #<ftype-pointer #x80000000>
+
+(let ([idx 1]) #<ftype-pointer #x8000002C>
+
+ (ftype-&ref B () x idx))
+
+(let ([idx -1]) #<ftype-pointer #x7FFFFFD4>
+
+ (ftype-&ref B () x idx))
+
+(ftype-&ref B (b1) x) #<ftype-pointer #x80000000>
+
+(ftype-&ref B (b2) x) #<ftype-pointer #x80000004>
+
+(ftype-&ref B (b2 5) x) #<ftype-pointer #x80000018>
+
+(let ([n 5]) (ftype-&ref B (b2 n) x)) #<ftype-pointer #x80000018>
+
+
+(ftype-&ref B (b1 b2) x) syntax error
+
+(ftype-&ref B (b2 15) x) run-time exception
+
+
+(define y (make-ftype-pointer BB #x90000000))
+
+(ftype-set! BB (bb2) y x)
+
+(ftype-&ref BB (bb1 b2) y) #<ftype-pointer #x90000004>
+
+(ftype-&ref BB (bb2 * b2) y) #<ftype-pointer #x80000004>
+
+(let ([idx 1]) #<ftype-pointer #x80000030>
+
+ (ftype-&ref BB (bb2 idx b2) y))
+
With no accessors and no index, as in the first use of ftype-&ref +above, the returned ftype-pointer might be eq? to +the input. +Otherwise, the ftype-pointer is freshly allocated. + +
+
+syntax: (ftype-set! ftype-name (a ...) fptr-expr val-expr)
+
syntax: (ftype-set! ftype-name (a ...) fptr-expr index val-expr)
+
+returns: unspecified
+
syntax: (ftype-ref ftype-name (a ...) fptr-expr)
+
syntax: (ftype-ref ftype-name (a ...) fptr-expr index)
+
+returns: an ftype-pointer object
+
+libraries: (chezscheme)
+
+
These forms are used to store values into or retrieve values from the +object pointed to by the value of fptr-expr, offset by +index, if present. +The value of fptr-expr must be +an ftype pointer (fptr) of the ftype identified by ftype-name, +and index must either be the identifier * or evaluate +to a fixnum, possibly negative. +The index is automatically scaled by the size of the ftype identified +by ftype-name, which allows the fptr to be treated as an array +of ftype-name objects and index as an index into that array. +An index of * or 0 is the same as no index. + +
+The sequence of accessors a ... must specify a +valid path through the identified ftype. +For struct, union, and bits ftypes, +an accessor must be a valid field name for the ftype, while for +pointer and array ftypes, an accessor must be the identifier +* or evaluate to a fixnum index. +For array ftypes, an index must be nonnegative, and for array ftypes +with nonzero length, an index must also be less than the length. +The field or element specified by the sequence of accessors must be a scalar +field, e.g., a pointer field or a field containing a base type +such as an int, char, or double. + +
+For ftype-set!, val-expr must evaluate to a value +of the appropriate type for the specified field, e.g., an ftype +pointer of the appropriate type or an appropriate base-type value. + +
+For both signed and unsigned integer fields, values in the range +-2w-1 through 2w - 1 are accepted, where w is the width in +bits of the integer field. +For signed integer fields, values in the range 2w-1 through 2w - 1 +are treated as two's complement representations of the corresponding +negative numbers. +For unsigned integer fields, values in the range -2w-1 through +-1 are similarly treated as two's complement representations of the +corresponding positive numbers. + +
+char and wchar_t (wchar) field values +are converted from (ftype-set!) or to (ftype-ref) +Scheme characters, as if with char->integer and +integer->char. +Characters stored by ftype-set! into a char +field must have Unicode scalar values in the range 0 through 255. +Under Windows and any other system where wchar_t +(wchar) is a 16-bit value, characters stored by +ftype-set! into a whar_t (wchar) +field must have Unicode scalar values in the range 0 through 216 - 1. +On systems where wchar_t is a 32-bit value, any +character can be stored in a wchar_t (wchar) +field. + +
+The examples below assume that B and C have been +defined as shown in the description of ftype-sizeof above. + +
+ +
(define b
+
+ (make-ftype-pointer B
+
+ (foreign-alloc
+
+ (* (ftype-sizeof B) 3))))
+
+(define c
+
+ (make-ftype-pointer C
+
+ (foreign-alloc (ftype-sizeof C))))
+
+
+(ftype-set! B (b1) b 5)
+
+(ftype-set! B (b1) b 1 6)
+
+(ftype-set! B (b1) c 5) exception: ftype mismatch
+
+(ftype-set! B (b2) b 0) exception: not a scalar
+
+(ftype-set! B (b2 -1) b 0) exception: invalid index
+
+(ftype-set! B (b2 0) b 50)
+
+(ftype-set! B (b2 4) b 55)
+
+(ftype-set! B (b2 10) b 55) exception: invalid index
+
+
+(ftype-set! C () c (ftype-&ref B () b 1))
+
+
+(= (ftype-pointer-address (ftype-ref C () c)) #t
+
+ (+ (ftype-pointer-address b) (ftype-sizeof B)))
+
+(= (ftype-pointer-address (ftype-&ref C (*) c)) #t
+
+ (+ (ftype-pointer-address b) (ftype-sizeof B)))
+
+(= (ftype-pointer-address (ftype-&ref C (-1) c)) #t
+
+ (ftype-pointer-address b))
+
+
+(ftype-ref C (-1 b1) c) 5
+
+(ftype-ref C (* b1) c) 6
+
+(ftype-ref C (-1 b2 0) c) 50
+
+(let ([i 4]) (ftype-ref C (-1 b2 i) c)) 55
+
+
+(ftype-set! C (-1 b2 0) c 75)
+
+(ftype-ref B (b2 0) b) 75
+
+(foreign-free (ftype-pointer-address c))
+
+(foreign-free (ftype-pointer-address b))
+
A function ftype pointer can be converted into +a Scheme-callable procedure via ftype-ref. +Assuming that a library defining memcpy has been loaded via +load-shared-object or memcpy has been registered +via one of the methods described in Section 4.7, +A Scheme-callable memcpy can be defined as follows. + +
+ +
(define-ftype bvcopy_t (function (u8* u8* size_t) void))
+
+(define bvcopy-fptr (make-ftype-pointer bvcopy_t "memcpy"))
+
+(define bvcopy (ftype-ref bvcopy_t () bvcopy-fptr))
+
+
+(define bv1 (make-bytevector 8 0))
+
+(define bv2 (make-bytevector 8 57))
+
+bv1 #vu8(0 0 0 0 0 0 0 0)
+
+bv2 #vu8(57 57 57 57 57 57 57 57)
+
+(bvcopy bv1 bv2 5)
+
+bv1 #vu8(57 57 57 57 57 0 0 0)
+
An ftype pointer can also be obtained as a return value from a +C function declared to return a pointer to a function ftype. + +
+Thus, ftype-ref with a function ftype is an alternative to +foreign-procedure +(Section 4.2) +for creating Scheme-callable wrappers for +C functions. + +
+procedure: (ftype-pointer-ftype fptr)
+
+returns: fptr's ftype, represented as an s-expression
+
+libraries: (chezscheme)
+
+
fptr must be an ftype-pointer object. + +
+ +
(define-ftype Q0
+
+ (struct
+
+ [x int]
+
+ [y int]))
+
+(define-ftype Q1
+
+ (struct
+
+ [x double]
+
+ [y char]
+
+ [z (endian big
+
+ (bits
+
+ [_ unsigned 3]
+
+ [a unsigned 9]
+
+ [b unsigned 4]))]
+
+ [w (* Q0)]))
+
+(define q1 (make-ftype-pointer Q1 0))
+
+(ftype-pointer-ftype q1) (struct
+
+ [x double]
+
+ [y char]
+
+ [z (endian big
+
+ (bits
+
+ [_ unsigned 3]
+
+ [a unsigned 9]
+
+ [b unsigned 4]))]
+
+ [w (* Q0)])
+
procedure: (ftype-pointer->sexpr fptr)
+
+returns: an s-expression representation of the object to which fptr points
+
+libraries: (chezscheme)
+
+
fptr must be an ftype-pointer object. + +
+For each unnamed field, i.e., each whose field name is an underscore, the +corresponding field value in the resulting s-expression is also an underscore. +Similarly, if a field is inaccessible, i.e., if its address is invalid, the +value is the symbol invalid. + +
+ +
(define-ftype Frob
+
+ (struct
+
+ [p boolean]
+
+ [q char]))
+
+(define-ftype Snurk
+
+ (struct
+
+ [a Frob]
+
+ [b (* Frob)]
+
+ [c (* Frob)]
+
+ [d (bits
+
+ [_ unsigned 15]
+
+ [dx signed 17])]
+
+ [e (array 5 double)]))
+
+(define x
+
+ (make-ftype-pointer Snurk
+
+ (foreign-alloc (ftype-sizeof Snurk))))
+
+(ftype-set! Snurk (b) x
+
+ (make-ftype-pointer Frob
+
+ (foreign-alloc (ftype-sizeof Frob))))
+
+(ftype-set! Snurk (c) x
+
+ (make-ftype-pointer Frob 0))
+
+(ftype-set! Snurk (a p) x #t)
+
+(ftype-set! Snurk (a q) x #\A)
+
+(ftype-set! Snurk (b * p) x #f)
+
+(ftype-set! Snurk (b * q) x #\B)
+
+(ftype-set! Snurk (d dx) x -2500)
+
+(do ([i 0 (fx+ i 1)])
+
+ ((fx= i 5))
+
+ (ftype-set! Snurk (e i) x (+ (* i 5.0) 3.0)))
+
+(ftype-pointer->sexpr x) (struct
+
+ [a (struct [p #t] [q #\A])]
+
+ [b (* (struct [p #f] [q #\B]))]
+
+ [c (* (struct [p invalid] [q invalid]))]
+
+ [d (bits [_ _] [dx -2500])]
+
+ [e (array 5 3.0 8.0 13.0 18.0 23.0)])
+
+
+When a bytevector value is passed in a foreign call as an argument of +type u8*, the foreign procedure receives a pointer to the +start of the bytevector's content. The function +object->reference-address returns that same address, but it +is valid only if the bytevector does not move. If the storage manager +later moves the bytevector in memory, then the address becomes +invalid. The bytevector can be locked with lock-object to +prevent the storage manage from relocating it, so that the content +address will remain valid, but then it must be explicitly unlocked +later with unlock-object. + +
+Having to explicitly lock and unlock objects can make interoperating +with foreign procedures difficult when the foreign procedure expects +an array of references (for example, as a char** argument). +It may seem that a vector of bytevectors could serve that +purpose, but although a Scheme vector is an array of references at +some level, a vector's reference to a bytevector does not point to the +start of the bytevector's content. + +
+A reference bytevector is a type of bytevector that can be used to +solve this problem by storing the addresses of the contents of +scheme objects using bytevector-reference-set!. +Reference bytevectors are recognized and treated +specially by the storage manager, so that the addresses contained in the +reference byte vector are both recognized as a reference to a scheme +object and updated appropriately if the storage manager moves that +object. A reference bytevector can refer to any type of Scheme object, +but the meaning of the address is specified for only three kinds of +object: The address for bytevectors and flvectors is the pointer to their +content, and the address for #f is 0. In addition, a +reference bytevector can +contain foreign addresses, which are addresses of memory outside of +the storage manager's ranges, but beware that an address range +released by a foreign allocator might later become a range that +belongs to the Scheme storage manager. During the time that a garbage +collection is possible (i.e., when interrupts have not been disabled), +every aligned word (i.e. byte offset that is a multiple of +(ftype-sizeof uptr)) in a reference bytevector must hold a valid object +reference or a foreign address. + +
+While all of the procedures described in this section support unaligned +access (for consistency with other bytevector operations), use extreme +caution when using any byte offset other than an even multiple of the +current machine's pointer size (i.e., (ftype-sizeof uptr)). Some +procedures note cases in which behavior is undefined. Undefined behavior +may include invalid memory references, corrupted data, or system crashes. + +
+procedure: (make-reference-bytevector n)
+
+returns: a reference bytevector of length n
+
+libraries: (chezscheme)
+
+
Like make-bytevector, but the result is a reference +bytevector that is initialized with all bytes being 0 +(i.e., all referenced objects being #f and any trailing bytes +after an even multiple of the current machine's pointer size being 0). + +
+procedure: (make-immobile-reference-bytevector n)
+
+returns: a reference bytevector of length n
+
+libraries: (chezscheme)
+
+
Like make-reference-bytevector, but creates a reference +bytevector that will not be relocated in memory by the storage +management system until it is reclaimed. + +
+procedure: (reference-bytevector? obj)
+
+returns: #t if obj is an reference bytevector, #f otherwise
+
+libraries: (chezscheme)
+
+
Note that every reference bytevector is also a bytevector that is +recognized by bytevector?, and equal? considers two +bytevectors independent of whether either is a reference bytevector. + +
+procedure: (bytevector-reference-set! bytevector n obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
bytevector must be a reference bytevector, and n must +be a nonnegative fixnum. The sum of n and the size of a pointer +(i.e., (ftype-sizeof uptr)) must not be greater than the length of +bytevector. + +
+Installs a reference to obj at byte offset n within +bytevector. In the case that obj is a bytevector or +flvector, the reference is represented as the starting address of the +bytevector or flvector's content. If obj is #f then the +reference is represented as 0. The reference occupies +(ftype-sizeof uptr) bytes. + +
+procedure: (bytevector-reference-ref bytevector n)
+
+returns: a Scheme object
+
+libraries: (chezscheme)
+
+
bytevector must be a reference bytevector, and n must +be a nonnegative fixnum. The sum of n and the size of a pointer +(i.e., (ftype-sizeof uptr)) must not be greater than the length of +bytevector. + +
+Returns the object that is referenced in bytevector at byte offset +n. If the (ftype-sizeof uptr) bytes at offset n do +not represent a reference to a valid Scheme object then behavior is undefined. + +
+procedure: (bytevector-reference*-ref bytevector n)
+
+returns: an allocated Scheme object or a positive exact integer
+
+libraries: (chezscheme)
+
+
Like bytevector-reference-ref, but if bytevector at +byte offset n holds a non-0 foreign address, +bytevector-reference*-ref returns an integer. The +representation of a reference to a Scheme object can overlap with the +representation of a foreign address; see +reference*-address->object. + + +
+procedure: (object->reference-address obj)
+
+returns: a nonnegative exact integer
+
+libraries: (chezscheme)
+
+
The result is 0 if obj is #f, and it is the +address of objs's content in the case that obj is a +bytevector or flvector---at least, at the point where +object->reference-address was called. Unless obj is +a locked or immobile bytevector or flvector, its address can change at +any time that a garbage collection is possible (i.e., when interrupts +are enabled). For other kinds of objs, the representation of the +returned address is not specified, except that it is a nonnegative +exact integer that is distinct from any other object's representation. + +
+procedure: (reference-address->object addr)
+
+returns: a Scheme object
+
+libraries: (chezscheme)
+
+
addr must be a nonnegative exact integer that is a valid reference +to a Scheme object, and the result is the referenced Scheme object. If +addr is not a valid reference to a Scheme object then behavior is undefined. + +
+procedure: (reference*-address->object addr)
+
+returns: a Scheme object, possibly addr itself
+
+libraries: (chezscheme)
+
+
addr must be a nonnegative exact integer that is a valid +reference to a Scheme object, or it must be an foreign address that is +outside the range that belongs to the storage manager. + +
+When addr is 0, the result is #f. Otherwise, +if addr is a foreign address, then addr itself is +returned. + +
+The representation of a reference to a bytevector or flvector is +guaranteed to be distinct from any foreign address, but other values +may have a representation that overlaps with foreign addresses, in which case +addr is returned (i.e., the foreign-address interpretation takes +precedence). Thus, reference*-address->object +and bytevector-reference*-ref are mainly useful for an address +that is known to be either a bytevector reference, an flvector +reference, or a foreign address. + +
+If addr is not a foreign address and does not reference a valid +Scheme object then behavior is undefined. + + + +
+ +
+Access to foreign procedures can be provided in several ways: + +
+
+
+
+
+ + + +
+procedure: (foreign-entry? entry-name)
+
+returns: #t if entry-name is an existing foreign procedure entry
+point, #f otherwise
+
+libraries: (chezscheme)
+
+
entry-name must be a string. +foreign-entry? may be used to determine if an entry exists for a foreign +procedure. + +
+The following examples assume that +a library that defines strlen has been loaded via +load-shared-object or that strlen has been registered +via one of the other methods described in this section. + +
+ +
(foreign-entry? "strlen") #t
+
+((foreign-procedure "strlen"
+
+ (string) size_t)
+
+ "hey!") 4
+
procedure: (foreign-entry entry-name)
+
+returns: the address of entry-name as an exact integer
+
+libraries: (chezscheme)
+
+
entry-name must be a string naming an existing foreign entry point. + +
+The following examples assume that +a library that defines strlen has been loaded via +load-shared-object or that strlen has been registered +via one of the other methods described in this section. + +
+ +
(let ([addr (foreign-entry "strlen")])
+
+ (and (integer? addr) (exact? addr))) #t
+
+
+(define-ftype strlen-type (function (string) size_t))
+
+(define strlen
+
+ (ftype-ref strlen-type ()
+
+ (make-ftype-pointer strlen-type "strlen")))
+
+(strlen "hey!") 4
+
procedure: (foreign-address-name address)
+
+returns: the entry name corresponding to address, if known, otherwise #f
+
+libraries: (chezscheme)
+
+
The following examples assume that +a library that defines strlen has been loaded via +load-shared-object or that strlen has been registered +via one of the other methods described in this section. + +
+ +
(foreign-address-name (foreign-entry "strlen")) "strlen" +
procedure: (load-shared-object path)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +load-shared-object loads the shared object named by path. +Shared objects may be system libraries or files created from ordinary +C programs. +All external symbols in the shared object, along with external symbols +available in other shared objects linked with the shared object, +are made available as foreign entries. + +
+This procedure is supported for most platforms upon which Chez Scheme +runs. + +
+If path does not begin with a "." or "/", the shared +object is searched for in a default set of directories determined +by the system. + +
+On most Unix systems, load-shared-object is based on the +system routine dlopen. +Under Windows, load-shared-object is based on LoadLibrary. +Refer to the documentation for these routines and for the C compiler +and loader for precise rules for locating and building shared objects. + +
+load-shared-object can be used to access built-in C library +functions, such as getenv. +The name of the shared object varies from one system to another. +On Linux systems: + +
+ +
(load-shared-object "libc.so.6") +
On Solaris, OpenSolaris, FreeBSD, NetBSD, and OpenBSD systems: + +
+ +
(load-shared-object "libc.so") +
On MacOS X systems: + +
+ +
(load-shared-object "libc.dylib") +
On Windows: + +
+ +
(load-shared-object "msvcrt.dll") +
Once the C library has been loaded, getenv should be available +as a foreign entry. + +
+ +
(foreign-entry? "getenv") #t +
An equivalent Scheme procedure may be defined and +invoked as follows. + +
+ +
(define getenv
+
+ (foreign-procedure "getenv"
+
+ (string)
+
+ string))
+
+(getenv "HOME") "/home/elmer/fudd"
+
+(getenv "home") #f
+
load-shared-object can be used to access user-created +libraries as well. +Suppose the C file "even.c" +contains + +
+ +
int even(n) int n; { return n == 0 || odd(n - 1); } +
and the C file "odd.c" contains + +
+ +
int odd(n) int n; { return n != 0 && even(n - 1); } +
The files must be compiled and linked into a shared object before +they can be loaded. +How this is done depends upon the host system. +On Linux, FreeBSD, OpenBSD, and OpenSolaris systems: + +
+ +
(system "cc -fPIC -shared -o evenodd.so even.c odd.c") +
Depending on the host configuration, the -m32 or +-m64 option might be needed to specify 32-bit +or 64-bit compilation as appropriate. + +
+On MacOS X (Intel or PowerPC) systems: + +
+ +
(system "cc -dynamiclib -o evenodd.so even.c odd.c") +
Depending on the host configuration, the -m32 or +-m64 option might be needed to specify 32-bit +or 64-bit compilation as appropriate. + +
+On 32-bit Sparc Solaris: + +
+ +
(system "cc -KPIC -G -o evenodd.so even.c odd.c") +
On 64-bit Sparc Solaris: + +
+ +
(system "cc -xarch=v9 -KPIC -G -o evenodd.so even.c odd.c") +
On Windows, we build a DLL (dynamic link library) file. +In order to make the compiler generate the appropriate entry +points, we alter even.c to read + +
+ +
#ifdef WIN32
+
+#define EXPORT extern __declspec (dllexport)
+
+#else
+
+#define EXPORT extern
+
+#endif
+
+
+EXPORT int even(n) int n; { return n == 0 || odd(n - 1); }
+
and odd.c to read + +
+ +
#ifdef WIN32
+
+#define EXPORT extern __declspec (dllexport)
+
+#else
+
+#define EXPORT extern
+
+#endif
+
+
+EXPORT int odd(n) int n; { return n != 0 && even(n - 1); }
+
We can then build the DLL as follows, giving +it the extension ".so" rather than ".dll" +for consistency with the other systems. + +
+ +
(system "cl -c -DWIN32 even.c")
+
+(system "cl -c -DWIN32 odd.c")
+
+(system "link -dll -out:evenodd.so even.obj odd.obj")
+
The resulting ".so" file can be loaded into Scheme and even and +odd made available as foreign procedures: + +
+ +
(load-shared-object "./evenodd.so")
+
+(let ([odd (foreign-procedure "odd"
+
+ (integer-32) boolean)]
+
+ [even (foreign-procedure "even"
+
+ (integer-32) boolean)])
+
+ (list (even 100) (odd 100))) (#t #f)
+
The filename is given as "./evenodd.so" rather than simply +"evenodd.so", because some systems look for shared libraries +in a standard set of system directories that does not include the +current directory. + + +
+procedure: (remove-foreign-entry entry-name)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
remove-foreign-entry blocks further access to the entry +specified by the string entry-name. +An exception is raised with condition type &assertion +if the entry does not exist. +Since access previously established by foreign-procedure is not affected, +remove-foreign-entry may be used to clean up after the desired interface +to a group of foreign procedures has been established. + +
+remove-foreign-entry can be used to remove entries registered using +Sforeign_symbol and Sregister_symbol but not +entries created as +a result of a call to load-shared-object. + + +
+ +
+Although the Chez Scheme foreign procedure interface is oriented primarily +toward procedures defined in C or available in C libraries, it +is possible to invoke procedures defined in other languages that follow C +calling conventions. +One source of difficulty may be the interpretation of names. +Since Unix-based C compilers often prepend an underscore to external +names, +the foreign interface attempts to interpret entry names in +a manner consistent with the host C compiler. +Occasionally, such as for assembly coded files, this entry +name interpretation may not be desired. +It can be prevented by prefixing the entry name with an "=" character. +For example, after loading an assembly file containing a procedure "foo" +one might have: + +
+ +
(foreign-entry? "foo") #f
+
+(foreign-entry? "=foo") #t
+
+
+Additional foreign interface support is provided via a set of +C +preprocessor macros and +C-callable library functions. +Some of these routines allow C programs to examine, +allocate, and alter Scheme objects. +Others permit C functions to call Scheme procedures via a +more primitive interface than that defined in +Section 4.3. +Still others permit the development of custom executable images +and use of the Scheme system as a subordinate program within +another program, e.g., for use as an extension language. + +
+C code that uses these routines must include the "scheme.h" +header file distributed with Chez Scheme and must be linked +(statically or dynamically) with the Chez Scheme kernel. +The header file contains definitions for the preprocessor macros and +extern declarations for the library functions. +The file is customized to the release of Chez Scheme and machine +type with which it is distributed; it +should be left unmodified to facilitate switching among Chez Scheme +releases, and the proper version of the header file should always be +used with C code compiled for use with a particular version of +Chez Scheme. +The version and machine type are defined in "scheme.h" +under the names VERSION and MACHINE_TYPE. + +
+The name of each routine begins with a capital S, e.g., +Sfixnump. +Many of the names are simple translations of the names of closely +related Scheme procedures, e.g., Sstring_to_symbol is the C +interface equivalent of string->symbol. +Most externally visible entries in the Chez Scheme executable that +are not documented here begin with capital S followed by an +underscore (S_); their use should be avoided. + +
+In addition to the various macros and external declarations given +in scheme.h, the header file also defines (typedefs) +several types used in the header file: + +
+
+
+
+
+
+ +
+These types may vary depending upon the platform, although ptr +is typically void *, iptr is typically long int, +and uptr is typically unsigned long int. + +
+Under Windows, defining SCHEME_IMPORT before including scheme.h +causes scheme.h to declare its entry points using +extern declspec (dllimport) rather than +extern declspec (dllexport) (the default). +Not defining SCHEME_IMPORT and instead defining SCHEME_STATIC +causes scheme.h to declare exports using just extern. +The static libraries distributed with Chez Scheme are built using +SCHEME_STATIC. + +
+The remainder of this section describes each of the C interface +routines in turn. +A declaration for each routine is given in ANSI C function prototype +notation to precisely specify the argument and result types. +Scheme objects have the C type ptr, which is defined in +"scheme.h". +Where appropriate, C values are accepted as arguments or returned as +values in place of Scheme objects. + +
+The preprocessor macros may evaluate their arguments more than once +(or not at all), so care should be taken to ensure that this does not +cause problems. + +
+ + + + + + + + + + + + +
+
Customization. The functions described here are used to initialize the Scheme system, +build the Scheme heap, and run the Scheme system from a separate +program. + +
+[func] char * Skernel_version(void)
+
+[func] void Sscheme_init(void (*abnormal_exit)(void))
+
+[func] void Sset_verbose(int v)
+
+[func] void Sregister_boot_file(const char *name)
+
+[func] void Sregister_boot_file_fd(const char *name, int fd)
+
+[func] void Sregister_boot_file_fd_segment(const char *name, int fd, iptr offset, iptr len, int close_after)
+
+[func] void Sbuild_heap(const char *exec, void (*custom_init)(void))
+
+[func] void Senable_expeditor(const char *history_file)
+
+[func] void Sretain_static_relocation(void)
+
+[func] int Sscheme_start(int argc, char *argv[])
+
+[func] int Sscheme_script(char *scriptfile, int argc, char *argv[])
+
+[func] int Sscheme_program(char *programfile, int argc, char *argv[])
+
+[func] void Scompact_heap(void)
+
+[func] void Sscheme_deinit(void)
+
+
+
+Skernel_version returns a string representing the Scheme +version. +It should be compared against the value of the VERSION preprocessor +macro before any of the initialization functions listed above are +used to verify that the correct "scheme.h" header file has +been used. + +
+Sscheme_init causes the Scheme system to +initialize its static memory in preparation for boot file +registration. +The abnormal_exit parameter should be a (possibly null) +pointer to a C function +of no arguments that takes appropriate action if the initialization or +subsequent heap-building process fails. +If null, the default action is to call exit(1). + +
+Sset_verbose sets verbose mode on for nonzero +values of v and off when v is zero. +In verbose mode, the system displays a trace of the search process +for subsequently registered boot files. + +
+Sregister_boot_file searches for +the named boot file and +register it for loading, while Sregister_boot_file_fd +provides a specific boot file as a file descriptor. +When only a boot file name is provided, the file is opened but not loaded until the heap is built via +Sbuild_heap. When a file descriptor is provided, the given file name +is used only for error reporting. +For the first boot file registered only, the system also +searches for the boot files upon which the named file +depends, either directly or indirectly. + +
+The Sregister_boot_file_fd_region function is an alternative +to Sregister_boot_file_fd that allows the same file +descriptor to be used for multiple boot files using different offsets +into the file. The len argument is used as a hint, but it can be +0 to mean that the size is unknown, or it can be larger than the +actual boot content; it must not be non-0 and smaller than the boot +content, and the boot content must be self-terminating independent +of len. No search is performed for dependencies. If the same file +descriptor is used for multiple boot files, then +close_after should be non-zero only for the last +one. The boot file content is read only when Sbuild_heap is +called. + +
+Sbuild_heap creates the Scheme heap from the registered boot +files. +exec is assumed to be the name of or path to the executable +image and is used when no boot files have been registered as +the base name for the boot-file search process. +exec may be null only if one or more boot files have +been registered. +custom_init must be a (possibly null) pointer to +a C function of no arguments; if non-null, it is called before any boot +files are loaded. + +
+Sscheme_start invokes the interactive startup procedure, i.e., +the value of the parameter scheme-start, with one Scheme +string argument for the first argc elements of argv, +not including argv[0]. +Sscheme_script similarly invokes the script startup +procedure, i.e., +the value of the parameter scheme-script, with one Scheme +string argument for scriptfile and the first argc elements +of argv, +not including argv[0]. +Sscheme_program similarly invokes the program startup +procedure, i.e., +the value of the parameter scheme-program, with one Scheme +string argument for programfile and the first argc elements +of argv, +not including argv[0]. + +
+Senable_expeditor enables the expression editor +(Section 2.2, Chapter 14), +which is disabled by default, +and determines the history file from which it restores and to +which it saves the history. +This procedure must be called after the heap is built, or +an error will result. +It must also be called before Sscheme_start in order +to be effective. +If the history_file argument is the null pointer, the +history is not restored or saved. +The preprocessor variable FEATURE_EXPEDITOR is defined +in scheme.h if support for the expression editor has +been compiled into the system. + +
+Sretain_static_relocation causes relocation information +to be retained for static generation code objects created by +heap compaction for the benefit of compute-size and +related procedures. + +
+Scompact_heap compacts the Scheme heap and places all objects +currently in the heap into a static generation. +Objects in the static generation are never collected. +That is, they are never moved during collection and the storage used +for them is never reclaimed even if they become inaccessible. +Scompact_heap is called implicitly after any boot files have been +loaded. + +
+Sscheme_deinit closes any open files, tears down the Scheme heap, +and puts the Scheme system in an uninitialized state. + + +
+
Predicates. The predicates described here correspond to the similarly named +Scheme predicates. +A trailing letter p, for "predicate," is used in place of +the question mark that customarily appears at the end of a Scheme +predicate name. +Each predicate accepts a single Scheme object and returns a boolean +(C integer) value. + +
+
+[macro] int Sfixnump(ptr obj)
+
+[macro] int Scharp(ptr obj)
+
+[macro] int Snullp(ptr obj)
+
+[macro] int Seof_objectp(ptr obj)
+
+[macro] int Sbwp_objectp(ptr obj)
+
+[macro] int Sbooleanp(ptr obj)
+
+[macro] int Spairp(ptr obj)
+
+[macro] int Ssymbolp(ptr obj)
+
+[macro] int Sprocedurep(ptr obj)
+
+[macro] int Sflonump(ptr obj)
+
+[macro] int Svectorp(ptr obj)
+
+[macro] int Sbytevectorp(ptr obj)
+
+[macro] int Sfxvectorp(ptr obj)
+
+[macro] int Sstringp(ptr obj)
+
+[macro] int Sbignump(ptr obj)
+
+[macro] int Sboxp(ptr obj)
+
+[macro] int Sinexactnump(ptr obj)
+
+[macro] int Sexactnump(ptr obj)
+
+[macro] int Sratnump(ptr obj)
+
+[macro] int Sinputportp(ptr obj)
+
+[macro] int Soutputportp(ptr obj)
+
+[macro] int Srecordp(ptr obj)
+
+
+
+
+
Accessors. Some of the accessors described here correspond to similarly named +Scheme procedures, while others are unique to this interface. +Sfixnum_value, Schar_value, Sboolean_value, +and Sflonum_value return the C equivalents of the given +Scheme value. + +
+
+[macro] iptr Sfixnum_value(ptr fixnum)
+
+[macro] uptr Schar_value(ptr character)
+
+[macro] int Sboolean_value(ptr obj)
+
+[macro] double Sflonum_value(ptr flonum)
+
+
+
+
+Sinteger_value and Sunsigned_value are similar to +Sfixnum_value, except they accept not only fixnum arguments +but bignum arguments in the range of C integer or unsigned values. +Sinteger_value and Sunsigned_value accept the same +range of Scheme integer values. +They differ only in the result type, and so allow differing +interpretations of negative and large unsigned values. + +
+
+[func] iptr Sinteger_value(ptr integer)
+
+[macro] uptr Sunsigned_value(ptr integer)
+
+
+
+
+Sinteger32_value, Sunsigned32_value, +Sinteger64_value, and Sunsigned64_value +accept signed or unsigned Scheme integers in the 32- +or 64-bit range and return integers of the appropriate +type for the machine type. + +
+
+[func] Sint32_t Sinteger32_value(ptr integer)
+
+[macro] Suint32_t Sunsigned32_value(ptr integer)
+
+[func] Sint64_t Sinteger64_value(ptr integer)
+
+[macro] Suint64_t Sunsigned64_value(ptr integer)
+
+
+
+
+The functions +Stry_integer_value, +Stry_integer32_value, and +Stry_integer64_value +also convert Scheme values to C integers. +Unlike the corresponding Sinteger_value functions, these functions do not raise exceptions. +Instead, they take additional result and reason arguments +and return 1 or 0 to indicate success or failure. +If integer can be converted to the requested type, these functions store +the value in result and return 1. +Otherwise, they return 0 without modifying result. +If integer cannot be converted to the requested type and +reason is not NULL, these functions store a +Scheme-style +format string in reason explaining why the conversion failed. +The corresponding functions for unsigned values are +Stry_unsigned_value, +Stry_unsigned32_value, and +Stry_unsigned64_value. + +
+
+[func] int Stry_integer_value(ptr integer, iptr* result, const char** reason)
+
+[func] int Stry_integer32_value(ptr integer, Sint32_t* result, const char** reason)
+
+[func] int Stry_integer64_value(ptr integer, Sint64_t* result, const char** reason)
+
+[func] int Stry_unsigned_value(ptr integer, uptr* result, const char** reason)
+
+[func] int Stry_unsigned32_value(ptr integer, Suint32_t* result, const char** reason)
+
+[func] int Stry_unsigned64_value(ptr integer, Suint64_t* result, const char** reason)
+
+
+
+
+Scar, Scdr, Ssymbol_to_string (corresponding +to symbol->string), and Sunbox are identical to their +Scheme counterparts. + +
+
+[macro] ptr Scar(ptr pair)
+
+[macro] ptr Scdr(ptr pair)
+
+[func] ptr Ssymbol_to_string(ptr sym)
+
+[macro] ptr Sunbox(ptr box)
+
+
+
+
+Sstring_length, Svector_length, +Sbytevector_length, and +Sfxvector_length each return a C integer representing the length +(in elements) of the object. + +
+
+[macro] iptr Sstring_length(ptr str)
+
+[macro] iptr Svector_length(ptr vec)
+
+[macro] iptr Sbytevector_length(ptr bytevec)
+
+[macro] iptr Sfxvector_length(ptr fxvec)
+
+
+
+
+Sstring_ref, Svector_ref, Sbytevector_u8_ref, +and Sfxvector_ref +correspond to their Scheme counterparts, except that the index arguments +are C integers, the return value for Sstring_ref is a C +character, and the return value for Sbytevector_u8_ref is an +octet (unsigned char). + +
+
+[macro] char Sstring_ref(ptr str, iptr i)
+
+[macro] ptr Svector_ref(ptr vec, iptr i)
+
+[macro] octet Sbytevector_u8_ref(ptr fxvec, iptr i)
+
+[macro] ptr Sfxvector_ref(ptr fxvec, iptr i)
+
+
+
+
+A Scheme bytevector is represented as a length field followed by a +sequence of octets (unsigned chars). +Sbytevector_data returns a pointer to the start of the sequence +of octets. +Extreme care should be taken to stop dereferencing the pointer returned by +Sbytevector_data or to lock the bytevector into memory (see +Slock_object below) before any Scheme code is executed, +whether by calling into Scheme or returning to a Scheme caller. +The storage manager may otherwise relocate or discard the object into which +the pointer points and may copy other data over the object. + +
+
+[macro] octet * Sbytevector_data(ptr bytevec)
+
+
+
+
+Srecord_type and Srecord_type_parent correspond to the +Scheme procedures record-rtd and record-type-parent. +Srecord_type_size returns the allocation size in bytes of an +instance of the record type. +The Srecord_uniform_ref accessor should be used only on +records whose fields are all Scheme values, which is a record +for which Srecord_type_uniformp composed with +Srecord_type returns true. + +
+
+[func] ptr Srecord_type(ptr rec)
+
+[func] ptr Srecord_type_parent(ptr rtd)
+
+[func] uptr Srecord_type_size(ptr rtd)
+
+[func] int Srecord_type_uniformp(ptr rtd)
+
+[macro] ptr Srecord_uniform_ref(ptr rec, iptr i)
+
+
+
+
+
Mutators. Changes to mutable objects that contain pointers, such as pairs and +vectors, must be tracked on behalf of the storage +manager, as described in one of the references [13]. +The operations described here perform this tracking automatically +where necessary. + +
+
+[func] void Sset_box(ptr box, ptr obj)
+
+[func] void Sset_car(ptr pair, ptr obj)
+
+[func] void Sset_cdr(ptr pair, ptr obj)
+
+[macro] void Sstring_set(ptr str, iptr i, char c)
+
+[func] void Svector_set(ptr vec, iptr i, ptr obj)
+
+[macro] void Sbytevector_u8_set(ptr bytevec, iptr i, octet n)
+
+[macro] void Sfxvector_set(ptr fxvec, iptr i, ptr fixnum)
+
+
+
+
+Some Scheme objects, such as procedures and numbers, +are not mutable, so no operators are provided for altering +the contents of those objects. + +
+
Constructors. The constructors described here create Scheme objects. +Some objects, such as fixnums and the empty list, are +represented as immediate values that do not require any heap +allocation; others, such as pairs and vectors, are represented +as pointers to heap allocated objects. + +
+Snil, Strue, Sfalse, Sbwp_object, +Seof_object, and +Svoid +construct constant immediate values representing +the empty list ( () ), the boolean values (#t and +#f), the broken-weak-pointer object (#!bwp), +the eof object (#!eof), and the void object. + +
+
+[macro] ptr Snil
+
+[macro] ptr Strue
+
+[macro] ptr Sfalse
+
+[macro] ptr Sbwp_object
+
+[macro] ptr Seof_object
+
+[macro] ptr Svoid
+
+
+
+
+Fixnums, characters, booleans, flonums, and strings may be created from +their C equivalents. + +
+
+[macro] ptr Sfixnum(iptr n)
+
+[macro] ptr Schar(char c)
+
+[macro] ptr Sboolean(int b)
+
+[func] ptr Sflonum(double x)
+
+[func] ptr Sstring(const char *s)
+
+[func] ptr Sstring_of_length(const char *s, iptr n)
+
+[func] ptr Sstring_utf8(const char *s, iptr n)
+;
+
+
+
+Sstring creates a Scheme copy of the C string s, while +Sstring_of_length creates a Scheme string of length n +and copies the first n bytes from s +into the new Scheme string. + +
+If the C string is encoded in UTF-8, use Sstring_utf8 +instead. Specify the number of bytes to convert as n or use -1 +to convert until the null terminator. + +
+It is possible to determine whether a C integer is within fixnum range +by comparing the fixnum value of a fixnum created from a C integer with +the C integer: + +
+ +
#define fixnum_rangep(x) (Sfixnum_value(Sfixnum(x)) == x) +
Sinteger and Sunsigned may be used to create Scheme +integers whether they are in fixnum range or not. + +
+
+[func] ptr Sinteger(iptr n)
+
+[func] ptr Sunsigned(uptr n)
+
+
+
+
+Sinteger and Sunsigned differ in their treatment of +negative C integer values as well as C unsigned integer values that would +appear negative if cast to integers. +Sinteger converts such values into negative Scheme values, +whereas Sunsigned converts such values into the appropriate +positive Scheme values. +For example, assuming a 32-bit, two's complement representation for +iptrs, Sinteger(-1) and Sinteger((iptr)0xffffffff) +both evaluate to the Scheme integer -1, whereas +Sunsigned(0xffffffff) and Sunsigned((uptr)-1) +both evaluate to the Scheme integer +#xffffffff (4294967295). + +
+Whichever routine is used, Sinteger_value and +Sunsigned_value always reproduce the corresponding C +input value, thus the following are all equivalent to x +if x is an iptr. + +
+ +
Sinteger_value(Sinteger(x))
+
+(iptr)Sunsigned_value(Sinteger(x))
+
+Sinteger_value(Sunsigned((uptr)x))
+
+(iptr)Sunsigned_value(Sunsigned((uptr)x))
+
Similarly, the following are all equivalent to x +if x is a uptr. + +
+ +
(uptr)Sinteger_value(Sinteger((iptr)x))
+
+Sunsigned_value(Sinteger((iptr)x))
+
+(uptr)Sinteger_value(Sunsigned(x))
+
+Sunsigned_value(Sunsigned(x))
+
Sinteger32, Sunsigned32, Sinteger64, +and Sunsigned64 are like the generic equivalents but +restrict their arguments to the 32- or 64-bit range. + +
+
+[func] ptr Sinteger32(Sint32_t n)
+
+[func] ptr Sunsigned32(Suint32_t n)
+
+[func] ptr Sinteger64(Sint64_t n)
+
+[func] ptr Sunsigned64(Suint64_t n)
+
+
+
+
+Scons and Sbox are identical to their Scheme +counterparts. + +
+
+[func] ptr Scons(ptr obj1, ptr obj2)
+
+[func] ptr Sbox(ptr obj)
+
+
+
+
+Sstring_to_symbol is similar to its Scheme counterpart, +string->symbol, except +that it takes a C string (character pointer) as input. + +
+
+[func] ptr Sstring_to_symbol(const char *s)
+
+
+
+
+Smake_string, Smake_vector, Smake_bytevector, +and Smake_fxvector are similar to their Scheme counterparts. + +
+
+[func] ptr Smake_string(iptr n, int c)
+
+[func] ptr Smake_vector(iptr n, ptr obj)
+
+[func] ptr Smake_bytevector(iptr n, int fill)
+
+[func] ptr Smake_fxvector(iptr n, ptr fixnum)
+
+
+
+
+Smake_uninitialized_string is similar to the one-argument +make-string. + +
+
+[func] ptr Smake_uninitialized_string(iptr n)
+
+
+
+
+
Windows-specific helper functions. The following helper functions are provided on Windows only. + +
+
+[func] char * Sgetenv(const char *name)
+
+
+
+
+Sgetenv returns the UTF-8-encoded value of UTF-8-encoded +environment variable name if found and NULL otherwise. Call +free on the returned value when it is no longer needed. + +
+
+[func] wchar_t * Sutf8_to_wide(const char *\s)
+
+[func] char * Swide_to_utf8(const wchar_t *\s)
+
+
+
+
+Sutf8_to_wide and Swide_to_utf8 convert between +UTF-8-encoded and UTF-16LE-encoded null-terminated strings. Call +free on the returned value when it is no longer needed. + +
+
Accessing top-level values. Top-level variable bindings may be accessed or assigned via +Stop_level_value and Sset_top_level_value. + +
+
+[func] ptr Stop_level_value(ptr sym)
+
+[func] void Sset_top_level_value(ptr sym, ptr obj)
+
+
+
+
+These procedures give fast access to the bindings in the original +interaction environment and do not reflect changes to the +interaction-environment parameter or top-level module imports. +To access the current interaction-environment binding for a symbol, it +is necessary to call the Scheme top-level-value and +set-top-level-value! procedures instead. + +
+
Locking Scheme objects. The storage manager periodically relocates objects in order to reclaim +storage and compact the heap. +This relocation is completely transparent to Scheme programs, since all +pointers to a relocated object are updated to refer to the new +location of the object. +The storage manager cannot, however, update Scheme pointers that reside +outside of the Scheme heap. + +
+As a general rule, all pointers from C variables or data structures +to Scheme objects should be discarded before entry (or reentry) into +Scheme. +That is, if a C procedure receives an object from Scheme or obtains it +via the mechanisms described in this section, all pointers to the +object should be considered invalid once the C procedure calls into +Scheme or returns back to Scheme. +Dereferencing an invalid pointer or passing it back to Scheme can +have disastrous effects, including unrecoverable memory faults. +The foregoing does not apply to immediate objects, e.g., fixnums, +characters, booleans, or the empty list. +It does apply to all heap-allocated objects, including pairs, vectors, +strings, all numbers other than fixnums, ports, procedures, and records. + +
+In practice, the best way to ensure that C code does not retain +pointers to Scheme objects is to immediately convert the Scheme objects +into C equivalents, if possible. +In certain cases, it is not possible to do so, yet retention of the +Scheme object is essential to the design of the C portions of the +program. +In these cases, the object may be locked via the library routine +Slock_object (or from Scheme, the equivalent procedure +lock-object). + +
+
+[func] void Slock_object(ptr obj)
+
+
+
+
+Locking an object prevents the storage manager from reclaiming or +relocating the object. +Locking should be used sparingly, as it introduces memory fragmentation +and increases storage management overhead. +Locking can also lead to accidental retention of storage if objects +are not unlocked. +Locking objects that have been made static via heap compaction +(see Scompact_heap above) +is unnecessary but harmless. + +
+Objects may be unlocked via Sunlock_object +(unlock-object). + +
+
+[func] void Sunlock_object(ptr obj)
+
+
+
+
+An object may be locked more than once by successive calls to +Slock_object or lock-object, in which case it must +be unlocked by an equal number of calls to +Sunlock_object or unlock-object before it is +truly unlocked. + +
+The function Slocked_objectp can be used to determine +if an object is locked. + +
+
+[func] int Slocked_objectp(ptr obj)
+
+
+
+
+When a foreign procedure call is made into Scheme, a return address +pointing into the Scheme code object associated with the foreign +procedure is passed implicitly to the C routine. +The system therefore locks the code object before calls are +made from C back into Scheme and unlocks it upon return from +Scheme. +This locking is performed automatically; user +code should never need to lock such code objects. + +
+An object contained within a locked object, such as an object in the car +of a locked pair, need not also be locked unless a separate C pointer +to the object exists. + +
+
Registering foreign entry points. Foreign entry points may be made visible to Scheme via +Sforeign_symbol or Sregister_symbol. + +
+
+[func] void Sforeign_symbol(const char *name, void *addr)
+
+[func] void Sregister_symbol(const char *name, void *addr)
+
+
+
+
+External entry points in object files or shared objects loaded as a +result of a call to load-shared-object are automatically +made visible by the system. +Once a foreign entry point is made visible, it may be named in a +foreign-procedure expression to create a Scheme-callable +version of the entry point. +Sforeign_symbol and Sregister_symbol allow +programs to register nonexternal +entry points, entry points in code linked statically with Chez Scheme, +and entry points into code loaded directly from C, i.e., without +load-shared-object. +Sforeign_symbol and Sregister_symbol differ only in +that Sforeign_symbol raises an exception when an attempt is made +to register an existing name, whereas Sregister_symbol +permits existing names to be redefined. + +
+
Obtaining Scheme entry points. Sforeign_callable_entry_point extracts the entry point from a code +object produced by foreign-callable, performing the same +operation as its Scheme counterpart, i.e., the Scheme procedure +foreign-callable-entry-point. + +
+
+[macro] (void (*) (void)) Sforeign_callable_entry_point(ptr code)
+
+
+
+
+This can be used to avoid converting the code object into an address +until just when it is needed, which may eliminate the need to lock +the code object in some circumstances, assuming that the code object +is not saved across any calls back into Scheme. + +
+The inverse translation can be made via Sforeign_callable_code_object. + +
+
+[macro] ptr Sforeign_callable_code_object((void (*addr)(void)))
+
+
+
+
+
Low-level support for calls into Scheme. Support for calling Scheme procedures from C is provided by the set of +routines documented below. +Calling a Scheme procedure that expects a small number of arguments +(0-3) involves the use of one of the following routines. + +
+
+[func] ptr Scall0(ptr procedure)
+
+[func] ptr Scall1(ptr procedure, ptr obj1)
+
+[func] ptr Scall2(ptr procedure, ptr obj1, ptr obj2)
+
+[func] ptr Scall3(ptr procedure, ptr obj1, ptr obj2, ptr obj3)
+
+
+
+
+In each case, +the first argument, procedure, should be a Scheme procedure. +The remaining arguments, which should be Scheme objects, are +passed to the procedure. +The tools described earlier in this section may be used to convert +C datatypes into their Scheme equivalents. +A program that automatically generates conversion code from +declarations that are similar to foreign-procedure expressions +is distributed with Chez Scheme. +It can be found in the Scheme library directory on most systems in the +file "foreign.ss". + +
+A Scheme procedure may be obtained in a number of ways. +For example, it may be received as an argument in a call +from Scheme into C, obtained via another call to Scheme, +extracted from a Scheme data structure, or obtained from the top-level +environment via Stop_level_value. + +
+A more general interface involving the following routines is available +for longer argument lists. + +
+
+[func] void Sinitframe(iptr n)
+
+[func] void Sput_arg(iptr i, ptr obj)
+
+[func] ptr Scall(ptr procedure, iptr n)
+
+
+
+
+A C procedure first calls Sinitframe with one argument, the +number of arguments to be passed to Scheme. +It then calls Sput_arg once for each argument (in any order), passing +Sput_arg the argument number (starting with 1) and +the argument. +Finally, it calls Scall to perform the call, passing it +the Scheme procedure and the number of arguments (the same number as +in the call to Sinitframe). +Programmers should ensure a Scheme call initiated via +Sinitframe is completed via Scall before any other +calls to Scheme are made and before a return to Scheme is attempted. +If for any reason the call is not completed after Sinitframe +has been called, it may not be possible to return to Scheme. + +
+The following examples serve to illustrate both the simpler and more +general interfaces. + +
+ +
/* a particularly silly way to multiply two floating-point numbers */
+
+double mul(double x, double y) {
+
+ ptr times = Stop_level_value(Sstring_to_symbol("*"));
+
+
+ return Sflonum_value(Scall2(times, Sflonum(x), Sflonum(y)));
+
+}
+
+
/* an equally silly way to call printf with five arguments */
+
+
+/* it is best to define interfaces such as the one below to handle
+
+ * calls into Scheme to prevent accidental attempts to nest frame
+
+ * creation and to help ensure that initiated calls are completed
+
+ * as discussed above. Specialized versions tailored to particular
+
+ * C argument types may be defined as well, with embedded conversions
+
+ * to Scheme objects. */
+
+ptr Scall5(ptr p, ptr x1, ptr x2, ptr x3, ptr x4, ptr x5) {
+
+ Sinitframe(5);
+
+ Sput_arg(1, x1);
+
+ Sput_arg(2, x2);
+
+ Sput_arg(3, x3);
+
+ Sput_arg(4, x4);
+
+ Sput_arg(5, x5);
+
+ Scall(p, 5);
+
+}
+
+
+static void dumpem(char *s, int a, double b, ptr c, char *d) {
+
+ printf(s, a, b, c, d);
+
+}
+
+
+static void foo(int x, double y, ptr z, char *s) {
+
+ ptr ois, sip, read, expr, eval, c_dumpem;
+
+ char *sexpr = "(foreign-procedure \"dumpem\" (string integer-32\
+
+ double-float scheme-object string) void)";
+
+
+ /* this series of statements is carefully crafted to avoid referencing
+
+ variables holding Scheme objects after calls into Scheme */
+
+ ois = Stop_level_value(Sstring_to_symbol("open-input-string"));
+
+ sip = Scall1(ois, Sstring(sexpr));
+
+ read = Stop_level_value(Sstring_to_symbol("read"));
+
+ expr = Scall1(read, sip);
+
+ eval = Stop_level_value(Sstring_to_symbol("eval"));
+
+ Sforeign_symbol("dumpem", (void *)dumpem);
+
+ c_dumpem = Scall1(eval, expr);
+
+ Scall5(c_dumpem,
+
+ Sstring("x = %d, y = %g, z = %x, s = %s\n"),
+
+ Sinteger(x),
+
+ Sflonum(y),
+
+ z,
+
+ Sstring(s));
+
+}
+
Calls from C to Scheme should not be made from C interrupt handlers. +When Scheme calls into C, the system saves the contents of certain +dedicated machine registers in a register save area. +When C then calls into Scheme, the registers are restored from the +register save area. +Because an interrupt can occur at any point in a computation, the +contents of the register save locations would typically contain invalid +information that would cause the Scheme system to fail to operate +properly. + +
+
Activating, deactivating, and destroying threads. Three functions are provided by the threaded versions of Scheme to +allow C code to notify Scheme when a thread should be activated, +deactivated, or destroyed. + +
+[func] int Sactivate_thread(void)
+
+[func] void Sdeactivate_thread(void)
+
+[func] int Sdestroy_thread(void)
+
+
+
+A thread created via the Scheme procedure fork-thread starts +in the active state and need not be activated. +Any thread that has been deactivated, and any +thread created by some mechanism other than fork-thread must, +however, be activated before it can access Scheme data or execute +Scheme code. A foreign callable that is declared with __collect_safe +can activate a calling thread. +Otherwise, Sactivate_thread must be used to activate a thread. +It returns 1 the first time the thread is activated and 0 on each +subsequent call until the activation is destroyed with Sdestroy_thread. + +
+Since active threads operating in C code prevent the storage management +system from garbage collecting, +a thread should be deactivated via Sdeactivate_thread or +through a foreign-procedure __collect_safe declaration whenever +the thread may spend a significant amount of time in C code. +This is especially important whenever the thread calls a C library +function, like read, that may block indefinitely. +Once deactivated, the thread must not touch any Scheme data or +execute any Scheme code until it is reactivated, with one exception. +The exception is that the thread may access or even modify a locked +Scheme object, such as a locked string, that contains no pointers to +other, unlocked Scheme objects. +(Objects that are not locked may be relocated by the garbage collector +while the thread is inactive.) + +
+Sdestroy_thread is used to notify the Scheme system that the +thread is shut down and any thread-specific data can be released. + +
+
Low-level synchronization primitives. The header file defines several preprocessor macros that can be +used to lock memory locations in a manner identical to the corresponding +ftype lock operations (sections 15.4 and +15.5). + +
+[macro] void INITLOCK(void *addr)
+
+[macro] void SPINLOCK(void *addr)
+
+[macro] void UNLOCK(void *addr)
+
+[macro] void LOCKED_INCR(void *addr, int *ret)
+
+[macro] void LOCKED_DECR(void *addr, int *ret)
+
+
+
+LOCKED_INCR and LOCKED_DECR set ret to a +nonzero (true) value if the incremented or decremented value is 0. +Otherwise they set ret to 0. + +
+ +
+This section presents a simple socket interface that +employs a combination of Scheme and C code. +The C code defines a set of convenient low-level operating-system +interfaces that can be used in the higher-level Scheme code to open, +close, read from, and write to sockets. + +
+The C code (csocket.c) is given below, followed by the Scheme code +(socket.ss). +The code should require little or no modification to run on most Unix +systems and can be modified to work under Windows (using the Windows +WinSock interface). + +
+A sample session demonstrating the socket interface follows the code. +See Section 9.17 for an example that demonstrates how +to use the same socket interface to build a process port that allows +transparent input from and output to a subprocess via a Scheme port. + +
+
C code. +
/* csocket.c */
+
+
+#include <sys/types.h>
+
+#include <sys/socket.h>
+
+#include <sys/un.h>
+
+#include <string.h>
+
+#include <errno.h>
+
+#include <signal.h>
+
+#include <sys/ioctl.h>
+
+#include <stdio.h>
+
+#include <unistd.h>
+
+
+/* c_write attempts to write the entire buffer, pushing through
+
+ interrupts, socket delays, and partial-buffer writes */
+
+int c_write(int fd, char *buf, ssize_t start, ssize_t n) {
+
+ ssize_t i, m;
+
+
+ buf += start;
+
+ m = n;
+
+ while (m > 0) {
+
+ if ((i = write(fd, buf, m)) < 0) {
+
+ if (errno != EAGAIN && errno != EINTR)
+
+ return i;
+
+ } else {
+
+ m -= i;
+
+ buf += i;
+
+ }
+
+ }
+
+ return n;
+
+}
+
+
+/* c_read pushes through interrupts and socket delays */
+
+int c_read(int fd, char *buf, size_t start, size_t n) {
+
+ int i;
+
+
+ buf += start;
+
+ for (;;) {
+
+ i = read(fd, buf, n);
+
+ if (i >= 0) return i;
+
+ if (errno != EAGAIN && errno != EINTR) return -1;
+
+ }
+
+}
+
+
+/* bytes_ready(fd) returns true if there are bytes available
+
+ to be read from the socket identified by fd */
+
+int bytes_ready(int fd) {
+
+ int n;
+
+
+ (void) ioctl(fd, FIONREAD, &n);
+
+ return n;
+
+}
+
+
+/* socket support */
+
+
+/* do_socket() creates a new AF_UNIX socket */
+
+int do_socket(void) {
+
+
+ return socket(AF_UNIX, SOCK_STREAM, 0);
+
+}
+
+
+/* do_bind(s, name) binds name to the socket s */
+
+int do_bind(int s, char *name) {
+
+ struct sockaddr_un sun;
+
+ int length;
+
+
+ sun.sun_family = AF_UNIX;
+
+ (void) strcpy(sun.sun_path, name);
+
+ length = sizeof(sun.sun_family) + sizeof(sun.sun_path);
+
+
+ return bind(s, (struct sockaddr*)(&sun), length);
+
+}
+
+
+/* do_accept accepts a connection on socket s */
+
+int do_accept(int s) {
+
+ struct sockaddr_un sun;
+
+ socklen_t length;
+
+
+ length = sizeof(sun.sun_family) + sizeof(sun.sun_path);
+
+
+ return accept(s, (struct sockaddr*)(&sun), &length);
+
+}
+
+
+/* do_connect initiates a socket connection */
+
+int do_connect(int s, char *name) {
+
+ struct sockaddr_un sun;
+
+ int length;
+
+
+ sun.sun_family = AF_UNIX;
+
+ (void) strcpy(sun.sun_path, name);
+
+ length = sizeof(sun.sun_family) + sizeof(sun.sun_path);
+
+
+ return connect(s, (struct sockaddr*)(&sun), length);
+
+}
+
+
+/* get_error returns the operating system's error status */
+
+char* get_error(void) {
+
+ extern int errno;
+
+ return strerror(errno);
+
+}
+
Scheme code. +
;;; socket.ss
+
+
+;;; Requires csocket.so, built from csocket.c.
+
+(load-shared-object "./csocket.so")
+
+
+;;; Requires from C library:
+
+;;; close, dup, execl, fork, kill, listen, tmpnam, unlink
+
+(case (machine-type)
+
+ [(i3le ti3le a6le ta6le) (load-shared-object "libc.so.6")]
+
+ [(i3osx ti3osx a6osx ta6osx) (load-shared-object "libc.dylib")]
+
+ [else (load-shared-object "libc.so")])
+
+
+;;; basic C-library stuff
+
+
+(define close
+
+ (foreign-procedure "close" (int)
+
+ int))
+
+
+(define dup
+
+ (foreign-procedure "dup" (int)
+
+ int))
+
+
+(define execl4
+
+ (let ((execl-help
+
+ (foreign-procedure "execl"
+
+ (string string string string void*)
+
+ int)))
+
+ (lambda (s1 s2 s3 s4)
+
+ (execl-help s1 s2 s3 s4 0))))
+
+
+(define fork
+
+ (foreign-procedure "fork" ()
+
+ int))
+
+
+(define kill
+
+ (foreign-procedure "kill" (int int)
+
+ int))
+
+
+(define listen
+
+ (foreign-procedure "listen" (int int)
+
+ int))
+
+
+(define tmpnam
+
+ (foreign-procedure "tmpnam" (void*)
+
+ string))
+
+
+(define unlink
+
+ (foreign-procedure "unlink" (string)
+
+ int))
+
+
+;;; routines defined in csocket.c
+
+
+(define accept
+
+ (foreign-procedure "do_accept" (int)
+
+ int))
+
+
+(define bytes-ready?
+
+ (foreign-procedure "bytes_ready" (int)
+
+ boolean))
+
+
+(define bind
+
+ (foreign-procedure "do_bind" (int string)
+
+ int))
+
+
+(define c-error
+
+ (foreign-procedure "get_error" ()
+
+ string))
+
+
+(define c-read
+
+ (foreign-procedure "c_read" (int u8* size_t size_t)
+
+ ssize_t))
+
+
+(define c-write
+
+ (foreign-procedure "c_write" (int u8* size_t ssize_t)
+
+ ssize_t))
+
+
+(define connect
+
+ (foreign-procedure "do_connect" (int string)
+
+ int))
+
+
+(define socket
+
+ (foreign-procedure "do_socket" ()
+
+ int))
+
+
+;;; higher-level routines
+
+
+(define dodup
+
+ ; (dodup old new) closes old and dups new, then checks to
+
+ ; make sure that resulting fd is the same as old
+
+ (lambda (old new)
+
+ (check 'close (close old))
+
+ (unless (= (dup new) old)
+
+ (error 'dodup
+
+ "couldn't set up child process io for fd ~s" old))))
+
+
+(define dofork
+
+ ; (dofork child parent) forks a child process and invokes child
+
+ ; without arguments and parent with the child's pid
+
+ (lambda (child parent)
+
+ (let ([pid (fork)])
+
+ (cond
+
+ [(= pid 0) (child)]
+
+ [(> pid 0) (parent pid)]
+
+ [else (error 'fork (c-error))]))))
+
+
+(define setup-server-socket
+
+ ; create a socket, bind it to name, and listen for connections
+
+ (lambda (name)
+
+ (let ([sock (check 'socket (socket))])
+
+ (unlink name)
+
+ (check 'bind (bind sock name))
+
+ (check 'listen (listen sock 1))
+
+ sock)))
+
+
+(define setup-client-socket
+
+ ; create a socket and attempt to connect to server
+
+ (lambda (name)
+
+ (let ([sock (check 'socket (socket))])
+
+ (check 'connect (connect sock name))
+
+ sock)))
+
+
+(define accept-socket
+
+ ; accept a connection
+
+ (lambda (sock)
+
+ (check 'accept (accept sock))))
+
+
+(define check
+
+ ; signal an error if status x is negative, using c-error to
+
+ ; obtain the operating-system's error message
+
+ (lambda (who x)
+
+ (if (< x 0)
+
+ (error who (c-error))
+
+ x)))
+
+
+(define terminate-process
+
+ ; kill the process identified by pid
+
+ (lambda (pid)
+
+ (define sigterm 15)
+
+ (kill pid sigterm)
+
+ (void)))
+
Sample session. +
> (define client-pid)
+
+> (define client-socket)
+
+> (let* ([server-socket-name (tmpnam 0)]
+
+ [server-socket (setup-server-socket server-socket-name)])
+
+ ; fork a child, use it to exec a client Scheme process, and set
+
+ ; up server-side client-pid and client-socket variables.
+
+ (dofork ; child
+
+ (lambda ()
+
+ ; the child establishes the socket input/output fds as
+
+ ; stdin and stdout, then starts a new Scheme session
+
+ (check 'close (close server-socket))
+
+ (let ([sock (setup-client-socket server-socket-name)])
+
+ (dodup 0 sock)
+
+ (dodup 1 sock))
+
+ (check 'execl (execl4 "/bin/sh" "/bin/sh" "-c" "exec scheme -q"))
+
+ (errorf 'client "returned!"))
+
+ (lambda (pid) ; parent
+
+ ; the parent waits for a connection from the client
+
+ (set! client-pid pid)
+
+ (set! client-socket (accept-socket server-socket))
+
+ (check 'close (close server-socket)))))
+
+> (define put ; procedure to send data to client
+
+ (lambda (x)
+
+ (let ([s (format "~s~%" x)])
+
+ (c-write client-socket s (string-length s)))
+
+ (void)))
+
+> (define get ; procedure to read data from client
+
+ (let ([buff (make-string 1024)])
+
+ (lambda ()
+
+ (let ([n (c-read client-socket buff (string-length buff))])
+
+ (printf "client:~%~a~%server:~%" (substring buff 0 n))))))
+
+> (get)
+
+server:
+
+> (put '(let ([x 3]) x))
+
+> (get)
+
+client:
+
+3
+
+server:
+
+> (terminate-process client-pid)
+
+> (exit)
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/gifs/ghostRightarrow.gif b/csug10.0/gifs/ghostRightarrow.gif
new file mode 100644
index 000000000..18271f802
Binary files /dev/null and b/csug10.0/gifs/ghostRightarrow.gif differ
diff --git a/csug10.0/index.html b/csug10.0/index.html
new file mode 120000
index 000000000..9c515ad15
--- /dev/null
+++ b/csug10.0/index.html
@@ -0,0 +1 @@
+csug.html
\ No newline at end of file
diff --git a/csug10.0/intro.html b/csug10.0/intro.html
new file mode 100644
index 000000000..0184f562f
--- /dev/null
+++ b/csug10.0/intro.html
@@ -0,0 +1,501 @@
+
+
+
+
+
+This book describes Chez Scheme extensions to the Revised6 +Report on Scheme [28] (R6RS). +It contains as well a concise summary of standard and Chez Scheme forms +and procedures, which gives the syntax of each form and the number and +types of arguments accepted by each procedure. +Details on standard R6RS features can be found in +The +Scheme Programming Language, 4th Edition (TSPL4) [11] or +the Revised6 Report on Scheme. +The Scheme Programming Language, 4th Edition also contains an +extensive introduction to the Scheme language and numerous short and +extended examples. + +
+Most of this document also applies equally to Petite Chez Scheme, +which is fully compatible with the complete Chez Scheme system but uses +a high-speed interpreter in place of Chez Scheme's +incremental native-code compiler. +Programs written for Chez Scheme run unchanged in +Petite Chez Scheme as long as they do not require the +compiler to be invoked. +In fact, Petite Chez Scheme is built from the same sources as +Chez Scheme, with all but the compiler sources included. +A detailed discussion of the impact of this distinction appears in +Section 2.8. + +
+The remainder of this chapter covers +Chez Scheme extensions to Scheme syntax (Section 1.1), +notational conventions used in this book (Section 1.2), +the use of parameters for system customization (Section 1.3), +and where to look for more information on +Chez Scheme (Section 1.4). + +
+Chapter 2 describes how one uses Chez Scheme +for program development, scripting, and application delivery, plus +how to get the compiler to generate the most efficient code +possible. +Chapter 3 describes debugging and object inspection +facilities. +Chapter 4 documents facilities for interacting with +separate processes or code written in other languages. +Chapter 5 describes binding forms. +Chapter 6 documents control structures. +Chapter 7 documents operations on nonnumeric objects, +while Chapter 8 documents various numeric operations, +including efficient type-specific operations. +Chapter 9 describes input/output operations and +generic ports, which allow the definition of ports with arbitrary +input/output semantics. +Chapter 10 discusses how R6RS libraries and top-level +programs are loaded into Chez Scheme along with various features for +controlling and tracking the loading process. +Chapter 11 describes syntactic extension and modules. +Chapter 12 describes system operations, such as operations +for interacting with the operating system and customizing +Chez Scheme's user interface. +Chapter 13 describes how to invoke and control the storage +management system and documents guardians and weak pairs. +Chapter 14 describes Chez Scheme's expression +editor and how it can be customized. +Chapter 15 documents the procedures and syntactic forms +that comprise the interface to Chez Scheme's native thread system. +Finally, Chapter 16 describes various compatibility features. + +
+The back of this book contains a bibliography, +the summary of forms, and an index. +The page numbers appearing in the summary of forms and +the italicized page numbers appearing in the index indicate the +locations in the text where forms and procedures are formally defined. +The summary of forms and index includes entries from TSPL4, so that +they cover the entire set of Chez Scheme features. +A TSPL4 entry is marked by a "t" prefix on the page number. + +
+Online versions and errata for this book and for TSPL4 can be found at +www.scheme.com. + +
+
Acknowledgments: +Michael Adams, Mike Ashley, Carl Bruggeman, Bob Burger, Sam +Daniel, George Davidson, Matthew Flatt, Aziz Ghuloum, Bob Hieb, Andy Keep, and Oscar Waddell have +contributed substantially to the development of Chez Scheme. +Chez Scheme's expression editor is based on a command-line editor for +Scheme developed from 1989 through 1994 by C. David Boyer. +File compression is performed with the use of the lz4 compression +library developed by Yann Collet or the zlib compression library +developed by Jean-loup Gailly and Mark Adler. +Implementations of the list and vector sorting routines are based on +Olin Shiver's opportunistic merge-sort algorithm and implementation. +Michael Lenaghan provided a number of corrections for earlier drafts +of this book. +Many of the features documented in this book were suggested by +current Chez Scheme users, and numerous comments from users have also +led to improvements in the text. +Additional suggestions for improvements to Chez Scheme and to this +book are welcome. + +
+ +
+Chez Scheme extends Scheme's syntax both at the object (datum) level +and at the level of syntactic forms. +At the object level, Chez Scheme supports additional representations for +symbols that contain nonstandard characters, +nondecimal numbers expressed in floating-point +and scientific notation, vectors with explicit lengths, +shared and cyclic structures, records, boxes, and more. +These extensions are described below. +Form-level extensions are described throughout the book and summarized +in the Summary of Forms, which also appears in the back of this book. + +
+Chez Scheme extends the syntax of identifiers in several ways. +First, the sequence of characters making up an identifier's name may +start with digits, periods, plus signs, and minus +signs as long as the sequence cannot be parsed as a number. +For example, 0abc, +++, and .. are all +valid identifiers in Chez Scheme. +Second, the single-character sequences { and +} are identifiers. +Third, identifiers containing arbitrary characters may be printed by +escaping them with \ or with |. +\ is used to escape a single character (except 'x', since +\x marks the start of a hex scalar value), +whereas | is used +to escape the group of characters that follow it up through the +matching |. +For example, \||\| is an identifier with a two-character +name consisting of the character | followed by the +character \, and |hit me!| is an identifier whose name +contains a space. + +
+In addition, gensyms (page 7.11) are printed with +#{ and +} brackets that enclose both the "pretty" and "unique" +names, e.g., #{g1426 e5g1c94g642dssw-a}. +They may also be printed using the pretty name only with the prefix +#:, e.g., +#:g1426. + +
+Arbitrary radixes from two through 36 may be specified with the prefix +#nr, +where n is the radix. +Case is not significant, so #nR may be used as well. +Digit values from 10 through 35 are specified as either lower- or upper-case +alphabetic characters, just as for hexadecimal numbers. +For example, #36rZZ is 35 × 36 + 35, or 1295. + +
+Chez Scheme also permits nondecimal numbers +to be printed in floating-point or scientific notation. +For example, #o1.4 is equivalent to 1.5, and +#b1e10 is equivalent to 4.0. +Digits take precedence over exponent specifiers, so that +#x1e20 is simply the four-digit hexadecimal number equivalent +to 7712. + +
+In addition to the standard named characters +#\alarm, +#\backspace, +#\delete, +#\esc, +#\linefeed, +#\newline, +#\page, +#\return, +#\space, +and +#\tab, +Chez Scheme recognizes +#\bel, +#\ls, +#\nel, +#\nul, +#\rubout, +and +#\vt (or #\vtab). +Characters whose scalar values are less than 256 may also be printed with +an octal syntax consisting of the prefix #\ followed by a three +octal-digit sequence. +For example, #\000 is equivalent to #\nul. + +
+Chez Scheme's fxvectors, or fixnum vectors, are printed like vectors +but with the prefix #vfx( in place of #(. +Similarly, flvectors, or flonum vectors, are printed with the prefix +#vfl(, and stencil vectors with the prefix #nvs(. +Vectors, bytevectors, fxvectors, and flvectors may be printed with an explicit length +prefix, and when the explicit length prefix is specified, duplicate +trailing elements may be omitted. +For example, +#(a b c) may be printed as +#3(a b c), +and a vector of length 100 containing all zeros may be printed as +#100(0). +Stencil vectors have a mask rather than an explicit length prefix, and it +is always included in the printed representation. + +
+Chez Scheme's boxes are printed with a +#& prefix, e.g., +#&17 is a box containing the integer 17. + +
+Records are printed with the syntax +#[type-name field ...], +where the symbol type-name is the name of the record +type and field ... are the printed +representations for the contents of the fields of the record. + +
+Shared and cyclic structure may be printed using the graph mark and +reference prefixes +#n= +and +#n#. +#n= is used to mark an item in the input, and +#n# is used to refer to the item marked n. +For example, '(#1=(a) . #1#) is a pair whose car and cdr +contain the same list, and #0=(a . #0#) is a cyclic +list, i.e., its cdr is itself. + +
+A $primitive form (see page 390) may +be abbreviated in the same manner as a quote form, using the +#% prefix. +For example, +#%car is equivalent to ($primitive car), +#2%car to ($primitive 2 car), and +#3%car to ($primitive 3 car). + +
+Chez Scheme's end-of-file object is printed #!eof. +If the end-of-file object appears outside of any datum within a file +being loaded, load will treat it as if it were a true +end of file and stop loading at that point. +Inserting #!eof into the middle of a file can thus be handy +when tracking down a load-time error. + +
+Broken pointers in weak pairs (see page 443) are +represented by the broken weak pointer object, which is +printed #!bwp. + +
+In addition to the standard delimiters (whitespace, open and close +parentheses, open and close brackets, double quotes, semi-colon, +and #), Chez Scheme also treats as delimiters +open and close braces, single quote, backward quote, and comma. + +
+Finally, Chez Scheme accepts #true and +#false as alternative spellings of the booleans +#t and #f. Like the external representation of numbers, case +is not significant; for example, #T, #True and #TRUE +are all equivalent. + +
+The Chez Scheme lexical extensions described above are disabled in an +input stream after an #!r6rs comment directive has been seen, +unless a #!chezscheme comment directive has been seen since. +Each library loaded implicitly via import and each RNRS top-level +program loaded via the --program command-line option, the +scheme-script command, or the load-program procedure is +treated as if it begins implicitly with an #!r6rs comment directive. + +
+The case of symbol and character names is normally significant, +as required by the Revised6 Report. +Names are folded, as if by string-foldcase, following a +#!fold-case comment directive in the same input stream +unless a #!no-fold-case has been seen since. +Names are also folded if neither directive has been seen and the +parameter case-sensitive has been set to #f. + +
+The printer invoked by write, put-datum, +pretty-print, and the format ~s +option always prints standard Revised6 Report objects +using the standard syntax, unless a different behavior is +requested via the setting of one of the print parameters. +For example, it prints symbols in the extended identifier syntax +of Chez Scheme described above using hex scalar value escapes, +unless the parameter +print-extended-identifiers is set to +true. +Similarly, it does not print the explicit length or suppress +duplicate trailing elements unless the parameter +print-vector-length is set to +true. + + +
+ +
+This book follows essentially the same notational conventions as +The Scheme Programming Language, 4th Edition. +These conventions are repeated below, with notes specific to +Chez Scheme. + +
+When the value produced by a procedure or syntactic form is said to +be unspecified, the form or procedure may +return any number of values, each of which may be any Scheme +object. +Chez Scheme usually returns a single, unique +void object +(see void) whenever +the result is unspecified; avoid counting on this behavior, however, +especially if your program may be ported to another Scheme implementation. +Printing of the void object is suppressed by Chez Scheme's waiter +(read-evaluate-print loop). + +
+This book uses the words "must" and "should" to +describe program requirements, such as the requirement to provide an index +that is less than the length of the vector in a call to +vector-ref. +If the word "must" is used, it means that the requirement is enforced +by the implementation, i.e., an exception is raised, usually with +condition type &assertion. +If the word "should" is used, an exception may or may not be raised, +and if not, the behavior of the program is undefined. +The phrase "syntax violation" is used to +describe a situation in which a program is malformed. +Syntax violations are detected prior to program execution. +When a syntax violation is detected, an exception of type &syntax +is raised and the program is not executed. + +
+Scheme objects are displayed in a typewriter typeface just +as they are to be typed at the keyboard. +This includes identifiers, constant objects, parenthesized Scheme +expressions, and whole programs. +An italic typeface is used to set off syntax variables in +the descriptions of syntactic forms and arguments in the descriptions of +procedures. +Italics are also used to set off technical terms the first time they +appear. +The first letter of an identifier that is not ordinarily capitalized +is not capitalized when it appears at the beginning of a sentence. +The same is true for syntax variables written in italics. + +
+In the description of a syntactic form or procedure, a pattern shows +the syntactic form or the application of the procedure. +The syntax keyword or procedure name is given in typewriter font, +as are parentheses. +The remaining pieces of the syntax or arguments are shown in italics, +using names that imply the types of the expressions or arguments expected +by the syntactic form or procedure. +Ellipses are used to specify +zero or more occurrences of a subexpression or argument. + + +
+ +
+All Chez Scheme system customization is done via +parameters. +A parameter is a procedure that encapsulates a hidden state variable. +When invoked without arguments, a parameter returns the value of +the encapsulated variable. +When invoked with one argument, the parameter changes the value +of the variable to the value of its argument. +A parameter may raise an exception if its argument is not appropriate, +or it may filter the argument in some way. + +
+New parameters may be created and used by programs running in +Chez Scheme. +Parameters are used rather than global variables for program customization +for two reasons: +First, unintentional redefinition of a customization variable can cause +unexpected problems, whereas unintentional redefinition of a +parameter simply makes the parameter inaccessible. +For example, a program that defines *print-level* for its own +purposes in early releases of Chez Scheme would have unexpected +effects on the printing of Scheme objects, whereas a program that +defines print-level for its own +purposes simply loses the ability to alter the printer's behavior. +Of course, a program that invokes print-level by accident can +still affect the system in unintended ways, but such an occurrence is +less likely, and can only happen in an incorrect program. + +
+Second, invalid values for parameters can be detected and rejected +immediately when the "assignment" is made, rather than at the point +where the first use occurs, when it is too late to recover and +reinstate the old value. +For example, an assignment of *print-level* to -1 would not +have been caught until the first call to write or +pretty-print, whereas an attempted assignment of -1 to the +parameter print-level, i.e., (print-level -1), is +flagged as an error immediately, before the change is actually made. + +
+Built-in system parameters are described in different sections +throughout this book and are listed along with other syntactic +forms and procedures in the Summary of Forms in the +back of this book. +Parameters marked "thread parameters" have per-thread values in threaded +versions of Chez Scheme, while the values of parameters marked "global +parameters" are shared by all threads. +Nonthreaded versions of Chez Scheme do not distinguish between +thread and global parameters. +See Sections 12.13 and 15.8 for +more information on creating and manipulating parameters. + + +
+ +
+The articles and technical reports listed below document various +features of Chez Scheme and its implementation: + +
+
+ +
+Links to abstracts and electronic versions of these publications are +available at the url +http://www.cs.indiana.edu/chezscheme/pubs/. + + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/io.html b/csug10.0/io.html
new file mode 100644
index 000000000..408f6f6ce
--- /dev/null
+++ b/csug10.0/io.html
@@ -0,0 +1,5078 @@
+
+
+
+
+
+This chapter describes Chez Scheme's generic port facility, +operations on ports, and various Chez Scheme extensions to the +standard set of input/output operations. +See Chapter 7 of The Scheme Programming Language, 4th Edition or the Revised6 Report +on Scheme for a description of standard input/output operations. +Definitions of a few sample generic ports are given in +Section 9.17. + +
+Chez Scheme closes file ports automatically after they become +inaccessible to the program or when the Scheme program exits, but it is +best to close ports explicitly whenever possible. + + +
+ +
+Chez Scheme's "generic port" facility +allows the programmer to add new types of textual ports with +arbitrary input/output semantics. +It may be used, for example, to define any of the built-in +Common Lisp [30] stream types, i.e., +synonym streams, +broadcast streams, +concatenated streams, +two-way streams, +echo streams, and +string streams. +It may also be used to define more exotic ports, such as ports that +represent windows on a bit-mapped display or ports that represent +processes connected to the current process via pipes or sockets. + +
+Each port has an associated port handler. +A port handler is a procedure that accepts messages in an +object-oriented style. +Each message corresponds to one of the low-level Scheme operations +on ports, such as read-char and close-input-port (but not +read, which is defined in terms of the lower-level operations). +Most of these operations simply call the handler immediately with +the corresponding message. + +
+Standard messages adhere to the following conventions: the message name is +the first argument to the handler. +It is always a symbol, and it is always the name of a primitive +Scheme operation on ports. +The additional arguments are the same as the arguments to the +primitive procedure and occur in the same order. +(The port argument to some of the primitive procedures is optional; +in the case of the messages passed to a handler, the port argument +is always supplied.) +The following messages are defined for built-in ports: + +
+ +
block-read port string count
+
+block-write port string count
+
+char-ready? port
+
+clear-input-port port
+
+clear-output-port port
+
+close-port port
+
+file-position port
+
+file-position port position
+
+file-length port
+
+flush-output-port port
+
+peek-char port
+
+port-name port
+
+read-char port
+
+unread-char char port
+
+write-char char port
+
Additional messages may be accepted by user-defined ports. + +
+Chez Scheme input and output is normally buffered for efficiency. +To support buffering, each input port contains an input buffer and +each output port contains an output buffer. +Bidirectional ports, ports that are both input ports and output +ports, contain both input and output buffers. +Input is not buffered if the input buffer is the empty string, +and output is not buffered if the output buffer is the empty +string. +In the case of unbuffered input and output, calls to read-char, +write-char, and similar messages cause the handler to be invoked +immediately with the corresponding message. +For buffered input and output, calls to these procedures cause the +buffer to be updated, and the handler is not called under normal +circumstances until the buffer becomes empty (for input) or full (for +output). +Handlers for buffered ports must not count +on the buffer being empty or full when read-char, write-char, and +similar messages are received, however, due to the possibility that (a) +the handler is invoked through some other mechanism, or (b) the +call to the handler is interrupted. + +
+In the presence of keyboard, timer, and other interrupts, it is +possible for a call to a port handler to be interrupted or for the +handler itself to be interrupted. +If the port is accessible outside of the interrupted code, there +is a possibility that the interrupt handler will cause input or +output to be performed on the port. +This is one reason, as stated above, that port handlers must not count +on the input buffer being empty or output buffer being full when a +read-char, write-char, or similar message is received. +In addition, port handlers may need to manipulate the buffers only +with interrupts disabled (using with-interrupts-disabled). + +
+Generic ports are created via one of the port construction +procedures make-input-port, +make-output-port, and make-input/output-port defined +later in this chapter. +Ports have seven accessible fields: + +
+
+The output-size and output-index fields are valid only for output +ports, and the input-size and input-index fields are valid only for +input ports. +The output and input size and index fields may be updated as well +using the corresponding "set-field!" procedure. + +
+A port's output size determines how much of the port's output buffer is +actually available for writing by write-char. +The output size is often the same as the string length of the port's +output buffer, but it can be set to less (but no less than zero) at the +discretion of the programmer. +The output index determines to which position in the port's +buffer the next character will be written. +The output index should be between 0 and the output size, +inclusive. +If no output has occurred since the buffer was last flushed, the +output index should be 0. +If the index is less than the size, write-char +stores its character argument into the specified character +position within the buffer and increments the index. +If the index is equal to the size, write-char leaves the fields of +the port unchanged and invokes the handler. + +
+A port's input size determines how much of the port's input buffer is +actually available for reading by read-char. +A port's input size and input index are constrained in the same manner +as output size and index, i.e., the input size must be between +0 and the string length of the input buffer (inclusive), and the input +index must be between 0 and the input size (inclusive). +Often, the input size is less than the length of the input buffer +because there are fewer characters available to read than would fit +in the buffer. +The input index determines from which position in the input buffer the +next character will be read. +If the index is less than the size, read-char extracts the character +in this position, increments the index, and returns the character. +If the index is equal to the size, read-char leaves the fields of +the port unchanged and invokes the handler. + +
+The operation of peek-char is similar to that of read-char, except +that it does not increment the input index. +unread-char decrements the input index if it is greater than 0, +otherwise it invokes the handler. +char-ready? returns #t if the input index is less than the input +size, otherwise it invokes the handler. + +
+Although the fields shown and discussed above are logically present in +a port, actual implementation details may differ. +The current Chez Scheme implementation uses a different representation +that allows read-char, write-char, and similar operations to be +open-coded with minimal overhead. +The access and assignment operators perform the conversion between the +actual representation and the one shown above. + +
+Port handlers receiving a message must return a value appropriate for +the corresponding operation. +For example, a handler receiving a read-char message must return a +character or eof object (if it returns). +For operations that return unspecified values, such as close-port, +the handler is not required to return any particular value. + +
+ +
+The Revised6 Report requires that the universe of a file-options +enumeration set must include no-create, no-fail, +and no-truncate, whose meanings are described within the +description of the file-options syntax in +Section 7.2 of The Scheme Programming Language, 4th Edition. +Chez Scheme defines a number of additional file options: + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+The language of the Revised6 Report provides three built-in codecs: +a latin-1 codec, a utf-8 codec, and a utf-16 codec. +Chez Scheme provides three additional codecs: a utf-16le codec, +utf-16be codec, and an "iconv" codec for non-Unicode character sets. +It also provides an alternative to the standard utf-16 codec that +defaults to little-endian format rather than the default big-endian +format. +This section describes these codecs, plus a current-transcoder +parameter that allows the programmer to determine the transcoder +used for a textual port whenever the transcoder is implicit, as for +open-input-file or load, along with the +predicate transcoder?, which should be standard but is not. + +
+procedure: (utf-16-codec)
+
procedure: (utf-16-codec endianness)
+
procedure: (utf-16le-codec)
+
procedure: (utf-16be-codec)
+
+returns: a codec
+
+libraries: (chezscheme)
+
+
endianness must be the symbol big or the symbol +little. + +
+The codec returned by utf-16-codec can be used to create and +process data written UTF-16 format. +When called without the endianness argument or with endianness +big, utf-16-codec returns a codec for standard UTF-16 +data, i.e., one that defaults to big-endian format if no byte-order mark +(BOM) is found. + +
+When output is transcoded with a transcoder based on this codec, a BOM is +emitted just before the first character written, and each character is +written as a UTF-16 character in big-endian format. +For input, a BOM is looked for at the start of the +input and, if present, controls the byte order of the remaining +UTF-16 characters. +If no BOM is present, big-endian order is assumed. +For input-output ports, the BOM is not emitted if the file is +read before written, and a BOM is not looked for if the file is written +before read. + +
+For textual ports created via transcoded-port, a BOM written or +read via the transcoder appears at the beginning of the underlying data +stream or file only if the binary port passed to transcoded-port +is positioned at the start of the data stream or file. +When the transcoder can determine this is the case, it sets a flag that +causes set-port-position! to position the port beyond the BOM if +an attempt is made to reposition the port to the start of the data stream +or file, so that the BOM is preserved. + +
+When called with endianness little, utf-16-codec +returns a codec that defaults to the little-endian format both for reading +and for writing. +For output-only streams or input/output streams that are written before read, +the result is standard UTF-16, with a BOM that specifies little-endian +format followed by characters in little-endian byte order. +For input-only streams or input/output streams that are read before written, +this codec allows programs to read from input streams that either +begin with a BOM or are encoded in UTF-16LE format. +This is particularly useful for handling files that might have been +produced by older Windows applications that claim to produce UTF-16 files +but actually produce UTF-16LE files. + +
+The Revised6 Report version of utf-16-codec lacks the +optional endianness argument. + +
+The codecs returned by utf-16le-codec and utf-16be-codec +are used to read and write data in the UTF-16LE and UTF-16BE formats, +i.e., UTF-16 with little-endian or big-endian byte order and no BOM. +For output, these codecs are useful for controlling whether and where +the BOM is emitted, since no BOM is emitted implicitly and a BOM +can be emitted explicitly as an ordinary character. +For input, these codecs are useful for processing files known to be +in little-endian or big-endian format with no BOM. + + +
+procedure: (iconv-codec code-page)
+
+returns: a codec
+
+libraries: (chezscheme)
+
+
code-page must be a string and should identify a codec accepted by +the iconv library installed on the target machine. +The codec returned by this procedure can be used to convert from the +non-Unicode single- and multiple-byte character sets supported by +iconv. +When used in the input direction, the codec converts byte sequences +into Scheme strings, and when used in the output direction, it converts +Scheme strings to byte sequences. + +
+The set of supported code pages depends on the version of +iconv available; consult the iconv documentation +or use the shell command iconv --list to obtain a list +of supported code pages. + +
+While the Windows operating system does not supply an iconv +library, it is possible to use iconv-codec on Windows systems by +supplying an iconv dynamic-link library (named iconv.dll, +libiconv.dll, or libiconv-2.dll) that provides +Posix-conformant iconv_open, iconv, and +iconv_close entry points either under those names or under the +alternative names libiconv_open, libiconv, and +libiconv_close. +The dll must be located in a standard location for dlls or in the +current directory of the process the first time iconv-codec +is called. + +
+thread parameter: current-transcoder
+
+libraries: (chezscheme)
+
+
The transcoder value of the current-transcoder parameter is used +whenever a textual file is opened with an implicit transcoder, e.g., by +open-input-file and other convenience I/O procedures, +compile-file include, load, and +pretty-file. +Its initial value is the value of the native-transcoder procedure. + + +
+procedure: (transcoder? obj)
+
+returns: #t if obj is a transcoder, #f otherwise
+
+libraries: (chezscheme)
+
+
thread parameter: transcoded-port-buffer-size
+
+libraries: (chezscheme)
+
+
transcoded-port-buffer-size is a parameter that specifies the size +of the string buffer that is allocated when creating a new transcoded port. +The value of this parameter must be a positive fixnum. +When transcoding a binary input port that implements port-position, +a transcoded input port maintains an fxvector the same size as +its string buffer to support port-position on the transcoded port. + +
+thread parameter: make-codec-buffer
+
+libraries: (chezscheme)
+
+
The value of make-codec-buffer must be a procedure. +The procedure is invoked with the binary port bp when +transcoded-port is called with a buffered port bp. +The procedure must return a mutable bytevector of length at least four. +The behavior of transcoded-port and its callers is unspecified if a +continuation captured within the make-codec-buffer procedure is invoked +multiple times. + +
+ +
+The procedures used to create, access, and alter ports directly +are described in this section. +Also described are several nonstandard operations on ports. + +
+Unless otherwise specified, procedures requiring either input ports or +output ports as arguments accept input/output ports as well, i.e., an +input/output port is both an input port and an output port. + +
+procedure: (make-input-port handler input-buffer)
+
procedure: (make-output-port handler output-buffer)
+
procedure: (make-input/output-port handler input-buffer output-buffer)
+
+returns: a new textual port
+
+libraries: (chezscheme)
+
+
handler must be a procedure, and +input-buffer and output-buffer must be strings. +Each procedure creates a generic port. +The handler associated with the port is handler, the +input buffer is input-buffer, and the +output buffer is output-buffer. +For make-input-port, the output buffer is undefined, and for +make-output-port, the input buffer is undefined. + +
+The input size of an input or input/output port is initialized to the +string length of the input buffer, and the input index is set to 0. +The output size and index of an output or input/output port are +initialized similarly. + +
+The length of an input or output buffer may be zero, in which case +buffering is effectively disabled. + +
+procedure: (port-handler port)
+
+returns: a procedure
+
+libraries: (chezscheme)
+
+
For generic ports, port-handler returns the handler passed to one +of the generic port creation procedures described above. +For ports created by open-input-file and similar procedures, +port-handler returns an internal handler that may be invoked in +the same manner as any other handler. + +
+procedure: (port-input-buffer input-port)
+
procedure: (port-input-size input-port)
+
procedure: (port-input-index input-port)
+
procedure: (textual-port-input-buffer textual-input-port)
+
procedure: (textual-port-input-size textual-input-port)
+
procedure: (textual-port-input-index textual-input-port)
+
procedure: (binary-port-input-buffer binary-input-port)
+
procedure: (binary-port-input-size binary-input-port)
+
procedure: (binary-port-input-index binary-input-port)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
These procedures return the input buffer, size, or index +of the input port. +The variants specialized to textual or binary ports are slightly +more efficient than their generic counterparts. + + +
+procedure: (set-port-input-index! input-port n)
+
procedure: (set-port-input-size! input-port n)
+
procedure: (set-port-input-buffer! input-port x)
+
procedure: (set-textual-port-input-index! textual-input-port n)
+
procedure: (set-textual-port-input-size! textual-input-port n)
+
procedure: (set-textual-port-input-buffer! textual-input-port string)
+
procedure: (set-binary-port-input-index! binary-input-port n)
+
procedure: (set-binary-port-input-size! binary-input-port n)
+
procedure: (set-binary-port-input-buffer! binary-input-port bytevector)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The procedure set-port-input-index! sets the input index field of +input-port to n, which must be a nonnegative integer less than +or equal to the port's input size. + +
+The procedure set-port-input-size! sets the input size field of +input-port to n, which must be a nonnegative integer less than +or equal to the string length of the port's input buffer. +It also sets the input index to 0. + +
+The procedure set-port-input-buffer! sets the input buffer field of +input-port to x, which must be a string for textual ports and a +bytevector for binary ports. +It also sets the input size to the length of the string or bytevector +and the input index to 0. + +
+The variants specialized to textual or binary ports are slightly +more efficient than their generic counterparts. + +
+procedure: (port-input-count input-port)
+
procedure: (textual-port-input-count textual-input-port)
+
procedure: (binary-port-input-count binary-input-port)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
These procedures return an exact integer representing the number of +characters or bytes left to be read from the port's input buffer, i.e., +the difference between the buffer size and index. + +
+The variants specialized to textual or binary ports are slightly +more efficient than their generic counterpart. + +
+procedure: (port-input-empty? input-port)
+
+returns: #t if the port's input buffer contains no more data, otherwise #f
+
+libraries: (chezscheme)
+
+
This procedure determines whether the port's input count is zero without +computing or returning the actual count. + +
+procedure: (port-output-buffer output-port)
+
procedure: (port-output-size output-port)
+
procedure: (port-output-index output-port)
+
procedure: (textual-port-output-buffer output-port)
+
procedure: (textual-port-output-size output-port)
+
procedure: (textual-port-output-index output-port)
+
procedure: (binary-port-output-buffer output-port)
+
procedure: (binary-port-output-size output-port)
+
procedure: (binary-port-output-index output-port)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
These procedures return the output buffer, size, or index +of the output port. +The variants specialized to textual or binary ports are slightly +more efficient than their generic counterparts. + + +
+procedure: (set-port-output-index! output-port n)
+
procedure: (set-port-output-size! output-port n)
+
procedure: (set-port-output-buffer! output-port x)
+
procedure: (set-textual-port-output-index! textual-output-port n)
+
procedure: (set-textual-port-output-size! textual-output-port n)
+
procedure: (set-textual-port-output-buffer! textual-output-port string)
+
procedure: (set-binary-port-output-index! output-port n)
+
procedure: (set-binary-port-output-size! output-port n)
+
procedure: (set-binary-port-output-buffer! binary-output-port bytevector)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The procedure set-port-output-index! sets the output index field of +the output port to n, which must be a nonnegative integer less than +or equal to the port's output size. + +
+The procedure set-port-output-size! sets the output size field of +the output port to n, which must be a nonnegative integer less than +or equal to the string length of the port's output buffer. +It also sets the output index to 0. + +
+The procedure set-port-output-buffer! sets the output buffer field of +output-port to x, which must be a string for textual ports and a +bytevector for binary ports. +It also sets the output size to the length of the string or bytevector +and the output index to 0. + +
+The variants specialized to textual or binary ports are slightly +more efficient than their generic counterparts. + +
+procedure: (port-output-count output-port)
+
procedure: (textual-port-output-count textual-output-port)
+
procedure: (binary-port-output-count binary-output-port)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
These procedures return an exact integer representing the amount of +space in characters or bytes available to be written in the +port's output buffer, i.e., the difference between the buffer size +and index. + +
+The variants specialized to textual or binary ports are slightly +more efficient than their generic counterpart. + +
+procedure: (port-output-full? output-port)
+
+returns: #t if the port's input buffer has no more room, otherwise #f
+
+libraries: (chezscheme)
+
+
This procedure determines whether the port's output count is zero without +computing or returning the actual count. + +
+procedure: (mark-port-closed! port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure directly marks the port closed so that no further +input or output operations are allowed on it. +It is typically used by handlers upon receipt of a close-port +message. + +
+procedure: (port-closed? port)
+
+returns: #t if port is closed, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(let ([p (open-output-string)])
+
+ (port-closed? p)) #f
+
+
+(let ([p (open-output-string)])
+
+ (close-port p)
+
+ (port-closed? p)) #t
+
+procedure: (set-port-bol! output-port obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
When obj is #f, the port's beginning-of-line (BOL) +flag is cleared; otherwise, the port's BOL flag is set. + +
+The BOL flag is consulted by fresh-line +(page 270) to determine if it needs to emit a +newline. +This flag is maintained automatically for file output ports, string output +ports, and transcript ports. +The flag is set for newly created file and string output ports, except +for file output ports created with the append option, for which +the flag is reset. +The BOL flag is clear for newly created generic ports and never set +automatically, but may be set explicitly using set-port-bol!. +The port is always flushed immediately before the flag is consulted, so it +need not be maintained on a per-character basis for buffered ports. + +
+procedure: (port-bol? port)
+
+returns: #t if port's BOL flag is set, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (set-port-eof! input-port obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
When obj is not #f, set-port-eof! marks input-port +so that, once its buffer is empty, the port is treated as if it were at +eof even if more data is available in the underlying byte or character +stream. +Once this artificial eof has been read, the eof mark is cleared, making +any additional data in the stream available beyond the eof. +This feature can be used by a generic port to simulate a stream consisting +of multiple input files. + +
+When obj is #f, the eof mark is cleared. + +
+The following example assumes /dev/zero provides an infinite stream of +zero bytes. + +
+ +
(define p
+
+ (parameterize ([file-buffer-size 3])
+
+ (open-file-input-port "/dev/zero")))
+
+(set-port-eof! p #t)
+
+(get-u8 p) #!eof
+
+(get-u8 p) 0
+
+(set-port-eof! p #t)
+
+(get-u8 p) 0
+
+(get-u8 p) 0
+
+(get-u8 p) #!eof
+
+(get-u8 p) 0
+
procedure: (port-name port)
+
+returns: the name associated with port
+
+libraries: (chezscheme)
+
+
The name may be any object but is usually a string or #f +(denoting no name). +For file ports, the name is typically a string naming the file. + +
+ +
(let ([p (open-input-file "myfile.ss")])
+
+ (port-name p)) "myfile.ss"
+
+
+(let ([p (open-output-string)])
+
+ (port-name p)) "string"
+
procedure: (set-port-name! port obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure sets port's name to obj, which should be +a string or #f (denoting no name). + + +
+procedure: (port-length port)
+
procedure: (file-length port)
+
+returns: the length of the file or other object to which port refers
+
procedure: (port-has-port-length? port)
+
+returns: #t if the port supports port-length, #f otherwise
+
+libraries: (chezscheme)
+
+
A port may allow the length of the underlying stream of characters or bytes +to be determined. +If so, the procedure port-has-port-length? returns +#t and port-length returns the current length. +For binary ports, the length is always an exact nonnegative integer byte +count. +For textual ports, the representation of a length is unspecified; it +may not be an exact nonnegative integer and, even if it is, it may not +represent either a byte or character count. +The length may be used at some later time to reset the length if the +port supports set-port-length!. +If port-length is called on a port that does not support it, +an exception with condition type &assertion is raised. + +
+File lengths beyond 232 might not be reported property +for compressed files on 32-bit versions of the system. + +
+file-length is identical to port-length. + +
+procedure: (set-port-length! port len)
+
+returns: unspecified
+
procedure: (port-has-set-port-length!? port)
+
+returns: #t if the port supports set-port-length!, #f otherwise
+
+libraries: (chezscheme)
+
+
A port may allow the length of the underlying stream of characters or bytes +to be set, i.e., extended or truncated. +If so, the procedure port-has-set-port-length!? returns +#t and set-port-length! changes the length. +For binary ports, the length len must be an exact nonnegative integer byte +count. +For textual ports, the representation of a length is unspecified, as +described in the entry for port-length above, but len must be +an appropriate length for the textual port, which is usually guaranteed +to be the case only if it was obtained from a call to port-length +on the same port. +If set-port-length! is called on a port that does not support it, +an exception with condition type &assertion is raised. + +
+It is not possible to set the length of a port opened with compression +to an arbitrary position, and the result of an attempt to set the length +of a compressed file beyond 232 on 32-bit versions of the system is +undefined. + + +
+procedure: (port-nonblocking? port)
+
+returns: #t if the port is in nonblocking mode, #f otherwise
+
procedure: (port-has-port-nonblocking?? port)
+
+returns: #t if the port supports port-nonblocking?, #f otherwise
+
+libraries: (chezscheme)
+
+
A port may allow the nonblocking status of the port to be determined. +If so, the procedure port-has-port-nonblocking?? returns +#t and port-nonblocking? returns a boolean value +reflecting whether the port is in nonblocking mode. + + +
+procedure: (set-port-nonblocking! port obj)
+
+returns: unspecified
+
procedure: (port-has-set-port-nonblocking!? port)
+
+returns: #t if the port supports set-port-nonblocking!, #f otherwise
+
+libraries: (chezscheme)
+
+
A port may allow reads or writes to be performed in a "nonblocking" fashion. +If so, the procedure port-has-set-port-nonblocking!? returns +#t and set-port-nonblocking! sets the port to nonblocking +mode (if obj is a true value) or blocking mode (if obj is #f). +If set-port-nonblocking! is called on a port that does not support it, +an exception with condition type &assertion is raised. + +
+Ports created by the standard Revised6 port opening procedures are +initially set in blocking mode by default. +The same is true for most of the procedures described in this document. +A generic port based on a nonblocking source may be nonblocking +initially. +A port returned by open-fd-input-port, +open-fd-output-port, or open-fd-input/output-port +is initially in nonblocking mode if the file-descriptor passed in is in +nonblocking mode. +Similarly, a port returned by standard-input-port, +standard-output-port, or standard-error-port is +initially in nonblocking mode if the underlying stdin, stdout, +or stderr file descriptor is in nonblocking mode. + +
+Although get-bytevector-some and get-string-some normally +cannot return an empty bytevector or empty string, they can if the port +is in nonblocking mode and no input is available. +Also, get-bytevector-some! and get-string-some! +may not read any data if the port is in nonblocking mode and +no data is available. +Similarly, put-bytevector-some and put-string-some +may not write any data if the port is in nonblocking mode and +no room is available. + +
+Nonblocking mode is not supported under Windows. + +
+procedure: (file-position port)
+
procedure: (file-position port pos)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
When the second argument is omitted, this procedure behaves like the R6RS +port-position procedure, and when present, like the R6RS +set-port-position! procedure. + +
+For compressed files opened with the compressed flag, +file-position returns the position in the +uncompressed stream of data. +Changing the position of a compressed input file opened with the +compressed flag generally requires rewinding and rereading the +file and might thus be slow. +The position of a compressed output file opened with the +compressed flag can be moved forward only; this is +accomplished by writing a (compressed) sequence of zeros. +File positions beyond 232 might not be reported property +for compressed files on 32-bit versions of the system. + + +
+procedure: (clear-input-port)
+
procedure: (clear-input-port input-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If input-port is not supplied, it defaults to the current input port. +This procedure discards any data in the buffer associated +with input-port. +This may be necessary, for example, to clear any type-ahead from the keyboard +in preparation for an urgent query. + +
+procedure: (clear-output-port)
+
procedure: (clear-output-port output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If output-port is not supplied, it defaults to the current output port. +This procedure discards any data in the buffer associated +with output-port. +This may be necessary, for example, to clear any pending output on an +interactive port in preparation for an urgent message. + + +
+procedure: (flush-output-port)
+
procedure: (flush-output-port output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If output-port is not supplied, it defaults to the current output port. +This procedure forces any data in the buffer associated +with output-port to be printed immediately. +The console output port is automatically flushed after a newline and before +input from the console input port; all ports are automatically flushed when +they are closed. +flush-output-port may be necessary, however, to force a message +without a newline to be sent to the console output port or to force output +to appear on a file without delay. + +
+procedure: (port-file-compressed! port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
port must be an input or an output port, but not an input/output port. +It must be a file port pointing to a regular file, i.e., a file on disk rather +than, e.g., a socket. +The port can be a binary or textual port. +If the port is an output port, subsequent output sent to the port +will be compressed. +If the port is an input port, subsequent input will be decompressed +if and only if the port is currently pointing at compressed data. +The compression format for output +is determined by the compress-format +parameter, while the compression format on input is inferred. +The compression level, which is relevant only for output, is determined +by the compress-level parameter. +This procedure has no effect if the port is already set for compression. + +
+thread parameter: compress-format
+
+libraries: (chezscheme)
+
+
compress-format determines the +compression algorithm and format used for output. Currently, +the possible values of the parameter are the symbols lz4 (the default) +and gzip. + +
+The lz4 format uses the LZ4 compression library developed by +Yann Collet. +It is therefore compatible with the lz4 program, which +means that lz4 may be used to uncompress files produced +by Chez Scheme and visa versa. + +
+The gzip format uses the zlib compression library developed by +Jean-loup Gailly and Mark Adler. +It is therefore compatible with the gzip program, which +means that gzip may be used to uncompress files produced +by Chez Scheme and visa versa. + +
+Reading lz4-compressed data tends to be much faster than reading +gzip-compressed data, while gzip-compressed data tends to +be significantly smaller. + +
+thread parameter: compress-level
+
+libraries: (chezscheme)
+
+
compress-level determines the amount of effort spent on +compression and is thus relevant only for output. +It can be set to one of the symbols minimum, low, +medium, high, or maximum, which are +listed in order from shortest to longest expected compression time +and least to greatest expected effectiveness. +Its default value is medium. + +
+ +
+String ports allow the creation and manipulation of strings via port +operations. +The procedure +open-input-string converts a string into a textual input port, +allowing the characters in the string to be read in sequence via input +operations such as read-char or read. +The procedure +open-output-string allows new strings to be built up with +output operations such as write-char and write. + +
+While string ports could be defined as generic ports, they are instead +supported as primitive by the implementation. + + +
+procedure: (open-input-string string)
+
+returns: a new string input port
+
+libraries: (chezscheme)
+
+
A string input port is similar to a file input port, except that +characters and objects drawn from the port come from string +rather than from a file. + +
+A string port is at "end of file" when the port reaches the end of the +string. +It is not necessary to close a string port, although it is okay to do so. + +
+ +
(let ([p (open-input-string "hi mom!")])
+
+ (let ([x (read p)])
+
+ (list x (read p)))) (hi mom!)
+
procedure: (with-input-from-string string thunk)
+
+returns: the values returned by thunk
+
+libraries: (chezscheme)
+
+
thunk must be a procedure and should accept zero arguments. +with-input-from-string parameterizes the current input port to be the +result of opening string for input during the +application of thunk. + +
+ +
(with-input-from-string "(cons 3 4)"
+
+ (lambda ()
+
+ (eval (read)))) (3 . 4)
+
procedure: (open-output-string)
+
+returns: a new string output port
+
+libraries: (chezscheme)
+
+
A string output port is similar to a file output port, except that +characters and objects written to the port are placed in a string +(which grows as needed) rather than to a file. +The string built by writing to a string output port may be obtained +with get-output-string. +See the example given for get-output-string below. +It is not necessary to close a string port, although it is okay to do so. + + +
+procedure: (get-output-string string-output-port)
+
+returns: the string associated with string-output-port
+
+libraries: (chezscheme)
+
+
string-output-port must be an port returned by open-output-string. + +
+As a side effect, get-output-string resets string-output-port +so that subsequent output to string-output-port is placed +into a fresh string. + +
+ +
(let ([p (open-output-string)])
+
+ (write 'hi p)
+
+ (write-char #\space p)
+
+ (write 'mom! p)
+
+ (get-output-string p)) "hi mom!"
+
An implementation of format (Section 9.13) might be +written using string-output ports to produce string output. + + +
+procedure: (with-output-to-string thunk)
+
+returns: a string containing the output
+
+libraries: (chezscheme)
+
+
thunk must be a procedure and should accept zero arguments. +with-output-to-string parameterizes the current output port to +a new string output port during the +application of thunk. +If thunk returns, the string associated with the new string output +port is returned, as with get-output-string. + +
+ +
(with-output-to-string
+
+ (lambda ()
+
+ (display "Once upon a time ...")
+
+ (newline))) "Once upon a time ...\n"
+
+
+thread parameter: file-buffer-size
+
+libraries: (chezscheme)
+
+
file-buffer-size is a parameter that determines the size of each +buffer created when the buffer mode is not none for a port +created by one of the file open operations, e.g., open-input-file +or open-file-output-port. +The value of this parameter must be a positive fixnum. + +
+procedure: (file-port? port)
+
+returns: #t if port is a file port, #f otherwise
+
+libraries: (chezscheme)
+
+
A file port is any port based directly +on an O/S file descriptor, e.g., one created by open-file-input-port, +open-output-port, open-fd-input-port, etc., but not +a string, bytevector, or custom port. + + +
+procedure: (port-file-descriptor port)
+
+returns: the file descriptor associated with port
+
+libraries: (chezscheme)
+
+
port must be a file port, i.e., a port for which file-port? +returns #t. + + +
+ +
+thread parameter: custom-port-buffer-size
+
+libraries: (chezscheme)
+
+
custom-port-buffer-size is a parameter that determines the sizes +of the buffers associated with newly created custom ports. +The value of this parameter must be a positive fixnum. + +
+ +
+global parameter: console-input-port
+
+libraries: (chezscheme)
+
+
console-input-port is a parameter that determines the +input port used by the waiter and interactive debugger. +When called with no arguments, it returns the +console input port. +When called with one argument, which must be a textual input port, +it changes the value of the console +input port. +The initial value of this parameter is a port tied to the standard +input (stdin) stream of the Scheme process. + +
+thread parameter: current-input-port
+
+libraries: (chezscheme)
+
+
current-input-port is a parameter that determines the +default port argument for most input procedures, including +read-char, peek-char, and read, +When called with no arguments, current-input-port returns the +current input port. +When called with one argument, which must be a textual input port, +it changes the value of the current +input port. +The Revised6 Report version of current-input-port accepts +only zero arguments, i.e., it cannot be used to change the current input +port. +The initial value of this parameter is the same port as the initial +value of console-input-port. + + +
+procedure: (open-input-file path)
+
procedure: (open-input-file path options)
+
+returns: a new input port
+
+libraries: (chezscheme)
+
+
path must be a string. +open-input-file opens a textual input port for the file named by +path. +An exception is raised with condition type +&i/o-filename if the file does not exist or cannot be +opened for input. + +
+options, if present, is a symbolic option name or option list. +Possible symbolic option names are +compressed, uncompressed, buffered, +and unbuffered. +An option list is a list containing zero or more symbolic option names. + +
+The mutually exclusive compressed and +uncompressed options determine whether the input file +should be decompressed if it is compressed (where the compression +format is inferred). +(See open-output-file.) +The default is uncompressed, so the uncompressed +option is useful only as documentation. + +
+The mutually exclusive buffered and unbuffered +options determine whether input is buffered. +When input is buffered, it is read in large blocks and buffered internally +for efficiency to reduce the number of operating system requests. +When the unbuffered option is specified, input is unbuffered, +but not fully, since one character of buffering is required to support +peek-char and unread-char. +Input is buffered by default, so the buffered option is useful +only as documentation. + + +
+For example, the call + +
+ +
(open-input-file "frob" '(compressed)) +
opens the file frob with decompression enabled. + +
+The Revised6 Report version of open-input-file does not +support the optional options argument. + +
+procedure: (call-with-input-file path procedure)
+
procedure: (call-with-input-file path procedure options)
+
+returns: the values returned by procedure
+
+libraries: (chezscheme)
+
+
path must be a string. +procedure should accept one argument. + +
+call-with-input-file creates a new input port for the file named +by path, as if with open-input-file, and passes this port to procedure. +If procedure returns normally, call-with-input-file closes the input port +and returns the values returned by procedure. + +
+call-with-input-file does not automatically close the input +port if a continuation created outside of procedure is invoked, since it +is possible that another continuation created inside of procedure will be +invoked at a later time, returning control to procedure. +If procedure does not return, an implementation is free to close the +input port only if it can prove that the input port is no longer accessible. +As shown in Section 5.6 of The Scheme Programming Language, 4th Edition, dynamic-wind may be used to +ensure that the port is closed if a continuation created outside of +procedure is invoked. + +
+See open-input-file above for a description of the optional +options argument. + +
+The Revised6 Report version of call-with-input-file does not +support the optional input argument. + +
+procedure: (with-input-from-file path thunk)
+
procedure: (with-input-from-file path thunk options)
+
+returns: the values returned by thunk
+
+libraries: (chezscheme)
+
+
path must be a string. +thunk must be a procedure and should accept zero arguments. + +
+with-input-from-file temporarily changes the current input port to be the +result of opening the file named by path, as if with open-input-file, during the +application of thunk. +If thunk returns, the port is closed and the current input port +is restored to its old value. + +
+The behavior of with-input-from-file is unspecified +if a continuation created outside +of thunk is invoked before thunk returns. +An implementation may close the port and restore the current input +port to its old value---but it may not. + +
+See open-input-file above for a description of the optional +options argument. + +
+The Revised6 Report version of with-input-from-file does not +support the optional options argument. + +
+procedure: (open-fd-input-port fd)
+
procedure: (open-fd-input-port fd b-mode)
+
procedure: (open-fd-input-port fd b-mode ?transcoder)
+
+returns: a new input port for the file descriptor fd
+
+libraries: (chezscheme)
+
+
fd must be a nonnegative exact integer and should be a valid +open file descriptor. +If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual input port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary input port. +See the lead-in to Section 7.2 of The Scheme Programming Language, 4th Edition +for a description of the constraints on and effects of the other +arguments. + +
+The file descriptor is closed when the port is closed. + +
+procedure: (standard-input-port)
+
procedure: (standard-input-port b-mode)
+
procedure: (standard-input-port b-mode ?transcoder)
+
+returns: a new input port connected to the process's standard input
+
+libraries: (chezscheme)
+
+
If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual input port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary input port. +The buffer mode b-mode defaults to block. + +
+The Revised6 Report version of this procedure does not accept the +optional b-mode and ?transcoder arguments, which limits +it to an implementation-dependent buffering mode (block in +Chez Scheme) and binary output. + +
+procedure: (get-string-some textual-input-port)
+
+returns: a nonempty string or the eof object
+
+libraries: (chezscheme)
+
+
If textual-input-port is at end of file, the eof object is returned. +Otherwise, get-string-some reads (as if with get-u8) +at least one character and possibly more, and returns a string containing +these characters. +The port's position is advanced past the characters read. +The maximum number of characters read by this operation is implementation-dependent. + +
+An exception to the "at least one character" guarantee occurs +if the port is in nonblocking mode (see set-port-nonblocking!) +and no input is ready. +In this case, an empty string is returned. + + +
+procedure: (get-string-some! textual-input-port string start n)
+
+returns: the count of characters read, as an exact nonnegative integer, or the eof object
+
+libraries: (chezscheme)
+
+
start and n must be exact nonnegative integers, and the sum of +start and n must not exceed the length of string. + +
+If n is 0, this procedure returns zero without attempting to +read from textual-input-port and without modifying string. + +
+Otherwise, if textual-input-port is at end of file, this procedure +returns the eof object, except it returns zero when the port is in nonblocking mode +(see set-port-nonblocking!) and the port cannot be determined +to be at end of file without blocking. +In either case, string is not modified. + +
+Otherwise, this procedure reads (as if with get-char) +up to n characters from the port, stores the characters in consecutive locations of string +starting at start, advances the port's position just past the characters read, and +returns the count of characters read. + +
+If the port is in nonblocking mode, this procedure reads no more +than it can without blocking and thus might read zero characters; +otherwise, it reads at least one character but no more than are available +when the first character becomes available. + +
+procedure: (get-bytevector-some! binary-input-port bytevector start n)
+
+returns: the count of bytes read, as an exact nonnegative integer, or the eof object
+
+libraries: (chezscheme)
+
+
start and n must be exact nonnegative integers, and the sum of +start and n must not exceed the length of bytevector. + +
+If n is 0, this procedure returns zero without attempting to +read from binary-input-port and without modifying bytevector. + +
+Otherwise, if binary-input-port is at end of file, this procedure +returns the eof object, except it returns zero when the port is in nonblocking mode +(see set-port-nonblocking!) and the port cannot be determined +to be at end of file without blocking. +In either case, bytevector is not modified. + +
+Otherwise, this procedure reads (as if with get-u8) +up to n bytes from the port, stores the bytes in consecutive locations of bytevector +starting at start, advances the port's position just past the bytes read, and +returns the count of bytes read. + +
+If the port is in nonblocking mode, this procedure reads no more +than it can without blocking and thus might read zero bytes; +otherwise, it reads at least one byte but no more than are available +when the first byte becomes available. + +
+procedure: (unread-char char)
+
procedure: (unread-char char textual-input-port)
+
procedure: (unget-char textual-input-port char)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
For unread-char, if textual-input-port is not supplied, it +defaults to the current input port. +These procedures "unread" the last character read from +textual-input-port. +char may or may not be ignored, depending upon the implementation. +In any case, char should be last character read from the port. +A character should not be unread twice on the same port +without an intervening call to read-char or get-char. + +
+unread-char and unget-char are provided for applications +requiring one character of lookahead and may be used in place of, or even +in combination with, peek-char or lookahead-char. +One character of lookahead is required in the procedure +read-word, which is defined below in terms of unread-char. +read-word returns the next word from a textual input port as a string, where +a word is defined to be a sequence of alphabetic characters. +Since it does not know until it reads one character too many that it has +read the entire word, read-word uses unread-char to +return the character to the input port. + +
+ +
(define read-word
+
+ (lambda (p)
+
+ (list->string
+
+ (let f ([c (read-char p)])
+
+ (cond
+
+ [(eof-object? c) '()]
+
+ [(char-alphabetic? c)
+
+ (cons c (f (read-char p)))]
+
+ [else
+
+ (unread-char c p)
+
+ '()])))))
+
In the alternate version below, peek-char is used instead of +unread-char. + +
+ +
(define read-word
+
+ (lambda (p)
+
+ (list->string
+
+ (let f ([c (peek-char p)])
+
+ (cond
+
+ [(eof-object? c) '()]
+
+ [(char-alphabetic? c)
+
+ (read-char p)
+
+ (cons c (f (peek-char p)))]
+
+ [else '()])))))
+
The advantage of unread-char in this situation is that only +one call to unread-char per word is required, whereas one +call to peek-char is required for each character in the word +plus the first character beyond. +In many cases, unread-char and unget-char do not enjoy +this advantage, and peek-char or lookahead-char +should be used instead. + + +
+procedure: (unget-u8 binary-input-port octet)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedures "unreads" the last byte read from +binary-input-port. +octet may or may not be ignored, depending upon the implementation. +In any case, octet should be last byte read from the port. +A byte should not be unread twice on the same port +without an intervening call to get-u8. + + +
+procedure: (input-port-ready? input-port)
+
+returns: #t if data is available on input-port, #f otherwise
+
+libraries: (chezscheme)
+
+
input-port-ready? allows a program to check to see if input is +available on a textual or binary input port without hanging. +If input is available or the port is at end of file, +input-port-ready? returns #t. +If it cannot determine from the port whether input is ready, +input-port-ready? raises an exception with condition type +&i/o-read-error. +Otherwise, it returns #f. + +
+procedure: (char-ready?)
+
procedure: (char-ready? textual-input-port)
+
+returns: #t if a character is available on textual-input-port, #f otherwise
+
+libraries: (chezscheme)
+
+
If textual-input-port is not supplied, it defaults to the current input port. +char-ready? is like input-port-ready? except it is +restricted to textual input ports. + + +
+procedure: (block-read textual-input-port string)
+
procedure: (block-read textual-input-port string count)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
count must be a nonnegative fixnum less than or equal to the +length of string. +If not provided, it defaults to the length of string. + +
+If textual-input-port is at end-of-file, an eof object is returned. +Otherwise, string is filled with as many characters as are +available for reading from textual-input-port up to count, +and the number of characters placed in the string is returned. + +
+If textual-input-port is buffered and the buffer is nonempty, +the buffered input or a portion thereof is returned; otherwise +block-read bypasses the buffer entirely. + +
+procedure: (read-token)
+
procedure: (read-token textual-input-port)
+
procedure: (read-token textual-input-port sfd bfp)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor. +bfp must be an exact nonnegative integer and should be the +character position of the next character to be read from +textual-input-port. + +
+Parsing of a Scheme datum is conceptually performed in two steps. +First, the sequence of characters that form the datum are grouped into +tokens, such as symbols, numbers, left parentheses, and +double quotes. +During this first step, whitespace and comments are discarded. +Second, these tokens are grouped into data. + +
+read performs both of these steps and creates an internal +representation of each datum it parses. +read-token may be used to perform the first step only, one +token at a time. +read-token is intended to be used by editors and program +formatters that must be able to parse a program or datum without +actually reading it. + +
+If textual-input-port is not supplied, it defaults to the current input port. +One token is read from the input port and returned as four values: + +
+
+
+
+
+The input port is left pointing to the first character position beyond +the token. + +
+When the token type fully specifies the token, +read-token returns #f for the value. +The token types are listed below with the corresponding value +in parentheses. + +
+
+The set of token types is likely to change in future releases of the +system; check the release notes for details on such changes. + +
+Specifying sfd and bfp improves the quality of error messages, +guarantees start and end can be determined, +and eliminates the overhead of asking for a file position on each call +to read-token. +In most cases, bfp should be 0 for the first call +to read-token at the start of a file, +and it should be the fourth return value (end) of the preceding +call to read-token for each subsequent +call. +This protocol is necessary to handle files containing multiple-byte +characters, since file positions do not necessarily correspond +to character positions. + +
+ +
(define s (open-input-string "(a b c)"))
+
+(read-token s) lparen
+
+ #f
+
+ 0
+
+ 1
+
+(define s (open-input-string "abc 123"))
+
+(read-token s) atomic
+
+ abc
+
+ 0
+
+ 3
+
+(define s (open-input-string ""))
+
+(read-token s) eof
+
+ #!eof
+
+ 0
+
+ 0
+
+(define s (open-input-string "#7=#7#"))
+
+(read-token s) mark
+
+ 7
+
+ 0
+
+ 3
+
+(read-token s) insert
+
+ 7
+
+ 3
+
+ 6
+
The information read-token returns is not always +sufficient for reconstituting the exact sequence of characters that +make up a token. +For example, 1.0 and 1e0 both return +type atomic with value 1.0. +The exact sequence of characters may be obtained only by repositioning +the port and reading a block of characters of the appropriate length, +using the relative positions given by start and end. + + +
+ +
+global parameter: console-output-port
+
+libraries: (chezscheme)
+
+
console-output-port is a parameter that determines the +output port used by the waiter and interactive debugger. +When called with no arguments, it returns the +console output port. +When called with one argument, which must be a textual output port, +it changes the value of the console +output port. +The initial value of this parameter is a port tied to the standard +output (stdout) stream of the Scheme process. + + +
+thread parameter: current-output-port
+
+libraries: (chezscheme)
+
+
current-output-port is a parameter that determines the +default port argument for most output procedures, +including write-char, newline, write, +display, and pretty-print. +When called with no arguments, current-output-port returns the +current output port. +When called with one argument, which must be a textual output port, +it changes the value of the current +output port. +The Revised6 Report version of current-output-port accepts +only zero arguments, i.e., it cannot be used to change the current output +port. +The initial value of this parameter is the same port as the initial +value of console-output-port. + + +
+thread parameter: console-error-port
+
+libraries: (chezscheme)
+
+
console-error-port is a parameter that can be used to set +or obtain the console error port, which determines the port to which +conditions and other messages are printed by the default exception +handler. +When called with no arguments, console-error-port returns the +console error port. +When called with one argument, which must be a textual output port, +it changes the value of the console +error port. + +
+If the system determines that the standard output (stdout) and standard +error (stderr) streams refer to the same file, socket, pipe, virtual +terminal, device, etc., this parameter is initially set to the same value +as the parameter console-output-port. +Otherwise, this parameter is initially set to a different port tied to the +standard error (stderr) stream of the Scheme process. + +
+thread parameter: current-error-port
+
+libraries: (chezscheme)
+
+
current-error-port is a parameter that can be used to set +or obtain the current error port. +When called with no arguments, current-error-port returns the +current error port. +When called with one argument, which must be a textual output port, +it changes the value of the current error port. +The Revised6 Report version of current-error-port accepts +only zero arguments, i.e., it cannot be used to change the current error +port. +The initial value of this parameter is the same port as the initial +value of console-error-port. + +
+procedure: (open-output-file path)
+
procedure: (open-output-file path options)
+
+returns: a new output port
+
+libraries: (chezscheme)
+
+
path must be a string. +open-output-file opens a textual output port for the file named by +path. + +
+options, if present, is a symbolic option name or option list. +Possible symbolic option names are +error, truncate, replace, append, +compressed, uncompressed, buffered, +unbuffered, exclusive, and nonexclusive. +An option list is a list containing zero or more symbolic option names +and possibly the two-element +option mode mode. + +
+The mutually exclusive error, truncate, +replace, and append options are used to direct what happens when +the file to be opened already exists. +
+The mutually exclusive compressed and +uncompressed options determine whether the output file is to +be compressed. +The compression format and level are determined by the +compress-format +and +compress-level +parameters. +Files are uncompressed by default, so the uncompressed +option is useful only as documentation. + +
+The mutually exclusive buffered and unbuffered +options determine whether output is buffered. +Unbuffered output is sent immediately to the file, whereas buffered +output not written until the port's output buffer is filled or the +port is flushed (via flush-output-port) or closed (via +flush-output-port or by the storage management system when +the port becomes inaccessible). +Output is buffered by default for efficiency, so the +buffered option is useful only as documentation. + +
+The mutually exclusive exclusive and nonexclusive +options determine whether access to the file is "exclusive." +When the exclusive option is specified, the file is locked until +the port is closed to prevent access by other processes. +On some systems the lock is advisory, i.e., it inhibits access by +other processes only if they also attempt to open exclusively. +Nonexclusive access is the default, so the nonexclusive option +is useful only as documentation. + +
+The mode option determines the permission bits +on Unix systems when the file is created by the operation, subject +to the process umask. +The subsequent element in the options list must be an exact integer +specifying the permissions in the manner of the Unix open +function. +The mode option is ignored under Windows. + +
+For example, the call + +
+ +
(open-output-file "frob" '(compressed truncate mode #o644)) +
opens the file frob with compression enabled. +If frob already exists it is truncated. +On Unix-based systems, if frob does not already exist, the permission +bits on the newly created file are set to logical and of #o644 and the +process's umask. + +
+The Revised6 Report version of open-output-file does not +support the optional options argument. + +
+procedure: (call-with-output-file path procedure)
+
procedure: (call-with-output-file path procedure options)
+
+returns: the values returned by procedure
+
+libraries: (chezscheme)
+
+
path must be a string. +procedure should accept one argument. + +
+call-with-output-file creates a new output port for the file named +by path, as if with open-output-file, and passes this port to procedure. +If procedure returns, call-with-output-file closes the output port +and returns the values returned by procedure. + +
+call-with-output-file does not automatically close the output +port if a continuation created outside of procedure is invoked, since it +is possible that another continuation created inside of procedure will be +invoked at a later time, returning control to procedure. +If procedure does not return, an implementation is free to close the +output port only if it can prove that the output port is no longer accessible. +As shown in Section 5.6 of The Scheme Programming Language, 4th Edition, dynamic-wind may be used to +ensure that the port is closed if a continuation created outside of +procedure is invoked. + +
+See open-output-file above for a description of the optional +options argument. + +
+The Revised6 Report version of call-with-output-file does not +support the optional options argument. + + +
+procedure: (with-output-to-file path thunk)
+
procedure: (with-output-to-file path thunk options)
+
+returns: the value returned by thunk
+
+libraries: (chezscheme)
+
+
path must be a string. +thunk must be a procedure and should accept zero arguments. + +
+with-output-to-file temporarily rebinds the current output port to be the +result of opening the file named by path, as if with open-output-file, +during the application of thunk. +If thunk returns, the port is closed and the current output port +is restored to its old value. + +
+The behavior of with-output-to-file is unspecified if a +continuation created outside of thunk is invoked before +thunk returns. +An implementation may close the port and restore the current output +port to its old value---but it may not. + +
+See open-output-file above for a description of the optional +options argument. + +
+The Revised6 Report version of with-output-to-file does not +support the optional options argument. + +
+procedure: (open-fd-output-port fd)
+
procedure: (open-fd-output-port fd b-mode)
+
procedure: (open-fd-output-port fd b-mode ?transcoder)
+
+returns: a new output port for the file descriptor fd
+
+libraries: (chezscheme)
+
+
fd must be a nonnegative exact integer and should be a valid +open file descriptor. +If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual output port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary output port. +See the lead-in to Section 7.2 of The Scheme Programming Language, 4th Edition +for a description of the constraints on and effects of the other +arguments. + +
+The file descriptor is closed when the port is closed. + +
+procedure: (standard-output-port)
+
procedure: (standard-output-port b-mode)
+
procedure: (standard-output-port b-mode ?transcoder)
+
+returns: a new output port connected to the process's standard output
+
+libraries: (chezscheme)
+
+
If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual output port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary output port. +The buffer mode b-mode defaults to line, which differs from +block in Chez Scheme only for textual output ports. + +
+The Revised6 Report version of this procedure does not accept the +optional b-mode and ?transcoder arguments, which limits +it to an implementation-dependent buffering mode (line in +Chez Scheme) and binary output. + + +
+procedure: (standard-error-port)
+
procedure: (standard-error-port b-mode)
+
procedure: (standard-error-port b-mode ?transcoder)
+
+returns: a new output port connected to the process's standard error
+
+libraries: (chezscheme)
+
+
If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual output port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary output port. +The buffer mode b-mode defaults to none. +See the lead-in to Section 7.2 of The Scheme Programming Language, 4th Edition +for a description of the constraints on and effects of the other +arguments. + +
+The Revised6 Report version of this procedure does not accept the +optional b-mode and ?transcoder arguments, which limits +it to an implementation-dependent buffering mode (none in +Chez Scheme) and binary output. + + +
+procedure: (put-bytevector-some binary-output-port bytevector)
+
procedure: (put-bytevector-some binary-output-port bytevector start)
+
procedure: (put-bytevector-some binary-output-port bytevector start n)
+
+returns: the number of bytes written
+
+libraries: (chezscheme)
+
+
start and n must be nonnegative exact integers, and the sum of +start and n must not exceed the length of bytevector. +If not supplied, start defaults to zero and n defaults to +the difference between the length of bytevector and start. + +
+This procedure normally writes the n bytes of bytevector +starting at start to the port and advances the its position past the +end of the bytes written. +If the port is in nonblocking mode (see set-port-nonblocking!), +however, the number of bytes written may be less than n, if +the system would have to block to write more bytes. + + +
+procedure: (put-string-some textual-output-port string)
+
procedure: (put-string-some textual-output-port string start)
+
procedure: (put-string-some textual-output-port string start n)
+
+returns: the number of characters written
+
+libraries: (chezscheme)
+
+
start and n must be nonnegative exact integers, and the sum of +start and n must not exceed the length of string. +If not supplied, start defaults to zero and n defaults to +the difference between the length of string and start. + +
+This procedure normally writes the n characters of string +starting at start to the port and advances the its position past the +end of the characters written. +If the port is in nonblocking mode (see set-port-nonblocking!), +however, the number of characters written may be less than n, if +the system would have to block to write more characters. + + +
+procedure: (display-string string)
+
procedure: (display-string string textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
display-string writes the characters contained within +string to textual-output-port or to the current-output port +if textual-output-port is not specified. +The enclosing string quotes are not printed, and special characters +within the string are not escaped. +display-string is a more efficient alternative to +display for displaying strings. + +
+procedure: (block-write textual-output-port string)
+
procedure: (block-write textual-output-port string count)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
count must be a nonnegative fixnum less than or equal to the +length of string. +If not provided, it defaults to the length of string. + +
+block-write writes the first count characters of string +to textual-output-port. +If the port is buffered and the buffer is nonempty, the +buffer is flushed before the contents of string are written. +In any case, the contents of string are written immediately, +without passing through the buffer. + +
+procedure: (truncate-port output-port)
+
procedure: (truncate-port output-port pos)
+
procedure: (truncate-file output-port)
+
procedure: (truncate-file output-port pos)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
truncate-port and truncate-file are identical. + +
+pos must be an exact nonnegative integer. It defaults to 0. + +
+These procedures truncate the file or other object associated with +output-port to pos and repositions the port +to that position, i.e., it combines the functionality of +set-port-length! and set-port-position! and +can be called on a port only if port-has-set-port-length!? and +port-has-set-port-position!? are both true of the port. + + +
+
+procedure: (fresh-line)
+
procedure: (fresh-line textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If textual-output-port is not supplied, it defaults to the current output port. + +
+This procedure behaves like newline, i.e., sends a newline +character to textual-output-port, unless it can determine that the port +is already positioned at the start of a line. +It does this by flushing the port and consulting the +"beginning-of-line" (BOL) flag associated with the port. +(See page 249.) + + +
+ +
+procedure: (open-input-output-file path)
+
procedure: (open-input-output-file path options)
+
+returns: a new input-output port
+
+libraries: (chezscheme)
+
+
path must be a string. +open-input-output-file opens a textual input-output port for the file named by +path. + +
+The port may be used to read from or write to the named file. +The file is created if it does not already exist. + +
+options, if present, is a symbolic option name or option list. +Possible symbolic option names are +buffered, +unbuffered, exclusive, and nonexclusive. +An option list is a list containing zero or more symbolic option names +and possibly the two-element +option mode mode. +See the description of open-output-file for an explanation +of these options. + +
+Input/output files are usually closed using close-port +but may also be closed with either +close-input-port or +close-output-port. + +
+procedure: (open-fd-input/output-port fd)
+
procedure: (open-fd-input/output-port fd b-mode)
+
procedure: (open-fd-input/output-port fd b-mode ?transcoder)
+
+returns: a new input/output port for the file descriptor fd
+
+libraries: (chezscheme)
+
+
fd must be a nonnegative exact integer and should be a valid +open file descriptor. +If ?transcoder is present and not #f, it must be a +transcoder, and this procedure returns a textual input/output port +whose transcoder is ?transcoder. +Otherwise, this procedure returns a binary input/output port. +See the lead-in to Section 7.2 of The Scheme Programming Language, 4th Edition +for a description of the constraints on and effects of the other +arguments. + +
+The file descriptor is closed when the port is closed. + + +
+ +
+The procedures described in this section convert bytevectors containing +single- and multiple-byte sequences in non-Unicode character sets to and +from Scheme strings. +They are available only under Windows. +Under other operating systems, and when an iconv DLL is +available under Windows, bytevector->string and +string->bytevector can be used with a transcoder based +on a codec constructed via +iconv-codec +to achieve the same results, with more control over the handling +of invalid characters and line endings. + +
+procedure: (multibyte->string code-page bytevector)
+
+returns: a string containing the characters encoded in bytevector
+
procedure: (string->multibyte code-page string)
+
+returns: a bytevector containing the encodings of the characters in string
+
+libraries: (chezscheme)
+
+
These procedures are available only under Windows. +The procedure multibyte->string is a wrapper for the Windows API +MultiByteToWideChar function, +and string->multibyte is a wrapper for the Windows API +WideCharToMultiByte function. + +
+code-page declares the encoding of the byte sequences in the input +or output bytevectors. +It must be an exact nonnegative integer identifying a code page or one of +the symbols cp-acp, cp-maccp, cp-oemcp, +cp-symbol, cp-thread-acp, cp-utf7, or +cp-utf8, which have the same meanings as the API function +meanings for the like-named constants. + +
+ +
+The pretty printer is a version of the write procedure that +produces more human-readable output via introduced whitespace, i.e., +line breaks and indentation. +The pretty printer is the default printer used by the read-eval-print +loop (waiter) to print the output(s) of each evaluated form. +The pretty printer may also be invoked explicitly by calling the +procedure pretty-print. + +
+The pretty printer's operation can be controlled via the pretty-format +procedure described later in this section, which allows the +programmer to specify how specific forms are to be printed, various +pretty-printer controls, also described later in this section, and also +by the generic input/output controls described in Section 9.14. + +
+procedure: (pretty-print obj)
+
procedure: (pretty-print obj textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If textual-output-port is not supplied, it defaults to the current output port. + +
+pretty-print is similar to write except that it uses +any number of spaces and newlines in order to print obj in a +style that is pleasing to look at and which shows the nesting level via +indentation. +For example, + +
+ +
(pretty-print '(define factorial (lambda (n) (let fact ((i n) (a 1))
+
+ (if (= i 0) a (fact (- i 1) (* a i)))))))
+
might produce + +
+ +
(define factorial
+
+ (lambda (n)
+
+ (let fact ([i n] [a 1])
+
+ (if (= i 0) a (fact (- i 1) (* a i))))))
+
procedure: (pretty-file ifn ofn)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
ifn and ofn must be strings. +pretty-file reads each object in turn from the file named by +ifn and pretty prints the object to the file named by ofn. +Comments present in the input are discarded by the reader and so do +not appear in the output file. +If the file named by ofn already exists, it is replaced. + +
+procedure: (pretty-format sym)
+
+returns: see below
+
procedure: (pretty-format sym fmt)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
By default, the pretty printer uses a generic algorithm for printing +each form. +This procedure is used to override this default and guide the +pretty-printers treatment of specific forms. +The symbol sym names a syntactic form or procedure. +With just one argument, pretty-format returns the current +format associated with sym, or #f if no format is +associated with sym. + +
+In the two-argument case, the format fmt is associated with +sym for future invocations of the pretty printer. +fmt must be in the formatting language described below. + +
+ + + +
+<fmt> | (quote symbol) | |
+ | | | var |
+ | | | symbol |
+ | | | (read-macro string symbol) |
+ | | | (meta) |
+ | | | (bracket . fmt-tail) |
+ | | | (alt fmt fmt*) |
+ | | | fmt-tail |
+fmt-tail | () | |
+ | | | (tab fmt ...) |
+ | | | (fmt tab ...) |
+ | | | (tab fmt . fmt-tail) |
+ | | | (fmt ...) |
+ | | | (fmt . fmt-tail) |
+ | | | (fill tab fmt ...) |
+tab | int | |
+ | | | #f + |
+Some of the format forms are used for matching when there are multiple +alternatives, while others are used for matching and control indentation +or printing. +A description of each fmt is given below. + +
+
+
+
+
+
+
+
+
+Indentation of list-structured forms is determined via the +fmt-tail specifier used to the last two cases above. +A description of each fmt-tail is given below. + +
+
+
+
+
+
+
+
+A tab determines the amount by which a list subform is indented. +If tab is a nonnegative exact integer int, the subform +is indented int spaces in from the character position just after +the opening parenthesis or bracket of the parent form. +If tab is #f, the standard indentation is used. +The standard indentation can be determined or changed via the parameter +pretty-standard-indent, which is described later in this +section. + +
+In cases where a format is given that doesn't quite match, the pretty +printer tries to use the given format as far as it can. +For example, if a format matches a list-structured form with a specific +number of subforms, but more or fewer subform are given, the pretty +printer will discard or replicate subform formats as necessary. + +
+Here is an example showing the formatting of let might be specified. + +
+ +
(pretty-format 'let
+
+ '(alt (let ([bracket var x] 0 ...) #f e #f e ...)
+
+ (let var ([bracket var x] 0 ...) #f e #f e ...)))
+
Since let comes in two forms, named and unnamed, two alternatives +are specified. +In either case, the bracket fmt is used to enclose the +bindings in square brackets, with all bindings after the first appearing +just below the first (and just after the enclosing opening parenthesis), +if they don't all fit on one line. +Each body form is indented by the standard indentation. + +
+thread parameter: pretty-line-length
+
thread parameter: pretty-one-line-limit
+
+libraries: (chezscheme)
+
+
The value of each of these parameters must be a positive fixnum. + +
+The parameters pretty-line-length and +pretty-one-line-limit control the output produced by +pretty-print. +pretty-line-length determines after which character position (starting +from the first) on a line the pretty printer attempts to cut off output. +This is a soft limit only; if necessary, the pretty-printer will go beyond +pretty-line-length. + +
+pretty-one-line-limit is similar to +pretty-line-length, except that it is relative to the first +nonblank position on each line of output. +It is also a soft limit. + + +
+thread parameter: pretty-initial-indent
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a nonnegative fixnum. + +
+The parameter pretty-initial-indent is used to tell +pretty-print where on an output +line it has been called. +If pretty-initial-indent is zero (the default), pretty-print +assumes that the first line of output it produces will start at the +beginning of the line. +If set to a nonzero value n, pretty-print assumes that the first +line will appear at character position n and will adjust its +printing of subsequent lines. + + +
+thread parameter: pretty-standard-indent
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a nonnegative fixnum. + +
+This determines the amount by which +pretty-print indents subexpressions of most forms, such as let +expressions, from the form's keyword or first subexpression. + + +
+thread parameter: pretty-maximum-lines
+
+libraries: (chezscheme)
+
+
The parameter pretty-maximum-lines controls how many lines +pretty-print prints when it is called. +If set to #f (the default), no limit is imposed; if set to a +nonnegative fixnum n, at most n lines are printed. + + +
+ +
+procedure: (format format-string obj ...)
+
procedure: (format #f format-string obj ...)
+
procedure: (format #t format-string obj ...)
+
procedure: (format textual-output-port format-string obj ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
When the first argument to format is a string or #f (first and +second forms above), +format constructs an output string from format-string and the +objects obj .... +Characters are copied from format-string to the output string from +left to right, until format-string is exhausted. +The format string may contain one or more format directives, which are +multi-character sequences prefixed by a tilde ( ~ ). +Each directive is replaced by some other text, often involving one or more +of the obj ... arguments, as determined by the semantics +of the directive. + +
+When the first argument is #t, output is sent to the current output +port instead, as with printf. +When the first argument is a port, output is sent to that port, as with +fprintf. +printf and fprintf are described later in this section. + +
+Chez Scheme's implementation of format supports all of the +Common Lisp [30] format directives except for those specific +to the Common Lisp pretty printer. +Please consult a Common Lisp reference or the +Common Lisp Hyperspec, +for complete documentation. +A few of the most useful directives are described below. + + +
+Absent any format directives, format simply displays its string +argument. + +
+ +
(format "hi there") "hi there" +
The ~s directive is replaced by the printed representation of +the next obj, which may be any object, in machine-readable format, +as with write. + +
+ +
(format "hi ~s" 'mom) "hi mom"
+
+(format "hi ~s" "mom") "hi \"mom\""
+
+(format "hi ~s~s" 'mom #\!) "hi mom#\\!"
+
The general form of a ~s directive is actually +~mincol,colinc,minpad,padchars, +and the s can be preceded by an at sign ( @ ) +modifier. +These additional parameters are used to control padding in the +output, with at least minpad copies of padchar +plus an integer multiple of colinc copies of padchar +to make the total width, including the written object, +mincol characters wide. +The padding is placed on the left if the @ modifier is +present, otherwise on the right. +mincol and minpad default to 0, colinc defaults +to 1, and padchar defaults to space. +If specified, padchar is prefixed by a single quote mark. + +
+ +
(format "~10s" 'hello) "hello "
+
+(format "~10@s" 'hello) " hello"
+
+(format "~10,,,'*@s" 'hello) "*****hello"
+
The ~a directive is similar, but prints the object as with +display. + +
+ +
(format "hi ~s~s" "mom" #\!) "hi \"mom\"#\\!"
+
+(format "hi ~a~a" "mom" #\!) "hi mom!"
+
A tilde may be inserted into the output with ~~, and a newline +may be inserted with ~% (or embedded in the string with +\n). + +
+ +
(format "~~line one,~%line two.~~") "~line one,\nline two.~"
+
+(format "~~line one,\nline two.~~") "~line one,\nline two.~"
+
Real numbers may be printed in floating-point notation with ~f. + +
+ +
(format "~f" 3.14159) 3.14159 +
Exact numbers may printed as well as inexact numbers in this manner; they +are simply converted to inexact first as if with exact->inexact. + +
+ +
(format "~f" 1/3) "0.3333333333333333" +
The general form is actually ~w,d,k,overflowchar,padcharf. +If specified, w determines the overall width of the output, +and d the number of digits to the right of the decimal point. +padchar, which defaults to space, is the pad character used +if padding is needed. +Padding is always inserted on the left. +The number is scaled by 10k when printed; k defaults to zero. +The entire w-character field is filled with copies of +overflowchar if overflowchar is specified and the number +cannot be printed in w characters. +k defaults to 1 +If an @ modifier is present, a plus sign is printed before the +number for nonnegative inputs; otherwise, a sign is printed only if the +number is negative. + +
+ +
(format "~,3f" 3.14159) "3.142"
+
+(format "~10f" 3.14159) " 3.14159"
+
+(format "~10,,,'#f" 1e20) "##########"
+
Real numbers may also be printed with ~e for scientific +notation or with ~g, which uses either floating-point or +scientific notation based on the size of the input. + +
+ +
(format "~e" 1e23) "1.0e+23"
+
+(format "~g" 1e23) "1.0e+23"
+
A real number may also be printed with ~$, which uses +monetary notation defaulting to two digits to the right of the +decimal point. + +
+ +
(format "$~$" (* 39.95 1.06)) "$42.35"
+
+(format "~$USD" 1/3) "0.33USD"
+
Words can be pluralized automatically using p. + +
(format "~s bear~:p in ~s den~:p" 10 1) "10 bears in 1 den" +
Numbers may be printed out in words or roman numerals using variations +on ~r. + +
+ +
(format "~r" 2599) "two thousand five hundred ninety-nine"
+
+(format "~:r" 99) "ninety-ninth"
+
+(format "~@r" 2599) "MMDXCIX"
+
Case conversions can be performed by bracketing a portion of the +format string with the ~@( and ~) directives. + +
+ +
(format "~@(~r~)" 2599) "Two thousand five hundred ninety-nine"
+
+(format "~@:(~a~)" "Ouch!") "OUCH!"
+
Some of the directives shown above have more options and parameters, and +there are other directives as well, including directives for conditionals, +iteration, indirection, and justification. +Again, please consult a Common Lisp reference for complete documentation. + +
+An implementation of a greatly simplified version of format +appears in Section 12.6 of The Scheme Programming Language, 4th Edition. + + +
+procedure: (printf format-string obj ...)
+
procedure: (fprintf textual-output-port format-string obj ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
These procedures are simple wrappers for format. +printf prints the formatted output to the current output, +as with a first-argument of #t to format, and +fprintf prints the formatted output to the textual-output-port, +as when the first argument to format is a port. + +
+ +
+The I/O control operations described in this section are used to +control how the reader reads and printer writes, displays, or +pretty-prints +characters, +symbols, +gensyms, +numbers, +vectors, +long or deeply nested lists or vectors, +and graph-structured objects. + + +
+
+procedure: (char-name obj)
+
+returns: see below
+
procedure: (char-name name char)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
char-name is used to associate names (symbols) with characters +or to retrieve the most recently associated name or character for a +given character or name. +A name can map to only one character, but more than one name +can map to the same character. +The name most recently associated with a character determines +how that character prints, and each name associated with a character +may be used after the #\ character prefix to name that +character on input. + +
+Character associations created by char-name are ignored by the +printer unless the parameter print-char-name is set to a true +value. +The reader recognizes character names established by char-name +except after #!r6rs, which is implied within a library or +R6RS top-level program. + +
+In the one-argument form, obj must be a symbol or character. +If it is a symbol and a character is associated with the +symbol, char-name returns that character. +If it is a symbol and no character is associated with the symbol, +char-name returns #f. +Similarly, if obj is a character, char-name returns the +most recently associated symbol for the character or #f if +no name is associated with the character. +For example, with the default set of character names: + +
+ +
(char-name #\space) space
+
+(char-name 'space) #\space
+
+(char-name 'nochar) #f
+
+(char-name #\a) #f
+
When passed two arguments, name is added to the set of names +associated with char, and any other association for name +is dropped. +char may be #f, in which case any other association +for name is dropped and no new association is formed. +In either case, any other names associated with char remain +associated with char. + +
+The following interactive session demonstrates the use of +char-name to establish and remove associations between +characters and names, including the association of more than +one name with a character. + +
+ +
(print-char-name #t)
+
+(char-name 'etx) #f
+
+(char-name 'etx #\x3)
+
+(char-name 'etx) #\etx
+
+(char-name #\x3) etx
+
+#\etx #\etx
+
+(eq? #\etx #\x3) #t
+
+#!r6rs #\etx exception: invalid character name etx
+
+#!chezscheme #\etx #\etx
+
+(char-name 'etx #\space)
+
+(char-name #\x3) #f
+
+(char-name 'etx) #\etx
+
+#\space #\etx
+
+(char-name 'etx #f)
+
+#\etx exception: invalid character name etx
+
+#\space #\space
+
(When using the expression editor, it is necessary to type Control-J to +force the editor to read the erroneous #\etx input on the two +inputs above that result in read errors, since typing Enter +causes the expression editor to read the input only if the input is +well-formed.) + +
+The reader does not recognize hex scalar value escapes in character names, +as it does in symbols, so #\new\x6c;ine is not equivalent +to #\newline. +In general, programmers should avoid the use of character name symbols +that cannot be entered without the use of hex scalar value escapes or +other symbol-name escape mechanisms, since such character names will +not be readable. + + +
+thread parameter: print-char-name
+
+libraries: (chezscheme)
+
+
When print-char-name is set to #f (the default), associations +created by char-name are ignored by write, +put-datum, pretty-print, and the format +"~s" directive. +Otherwise, these procedures use the names established by +char-name when printing character objects. + +
+ +
(char-name 'etx #\x3)
+
+(format "~s" #\x3) "#\\x3"
+
+(parameterize ([print-char-name #t])
+
+ (format "~s" #\x3)) "#\\etx"
+
thread parameter: case-sensitive
+
+libraries: (chezscheme)
+
+
The case-sensitive parameter determines whether the +reader is case-sensitive with respect to symbol and character names. +When set to true (the default, as required by the Revised6 Report) +the case of alphabetic characters +within symbol names is significant. +When set to #f, case is insignificant. +More precisely, when set to #f, symbol and character names are +folded (as if by string-foldcase); otherwise, they are left +as they appear in the input. + +
+The value of the case-sensitive matters only +if neither #!fold-case nor #!no-fold-case has appeared +previously in the same input stream. +That is, symbol and character name are folded if #!fold-case has +been seen. +They are not folded if #!no-fold-case has been seen. +If neither has been seen, they are folded if and only if +(case-sensitive) is #f. + +
+ +
(case-sensitive) #t
+
+(eq? 'abc 'ABC) #f
+
+'ABC ABC
+
+(case-sensitive #f)
+
+'ABC abc
+
+(eq? 'abc 'ABC) #t
+
thread parameter: print-graph
+
+libraries: (chezscheme)
+
+
When print-graph is set to a true value, +write and pretty-print +locate and print objects with shared structure, including +cycles, in a notation that may be read subsequently with read. +This notation employs the syntax +"#n=obj," +where n +is a nonnegative integer and obj is the printed representation +of an object, to label the first occurrence of obj in the output. +The syntax +"#n#" +is used to refer to the object labeled by +n thereafter in the output. +print-graph is set to #f by default. + +
+If graph printing is not enabled, +the settings of print-length and print-level +are insufficient to force finite output, +and write or pretty-print detects a cycle in an +object it is given to print, +a warning is issued (an exception with condition type &warning is +raised) and the object is printed as if +print-graph were enabled. + +
+Since objects printed through the ~s option in the format control +strings of format, printf, and fprintf are printed as with +write, the printing of such objects is also affected by print-graph. + +
+ +
(parameterize ([print-graph #t])
+
+ (let ([x (list 'a 'b)])
+
+ (format "~s" (list x x)))) "(#0=(a b) #0#)"
+
+
+(parameterize ([print-graph #t])
+
+ (let ([x (list 'a 'b)])
+
+ (set-car! x x)
+
+ (set-cdr! x x)
+
+ (format "~s" x))) "#0=(#0# . #0#)"
+
The graph syntax is understood by the procedure +read, allowing graph structures +to be printed and read consistently. + + +
+thread parameter: print-level
+
thread parameter: print-length
+
+libraries: (chezscheme)
+
+
These parameters can be used to limit the extent to which nested +or multiple-element structures are printed. +When called without arguments, print-level returns the current +print level and print-length returns the current print length. +When called with one argument, which must be a nonnegative fixnum or +#f, print-level sets the current print level and +print-length sets the current print length to the argument. + +
+When print-level is set to a nonnegative integer n, +write and pretty-print +traverse only n levels deep into nested structures. +If a structure being printed exceeds n levels of nesting, +the substructure beyond that point is replaced in the output by an +ellipsis +( ... ). +print-level is set to #f by default, which places +no limit on the number of levels printed. + +
+When print-length is set to a nonnegative integer n, the +procedures write and pretty-print +print only n elements of a list or vector, +replacing the remainder of the list or vector with an +ellipsis +( ... ). +print-length is set to #f by default, which places +no limit on the number of elements printed. + +
+Since objects printed through the ~s option in +the format control strings of format, printf, and fprintf are +printed as with write, +the printing of such objects is also affected by print-level +and print-length. + +
+The parameters print-level and print-length are useful for +controlling the volume of output in contexts where only a small portion +of the output is needed to identify the object being printed. +They are also useful in situations where circular structures may be +printed (see also print-graph). + +
+ +
(format "~s" '((((a) b) c) d e f g)) "((((a) b) c) d e f g)"
+
+
+(parameterize ([print-level 2])
+
+ (format "~s" '((((a) b) c) d e f g))) "(((...) c) d e f g)"
+
+
+(parameterize ([print-length 3])
+
+ (format "~s" '((((a) b) c) d e f g))) "((((a) b) c) d e ...)"
+
+
+(parameterize ([print-level 2]
+
+ [print-length 3])
+
+ (format "~s" '((((a) b) c) d e f g))) "(((...) c) d e ...)"
+
thread parameter: print-radix
+
+libraries: (chezscheme)
+
+
The print-radix parameter determines the radix in which +numbers are printed by write, pretty-print, and +display. +Its value should be an integer between 2 and 36, inclusive. +Its default value is 10. + +
+When the value of print-radix is not 10, write and +pretty-print print a radix prefix before the number +(#b for radix 2, #o for radix 8, #x for +radix 16, and #nr for any other radix n). + +
+Since objects printed through the ~s and +~a options in the format control strings of +format, printf, and fprintf are printed as +with write and display, the printing of such objects +is also affected by print-radix. + +
+ +
(format "~s" 11242957) "11242957"
+
+
+(parameterize ([print-radix 16])
+
+ (format "~s" 11242957)) "#xAB8DCD"
+
+
+(parameterize ([print-radix 16])
+
+ (format "~a" 11242957)) "AB8DCD"
+
thread parameter: print-gensym
+
+libraries: (chezscheme)
+
+
When +print-gensym is set to #t (the default) +gensyms are printed with an +extended symbol syntax that includes both the pretty name and the unique +name of the gensym: +#{pretty-name unique-name}. +When set to pretty, the pretty name only is shown, with the +prefix #:. +When set to pretty/suffix, +the printer prints the gensym's "pretty" name along with a +suffix based on the gensym's "unique" name, separated by a dot ( "." ). +If the gensym's unique name is generated automatically during the current +session, the suffix is that portion of the unique name that is not common +to all gensyms created during the current session. +Otherwise, the suffix is the entire unique name. +When set to #f, the pretty name only is shown, with no +prefix. + +
+Since objects printed through the ~s option in the +format control strings of format, printf, +errorf, etc., are printed as with write, the printing of +such objects is also affected by print-gensym. + +
+When printing an object that may contain more than one occurrence of a +gensym and print-graph is set to pretty or #f, +it is useful to set print-graph to #t so that +multiple occurrences of the same gensym are marked as identical in +the output. + +
+ +
(let ([g (gensym)])
+
+ (format "~s" g)) "#{g0 bdids2xl6v49vgwe-a}"
+
+
+(let ([g (gensym)])
+
+ (parameterize ([print-gensym 'pretty])
+
+ (format "~s" g))) "#:g1
+
+
+(let ([g (gensym)])
+
+ (parameterize ([print-gensym #f])
+
+ (format "~s" g))) "g2"
+
+
+(let ([g (gensym)])
+
+ (parameterize ([print-graph #t] [print-gensym 'pretty])
+
+ (format "~s" (list g g)))) "(#0=#:g3 #0#)"
+
+
+(let ([g1 (gensym "x")]
+
+ [g2 (gensym "x")]
+
+ [g3 (gensym "y")])
+
+ (parameterize ([print-gensym 'pretty/suffix])
+
+ (format "~s ~s ~s" g1 g2 g3))) "x.1 x.2 y.3"
+
thread parameter: print-brackets
+
+libraries: (chezscheme)
+
+
When print-brackets is set to a true value, the pretty printer +(see pretty-print) uses square +brackets rather than parentheses around certain subexpressions of +common control structures, e.g., around let bindings and +cond clauses. +print-brackets is set to #t by default. + +
+ +
(let ([p (open-output-string)])
+
+ (pretty-print '(let ([x 3]) x) p) "(let ([x 3]) x)
+
+ (get-output-string p)) "
+
+
+(parameterize ([print-brackets #f])
+
+ (let ([p (open-output-string)])
+
+ (pretty-print '(let ([x 3]) x) p) "(let ((x 3)) x)
+
+ (get-output-string p))) "
+
thread parameter: print-extended-identifiers
+
+libraries: (chezscheme)
+
+
Chez Scheme extends the syntax of identifiers as described in +Section 1.1, except within a set of forms prefixed by +#!r6rs (which is implied in a library or top-level program). + +
+When this parameter is set to false (the default), identifiers in the +extended set are printed with hex scalar value escapes as necessary to +conform to the R6RS syntax for identifiers. +When this parameter is set to a true value, identifiers in the +extended set are printed without the escapes. +Identifiers whose names fall outside of both syntaxes are printed with +the escapes regardless of the setting of this parameter. + +
+For example: + +
+ +
(parameterize ([print-extended-identifiers #f])
+
+ (printf "~s\n~s\n"
+
+ '(1+ --- { } .xyz)
+
+ (string->symbol "123")))
+
prints + +
+ +
(\x31;+ \x2D;-- \x7B; \x7D; \x2E;xyz)
+
+\x31;23
+
while + +
+ +
(parameterize ([print-extended-identifiers #t])
+
+ (printf "~s\n~s\n"
+
+ '(1+ --- { } .xyz)
+
+ (string->symbol "123")))
+
prints + +
+ +
(1+ --- { } .xyz)
+
+\x31;23
+
thread parameter: print-vector-length
+
+libraries: (chezscheme)
+
+
When print-vector-length is set to a true value, +write, put-datum, and pretty-print includes the length +for all vectors between the "#" and open parenthesis, +all bytevectors between the "#vu8" and open parenthesis, +and all fxvectors between the "#vfx" and open parenthesis. +This parameter is set to #f by default. + +
+When print-vector-length is set to a +true value, write, put-datum, and pretty-print +also suppress duplicated trailing elements in the vector to +reduce the amount of output. +This form is also recognized by the reader. + +
+Since objects printed through the ~s option in the +format control strings of format, printf, and +fprintf are printed as with write, the printing of +such objects is also affected by the setting of +print-vector-length. + +
+ +
(format "~s" (vector 'a 'b 'c 'c 'c)) "#(a b c c c)"
+
+
+(parameterize ([print-vector-length #t])
+
+ (format "~s" (vector 'a 'b 'c 'c 'c))) "#5(a b c)"
+
+
+(parameterize ([print-vector-length #t])
+
+ (format "~s" (bytevector 1 2 3 4 4 4))) "#6vu8(1 2 3 4)"
+
+
+(parameterize ([print-vector-length #t])
+
+ (format "~s" (fxvector 1 2 3 4 4 4))) "#6vfx(1 2 3 4)"
+
thread parameter: print-precision
+
+libraries: (chezscheme)
+
+
When print-precision is set to #f (the default), +write, put-datum, pretty-print, and the +format "~s" directive do not include the +vertical-bar "mantissa-width" syntax after each floating-point +number---except for subnormal floating-point numbers, in which case precision printing +is controlled by print-subnormal-precision. +When set to a nonnegative exact integer, the mantissa width is +included, as per the precision argument to +number->string. + +
+ +
(format "~s" 1e-100) "1e-100"
+
+(parameterize ([print-precision 32])
+
+ (format "~s" 1e-100)) ; => "1e-100|53"
+
+(format "~s" 1e-310) "1e-310|45"
+
thread parameter: print-subnormal-precision
+
+libraries: (chezscheme)
+
+
When print-subnormal-precision is set to a true value (the default), +write, put-datum, pretty-print, and the +format "~s" directive include the +vertical-bar "mantissa-width" syntax after each floating-point +number whose value is subnormal (roughly 4.94e-324 to 2.225e-308), +regardless of the value of print-precision. +When print-subnormal-precision and print-precision are +both set to #f, precision is not printed for a subnormal value. + +
+ +
(format "~s" 1e-310) "1e-310|45"
+
+(parameterize ([print-subnormal-precision #f])
+
+ (format "~s" 1e-310)) ; => "1e-310"
+
+(parameterize ([print-precision 32]
+
+ [print-subnormal-precision #f])
+
+ (format "~s" 1e-310)) ; => "1e-310|45"
+
thread parameter: print-positive-exponent-sign
+
+libraries: (chezscheme)
+
+
When print-positive-exponent-sign is set to a true value, then +when a flonum is printed in exponential form and the exponent is positive, +a plus sign is written before the exponent. When +print-positive-exponent-sign is set #f (the +default), no plus sign is written before a positive exponent. + +
+thread parameter: print-select-flonum-exponential-format
+
+libraries: (chezscheme)
+
+
The value of print-select-flonum-exponential-format must be a +procedure that accepts three arguments: a radix as an integer +between 2 and 36 (inclusive), an exponent as an integer, and +the number of non-zero significant digits in the flonum's printed form +using the matissa (where the first digit is before the "decimal" point). +If the procedure returns a true value, a number is printed in expotential +form, otherwise it is printed in nonexponential form. + +
+ +
(format "~s ~s" 1e2 1e8) "100.0 100000000.0"
+
+(parameterize ([print-select-flonum-exponential-format
+
+ (lambda (radix exponent digits)
+
+ (> exponent 3))])
+
+ (format "~s ~s" 1e2 1e8)) "100.0 1e8"
+
+(parameterize ([print-select-flonum-exponential-format
+
+ (lambda (radix exponent digits)
+
+ (< digits 3))])
+
+ (format "~s ~s ~s" 1e2 1.5e8 3.14159e-8)) "1e2 1.5e8 0.0000000314159"
+
thread parameter: print-unicode
+
+libraries: (chezscheme)
+
+
When print-unicode is set to #f, +write, put-datum, pretty-print, and the +format "~s" directive display Unicode characters +with encodings 8016 (128) and above that appear +within character objects, symbols, and strings +using hexadecimal character escapes. +When set to a true value (the default), they are displayed like +other printing characters, as if by put-char. + +
+ +
(format "~s" #\x3bb) "#\\"
+
+(parameterize ([print-unicode #f])
+
+ (format "~s" #\x3bb)) "#\\x3BB"
+
+
+The procedures write and pretty-print print objects in a +human readable format. +For objects with external datum representations, the output produced by +write and pretty-print is also machine-readable with +read. +Objects with external datum representations include pairs, symbols, +vectors, strings, numbers, characters, booleans, and records but not +procedures and ports. + +
+An alternative fast loading, or fasl, format may be used for +objects with external datum representations. +The fasl format is not human readable, but it is machine readable and both +more compact and more quickly processed by read. +This format is always used for compiled code generated by +compile-file, but it may also be used for data that needs to be +written and read quickly, such as small databases encoded with Scheme data +structures. + +
+Objects are printed in fasl format with fasl-write. +Because the fasl format is a binary format, fasl output must be written +to a binary port. +For this reason, it is not possible to include data written in fasl +format with textual data in the same file, as was the case in +earlier versions of Chez Scheme. +Similarly, the (textual) reader does not handle objects written in +fasl format; the procedure fasl-read, which requires a binary +input port, must be used instead. + + +
+procedure: (fasl-write obj binary-output-port)
+
procedure: (fasl-write obj binary-output-port external-pred)
+
procedure: (fasl-write obj binary-output-port external-pred omit-rtds?)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
fasl-write writes the fasl representation of obj to +binary-output-port. +An exception is raised with condition-type &assertion if +obj or any portion of obj has no external fasl representation, +e.g., if obj is or contains a procedure. + +
+If externals-pred is provided and not #f, then it must be a +procedure that accepts one argument. It is applied to each distinct object +encountered in obj, including symbols, but not necessarily values of +other primitive datatypes for which equal? implies eq?. If +externals-pred returns true for an object, that object is not +written to the fasl representation. Instead, a placeholder is written +containing a position as the number of preceding calls to +externals-pred that had returned true. Typically, for each +object where it returns true, externals-pred saves the object +through its closure. When the fasl representation is read with +fasl-read, a vector with as many items as generated positions +must be provided, and each placeholder is replaced with the +corresponding vector element. Beware that replacing values used for +system-internal data structures (which are always instances of primitive +datatypes) with non-equal values at load time results in undefined +behavior. + +
+If omit-rtds? is present and true, then any record types +relevant to obj are not written to the fasl representation. +When the fasl representation is read, these record types must already +be declared in the loading context, and the +loading context is assumed to have compatible record-type +registrations using the same unique ID. Behavior if the loading context +has an incompatible record-type registration using the same +(ostensibly unique) ID is undefined. + +
+The fasl representation of obj is compressed if the parameter +fasl-compressed, described below, is set to #t, +its default value. +For this reason, binary-output-port generally should not be opened +with the compressed option. +A warning is issued (an exception with condition type &warning +is raised) on the first attempt to write fasl objects to or read +fasl objects from a compressed file. + +
+ +
(define bop (open-file-output-port "tmp.fsl"))
+
+(fasl-write '(a b c) bop)
+
+(close-port bop)
+
+
+(define bip (open-file-input-port "tmp.fsl"))
+
+(fasl-read bip) (a b c)
+
+(fasl-read bip) #!eof
+
+(close-port bip)
+
procedure: (fasl-read binary-input-port)
+
procedure: (fasl-read binary-input-port situation)
+
procedure: (fasl-read binary-input-port situation externals)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If present, situation must be one of the symbols load, +visit, or revisit; it defaults to load. +If present, exterrnals must be a vector; it defaults to +'#(). + +
+fasl-read reads one object from +binary-input-port, which must be positioned at the +front of an object written in fasl format. +fasl-read returns the eof object if the file is positioned +at the end of file. +If the situation is visit, fasl-read skips over +any revisit (run-time-only) objects, and +if the situation is revisit, fasl-read skips over +any visit (compile-time-only) objects. +It doesn't skip any if the situation is load. +Similarly, objects marked as both visit and revisit (e.g., object code +corresponding to source code within an eval-when form with +situation load or situations visit and revisit) +are never skipped. + +
+The externals vector must have the same length as the number +of true-returning calls to external-pred during the +fasl-write call that produced the fasl representation. + +
+fasl-read automatically decompresses the representation +of each fasl object written in compressed format by fasl-write. +Thus, binary-input-port generally should not be opened with +the compressed option. +A warning is issued (an exception with condition type &warning +is raised) on the first attempt to write fasl objects to or read +fasl objects from a compressed file. + +
+ +
(define bop (open-file-output-port "tmp.fsl"))
+
+(fasl-write '(a b c) bop)
+
+(close-port bop)
+
+
+(define bip (open-file-input-port "tmp.fsl"))
+
+(fasl-read bip) (a b c)
+
+(fasl-read bip) #!eof
+
+(close-port bip)
+
thread parameter: fasl-compressed
+
+libraries: (chezscheme)
+
+
When this parameter is set to its default value, #t, +fasl-write compresses the representation of each object +as it writes it, often resulting in substantially smaller output +but possibly taking more time to write and read. +The compression format and level are determined by the +compress-format +and +compress-level +parameters. + + +
+procedure: (fasl-file ifn ofn)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
ifn and ofn must be strings. +fasl-file may be used to convert a file in human-readable +format into an equivalent +file written in fasl format. +fasl-file reads each object in turn from the file named by +ifn and writes the fasl format for the object onto the file +named by ofn. +If the file named by ofn already exists, it is replaced. + + +
+ +
+This section describes operations on files, directories, and pathnames. + +
+global parameter: current-directory
+
global parameter: cd
+
+libraries: (chezscheme)
+
+
When invoked without arguments, current-directory returns a string +representing the current working directory. +Otherwise, the current working directory is changed to the directory +specified by the argument, which must be a string representing a valid +directory pathname. + +
+cd is bound to the same parameter. + +
+procedure: (directory-list path)
+
+returns: a list of file names
+
+libraries: (chezscheme)
+
+
path must be a string. +The return value is a list of strings representing the names of +files found in the directory named by path. +directory-list raises an exception with condition +type &i/o-filename if path does not name a directory +or if the process cannot list the directory. + +
+procedure: (file-exists? path)
+
procedure: (file-exists? path follow?)
+
+returns: #t if the file named by path exists, #f otherwise
+
+libraries: (chezscheme)
+
+
path must be a string. +If the optional follow? argument is true (the default), +file-exists? follows symbolic links; otherwise it does not. +Thus, file-exists? will return #f when handed the +pathname of a broken symbolic link unless follow? is provided +and is #f. + +
+The Revised6 Report file-exists? does not accept the +optional follow? argument. +Whether it follows symbolic links is unspecified. + +
+procedure: (file-regular? path)
+
procedure: (file-regular? path follow?)
+
+returns: #t if the file named by path is a regular file, #f otherwise
+
+libraries: (chezscheme)
+
+
path must be a string. +If the optional follow? argument is true (the default), +file-regular? follows symbolic links; otherwise it does not. + +
+procedure: (file-directory? path)
+
procedure: (file-directory? path follow?)
+
+returns: #t if the file named by path is a directory, #f otherwise
+
+libraries: (chezscheme)
+
+
path must be a string. +If the optional follow? argument is true (the default), +this procedure follows symbolic links; otherwise it does not. + +
+procedure: (file-symbolic-link? path)
+
+returns: #t if the file named by path is a symbolic link, #f otherwise
+
+libraries: (chezscheme)
+
+
path must be a string. +file-symbolic-link? never follows symbolic links in making its +determination. + +
+procedure: (file-access-time path/port)
+
procedure: (file-access-time path/port follow?)
+
+returns: the access time of the specified file
+
procedure: (file-change-time path/port)
+
procedure: (file-change-time path/port follow?)
+
+returns: the change time of the specified file
+
procedure: (file-modification-time path/port)
+
procedure: (file-modification-time path/port follow?)
+
+returns: the modification time of the specified file
+
+libraries: (chezscheme)
+
+
path/port must be a string or port. +If path/port is a string, the time returned is for the file named +by the string, and the optional follow? argument determines whether +symbolic links are followed. +If follow? is true (the default), +this procedure follows symbolic links; otherwise it does not. +If path/port is a port, it must be a file port, and the time returned +is for the associated file. +In this case, follow? is ignored. + +
+The returned times are represented as time objects +(Section 12.10). + + +
+procedure: (mkdir path)
+
procedure: (mkdir path mode)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +mode must be a fixnum. + +
+mkdir creates a directory with the name given by path. +All path path components leading up to the last must already +exist. +If the optional mode argument is present, it overrides the default +permissions for the new directory. +Under Windows, the mode argument is ignored. + +
+mkdir raises an exception with condition +type &i/o-filename if the directory cannot be created. + + +
+procedure: (delete-file path)
+
procedure: (delete-file path error?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
path must be a string. +delete-file removes the file named by path. +If the optional error? argument is #f (the default), +delete-file returns a boolean value: #t if the +operation is successful and #f if it is not. +Otherwise, delete-file returns an unspecified value if the +operation is successful and raises an exception with condition +type &i/o-filename if it is not. + +
+The Revised6 Report delete-file does not accept the +optional error? argument but behaves as if error? +is true. + +
+procedure: (delete-directory path)
+
procedure: (delete-directory path error?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
path must be a string. +delete-directory removes the directory named by path. +If the optional error? argument is #f (the default), +delete-directory returns a boolean value: #t if the +operation is successful and #f if it is not. +Otherwise, delete-directory returns an unspecified value if the +operation is successful and raises an exception with condition +type &i/o-filename if it is not. +The behavior is unspecified if the directory is not empty, but on +most systems the operations will not succeed. + +
+procedure: (rename-file old-pathname new-pathname)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
old-pathname and new-pathname must be strings. +rename-file changes the name of the file named by old-pathname +to new-pathname. +If the file does not exist or cannot be renamed, +an exception is raised with condition type &i/o-filename. + +
+procedure: (chmod path mode)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +mode must be a fixnum. + +
+chmod sets the permissions on the file named by +path to mode. +Bits 0, 1, and 2 of mode are the execute, write, and read permission bits +for users other than the file's owner who are not in the file's group. +Bits 3-5 are the execute, write, and read permission bits for users other +than the file's owner but in the file's group. +Bits 6-8 are the execute, write, and read permission bits +for the file's owner. +Bits 7-9 are the Unix sticky, set-group-id, and set-user-id bits. +Under Windows, all but the user "write" bit are ignored. +If the file does not exist or the permissions cannot be changed, +an exception is raised with condition type &i/o-filename. + +
+procedure: (get-mode path)
+
procedure: (get-mode path follow?)
+
+returns: the current permissions mode for path
+
+libraries: (chezscheme)
+
+
path must be a string. +get-mode retrieves the permissions on the file named by +path and returns them as a fixnum in the same form as the mode +argument to chmod. +If the optional follow? argument is true (the default), +this procedure follows symbolic links; otherwise it does not. + + +
+procedure: (directory-separator? char)
+
+returns: #t if char is a directory separator, #f otherwise
+
+libraries: (chezscheme)
+
+
The character #\/ is a directory separator on all +current machine types, and #\\ is a directory separator +under Windows. + +
+procedure: (directory-separator)
+
+returns: the preferred directory separator
+
+libraries: (chezscheme)
+
+
The preferred directory separator is #\\ for Windows and +#\/ for other systems. + +
+procedure: (path-build dir-path path)
+
+returns: a combined path
+
+libraries: (chezscheme)
+
+
Combines dir-path and path, adding a directory separator +between them if needed. + +
+procedure: (path-first path)
+
procedure: (path-rest path)
+
procedure: (path-last path)
+
procedure: (path-parent path)
+
procedure: (path-extension path)
+
procedure: (path-root path)
+
+returns: the specified component of path
+
procedure: (path-absolute? path)
+
+returns: #t if path is absolute, otherwise #f
+
+libraries: (chezscheme)
+
+
path must be a string. +The return value is also a (possibly empty) string. + +
+The path first component is the first directory in the path, or the +empty string if the path consists only of a single filename. +The path rest component is the portion of the path that does not +include the path first component or the directory separator (if +any) that separates it from the rest of the path. +The path last component is the last (filename) portion of path. +The path parent component is the portion of path that does not +include the path last component, if any, or the directory separator that +separates it from the rest of the path. + +
+If the first component of the path names a root directory (including drives +and shares under Windows), home directory +(e.g., ~/abc or ~user/abc), +the current directory (.), or the parent directory +(..), path-first returns that component. +For paths that consist only of such a directory, +both path-first and path-parent act as +identity procedures, while path-rest and path-last +return the empty string. + +
+The path extension component is the portion of path that follows +the last dot (period) in the last component of a path name. +The path root component is the portion of path that does not +include the extension, if any, or the dot that precedes it. + +
+If the first component names a root directory (including drives +and shares under Windows) or home directory, +path-absolute? returns #t. +Otherwise, path-absolute? returns #f. + +
+The tables below identify the components for several example paths, +with underscores representing empty strings. + +
+
+path | abs | first | rest | parent | last | root | ext |
+a | #f | _ | a | _ | a | a | _ |
+a/ | #f | a | _ | a | _ | a/ | _ |
+a/b | #f | a | b | a | b | a/b | _ |
+a/b.c | #f | a | b.c | a | b.c | a/b | c |
+/ | #t | / | _ | / | _ | / | _ |
+/a/b.c | #t | / | a/b.c | /a | b.c | /a/b | c |
+~/a/b.c | #t | ~ | a/b.c | ~/a | b.c | ~/a/b | c |
+~u/a/b.c | #t | ~u | a/b.c | ~u/a | b.c | ~u/a/b | c |
+../.. | #f | .. | .. | .. | .. | ../.. | _ |
+ |
+The second table shows the components when Windows drives and shares +are involved. + +
+
+path | abs | first | rest | parent | last | root | ext |
+c: | #f | c: | _ | c: | _ | c: | _ |
+c:/ | #t | c:/ | _ | c:/ | _ | c:/ | _ |
+c:a/b | #f | c: | a/b | c:a | b | c:a/b | _ |
+//s/a/b.c | #t | //s | a/b.c | //s/a | b.c | //s/a/b | c |
+//s.com | #t | //s.com | _ | //s.com | _ | //s.com | _ |
+ |
+The following procedure can be used to reproduce the tables above. + +
+ +
(define print-table
+
+ (lambda path*
+
+ (define print-row
+
+ (lambda (abs? path first rest parent last root extension)
+
+ (printf "~a~11t~a~17t~a~28t~a~39t~a~50t~a~61t~a~73t~a\n"
+
+ abs? path first rest parent last root extension)))
+
+ (print-row "path" "abs" "first" "rest" "parent" "last" "root" "ext")
+
+ (for-each
+
+ (lambda (path)
+
+ (define uscore (lambda (s) (if (eqv? s "") "_" s)))
+
+ (apply print-row path
+
+ (map (lambda (s) (if (eqv? s "") "_" s))
+
+ (list (path-absolute? path) (path-first path)
+
+ (path-rest path) (path-parent path) (path-last path)
+
+ (path-root path) (path-extension path)))))
+
+ path*)))
+
For example, the first table can be produced with: + +
+ +
(print-table "a" "a/" "a/b" "a/b.c" "/" "/a/b.c" "~/a/b.c"
+
+ "~u/a/b.c" "../..")
+
while the second can be produced (under Windows) with: + +
+ +
(print-table "c:" "c:/" "c:a/b" "//s/a/b.c" "//s.com") +
+
+This section presents the definitions for three types of generic ports: +two-way ports, transcript ports, and process ports. + +
+
Two-way ports. The first example defines make-two-way-port, which constructs a +textual input/output port from a given pair of textual input and output ports. +For example: + +
+ +
(define ip (open-input-string "this is the input"))
+
+(define op (open-output-string))
+
+(define p (make-two-way-port ip op))
+
The port returned by make-two-way-port is both an input and an output +port, and it is also a textual port: + +
+ +
(port? p) #t
+
+(input-port? p) #t
+
+(output-port? p) #t
+
+(textual-port? p) #t
+
Items read from a two-way port come from the constituent input port, +and items written to a two-way port go to the constituent output +port: + +
+ +
(read p) this
+
+(write 'hello p)
+
+(get-output-string op) hello
+
The definition of make-two-way-port is straightforward. +To keep the example simple, +no local buffering is performed, +although it would be more efficient to do so. + +
+ +
(define make-two-way-port
+
+ (lambda (ip op)
+
+ (define handler
+
+ (lambda (msg . args)
+
+ (record-case (cons msg args)
+
+ [block-read (p s n) (block-read ip s n)]
+
+ [block-write (p s n) (block-write op s n)]
+
+ [char-ready? (p) (char-ready? ip)]
+
+ [clear-input-port (p) (clear-input-port ip)]
+
+ [clear-output-port (p) (clear-output-port op)]
+
+ [close-port (p) (mark-port-closed! p)]
+
+ [flush-output-port (p) (flush-output-port op)]
+
+ [file-position (p . pos) (apply file-position ip pos)]
+
+ [file-length (p) (file-length ip)]
+
+ [peek-char (p) (peek-char ip)]
+
+ [port-name (p) "two-way"]
+
+ [read-char (p) (read-char ip)]
+
+ [unread-char (c p) (unread-char c ip)]
+
+ [write-char (c p) (write-char c op)]
+
+ [else (assertion-violationf 'two-way-port
+
+ "operation ~s not handled"
+
+ msg)])))
+
+ (make-input/output-port handler "" "")))
+
Most of the messages are passed directly to one of the constituent +ports. +Exceptions are close-port, which is handled directly by +marking the port closed, port-name, which is also handled directly. +file-position and file-length are rather arbitrarily +passed off to the input port. + + +
+
Transcript ports. The next example defines make-transcript-port, which constructs a +textual input/output port from three ports: a textual input port ip and two textual +output ports, op and tp. +Input read from a transcript port comes from ip, and output +written to a transcript port goes to op. +In this manner, transcript ports are similar to two-way ports. +Unlike two-way ports, input from ip and output to op is +also written to tp, so that tp reflects both input from +ip and output to op. + +
+Transcript ports may be used to define the Scheme procedures +transcript-on and transcript-off, or the Chez Scheme procedure +transcript-cafe. +For example, here is a definition of transcript-cafe: + +
+ +
(define transcript-cafe
+
+ (lambda (pathname)
+
+ (let ([tp (open-output-file pathname 'replace)])
+
+ (let ([p (make-transcript-port
+
+ (console-input-port)
+
+ (console-output-port)
+
+ tp)])
+
+ ; set both console and current ports so that
+
+ ; the waiter and read/write will be in sync
+
+ (parameterize ([console-input-port p]
+
+ [console-output-port p]
+
+ [current-input-port p]
+
+ [current-output-port p])
+
+ (let-values ([vals (new-cafe)])
+
+ (close-port p)
+
+ (close-port tp)
+
+ (apply values vals)))))))
+
The implementation of transcript ports is significantly more complex +than the implementation of two-way ports defined above, primarily +because it buffers input and output locally. +Local buffering is needed to allow the transcript file to reflect +accurately the actual input and output performed in the presence of +unread-char, clear-output-port, and clear-input-port. +Here is the code: + + +
+ +
(define make-transcript-port
+
+ (lambda (ip op tp)
+
+ (define (handler msg . args)
+
+ (record-case (cons msg args)
+
+ [block-read (p str cnt)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (if (< i s)
+
+ (let ([cnt (fxmin cnt (fx- s i))])
+
+ (do ([i i (fx+ i 1)]
+
+ [j 0 (fx+ j 1)])
+
+ ((fx= j cnt)
+
+ (set-port-input-index! p i)
+
+ cnt)
+
+ (string-set! str j (string-ref b i))))
+
+ (let ([cnt (block-read ip str cnt)])
+
+ (unless (eof-object? cnt)
+
+ (block-write tp str cnt))
+
+ cnt))))]
+
+ [char-ready? (p)
+
+ (or (< (port-input-index p) (port-input-size p))
+
+ (char-ready? ip))]
+
+ [clear-input-port (p)
+
+ ; set size to zero rather than index to size
+
+ ; in order to invalidate unread-char
+
+ (set-port-input-size! p 0)]
+
+ [clear-output-port (p)
+
+ (set-port-output-index! p 0)]
+
+ [close-port (p)
+
+ (with-interrupts-disabled
+
+ (flush-output-port p)
+
+ (set-port-output-size! p 0)
+
+ (set-port-input-size! p 0)
+
+ (mark-port-closed! p))]
+
+ [file-position (p . pos)
+
+ (if (null? pos)
+
+ (most-negative-fixnum)
+
+ (assertion-violationf 'transcript-port "cannot reposition"))]
+
+ [flush-output-port (p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-output-buffer p)]
+
+ [i (port-output-index p)])
+
+ (unless (fx= i 0)
+
+ (block-write op b i)
+
+ (block-write tp b i)
+
+ (set-port-output-index! p 0)
+
+ (set-port-bol! p
+
+ (char=? (string-ref b (fx- i 1)) #\newline))))
+
+ (flush-output-port op)
+
+ (flush-output-port tp))]
+
+ [peek-char (p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (if (fx< i s)
+
+ (string-ref b i)
+
+ (begin
+
+ (flush-output-port p)
+
+ (let ([s (block-read ip b)])
+
+ (if (eof-object? s)
+
+ s
+
+ (begin
+
+ (block-write tp b s)
+
+ (set-port-input-size! p s)
+
+ (string-ref b 0))))))))]
+
+ [port-name (p) "transcript"]
+
+ [constituent-ports (p) (values ip op tp)]
+
+ [read-char (p)
+
+ (with-interrupts-disabled
+
+ (let ([c (peek-char p)])
+
+ (unless (eof-object? c)
+
+ (set-port-input-index! p
+
+ (fx+ (port-input-index p) 1)))
+
+ c))]
+
+ [unread-char (c p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (when (fx= i 0)
+
+ (assertion-violationf 'unread-char
+
+ "tried to unread too far on ~s"
+
+ p))
+
+ (set-port-input-index! p (fx- i 1))
+
+ ; following could be skipped; it's supposed
+
+ ; to be the same character anyway
+
+ (string-set! b (fx- i 1) c)))]
+
+ [write-char (c p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-output-buffer p)]
+
+ [i (port-output-index p)]
+
+ [s (port-output-size p)])
+
+ (string-set! b i c)
+
+ ; could check here to be sure that we really
+
+ ; need to flush; we may end up here even if
+
+ ; the buffer isn't full
+
+ (block-write op b (fx+ i 1))
+
+ (block-write tp b (fx+ i 1))
+
+ (set-port-output-index! p 0)
+
+ (set-port-bol! p (char=? c #\newline))))]
+
+ [block-write (p str cnt)
+
+ (with-interrupts-disabled
+
+ ; flush buffered data
+
+ (let ([b (port-output-buffer p)]
+
+ [i (port-output-index p)])
+
+ (unless (fx= i 0)
+
+ (block-write op b i)
+
+ (block-write tp b i)
+
+ (set-port-output-index! p 0)
+
+ (set-port-bol! p (char=? (string-ref b (fx- i 1)) #\newline))))
+
+ ; write new data
+
+ (unless (fx= cnt 0)
+
+ (block-write op str cnt)
+
+ (block-write tp str cnt)
+
+ (set-port-bol! p
+
+ (char=? (string-ref str (fx- cnt 1)) #\newline))))]
+
+ [else (assertion-violationf 'transcript-port
+
+ "operation ~s not handled"
+
+ msg)]))
+
+ (let ([ib (make-string 1024)] [ob (make-string 1024)])
+
+ (let ([p (make-input/output-port handler ib ob)])
+
+ (set-port-input-size! p 0)
+
+ (set-port-output-size! p (fx- (string-length ob) 1))
+
+ p))))
+
The chosen length of both the input and output ports is the same; this +is not necessary. +They could have different lengths, or one could be buffered locally and +the other not buffered locally. +Local buffering could be disabled effectively by providing zero-length +buffers. + +
+After we create the port, the input size is set to zero since there +is not yet any data to be read. +The port output size is set to one less than the length of the buffer. +This is done so that write-char always has one character position +left over into which to write its character argument. +Although this is not necessary, it does simplify the code somewhat +while allowing the buffer to be flushed as soon as the last character +is available. + +
+Block reads and writes are performed on the constituent ports for +efficiency and (in the case of writes) to ensure that the operations +are performed immediately. + +
+The call to flush-output-port in the handling of read-char insures +that all output written to op appears before input is read from +ip. +Since block-read is typically used to support higher-level operations +that are performing their own buffering, or for direct input and output +in support of I/O-intensive applications, the flush call has been +omitted from that part of the handler. + +
+Critical sections are used whenever the handler manipulates one of the +buffers, to protect against untimely interrupts that could lead to +reentry into the handler. +The critical sections are unnecessary if no such reentry is possible, +i.e., if only one "thread" of the computation can have access to the +port. + +
+
Process ports. The final example +demonstrates how to incorporate the socket interface +defined in Section 4.10 into a generic port that +allows transparent communication with subprocesses via normal Scheme +input/output operations. + +
+A process port is created with open-process, which accepts a +shell command as a string. +open-process sets up a socket, forks a child process, sets up +two-way communication via the socket, and invokes the command in a +subprocess. + +
+The sample session below demonstrates the use of open-process, +running and communicating with another Scheme process started with the +"-q" switch to suppress the greeting and prompts. + +
+ +
> (define p (open-process "exec scheme -q"))
+
+> (define s (make-string 1000 #\nul))
+
+> (pretty-print '(+ 3 4) p)
+
+> (read p)
+
+7
+
+> (pretty-print '(define (f x) (if (= x 0) 1 (* x (f (- x 1))))) p)
+
+> (pretty-print '(f 10) p)
+
+> (read p)
+
+3628800
+
+> (pretty-print '(exit) p)
+
+> (read p)
+
+#!eof
+
+> (close-port p)
+
Since process ports, like transcript ports, are two-way, the implementation +is somewhat similar. +The main difference is that a transcript port reads from and writes to its +subordinate ports, whereas a process port reads from and writes to a socket. +When a process port is opened, the socket is created and subprocess +invoked, and when the port is closed, the socket is closed and the +subprocess is terminated. + +
+ +
(define open-process
+
+ (lambda (command)
+
+ (define handler
+
+ (lambda (pid socket)
+
+ (define (flush-output who p)
+
+ (let ([i (port-output-index p)])
+
+ (when (fx> i 0)
+
+ (check who (c-write socket (port-output-buffer p) i))
+
+ (set-port-output-index! p 0))))
+
+ (lambda (msg . args)
+
+ (record-case (cons msg args)
+
+ [block-read (p str cnt)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (if (< i s)
+
+ (let ([cnt (fxmin cnt (fx- s i))])
+
+ (do ([i i (fx+ i 1)]
+
+ [j 0 (fx+ j 1)])
+
+ ((fx= j cnt)
+
+ (set-port-input-index! p i)
+
+ cnt)
+
+ (string-set! str j (string-ref b i))))
+
+ (begin
+
+ (flush-output 'block-read p)
+
+ (let ([n (check 'block-read
+
+ (c-read socket str cnt))])
+
+ (if (fx= n 0)
+
+ #!eof
+
+ n))))))]
+
+ [char-ready? (p)
+
+ (or (< (port-input-index p) (port-input-size p))
+
+ (bytes-ready? socket))]
+
+ [clear-input-port (p)
+
+ ; set size to zero rather than index to size
+
+ ; in order to invalidate unread-char
+
+ (set-port-input-size! p 0)]
+
+ [clear-output-port (p) (set-port-output-index! p 0)]
+
+ [close-port (p)
+
+ (with-interrupts-disabled
+
+ (flush-output 'close-port p)
+
+ (set-port-output-size! p 0)
+
+ (set-port-input-size! p 0)
+
+ (mark-port-closed! p)
+
+ (terminate-process pid))]
+
+ [file-length (p) 0]
+
+ [file-position (p . pos)
+
+ (if (null? pos)
+
+ (most-negative-fixnum)
+
+ (assertion-violationf 'process-port "cannot reposition"))]
+
+ [flush-output-port (p)
+
+ (with-interrupts-disabled
+
+ (flush-output 'flush-output-port p))]
+
+ [peek-char (p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (if (fx< i s)
+
+ (string-ref b i)
+
+ (begin
+
+ (flush-output 'peek-char p)
+
+ (let ([s (check 'peek-char
+
+ (c-read socket b (string-length b)))])
+
+ (if (fx= s 0)
+
+ #!eof
+
+ (begin (set-port-input-size! p s)
+
+ (string-ref b 0))))))))]
+
+ [port-name (p) "process"]
+
+ [read-char (p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (if (fx< i s)
+
+ (begin
+
+ (set-port-input-index! p (fx+ i 1))
+
+ (string-ref b i))
+
+ (begin
+
+ (flush-output 'peek-char p)
+
+ (let ([s (check 'read-char
+
+ (c-read socket b (string-length b)))])
+
+ (if (fx= s 0)
+
+ #!eof
+
+ (begin (set-port-input-size! p s)
+
+ (set-port-input-index! p 1)
+
+ (string-ref b 0))))))))]
+
+ [unread-char (c p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-input-buffer p)]
+
+ [i (port-input-index p)]
+
+ [s (port-input-size p)])
+
+ (when (fx= i 0)
+
+ (assertion-violationf 'unread-char
+
+ "tried to unread too far on ~s"
+
+ p))
+
+ (set-port-input-index! p (fx- i 1))
+
+ ; following could be skipped; supposed to be
+
+ ; same character
+
+ (string-set! b (fx- i 1) c)))]
+
+ [write-char (c p)
+
+ (with-interrupts-disabled
+
+ (let ([b (port-output-buffer p)]
+
+ [i (port-output-index p)]
+
+ [s (port-output-size p)])
+
+ (string-set! b i c)
+
+ (check 'write-char (c-write socket b (fx+ i 1)))
+
+ (set-port-output-index! p 0)))]
+
+ [block-write (p str cnt)
+
+ (with-interrupts-disabled
+
+ ; flush buffered data
+
+ (flush-output 'block-write p)
+
+ ; write new data
+
+ (check 'block-write (c-write socket str cnt)))]
+
+ [else
+
+ (assertion-violationf 'process-port
+
+ "operation ~s not handled"
+
+ msg)]))))
+
+ (let* ([server-socket-name (tmpnam 0)]
+
+ [server-socket (setup-server-socket server-socket-name)])
+
+ (dofork
+
+ (lambda () ; child
+
+ (check 'close (close server-socket))
+
+ (let ([sock (setup-client-socket server-socket-name)])
+
+ (dodup 0 sock)
+
+ (dodup 1 sock))
+
+ (check 'execl (execl4 "/bin/sh" "/bin/sh" "-c" command))
+
+ (assertion-violationf 'open-process "subprocess exec failed"))
+
+ (lambda (pid) ; parent
+
+ (let ([sock (accept-socket server-socket)])
+
+ (check 'close (close server-socket))
+
+ (let ([ib (make-string 1024)] [ob (make-string 1024)])
+
+ (let ([p (make-input/output-port
+
+ (handler pid sock)
+
+ ib ob)])
+
+ (set-port-input-size! p 0)
+
+ (set-port-output-size! p (fx- (string-length ob) 1))
+
+ p))))))))
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/libraries.html b/csug10.0/libraries.html
new file mode 100644
index 000000000..1896d8c09
--- /dev/null
+++ b/csug10.0/libraries.html
@@ -0,0 +1,1432 @@
+
+
+
+
+
+The Revised6 Report describes two units of portable code: +libraries and top-level programs. +A library is a named collection of bindings with a declared set of +explicitly exported bindings, a declared set of imported libraries, and a +body that initializes its bindings. +A top-level program is a stand-alone program with a declared set of +imported libraries and a body that is run when the top-level program is +run. +The bindings in a library are created and its initialization code run only +if the library is used, directly or indirectly, by a top-level program. + +
+The import declarations appearing within libraries and top-level +programs serve two purposes: first, they cause the imported libraries to +be loaded, and second, they cause the bindings of the imported libraries +to become visible in the importing library or top-level program. +Libraries are typically stored in the file system, with one library per +file, and the library name typically identifies the file-system path to +the library, possibly relative to a default or programmer-specified set of +library locations. +The exact mechanism by which top-level programs are run and libraries are +loaded is implementation-dependent. + +
+This chapter describes the mechanisms by which libraries and programs are +loaded in Chez Scheme along with various features for controlling and +tracking this process. +It also describes the set of built-in libraries and syntactic forms for +defining new libraries and top-level programs outside of a library or +top-level program file. + + + +
+ +
+In addition to the RNRS libraries mandated by the Revised6 Report: + +
+ +
(rnrs base (6))
+
+ (rnrs arithmetic bitwise (6))
+
+ (rnrs arithmetic fixnums (6))
+
+ (rnrs arithmetic flonums (6))
+
+ (rnrs bytevectors (6))
+
+ (rnrs conditions (6))
+
+ (rnrs control (6))
+
+ (rnrs enums (6))
+
+ (rnrs eval (6))
+
+ (rnrs exceptions (6))
+
+ (rnrs files (6))
+
+ (rnrs hashtables (6))
+
+ (rnrs io ports (6))
+
+ (rnrs io simple (6))
+
+ (rnrs lists (6))
+
+ (rnrs mutable-pairs (6))
+
+ (rnrs mutable-strings (6))
+
+ (rnrs programs (6))
+
+ (rnrs r5rs (6))
+
+ (rnrs records procedural (6))
+
+ (rnrs records syntactic (6))
+
+ (rnrs records inspection (6))
+
+ (rnrs sorting (6))
+
+ (rnrs syntax-case (6))
+
+ (rnrs unicode (6))
+
Chez Scheme also provides two additional libraries: (chezscheme) +and (chezscheme csv7). +The former can also be referenced as (scheme) and the latter can +also be referenced as (scheme csv7). + +
+The (chezscheme) library exports bindings for every identifier whose +binding is described in this document, including those for keywords like +lambda, auxiliary keywords like else, module names +like scheme, and procedure names like cons. +In most cases where an identifier exported from the +(chezscheme) library corresponds to an identifier exported from +one of the RNRS libraries, the bindings are identical. +In some cases, however, the (chezscheme) bindings extend the +rnrs bindings in some way. +For example, the (chezscheme) syntax-rules form allows +its clauses to have fenders (Section 11.2), while the +(rnrs) syntax-rules form does not. +Similarly, the (chezscheme) current-input-port procedure +accepts an optional port argument that, when specified, sets the +current input port to port (Section 9.8), while the +(rnrs) current-input-port procedure does not. +When the (chezscheme) library extends an RNRS binding in some +way, the (chezscheme) library also exports the RNRS version, +with the name prefixed by r6rs:, e.g., r6rs:syntax-rules +or r6rs:current-input-port. + +
+The (chezscheme csv7) Version 7 backward compatibility library +contains bindings for a set of syntactic forms and procedures whose syntax +or semantics directly conflicts with the RNRS bindings for the same +identifiers. +The following identifiers are exported from (chezscheme csv7). + +
+ +
record-field-accessible?
+
+record-field-accessor
+
+record-field-mutable?
+
+record-field-mutator
+
+record-type-descriptor
+
+record-type-field-decls
+
+record-type-field-names
+
+record-type-name
+
+record-type-symbol
+
The bindings of this library should be used only for old code; new +code should use the RNRS variants. +Each of these is also available in the (chezscheme) library with +the prefix csv7:, e.g., csv7:record-type-name. + +
+The interaction environment in which code outside of a library or +RNRS top-level program is scoped contains all of the bindings of the +(chezscheme) library, as described in +Section 2.3. + + +
+ +
+A top-level program must reside in its own file, which may have any +name and may reside anywhere in the file system. +A top-level program residing in a file is run by one of three mechanisms: +the scheme-script command, the --program command-line +argument, or the load-program procedure. + +
+The scheme-script command is used as follows: + +
+ +
scheme-script program-filename arg ... +
It may also be run implicitly on Unix-based systems by placing the line + +
+ +
#! /usr/bin/env scheme-script +
at the front of the file containing the top-level program, making the +top-level program file executable, and executing the file. +This line may be replaced with + +
+ +
#! /usr/bin/scheme-script +
with /usr/bin replaced by the absolute path to the directory +containing scheme-script if it is not in /usr/bin. +The first form is recommended in the nonnormative appendices to the +Revised6 Report [29], and works wherever +scheme-script appears in the path. + +
+The --program command is used similarly with the scheme +or petite executables, either by running: + +
+ +
scheme --program program-filename arg ...
+
+petite --program program-filename arg ...
+
or by including + +
+ +
#! /usr/bin/scheme --script +
or + +
+ +
#! /usr/bin/petite --script +
at the front of the top-level program file, making the file executable, +and executing the file. +Again, /usr/bin should be replaced with the absolute path to +the actual directory in which scheme and/or petite +resides, if not /usr/bin. + +
+The load-program procedure, described in +Section 12.4, is used like load: + +
+ +
(load-program string) +
where string names the file in which the top-level program resides. + +
+Regardless of the mechanism used, if the opening line is in one of the +forms described above, or more generally, consists of +#! followed by a space or a forward slash, the opening line +is not considered part of the program and is ignored once the Scheme +system starts up and begins to run the program. +Thus, the line may be present even in a file loaded by load-program. +In fact, load-program is ultimately used by the other two +mechanisms described above, via the value of the scheme-program +parameter described in Section 12.8, and it is +load-program that scans past the #! line, if present, +before evaluating the program. + +
+A top-level program may be compiled with the +compile-program +procedure described in Section 12.4. +compile-program copies the #! line from the source +file to the object file, followed by a compiled version of the source +code. +Any libraries upon which the top-level program depends, other than +built-in libraries, must be compiled first via compile-file +or compile-library. +This can be done manually or by setting the parameter +compile-imported-libraries to #t before compiling +the program. +The program must be recompiled if any of the libraries upon which +it depends are recompiled. +A compiled top-level program can be run just like a source top-level +program via each of the mechanisms described above. + +
+In Chez Scheme, a library may also be defined in the REPL or placed in a +file to be loaded via load or load-library. +The syntax for a library is the same whether the library is placed in +its own file and implicitly loaded via import, entered into +the REPL, or placed in a file along with other top-level expressions to +be evaluated by load. +A top-level program may also be defined in the REPL or placed in a file +to be loaded via load, but in this case, the syntax is slightly +different. +In the language of the Revised6 Report, a top-level program is merely +an unwrapped sequence of subforms consisting of an import form +and a body, delimited only by the boundaries of the file in which it +resides. +In order for a top-level program to be entered in the REPL or placed in +a file to be evaluated by load, Chez Scheme allows top-level +programs to be enclosed in a +top-level-program form. + +
+ +
+syntax: (library name exports imports library-body)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The library form defines a new library with the specified +name, exports, imports, and body. +Details on the syntax and semantics of the library form are given in +Section 10.3 of The Scheme Programming Language, 4th Edition and in the Revised6 +Report. + +
+Only one version of a library can be loaded at any given time, and an +exception is raised if a library is implicitly loaded via import +when another version of the library has already been loaded. +Chez Scheme permits a different version of the library, or a new +instance of the same version, to be entered explicitly into the REPL +or loaded explicitly from a file, to facilitate interactive testing +and debugging. +The programmer should take care to make sure that any code that uses +the library is also reentered or reloaded, to make sure that code +accesses the bindings of the new instance of the library. + +
+ +
(library (test (1)) (export x) (import (rnrs)) (define x 3))
+
+(import (test))
+
+(define f (lambda () x))
+
+(f) 3
+
+
+(library (test (1)) (export x) (import (rnrs)) (define x 4))
+
+(import (test))
+
+(f) 3 ; oops---forgot to redefine f
+
+(define f (lambda () x))
+
+(f) 4
+
+
+(library (test (2)) (export x) (import (rnrs)) (define x 5))
+
+(import (test))
+
+(define f (lambda () x))
+
+(f) 5
+
As with module imports (Section 11.5), a library +import may appear anywhere a definition may appear, including at +top level in the REPL, in a file to be loaded by load, or within +a lambda, let, letrec, letrec*, +etc., body. +The same import form may be used to import from both libraries +and modules. + +
+ +
(library (foo) (export a) (import (rnrs)) (define a 'a-from-foo))
+
+(module bar (b) (define b 'b-from-bar))
+
+(let () (import (foo) bar) (list a b)) (a-from-foo b-from-bar)
+
The import keyword is not visible within a library body +unless the library imports it from the (chezscheme) library. + +
+syntax: (top-level-program imports body)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A top-level-program form may be entered into the REPL or placed +in a file to be loaded via load, where it behaves as if its +subforms were placed in a file and loaded via load-program. +Details on the syntax and semantics of a top-level program are given in +Section 10.3 of The Scheme Programming Language, 4th Edition and in the Revised6 +Report. + +
+The following transcript illustrates a top-level-program being +tested in the REPL. + +
+ +
> (top-level-program (import (rnrs))
+
+ (display "hello!\n"))
+
+hello!
+
+
+Although not required by the Revised6 Report, +Chez Scheme supports the use of standalone import and +export forms. +The import forms can appear anywhere other definitions +can appear, including within a library body, +module (Section 11.5) body, +lambda or other local body, and at top level. +The export forms can appear within the definitions of a +library or module body to specify additional +exports for the library or module. + +
+Within a library or top-level program, the keywords for +these forms must be imported from the (chezscheme) +library to be available for use, since they are not +defined in any of the Revised6 Report libraries. + +
+syntax: (import import-spec ...)
+
syntax: (import-only import-spec ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
An import or import-only form is a definition and can +appear anywhere other definitions can appear, including +at the top level of a program, nested within the bodies of +lambda expressions, and nested within modules +and libraries. + +
+Each import-spec must take one of the following forms. + +
+ +
import-set
+
+(for import-set import-level ...)
+
The for wrapper and import-level are described in +Chapter 10 of The Scheme Programming Language, 4th Edition. +They are ignored by Chez Scheme, which determines +automatically the levels at which identifiers must +be imported, as permitted by the Revised6 Report. +This frees the programmer from the obligation +to do so and results in more generality as well as more +precision in the set of libraries actually imported +at compile and run time [21,19]. + +
+An import-set must take one of the following forms: + +
+ +
library-spec
+
+module-name
+
+(only import-set identifier ...)
+
+(except import-set identifier ...)
+
+(prefix import-set prefix)
+
+(add-prefix import-set prefix)
+
+(drop-prefix import-set prefix)
+
+(rename import-set (import-name internal-name) ...)
+
+(alias import-set (import-name internal-name) ...)
+
Several of these are specified by the Revised6 Report; the remainder +are Chez Scheme extensions, including module-name and the +add-prefix, drop-prefix, and alias forms. + +
+An import or import-only form makes the specified bindings +visible in the scope in which they appear. +Except at top level, they differ in that import leaves all bindings +except for those shadowed by the imported names visible, whereas import-only +hides all existing bindings, i.e., makes only the imported names visible. +At top level, import-only behaves like import. + +
+Each import-set identifies a set of names to make visible +as follows. + +
+
+
+
+
+
+
+
+
+
+The alias form differs from the rename form in that both +import-name and internal-name are in the resulting set, +rather than just internal-name. + +
+It is a syntax violation if the +given selection or transformation cannot be made because of a missing +export or prefix. + +
+An identifier made visible via an import of a module or library is scoped as if its +definition appears where the import occurs. +The following example illustrates these scoping rules, using a local +module m. + +
+ +
(library (A) (export x) (import (rnrs)) (define x 0))
+
+(let ([x 1])
+
+ (module m (x setter)
+
+ (define-syntax x (identifier-syntax z))
+
+ (define setter (lambda (x) (set! z x)))
+
+ (define z 2))
+
+ (let ([y x] [z 3])
+
+ (import m (prefix (A) a:))
+
+ (setter 4)
+
+ (list x a:x y z))) (4 0 1 3)
+
The inner let expression binds y to the value of +the x bound by the outer let. +The import of m makes the definitions of x +and setter visible within the inner let. +The import of (A) makes the variable x exported +from (A) visible as a:x within the body of the +inner let. +Thus, in the expression (list x a:x y z), x refers to the +identifier macro exported from m while a:x refers to the +variable x exported from (A) and y and z +refer to the bindings established by the inner let. +The identifier macro x expands into a reference to +the variable z defined within the module. + +
+With local import forms, it is rarely necessary to use the extended +import specifiers. +For example, an abstraction that encapsulates the import and reference +can easily be defined and used as follows. + +
+ +
(define-syntax from
+
+ (syntax-rules ()
+
+ [(_ m id) (let () (import-only m) id)]))
+
+
+(library (A) (export x) (import (rnrs)) (define x 1))
+
+(let ([x 10])
+
+ (module M (x) (define x 2))
+
+ (cons (from (A) x) (from M x))) (1 . 2)
+
The definition of from could use import rather than +import-only, but by using import-only we get feedback +if an attempt is made to import an identifier from a library or +module that does not export the identifier. +With import instead of import-only, the current binding, +if any, would be visible if the library or module does not export the +specified name. + +
+ +
(define-syntax lax-from
+
+ (syntax-rules ()
+
+ [(_ m id) (let () (import m) id)]))
+
+
+(library (A) (export x) (import (rnrs)) (define x 1))
+
+
+(let ([x 10])
+
+ (module M (x) (define x 2))
+
+ (+ (from (A) x) (from M y))) exception: unbound identifier y
+
+
+
+(let ([x 10] [y 20])
+
+ (module M (x) (define x 2))
+
+ (+ (lax-from (A) x) (lax-from M y))) 21
+
Import visibility interacts with hygienic macro expansion in such a +way that, as one might expect, +an identifier x imported from a module M is treated in +the importing context as if the corresponding export identifier had +been present in the import form along with M. + +
+The from abstraction above works because both M and id +appear in the input to the abstraction, so the imported id captures +the reference to id. + +
+The following variant of from also works, because both names are +introduced into the output by the transformer. + +
+ +
(module M (x) (define x 'x-of-M))
+
+(define-syntax x-from-M
+
+ (syntax-rules ()
+
+ [(_) (let () (import M) x)]))
+
+
+(let ([x 'local-x]) (x-from-M)) x-of-M
+
On the other hand, imports of introduced module names do not capture +free references. + +
+ +
(let ([x 'local-x])
+
+ (define-syntax alpha
+
+ (syntax-rules ()
+
+ [(_ var) (let () (import M) (list x var))]))
+
+
+
+ (alpha x)) (x-of-M local-x)
+
Similarly, imports from free module names do not capture references +to introduced variables. + +
+ +
(let ([x 'local-x])
+
+ (define-syntax beta
+
+ (syntax-rules ()
+
+ [(_ m var) (let () (import m) (list x var))]))
+
+
+ (beta M x)) (local-x x-of-M)
+
This semantics extends to prefixed, renamed, and aliased bindings +created by the extended import specifiers prefix, +rename, and alias. + +
+The from abstraction +works for variables but not for exported keywords, record names, +or module names, since the output is an expression and may thus appear only where +expressions may appear. +A generalization of this technique is used in the following definition +of import*, which supports renaming of imported bindings and +selective import of specific bindings---without the use of the built-in +import subforms for selecting and renaming identifiers + +
+ +
(define-syntax import*
+
+ (syntax-rules ()
+
+ [(_ m) (begin)]
+
+ [(_ m (new old))
+
+ (module (new)
+
+ (module (tmp)
+
+ (import m)
+
+ (alias tmp old))
+
+ (alias new tmp))]
+
+ [(_ m id) (module (id) (import m))]
+
+ [(_ m spec0 spec1 ...)
+
+ (begin (import* m spec0) (import* m spec1 ...))]))
+
To selectively import an identifier from module or library m, the +import* form expands into an anonymous module that first +imports all exports of m then re-exports only the selected +identifier. +To rename on import the macro expands into an anonymous module that +instead exports an alias (Section 11.10) bound to the new name. + +
+If the output placed the definition of new in the same +scope as the import of m, a naming conflict would arise +whenever new is also present in the interface +of m. +To prevent this, the output instead places the import within a nested +anonymous module and links old and new +by means of an alias for the introduced identifier tmp. + +
+The macro expands recursively to handle multiple import specifications. +Each of the following examples imports cons as + and + as +cons, which is probably not a very good idea. + +
+ +
(let ()
+
+ (import* scheme (+ cons) (cons +))
+
+ (+ (cons 1 2) (cons 3 4))) (3 . 7)
+
+
+(let ()
+
+ (import* (rnrs) (+ cons) (cons +))
+
+ (+ (cons 1 2) (cons 3 4))) (3 . 7)
+
syntax: (export export-spec ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
An export form is a definition and can appear with other +definitions at the front of a library or module. +It is a syntax error for an export form to appear in other +contexts, including at top level or among the definitions of a +top-level program or lambda body. + +
+Each export-spec must take one of the following forms. + +
+ +
identifier
+
+(rename (internal-name export-name) ...)
+
+(import import-spec ...)
+
where each internal-name and export-name is an identifier. +The first two are syntactically identical to library +export-specs, while the third is syntactically +identical to a Chez Scheme import form, which is an extension of the +R6RS library import subform. +The first form names a single export, identifier, whose export +name is the same as its internal name. +The second names a set of exports, each of whose export name is +given explicitly and may differ from its internal name. + +
+For the third, the identifiers identified by the import form +become exports, with aliasing, renaming, prefixing, etc., as specified by the +import-specs. +The module or library whose bindings are exported by an import +form appearing within an export form can +be defined within or outside the exporting module or library and need +not be imported elsewhere within the exporting module or library. + +
+The following library exports a two-armed-only variant of if +along with all remaining bindings of the (rnrs) library. + +
+ +
(library (rnrs-no-one-armed-if) (export) (import (except (chezscheme) if))
+
+ (export if (import (except (rnrs) if)))
+
+ (define-syntax if
+
+ (let ()
+
+ (import (only (rnrs) if))
+
+ (syntax-rules ()
+
+ [(_ tst thn els) (if tst thn els)]))))
+
+
+(import (rnrs-no-one-armed-if))
+
+(if #t 3 4) 3
+
+(if #t 3) exception: invalid syntax
+
Another way to define the same library would be to define the +two-armed-only if with a different internal name and use +rename to export it under the name if: + +
+ +
(library (rnrs-no-one-armed-if) (export) (import (chezscheme))
+
+ (export (rename (two-armed-if if)) (import (except (rnrs) if)))
+
+ (define-syntax two-armed-if
+
+ (syntax-rules ()
+
+ [(_ tst thn els) (if tst thn els)])))
+
+
+(import (rnrs-no-one-armed-if))
+
+(if #t 3 4) 3
+
+(if #t 3) exception: invalid syntax
+
The placement of the export form in the library body is +irrelevant, e.g., the export form can appear after the +definition in the examples above. + + +
+syntax: (indirect-export id indirect-id ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This form is a definition and can appear wherever any other definition +can appear. + +
+An indirect-export form declares that the named +indirect-ids are indirectly exported to top level if id +is exported to top level. + +
+In general, if an identifier is not directly exported by a library or +module, it can be referenced outside of the library or module only in +the expansion of a macro defined within and exported from the library +or module. +Even this cannot occur for libraries or modules defined at top level +(or nested within other libraries or modules), unless either (1) +the library or module has been set up to implicitly export all +identifiers as indirect exports, or (2) each indirectly exported +identifier is explicitly declared as an indirect export of some +other identifier that is exported, either directly or indirectly, from +the library or module, via an indirect-export or the built-in +indirect export feature of a module export subform. +By default, (1) is true for a library and false for a module, but the +default can be overridden via the implicit-exports +form, which is described below. + +
+This form is meaningful only within a top-level library, top-level module, +or module enclosed within a library or top-level module, although it +has no effect if the library or module already implicitly exports all +bindings. +It is allowed anywhere else definitions can appear, however, so macros +that expand into indirect export forms can be used in any definition +context. + +
+Indirect exports are listed so the compiler can determine the +exact set of bindings (direct and indirect) that must be inserted +into the top-level environment, and conversely, the set of bindings +that may be treated more efficiently as local bindings (and +perhaps discarded, if they are not used). + +
+In the example below, indirect-export is used to indirectly +export count to top level when current-count is +exported to top level. + +
+ +
(module M (bump-count current-count)
+
+ (define-syntax current-count (identifier-syntax count))
+
+ (indirect-export current-count count)
+
+ (define count 0)
+
+ (define bump-count
+
+ (lambda ()
+
+ (set! count (+ count 1)))))
+
+
+(import M)
+
+(bump-count)
+
+current-count 1
+
+count exception: unbound identifier count
+
An indirect-export form is not required to make count +visible for bump-count, since it is a procedure whose code +is contained within the module rather than a macro that might expand +into a reference to count somewhere outside the module. + +
+It is often useful to use indirect-export in the output +of a macro that expands into another macro named a if +a expands into references to identifiers that might not +be directly exported, as illustrated by the alternative definition +of module M above. + +
+ +
(define-syntax define-counter
+
+ (syntax-rules ()
+
+ [(_ getter bumper init incr)
+
+ (begin
+
+ (define count init)
+
+ (define-syntax getter (identifier-syntax count))
+
+ (indirect-export getter count)
+
+ (define bumper
+
+ (lambda ()
+
+ (set! count (incr count)))))]))
+
+
+(module M (bump-count current-count)
+
+ (define-counter current-count bump-count 0 add1))
+
syntax: (implicit-exports #t)
+
syntax: (implicit-exports #f)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
An implicit-exports form is a definition and can appear with other +definitions at the front of a library or module. +It is a syntax error for an implicit-exports form to appear in other +contexts, including at top level or among the definitions of a +top-level program or lambda body. + +
+The implicit-exports form determines whether identifiers +not directly exported from a module or library are automatically +indirectly exported to the top level if any meta-binding (keyword, meta +definition, or property definition) is directly exported to top level +from the library or module. +The default for libraries is #t, to match the behavior required +by the Revised6 Report, while the default for modules is #f. +The implicit-exports form is meaningful only within a library, +top-level module, or module enclosed within a library or top-level module. +It is allowed in a module enclosed within a lambda, let, +or similar body, but ignored there because none of that module's bindings +can be exported to top level. + +
+The advantage of (implicit-exports #t) is that indirect exports +need not be listed explicitly, which is convenient. +A disadvantage is that it often results in more bindings than necessary +being elevated to top level where they cannot be discarded as useless +by the optimizer. +For modules, another disadvantage is such bindings +cannot be proven immutable, which inhibits important optimizations such +as procedure inlining. +This can result in significantly lower run-time performance. + +
+ +
+procedure: (invoke-library libref)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
libref must be an s-expression in the form of a library reference. +The syntax for library references is given in +Chapter 10 of The Scheme Programming Language, 4th Edition and in the Revised6 +Report. + +
+A library is implicitly invoked when or before some expression +outside the library (e.g., in another library or in a top-level +program) evaluates a reference to one of the library's exported +variables. +When the library is invoked, its body expressions (the right-hand-sides +of the library's variable definitions and its initialization +expressions) are evaluated. +Once invoked, the library is not invoked again within the same process, +unless it is first explicitly redefined or reloaded. + +
+invoke-library explicitly invokes the library specified +by libref if it has not already been invoked or has since +been redefined or reloaded. +If the library has not yet been loaded, invoke-library +first loads the library via the process described in +Section 2.4. + +
+invoke-library is typically only useful for libraries whose +body expressions have side effects. +It is useful to control when the side effects occur and to force +invocation of a library that has no exported variables. +Invoking a library does not force the compile-time code (macro +transformer expressions and meta definitions) to be loaded or +evaluated, nor does it cause the library's bindings to become +visible. + +
+It is good practice to avoid externally visible side effects in +library bodies so the library can be used equally well at compile +time and run time. +When feasible, consider moving the side effects of a library body +to an initialization routine and adding a top-level program that +imports the library and calls the initialization routine. +With this structure, calls to invoke-library on the +library can be replaced by calls to +load-program on the +top-level program. + +
+ +
+The parameters described below control where import looks +when attempting to load a library, whether it compiles the libraries +it loads, and whether it displays tracking messages as it performs its +search. + +
+thread parameter: library-directories
+
thread parameter: library-extensions
+
+libraries: (chezscheme)
+
+
The parameter library-directories determines where the files +containing library source and object code are located in the file system, +and the parameter library-extensions determines the filename +extensions for the files holding the code, as described in +section 2.4. +The values of both parameters are lists of pairs of strings. +The first string in each library-directories pair identifies a +source-file root directory, and the second identifies the corresponding +object-file root directory. +Similarly, the first string in each library-extensions pair +identifies a source-file extension, and the second identifies the +corresponding object-file extension. +The full path of a library source or object file consists of the source or +object root followed by the components of the library name prefixed by +slashes, with the library extension added on the end. +For example, for root /usr/lib/scheme, library name +(app lib1), and extension .sls, the full path is +/usr/lib/scheme/app/lib1.sls. +If the library name portion forms an absolute pathname, e.g., +~/.myappinit, the library-directories parameter is +ignored and no prefix is added. + +
+The initial values of these parameters are shown below. + +
+ +
(library-directories) (("." . "."))
+
+
+(library-extensions) ((".chezscheme.sls" . ".chezscheme.so")
+
+ (".ss" . ".so")
+
+ (".sls" . ".so")
+
+ (".scm" . ".so")
+
+ (".sch" . ".so"))
+
As a convenience, when either of these parameters is set, any element of +the list can be specified as a single source string, in which case the +object string is determined automatically. +For library-directories, the object string is the same as +the source string, effectively naming the +same directory as a source- and object-code root. +For library-extensions, the object string is the result of +removing the last (or only) extension from the string and appending +".so". +The library-directories and library-extensions +parameters also accept as input strings in the format described +in Section 2.5 +for the +--libdirs and +--libexts command-line +options. + +
+thread parameter: compile-imported-libraries
+
+libraries: (chezscheme)
+
+
When the value of this parameter is #t, import +automatically calls the value of the compile-library-handler parameter (which defaults +to a procedure that simply calls compile-library) on any imported library if +the object file is missing, older than the corresponding source file, +older than any source files included (via include) when the +object file was created, or itself requires a library that has been or must +be recompiled, as described in Section 2.4. +The library-timestamp-mode parameter controls the meaning of "older." +The default initial value of this parameter is #f. +It can be set to #t via the command-line option +--compile-imported-libraries. + +
+When import compiles a library via this mechanism, it does not +also load the compiled library, because this would cause portions of +library to be reevaluated. +Because of this, run-time expressions in the file outside of a +library form will not be evaluated. +If such expressions are present and should be evaluated, the library +should be loaded explicitly. + +
+thread parameter: import-notify
+
+libraries: (chezscheme)
+
+
When the new parameter import-notify is set to a true value, +import displays messages to the console-output port as it +searches for the file containing each library it needs to load. +The default value of this parameter is #f. + +
+thread parameter: library-search-handler
+
+libraries: (chezscheme)
+
+
The value of parameter must be a procedure that follows the protocol described +below for default-library-search-handler, which is the default value +of this parameter. + +
+The value of this parameter is invoked to locate the source or object code for +a library during import, compile-whole-program, or +compile-whole-library. + +
+procedure: (default-library-search-handler who library directories extensions)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
This procedure is the default value of the library-search-handler, +which is +called to locate the source or object code for a library +during import, +compile-whole-program, or compile-whole-library. +who is a symbol that provides context in import-notify messages. +library is the name of the desired library. +directories is a list of source and object directory pairs in +the form returned by library-directories. +extensions is a list of source and object extension pairs in the form +returned by library-extensions. + +
+This procedure searches the specified directories until it finds a library source or +object file with one of the specified extensions. +If it finds the source file first, it constructs the corresponding +object file path and checks whether the file exists. +If it finds the object file first, the procedure looks for a corresponding +source file with one of the given source extensions in a source directory paired +with that object directory. +The procedure returns three values: +the file-system path of the library source file or #f if not found, +the file-system path of the corresponding object file, which may be #f, +and a boolean that is true if the object file exists. + +
+thread parameter: library-timstamp-mode
+
+libraries: (chezscheme)
+
+
The value of parameter must be either 'modification-time (the +default) or 'exists. If it is 'modification-time, +the timestamp of library source and object files is obtained with +file-modification-time to determine whether a file is older +than the other. If the parameter's value is 'exists, then all +files that exist are considered to have the same age. This parameter's +value can be set to 'exists via the command-line option +--disable-library-timestamps. + + +
+ +
+procedure: (library-list)
+
+returns: a list of the libraries currently defined
+
+libraries: (chezscheme)
+
+
The set of libraries initially defined includes those listed in +Section 10.1 above. + +
+procedure: (library-version libref)
+
+returns: the version of the specified library
+
procedure: (library-exports libref)
+
+returns: a list of the exports of the specified library
+
procedure: (library-requirements libref)
+
+returns: a list of libraries required by the specified library
+
procedure: (library-requirements libref options)
+
+returns: a list of libraries required by the specified library, filtered by options
+
procedure: (library-object-filename libref)
+
+returns: the name of the object file holding the specified library, if any
+
+libraries: (chezscheme)
+
+
Information can be obtained only for built-in libraries or libraries +previously loaded into the system. +libref must be an s-expression in the form of a library reference. +The syntax for library references is given in +Chapter 10 of The Scheme Programming Language, 4th Edition and in the Revised6 +Report. + +
+The library-version return value is a list of numbers +(possibly empty) representing the library's version. + +
+The list of exports returned by library-exports is a list of +symbols, each identifying one of the library's exports. +The order in which the elements appear is unspecified. + +
+When the optional options argument is supplied, it must be +an enumeration set over the symbols constituting +valid library-requirements options, as described in the +library-requirements-options entry below. +It defaults to a set containing all of the options. +Each element of the list of libraries returned by +library-requirements is an s-expression form of a library +reference. +The library reference includes the actual version of the library that is +present in the system (if nonempty), even if a version was not specified +when it was imported. +The order in which the libraries appear in the list returned by +library-requirements is unspecified. + +
+library-object-filename returns a string naming the object +file if the specified library was loaded from or compiled to an object +file. +Otherwise, it returns #f. + + +
+ +
(with-output-to-file "A.ss"
+
+ (lambda ()
+
+ (pretty-print
+
+ '(library (A (1 2)) (export x z)
+
+ (import (rnrs))
+
+ (define x 'ex)
+
+ (define y 23)
+
+ (define-syntax z
+
+ (syntax-rules ()
+
+ [(_ e) (+ y e)])))))
+
+ 'replace)
+
+(with-output-to-file "B.ss"
+
+ (lambda ()
+
+ (pretty-print
+
+ '(library (B) (export x w)
+
+ (import (rnrs) (A))
+
+ (define w (cons (z 12) x)))))
+
+ 'replace)
+
+(compile-imported-libraries #t)
+
+(import (B))
+
+(library-exports '(A)) (x z) ; or (z x)
+
+(library-exports '(A (1 2))) (x z) ; or (z x)
+
+(library-exports '(B)) (x w) ; or (w x)
+
+(library-version '(A)) (1 2)
+
+(library-version '(B)) ()
+
+(library-requirements '(A)) ((rnrs (6)))
+
+(library-requirements '(B)) ((rnrs (6)) (A (1 2)))
+
+(library-object-filename '(A)) "A.so"
+
+(library-object-filename '(B)) "B.so"
+
syntax: (library-requirements-options symbol ...)
+
+returns: a library-requirements-options enumeration set
+
+libraries: (chezscheme)
+
+
Library-requirements-options enumeration sets are passed to +library-requirements to determine the library requirements +to be listed. The available options are described below. + +
+
+
+
+
+ + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/math/csug/0.gif b/csug10.0/math/csug/0.gif
new file mode 100644
index 000000000..1ec3d7c25
Binary files /dev/null and b/csug10.0/math/csug/0.gif differ
diff --git a/csug10.0/math/csug/1.gif b/csug10.0/math/csug/1.gif
new file mode 100644
index 000000000..f5a519132
Binary files /dev/null and b/csug10.0/math/csug/1.gif differ
diff --git a/csug10.0/math/csug/2.gif b/csug10.0/math/csug/2.gif
new file mode 100644
index 000000000..e811a36a6
Binary files /dev/null and b/csug10.0/math/csug/2.gif differ
diff --git a/csug10.0/math/csug/3.gif b/csug10.0/math/csug/3.gif
new file mode 100644
index 000000000..7e0607eb4
Binary files /dev/null and b/csug10.0/math/csug/3.gif differ
diff --git a/csug10.0/math/csug/4.gif b/csug10.0/math/csug/4.gif
new file mode 100644
index 000000000..24c9f34ad
Binary files /dev/null and b/csug10.0/math/csug/4.gif differ
diff --git a/csug10.0/math/csug/5.gif b/csug10.0/math/csug/5.gif
new file mode 100644
index 000000000..a59581721
Binary files /dev/null and b/csug10.0/math/csug/5.gif differ
diff --git a/csug10.0/numeric.html b/csug10.0/numeric.html
new file mode 100644
index 000000000..debddfbaf
--- /dev/null
+++ b/csug10.0/numeric.html
@@ -0,0 +1,1949 @@
+
+
+
+
+
+This chapter describes Chez Scheme extensions to the standard set of +operations on numbers. +See Chapter 6 of The Scheme Programming Language, 4th Edition or the Revised6 Report +on Scheme for a description of standard operations on numbers. + +
+Chez Scheme supports the full set of Scheme numeric datatypes, including +exact and inexact integer, rational, real, and complex numbers. +A variety of representations are used to support these datatypes: + +
+
+
+
+
+
+
+Most numbers can be represented in only one way; however, real numbers +are sometimes represented as inexact complex numbers with imaginary +component equal to zero. + +
+Chez Scheme extends the syntax of numbers with arbitrary radixes from +two through 36, nondecimal floating-point and scientific notation, +and printed representations for +IEEE infinities and NANs. (NAN stands for "not-a-number.") + +
+Arbitrary radixes are specified with the prefix #nr, where +n ranges from 2 through 36. +Digits beyond 9 are specified with the letters (in either +upper or lower case) a through z. +For example, #2r101 is 510, and +#36rZ is 3510. + +
+For higher radixes, an ambiguity arises between the interpretation of +certain letters, e.g., e, as digits or exponent specifiers; in +such cases, the letter is assumed to be a digit. +For example, the e in #x3.2e5 is interpreted as a +digit, not as an exponent marker, whereas in 3.2e5 it is +treated as an exponent marker. + +
+IEEE infinities are printed as +inf.0 and -inf.0, +while IEEE NANs are printed as +nan.0 or -nan.0. +(+nan.0 is used on output for all NANs.) + +
+ +
(/ 1.0 0.0) +inf.0
+
+(/ 1.0 -0.0) -inf.0
+
+(/ 0.0 0.0) +nan.0
+
+(/ +inf.0 -inf.0) +nan.0
+
The first section of this chapter describes type-specific numeric type +predicates. +Sections 8.2 through 8.4 +describe fast, type-specific +numeric operations on fixnums, flonums, and inexact complex numbers +(flonums and/or inexact complexnums). +The fixnum-specific versions should be used only when the programmer +is certain that the operands and results (where appropriate) will be +fixnums, i.e., integers in the range (most-negative-fixnum) to +(most-positive-fixnum), inclusive. +The flonum-specific versions should be used only when the +inputs and outputs (where appropriate) are certain to be flonums. +The mixed flonum/complexnum versions should be used only when the +inputs are certain to be either flonums or inexact complexnums. +Section 8.5 describes operations, both +arbitrary precision and fixnum-specific, that allow +exact integers to be treated as sets or sequences of bits. +Random number generation is covered Section 8.6, +and miscellaneous numeric operations are covered in the +Section 8.7. + + +
+ +
+The Revised6 Report distinguishes two types of special numeric objects: +fixnums and flonums. +Chez Scheme additionally distinguishes bignums (exact integers outside +of the fixnum range) and ratnums (ratios of exact integers). +It also provides a predicate for recognizing cflonums, which are +flonums or inexact complex numbers. + +
+procedure: (bignum? obj)
+
+returns: #t if obj is a bignum, otherwise #f
+
+libraries: (chezscheme)
+
+
+
+(bignum? 0) #f
+
+(bignum? (most-positive-fixnum)) #f
+
+(bignum? (most-negative-fixnum)) #f
+
+(bignum? (* (most-positive-fixnum) 2)) #t
+
+(bignum? 3/4) #f
+
+(bignum? 'a) #f
+
procedure: (ratnum? obj)
+
+returns: #t if obj is a ratnum, otherwise #f
+
+libraries: (chezscheme)
+
+
+
+(ratnum? 0) #f
+
+(ratnum? (* (most-positive-fixnum) 2)) #f
+
+(ratnum? 3/4) #t
+
+(ratnum? -10/2) #f
+
+(ratnum? -11/2) #t
+
+(ratnum? 'a) #f
+
procedure: (cflonum? obj)
+
+returns: #t if obj is an inexact complexnum or flonum, otherwise #f
+
+libraries: (chezscheme)
+
+
+
+(cflonum? 0) #f
+
+(cflonum? 0.0) #t
+
+(cflonum? 3+4i) #f
+
+(cflonum? 3.0+4i) #t
+
+(cflonum? +i) #f
+
+(cflonum? +1.0i) #t
+
+
+Fixnum-specific procedures normally check their inputs and outputs (where +appropriate), but at optimization level 3 the compiler generates, in most +cases, code that does not perform these checks. + +
+procedure: (most-positive-fixnum)
+
+returns: the most positive fixnum supported by the system
+
procedure: (most-negative-fixnum)
+
+returns: the most negative fixnum supported by the system
+
+libraries: (chezscheme)
+
+
These procedures are identical to the Revised6 Report +greatest-fixnum and least-fixnum procedures. + + +
+procedure: (fx= fixnum1 fixnum2 ...)
+
procedure: (fx< fixnum1 fixnum2 ...)
+
procedure: (fx> fixnum1 fixnum2 ...)
+
procedure: (fx<= fixnum1 fixnum2 ...)
+
procedure: (fx>= fixnum1 fixnum2 ...)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
The predicate fx= returns #t if its arguments are equal. +The predicate fx< returns #t if its arguments are monotonically +increasing, i.e., each argument is greater than the preceding ones, +while fx> returns #t if its arguments are monotonically decreasing. +The predicate fx<= returns #t if its arguments are monotonically +nondecreasing, i.e., each argument is not less than the preceding ones, +while fx>= returns #t if its arguments are monotonically nonincreasing. +When passed only one argument, each of these predicates returns #t. + +
+These procedures are similar to the Revised6 Report procedures +fx=?, fx<?, fx>?, fx<=?, +and fx>=? except that the Revised6 Report procedures +require two or more arguments, and their names have the "?" +suffix. + +
+ +
(fx= 0) #t
+
+(fx= 0 0) #t
+
+(fx< (most-negative-fixnum) 0 (most-positive-fixnum)) #t
+
+(let ([x 3]) (fx<= 0 x 9)) #t
+
+(fx<= 0 3 3) #t
+
+(fx>= 0 0 (most-negative-fixnum)) #t
+
procedure: (fxnonpositive? fixnum)
+
+returns: #t if fixnum is not greater than zero, #f otherwise
+
procedure: (fxnonnegative? fixnum)
+
+returns: #t if fixnum is not less than zero, #f otherwise
+
+libraries: (chezscheme)
+
+
fxnonpositive? is equivalent to (lambda (x) (fx<= x 0)), +and +fxnonnegative? is equivalent to (lambda (x) (fx>= x 0)). + +
+ +
(fxnonpositive? 128) #f
+
+(fxnonpositive? 0) #t
+
+(fxnonpositive? -1) #t
+
+
+(fxnonnegative? -65) #f
+
+(fxnonnegative? 0) #t
+
+(fxnonnegative? 1) #t
+
procedure: (fx+ fixnum ...)
+
+returns: the sum of the arguments fixnum ...
+
+libraries: (chezscheme)
+
+
When called with no arguments, fx+ returns 0. + +
+ +
(fx+) 0
+
+(fx+ 1 2) 3
+
+(fx+ 3 4 5) 12
+
+(apply fx+ '(1 2 3 4 5)) 15
+
procedure: (fx- fixnum1 fixnum2 ...)
+
+returns: a fixnum
+
+libraries: (chezscheme)
+
+
When called with one argument, fx- returns the negative of fixnum1. +Thus, (fx- fixnum1) is an idiom for (fx- 0 fixnum1). + +
+When called with two or more arguments, fx- returns the result of +subtracting the sum of the numbers fixnum2 ... from +fixnum1. + +
+ +
(fx- 3) -3
+
+(fx- 4 3) 1
+
+(fx- 4 3 2 1) -2
+
procedure: (fx* fixnum ...)
+
+returns: the product of the arguments fixnum ...
+
+libraries: (chezscheme)
+
+
When called with no arguments, fx* returns 1. + +
+ +
(fx*) 1
+
+(fx* 1 2) 2
+
+(fx* 3 -4 5) -60
+
+(apply fx* '(1 -2 3 -4 5)) 120
+
procedure: (fx/ fixnum1 fixnum2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
When called with one argument, fx/ returns the reciprocal +of fixnum1. +That is, (fx/ fixnum1) is an idiom for +(fx/ 1 fixnum1). + +
+When called with two or more arguments, fx/ returns +the result of +dividing fixnum1 by the product of the remaining arguments +fixnum2 .... + +
+ +
(fx/ 1) 1
+
+(fx/ -17) 0
+
+(fx/ 8 -2) -4
+
+(fx/ -9 2) -4
+
+(fx/ 60 5 3 2) 2
+
procedure: (fx+/wraparound fixnum ...)
+
procedure: (fx-/wraparound fixnum ...)
+
procedure: (fx*/wraparound fixnum ...)
+
procedure: (fxsll/wraparound fixnum ...)
+
+returns: the arithmetic result, wrapping on overflow
+
+libraries: (chezscheme)
+
+
These functions are like fx+, fx-, fx*, and +fxsll, but when the result is too large to fit in a fixnum, +as many high bits of the result as necessary are discarded to make the result representable +as a fixnum. + +
+procedure: (fx1+ fixnum)
+
procedure: (fx1- fixnum)
+
+returns: fixnum plus 1 or fixnum minus 1
+
+libraries: (chezscheme)
+
+
+
(define fxplus
+
+ (lambda (x y)
+
+ (if (fxzero? x)
+
+ y
+
+ (fxplus (fx1- x) (fx1+ y)))))
+
+
+(fxplus 7 8) 15
+
fx1+ and fx1- can be defined as follows: + +
+ +
(define fx1+ (lambda (x) (fx+ x 1)))
+
+(define fx1- (lambda (x) (fx- x 1)))
+
procedure: (fxquotient fixnum1 fixnum2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
fxquotient is identical to fx/. +See the description of fx/ above. + + +
+procedure: (fxremainder fixnum1 fixnum2)
+
+returns: the fixnum remainder of fixnum1 divided by fixnum2
+
+libraries: (chezscheme)
+
+
The result of fxremainder has the same sign as fixnum1. + +
+ +
(fxremainder 16 4) 0
+
+(fxremainder 5 2) 1
+
+(fxremainder -45 7) -3
+
+(fxremainder 10 -3) 1
+
+(fxremainder -17 -9) -8
+
procedure: (fxmodulo fixnum1 fixnum2)
+
+returns: the fixnum modulus of fixnum1 and fixnum2
+
+libraries: (chezscheme)
+
+
The result of fxmodulo has the same sign as fixnum2. + +
+ +
(fxmodulo 16 4) 0
+
+(fxmodulo 5 2) 1
+
+(fxmodulo -45 7) 4
+
+(fxmodulo 10 -3) -2
+
+(fxmodulo -17 -9) -8
+
procedure: (fxabs fixnum)
+
+returns: the absolute value of fixnum
+
+libraries: (chezscheme)
+
+
+
+(fxabs 1) 1
+
+(fxabs -1) 1
+
+(fxabs 0) 0
+
+
+Inexact real numbers are normally represented by flonums. +A flonum is a single 64-bit double-precision floating point +number. +This section describes operations on flonums, most of which accept +flonum arguments and return flonum values. +In most cases, the operations are inline-coded or coded as machine +language subroutines at optimize-level 3 with +no argument type checking; full type checking is performed at lower +optimize levels. +Flonum-specific procedure names begin with the prefix "fl" to +set them apart from their generic counterparts. + +
+Inexact real numbers may also be represented by inexact complexnums +with imaginary parts equal to zero, which cannot be used as input +to the flonum-specific operators. +Such numbers are produced, however, only from operations involving +complex numbers with nonzero imaginary parts, by explicit calls +to fl-make-rectangular, make-rectangular, or +make-polar, or by numeric input in either polar or rectangular +format. + +
+procedure: (flonum->fixnum flonum)
+
+returns: the fixnum representation of flonum, truncated
+
+libraries: (chezscheme)
+
+
The truncated value of flonum must fall within the fixnum range. +flonum->fixnum is a restricted version of +exact, +which converts any numeric representation +to its exact equivalent. + +
+ +
(flonum->fixnum 0.0) 0
+
+(flonum->fixnum 3.9) 3
+
+(flonum->fixnum -2.2) -2
+
procedure: (fl= flonum1 flonum2 ...)
+
procedure: (fl< flonum1 flonum2 ...)
+
procedure: (fl> flonum1 flonum2 ...)
+
procedure: (fl<= flonum1 flonum2 ...)
+
procedure: (fl>= flonum1 flonum2 ...)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
The predicate fl= returns #t if its arguments are equal. +The predicate fl< returns #t if its arguments are monotonically +increasing, i.e., each argument is greater than the preceding ones, +while fl> returns #t if its arguments are monotonically decreasing. +The predicate fl<= returns #t if its arguments are monotonically +nondecreasing, i.e., each argument is not less than the preceding ones, +while fl>= returns #t if its arguments are monotonically nonincreasing. +When passed only one argument, each of these predicates returns #t. + +
+IEEE NANs are not comparable, i.e., comparisons involving NANs always return +#f. + +
+These procedures are similar to the Revised6 Report procedures +fl=?, fl<?, fl>?, fl<=?, +and fl>=? except that the Revised6 Report procedures +require two or more arguments, and their names have the "?" +suffix. + +
+ +
(fl= 0.0) #t
+
+(fl= 0.0 0.0) #t
+
+(fl< -1.0 0.0 1.0) #t
+
+(fl> -1.0 0.0 1.0) #f
+
+(fl<= 0.0 3.0 3.0) #t
+
+(fl>= 4.0 3.0 3.0) #t
+
+(fl< 7.0 +inf.0) #t
+
+(fl= +nan.0 0.0) #f
+
+(fl= +nan.0 +nan.0) #f
+
+(fl< +nan.0 +nan.0) #f
+
+(fl> +nan.0 +nan.0) #f
+
procedure: (flnonpositive? fl)
+
+returns: #t if fl is not greater than zero, #f otherwise
+
procedure: (flnonnegative? fl)
+
+returns: #t if fl is not less than zero, #f otherwise
+
+libraries: (chezscheme)
+
+
flnonpositive? is equivalent to (lambda (x) (fl<= x 0.0)), +and +flnonnegative? is equivalent to (lambda (x) (fl>= x 0.0)). + +
+Even if the flonum representation distinguishes -0.0 from +0.0, both +are considered nonpositive and nonnegative. + +
+ +
(flnonpositive? 128.0) #f
+
+(flnonpositive? 0.0) #t
+
+(flnonpositive? -0.0) #t
+
+(flnonpositive? -1.0) #t
+
+
+(flnonnegative? -65.0) #f
+
+(flnonnegative? 0.0) #t
+
+(flnonnegative? -0.0) #t
+
+(flnonnegative? 1.0) #t
+
+
+(flnonnegative? +nan.0) #f
+
+(flnonpositive? +nan.0) #f
+
+
+(flnonnegative? +inf.0) #t
+
+(flnonnegative? -inf.0) #f
+
procedure: (flsingle fl)
+
+returns: a possibly less precise variant of fl
+
+libraries: (chezscheme)
+
+
Potentially discards precision from fl so that the result is +representable as a 32-bit IEEE floating-point number. + +
+procedure: (decode-float x)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
x must be a flonum. +decode-float returns a vector with three integer elements, +m, e, and s, such that +x = sm2e. +It is useful primarily in the printing of floating-point numbers. + +
+ +
(decode-float 1.0) #(4503599627370496 -52 1)
+
+(decode-float -1.0) #(4503599627370496 -52 -1)
+
+
+(define slow-identity
+
+ (lambda (x)
+
+ (inexact
+
+ (let ([v (decode-float x)])
+
+ (let ([m (vector-ref v 0)]
+
+ [e (vector-ref v 1)]
+
+ [s (vector-ref v 2)])
+
+ (* s m (expt 2 e)))))))
+
+
+(slow-identity 1.0) 1.0
+
+(slow-identity -1e20) -1e20
+
procedure: (fllp flonum)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
fllp returns the 12-bit integer consisting of the exponent +plus highest order represented bit of a flonum (ieee 64-bit +floating-point number). +It can be used to compute a fast approximation of the logarithm of +the number. + +
+ +
(fllp 0.0) 0
+
+(fllp 1.0) 2046
+
+(fllp -1.0) 2046
+
+
+(fllp 1.5) 2047
+
+
+(fllp +inf.0) 4094
+
+(fllp -inf.0) 4094
+
+
+(fllp #b1.0e-1111111111) 1
+
+(fllp #b1.0e-10000000000) 0
+
+
+The procedures described in this section provide mechanisms for +creating and operating on inexact complex numbers. +Inexact complex numbers with nonzero imaginary parts are represented as +inexact complexnums. +An inexact complexnum contains two 64-bit double-precision floating point +numbers. +Inexact complex numbers +with imaginary parts equal to zero (in other words, inexact real numbers) +may be represented as either inexact complexnums or flonums. +The operations described in this section accept any mix of +inexact complexnum and flonum arguments +(collectively, "cflonums"). + +
+In most cases, the operations are performed with minimal type checking +at optimize-level 3; full type checking is performed at lower optimize +levels. +Inexact complex procedure names begin with the prefix "cfl" +to set them apart from their generic counterparts. + + +
+procedure: (fl-make-rectangular flonum1 flonum2)
+
+returns: an inexact complexnum
+
+libraries: (chezscheme)
+
+
The inexact complexnum produced by fl-make-rectangular has real part equal +to flonum1 and imaginary part equal to flonum2. + +
+ +
(fl-make-rectangular 2.0 -3.0) 2.0-3.0i
+
+(fl-make-rectangular 2.0 0.0) 2.0+0.0i
+
+(fl-make-rectangular 2.0 -0.0) 2.0-0.0i
+
procedure: (cfl-real-part cflonum)
+
+returns: the real part of cflonum
+
procedure: (cfl-imag-part cflonum)
+
+returns: the imaginary part of cflonum
+
+libraries: (chezscheme)
+
+
+ +
(cfl-real-part 2.0-3.0i) 2.0
+
+(cfl-imag-part 2.0-3.0i) -3.0
+
+(cfl-imag-part 2.0-0.0i) -0.0
+
+(cfl-imag-part 2.0-inf.0i) -inf.0
+
procedure: (cfl= cflonum ...)
+
+returns: #t if its arguments are equal, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(cfl= 7.0+0.0i 7.0) #t
+
+(cfl= 1.0+2.0i 1.0+2.0i) #t
+
+(cfl= 1.0+2.0i 1.0-2.0i) #f
+
procedure: (cfl+ cflonum ...)
+
procedure: (cfl* cflonum ...)
+
procedure: (cfl- cflonum1 cflonum2 ...)
+
procedure: (cfl/ cflonum1 cflonum2 ...)
+
+returns: a cflonum
+
+libraries: (chezscheme)
+
+
These procedures compute the sum, difference, product, or quotient +of inexact complex quantities, whether these quantities are represented +by flonums or inexact complexnums. +For example, if cfl+ receives two flonum arguments a and b, it +returns the sum a + b; in this case, it behaves the same as fl+. +With two inexact complexnum arguments a + bi and c + di, it returns +the sum (a + c) + (b + d)i. +If one argument is a flonum a and the other an inexact complexnum +c + di, cfl+ returns (a + c) + di. + +
+When passed zero arguments, cfl+ returns 0.0 and +cfl* returns 1.0. +When passed one argument, cfl- returns the additive inverse +of the argument, and cfl/ returns the multiplicative inverse +of the argument. +When passed three or more arguments, cfl- returns the +difference between its first and the sum of its remaining arguments, +and cfl/ returns the quotient of its first and the product +of its remaining arguments. + + +
+ +
(cfl+) 0.0
+
+(cfl*) 1.0
+
+(cfl- 5.0+1.0i) -5.0-1.0i
+
+(cfl/ 2.0+2.0i) 0.25-0.25i
+
+
+(cfl+ 1.0+2.2i -3.7+5.3i) -2.7+7.5i
+
+(cfl+ 1.0 -5.3) -4.3
+
+(cfl+ 1.0 2.0 -5.3i) 3.0-5.3i
+
+(cfl- 1.0+2.5i -3.7) 4.7+2.5i
+
+(cfl* 1.0+2.0i 3.0+4.0i) -5.0+10.0i
+
+(cfl/ -5.0+10.0i 1.0+2.0i 2.0) 1.5+2.0i
+
procedure: (cfl-conjugate cflonum)
+
+returns: complex conjugate of cflonum
+
+libraries: (chezscheme)
+
+
The procedure cfl-conjugate, when passed an inexact complex argument +a + bi, returns its complex conjugate a + (-b)i. + +
+See also conjugate, which is a generic +version of this operator that returns the complex conjugate of any +valid representation for a complex number. + +
+ +
(cfl-conjugate 3.0) 3.0
+
+(cfl-conjugate 3.0+4.0i) 3.0-4.0i
+
+(cfl-conjugate 1e-20-2e-30i) 1e-20+2e-30i
+
procedure: (cfl-magnitude-squared cflonum)
+
+returns: magnitude of cflonum squared
+
+libraries: (chezscheme)
+
+
The procedure cfl-magnitude-squared, when passed an inexact complex +argument a + bi returns a flonum representing the magnitude of the +argument squared, i.e., a2 + b2. + +
+See also magnitude-squared, +which is a generic version of this +operator that returns the magnitude squared of any valid representation +for a complex number. +Both operations are similar to the magnitude procedure, +which returns the magnitude, sqrt(a2 + b2), of its generic complex +argument. + +
+ +
(cfl-magnitude-squared 3.0) 9.0
+
+(cfl-magnitude-squared 3.0-4.0i) 25.0
+
+
+Chez Scheme provides a set of logical operators that allow exact +integers (fixnums and bignums) to be treated as sets or sequences +of bits. +These operators include +logand (bitwise logical and), +logior (bitwise logical or), +logxor (bitwise logical exclusive or), +lognot (bitwise logical not), +logtest (test multiple bits), +logbit? (test single bit), +logbit0 (reset single bit), +logbit1 (set single bit), +and ash (arithmetic shift). +Each of these operators treats its arguments as two's complement integers, +regardless of the underlying representation. +This treatment can be exploited to represent infinite sets: +a negative number represents an infinite number of one bits beyond the +leftmost zero, and a nonnegative number represents an infinite number of zero +bits beyond the leftmost one bit. + +
+Fixnum equivalents of the logical operators are provided, as +fxlogand, fxlogior, fxlogxor, +fxlognot, fxlogtest, fxlogbit?, +fxlogbit0, and fxlogbit1. +Three separate fixnum operators are provided for shifting: +fxsll (shift-left logical), +fxsrl (shift-right logical), +fxsra (shift-right arithmetic). +Logical and arithmetic shifts differ only for right shifts. +Shift-right logical shifts in zero bits on the left end, and shift-right +arithmetic replicates the sign bit. + +
+Logical shifts do not make sense for arbitrary-precision integers, +since these have no "left end" into which bits must be shifted. + +
+procedure: (logand int ...)
+
+returns: the logical "and" of the arguments int ...
+
+libraries: (chezscheme)
+
+
The arguments must be exact integers (fixnums or bignums) and are treated +as two's complement integers, regardless of the underlying representation. +With no arguments, logand returns -1, i.e., all bits set. + +
+ +
(logand) -1
+
+(logand 15) 15
+
+(logand -1 -1) -1
+
+(logand -1 0) 0
+
+(logand 5 3) 1
+
+(logand #x173C8D95 7) 5
+
+(logand #x173C8D95 -8) #x173C8D90
+
+(logand #b1100 #b1111 #b1101) #b1100
+
procedure: (logior int ...)
+
procedure: (logor int ...)
+
+returns: the logical "or" of the arguments int ...
+
+libraries: (chezscheme)
+
+
The arguments must be exact integers (fixnums or bignums) and are treated +as two's complement integers, regardless of the underlying representation. +With no arguments, logior returns 0, i.e., all bits reset. + +
+ +
(logior) 0
+
+(logior 15) 15
+
+(logior -1 -1) -1
+
+(logior -1 0) -1
+
+(logior 5 3) 7
+
+(logior #b111000 #b101010) #b111010
+
+(logior #b1000 #b0100 #b0010) #b1110
+
+(apply logior '(1 2 4 8 16)) 31
+
procedure: (logxor int ...)
+
+returns: the logical "exclusive or" of the arguments int ...
+
+libraries: (chezscheme)
+
+
The arguments must be exact integers (fixnums or bignums) and are treated +as two's complement integers, regardless of the underlying representation. +With no arguments, logxor returns 0, i.e., all bits reset. + +
+ +
(logxor) 0
+
+(logxor 15) 15
+
+(logxor -1 -1) 0
+
+(logxor -1 0) -1
+
+(logxor 5 3) 6
+
+(logxor #b111000 #b101010) #b010010
+
+(logxor #b1100 #b0100 #b0110) #b1110
+
procedure: (lognot int)
+
+returns: the logical "not" of int
+
+libraries: (chezscheme)
+
+
The argument must be an exact integer (fixnum or bignum) and is treated +as a two's complement integer, regardless of the underlying representation. + +
+ +
(lognot -1) 0
+
+(lognot 0) -1
+
+(lognot 7) -8
+
+(lognot -8) 7
+
procedure: (logbit? index int)
+
+returns: #t if the specified bit is set, otherwise #f
+
+libraries: (chezscheme)
+
+
index must be a nonnegative exact integer. +int must be an exact integer (fixnum or bignum) and is treated +as a two's complement integer, regardless of the underlying representation. + +
+logbit? returns #t if the bit at index index +of int is set (one) and #f otherwise. +The index is zero-based, counting from the lowest-order toward +higher-order bits. +There is no upper limit on the index; for nonnegative values of int, +the bits above the highest order set bit are all considered to be zero, +and for negative values, the bits above the highest order reset bit are +all considered to be one. + +
+logbit? is equivalent to + +
+ +
(lambda (k n) (not (zero? (logand n (ash 1 k))))) +
but more efficient. + +
+ +
(logbit? 0 #b1110) #f
+
+(logbit? 1 #b1110) #t
+
+(logbit? 2 #b1110) #t
+
+(logbit? 3 #b1110) #t
+
+(logbit? 4 #b1110) #f
+
+(logbit? 100 #b1110) #f
+
+
+(logbit? 0 -6) #f ; the two's complement of -6 is 1...1010
+
+(logbit? 1 -6) #t
+
+(logbit? 2 -6) #f
+
+(logbit? 3 -6) #t
+
+(logbit? 100 -6) #t
+
+
+(logbit? (random 1000000) 0) #f
+
+(logbit? (random 1000000) -1) #t
+
+
+(logbit? 20000 (ash 1 20000)) #t
+
procedure: (logtest int1 int2)
+
+returns: #t if any common bits are set, otherwise #f
+
+libraries: (chezscheme)
+
+
The arguments must be exact integers (fixnums or bignums) and are treated +as two's complement integers, regardless of the underlying representation. + +
+logtest returns #t if any bit set in one argument is +also set in the other. +It returns #f if the two arguments have no set bits in common. + +
+logtest is equivalent to + +
+ +
(lambda (n1 n2) (not (zero? (logand n1 n2)))) +
but more efficient. + +
+ +
(logtest #b10001 #b1110) #f
+
+(logtest #b10101 #b1110) #t
+
+(logtest #b111000 #b110111) #t
+
+
+(logtest #b101 -6) #f ; the two's complement of -6 is 1...1010
+
+(logtest #b1000 -6) #t
+
+(logtest 100 -6) #t
+
+
+(logtest (+ (random 1000000) 1) 0) #f
+
+(logtest (+ (random 1000000) 1) -1) #t
+
+
+(logtest (ash #b101 20000) (ash #b111 20000)) #t
+
procedure: (logbit0 index int)
+
+returns: the result of clearing bit index of int
+
+libraries: (chezscheme)
+
+
index must be a nonnegative exact integer. +int must be an exact integer (fixnum or bignum) and is treated +as a two's complement integer, regardless of the underlying representation. + +
+The index is zero-based, counting from the lowest-order toward +higher-order bits. +As with logbit?, there is no upper limit on the index. + +
+logbit0 is equivalent to + +
+ +
(lambda (i n) (logand (lognot (ash 1 i)) n)) +
but more efficient. + +
+ +
(logbit0 3 #b10101010) #b10100010
+
+(logbit0 4 #b10101010) #b10101010
+
+(logbit0 0 -1) -2
+
procedure: (logbit1 index int)
+
+returns: the result of setting bit index of int
+
+libraries: (chezscheme)
+
+
index must be a nonnegative exact integer. +int must be an exact integer (fixnum or bignum) and is treated +as a two's complement integer, regardless of the underlying representation. + +
+The index is zero-based, counting from the lowest-order toward +higher-order bits. +As with logbit?, there is no upper limit on the index. + +
+logbit1 is equivalent to + +
+ +
(lambda (i n) (logor (ash 1 i) n)) +
but more efficient. + +
+ +
(logbit1 3 #b10101010) #b10101010
+
+(logbit1 4 #b10101010) #b10111010
+
+(logbit1 4 0) #b10000
+
+(logbit1 0 -2) -1
+
procedure: (ash int count)
+
+returns: int shifted left arithmetically by count.
+
+libraries: (chezscheme)
+
+
Both arguments must be exact integers. +The first argument is treated as a two's complement integer, regardless +of the underlying representation. +If count is negative, int is shifted right by +-count bits. + +
+ +
(ash 8 0) 8
+
+(ash 8 2) 32
+
+(ash 8 -2) 2
+
+(ash -1 2) -4
+
+(ash -1 -2) -1
+
procedure: (fxlogand fixnum ...)
+
+returns: the logical "and" of the arguments fixnum ...
+
+libraries: (chezscheme)
+
+
The arguments are treated as two's complement integers, regardless +of the underlying representation. +With no arguments, fxlogand returns -1, i.e., all bits set. + +
+ +
(fxlogand) -1
+
+(fxlogand 15) 15
+
+(fxlogand -1 -1) -1
+
+(fxlogand -1 0) 0
+
+(fxlogand 5 3) 1
+
+(fxlogand #b111000 #b101010) #b101000
+
+(fxlogand #b1100 #b1111 #b1101) #b1100
+
procedure: (fxlogior fixnum ...)
+
procedure: (fxlogor fixnum ...)
+
+returns: the logical "or" of the arguments fixnum ...
+
+libraries: (chezscheme)
+
+
The arguments are treated as two's complement integers, regardless +of the underlying representation. +With no arguments, fxlogior returns 0, i.e., all bits reset. + +
+ +
(fxlogior) 0
+
+(fxlogior 15) 15
+
+(fxlogior -1 -1) -1
+
+(fxlogior -1 0) -1
+
+(fxlogior #b111000 #b101010) #b111010
+
+(fxlogior #b1000 #b0100 #b0010) #b1110
+
+(apply fxlogior '(1 2 4 8 16)) 31
+
procedure: (fxlogxor fixnum ...)
+
+returns: the logical "exclusive or" of the arguments fixnum ...
+
+libraries: (chezscheme)
+
+
The arguments are treated as two's complement integers, regardless +of the underlying representation. +With no arguments, fxlogxor returns 0, i.e., all bits reset. + +
+ +
(fxlogxor) 0
+
+(fxlogxor 15) 15
+
+(fxlogxor -1 -1) 0
+
+(fxlogxor -1 0) -1
+
+(fxlogxor 5 3) 6
+
+(fxlogxor #b111000 #b101010) #b010010
+
+(fxlogxor #b1100 #b0100 #b0110) #b1110
+
procedure: (fxlognot fixnum)
+
+returns: the logical "not" of fixnum
+
+libraries: (chezscheme)
+
+
The argument is treated as a two's complement integer, regardless +of the underlying representation. + +
+ +
(fxlognot -1) 0
+
+(fxlognot 0) -1
+
+(fxlognot 1) -2
+
+(fxlognot -2) 1
+
procedure: (fxlogbit? index fixnum)
+
+returns: #t if the specified bit is set, otherwise #f
+
+libraries: (chezscheme)
+
+
index must be a nonnegative fixnum. +fixnum is treated as a two's complement integer, regardless of +the underlying representation. + +
+fxlogbit? returns #t if the bit at index index +of fixnum is set (one) and #f otherwise. +The index is zero-based, counting from the lowest-order toward +higher-order bits. +The index is limited only by the fixnum range; for nonnegative values of +fixnum, the bits above the highest order set bit are all considered +to be zero, and for negative values, the bits above the highest order +reset bit are all considered to be one. + +
+ +
(fxlogbit? 0 #b1110) #f
+
+(fxlogbit? 1 #b1110) #t
+
+(fxlogbit? 2 #b1110) #t
+
+(fxlogbit? 3 #b1110) #t
+
+(fxlogbit? 4 #b1110) #f
+
+(fxlogbit? 100 #b1110) #f
+
+
+(fxlogbit? 0 -6) #f ; the two's complement of -6 is 1...1010
+
+(fxlogbit? 1 -6) #t
+
+(fxlogbit? 2 -6) #f
+
+(fxlogbit? 3 -6) #t
+
+(fxlogbit? 100 -6) #t
+
+
+(fxlogbit? (random 1000000) 0) #f
+
+(fxlogbit? (random 1000000) -1) #t
+
procedure: (fxlogtest fixnum1 fixnum2)
+
+returns: #t if any common bits are set, otherwise #f
+
+libraries: (chezscheme)
+
+
The arguments are treated as two's complement integers, regardless of +the underlying representation. + +
+fxlogtest returns #t if any bit set in one argument is +also set in the other. +It returns #f if the two arguments have no set bits in common. + +
+ +
(fxlogtest #b10001 #b1110) #f
+
+(fxlogtest #b10101 #b1110) #t
+
+(fxlogtest #b111000 #b110111) #t
+
+
+(fxlogtest #b101 -6) #f ; the two's complement of -6 is 1...1010
+
+(fxlogtest #b1000 -6) #t
+
+(fxlogtest 100 -6) #t
+
+
+(fxlogtest (+ (random 1000000) 1) 0) #f
+
+(fxlogtest (+ (random 1000000) 1) -1) #t
+
procedure: (fxlogbit0 index fixnum)
+
+returns: the result of clearing bit index of fixnum
+
+libraries: (chezscheme)
+
+
fixnum is treated +as a two's complement integer, regardless of the underlying representation. +index must be nonnegative and less than the number of +bits in a fixnum, excluding the sign bit, i.e., less than +(integer-length (most-positive-fixnum)). +The index is zero-based, counting from the lowest-order toward +higher-order bits. + +
+fxlogbit0 is equivalent to + +
+ +
(lambda (i n) (fxlogand (fxlognot (fxsll 1 i)) n)) +
but more efficient. + +
+ +
(fxlogbit0 3 #b10101010) #b10100010
+
+(fxlogbit0 4 #b10101010) #b10101010
+
+(fxlogbit0 0 -1) -2
+
procedure: (fxlogbit1 index fixnum)
+
+returns: the result of setting bit index of fixnum
+
+libraries: (chezscheme)
+
+
fixnum is treated +as a two's complement integer, regardless of the underlying representation. +index must be nonnegative and less than the number of +bits in a fixnum, excluding the sign bit, i.e., less than +(integer-length (most-positive-fixnum)). +The index is zero-based, counting from the lowest-order toward +higher-order bits. + +
+fxlogbit1 is equivalent to + +
+ +
(lambda (i n) (fxlogor (fxsll 1 i) n)) +
but more efficient. + +
+ +
(fxlogbit1 3 #b10101010) #b10101010
+
+(fxlogbit1 4 #b10101010) #b10111010
+
+(fxlogbit1 4 0) #b10000
+
+(fxlogbit1 0 -2) -1
+
procedure: (fxsll fixnum count)
+
+returns: fixnum shifted left by count
+
+libraries: (chezscheme)
+
+
fixnum is treated as a two's complement integer, regardless +of the underlying representation. +count must be nonnegative and not more than the number of +bits in a fixnum, i.e., +(+ (integer-length (most-positive-fixnum)) 1). +An exception is raised with condition-type +&implementation-restriction if the result cannot be represented +as a fixnum. + +
+ +
(fxsll 1 2) 4
+
+(fxsll -1 2) -4
+
procedure: (fxsrl fixnum count)
+
+returns: fixnum logically shifted right by count
+
+libraries: (chezscheme)
+
+
fixnum is treated as a two's complement integer, regardless +of the underlying representation. +count must be nonnegative and not more than the number of +bits in a fixnum, i.e., +(+ (integer-length (most-positive-fixnum)) 1). + +
+ +
(fxsrl 4 2) 1
+
+(= (fxsrl -1 1) (most-positive-fixnum)) #t
+
procedure: (fxsra fixnum count)
+
+returns: fixnum arithmetically shifted right by count
+
+libraries: (chezscheme)
+
+
fixnum is treated as a two's complement integer, regardless +of the underlying representation. +count must be nonnegative and not more than the number of +bits in a fixnum, i.e., +(+ (integer-length (most-positive-fixnum)) 1). + +
+ +
(fxsra 64 3) 8
+
+(fxsra -1 1) -1
+
+(fxsra -64 3) -8
+
procedure: (fxpopcount fixnum)
+
procedure: (fxpopcount32 fixnum)
+
procedure: (fxpopcount16 fixnum)
+
+returns: number of bits set in fixnum
+
+libraries: (chezscheme)
+
+
fixnum must be non-negative, and it must have a width of no more than 32 for +fxpopcount32 or no more than 16 for fxpopcount16. +fixnum is treated as a two's complement integer, regardless +of the underlying representation. + +
+See also fxbit-count, which produces the same result as +fxpopcount for the domain of fxpopcount. Because +fxbit-count also handles negative arguments, however, it does +not map as simply to certain processor instructions. + + +
+ +
+procedure: (random real)
+
+returns: a nonnegative pseudo-random number less than real
+
+libraries: (chezscheme)
+
+
real must be a positive integer or positive inexact real number. + +
+ +
(random 1) 0
+
+(random 1029384535235) 1029384535001, every now and then
+
+(random 1.0) 0.5, every now and then
+
thread parameter: random-seed
+
+libraries: (chezscheme)
+
+
The random number generator allows the +current random seed to be obtained and modified via the parameter +random-seed. + +
+When called without arguments, random-seed returns the current +random seed. +When called with one argument, which must be a nonnegative exact integer +ranging from 1 through 232 - 1, random-seed sets the current +random seed to the argument. + +
+ +
(let ([s (random-seed)])
+
+ (let ([r1 (random 1.0)])
+
+ (random-seed s)
+
+ (eqv? (random 1.0) r1))) #t
+
procedure: (make-pseudo-random-generator)
+
+returns: a fresh pseudo-random generator
+
+libraries: (chezscheme)
+
+
Creates a pseudo-random generator state for use with +pseudo-random-generator-next!. This generator uses a more +modern algorithm than random and generates number sequences +that better approximate true randomness. + +
+The initial state of the pseudo-random generator is based on the +current time, which is good enough for generating variability in most +programs but not good enough for security purposes. + +
+procedure: (pseudo-random-generator? val)
+
+returns: a boolean
+
+libraries: (chezscheme)
+
+
Checks whether val is a pseudo-random generator state. + +
+procedure: (pseudo-random-generator-next! prgen)
+
procedure: (pseudo-random-generator-next! prgen below-int)
+
+returns: a pseudo-random number
+
+libraries: (chezscheme)
+
+
prgen must be a pseudo-random generator state. If below-int is +provided, it must be a positive, exact integer. + +
+Steps a pseudo-random generator to produce a number. The result is an +inexact number between 0.0 (inclusive) and 1.0 +(exclusive) if below-int is not provided. If below-int is +provided, the result is an exact integer between 0 (inclusive) +and below-int (exclusive). + +
+procedure: (pseudo-random-generator-seed! prgen seed-int)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
prgen must be a pseudo-random generator state, and seed-int must +be a nonnegative, exact integer. + +
+Sets the state of a pseudo-random generator using only 31 or so bits +of seed-int. This procedure is useful for initializing the state +of a pseudo-random generator to one of a small number of known states +for triggering predictable output, but it is not a good way to put a +generator into an unpredictable state. + +
+procedure: (pseudo-random-generator->vector prgen)
+
+returns: a vector
+
+libraries: (chezscheme)
+
procedure: (vector->pseudo-random-generator vec)
+
procedure: (vector->pseudo-random-generator! prgen vec)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
prgen must be a pseudo-random generator state, and vec must +be a vector previously produced by pseudo-random-generator->vector. + +
+pseudo-random-generator->vector converts the current state of +a pseudo-random generator to a vector of numbers, vector->pseudo-random-generator +creates a fresh pseudo-random generator with the same state, and +vector->pseudo-random-generator! +changes an existing pseudo-random generator to have the same state. + + +
+ +
+procedure: (= num1 num2 num3 ...)
+
procedure: (< real1 real2 real3 ...)
+
procedure: (> real1 real2 real3 ...)
+
procedure: (<= real1 real2 real3 ...)
+
procedure: (>= real1 real2 real3 ...)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
These predicates are identical to the Revised6 Report counterparts, +except they are extended to accept one or more rather than two or more +arguments. +When passed one argument, each of these predicates returns #t. + +
+ +
(> 3/4) #t
+
+(< 3/4) #t
+
+(= 3/4) #t
+
procedure: (1+ num)
+
procedure: (add1 num)
+
procedure: (1- num)
+
procedure: (-1+ num)
+
procedure: (sub1 num)
+
+returns: num plus 1 or num minus 1
+
+libraries: (chezscheme)
+
+
1+ and add1 are equivalent to +(lambda (x) (+ x 1)); +1-, -1+, and sub1 are equivalent to +(lambda (x) (- x 1)). + +
+ +
(define plus
+
+ ; x should be a nonnegative integer
+
+ (lambda (x y)
+
+ (if (zero? x)
+
+ y
+
+ (plus (1- x) (1+ y)))))
+
+
+(plus 7 8) 15
+
+
+(define double
+
+ ; x should be a nonnegative integer
+
+ (lambda (x)
+
+ (if (zero? x)
+
+ 0
+
+ (add1 (add1 (double (sub1 x)))))))
+
+
+(double 7) 14
+
procedure: (expt-mod int1 int2 int3)
+
+returns: int1 raised to the int2 power, modulo int3
+
+libraries: (chezscheme)
+
+
int1, int2 and int3 +must be nonnegative integers. +expt-mod performs its computation in such a way that the +intermediate results are never much larger than int3. +This means that when int2 is large, expt-mod is more efficient +than the equivalent procedure (lambda (x y z) (modulo (expt x y) z)). + +
+ +
(expt-mod 2 4 3) 1
+
+(expt-mod 2 76543 76543) 2
+
procedure: (isqrt n)
+
+returns: the integer square root of n
+
+libraries: (chezscheme)
+
+
n must be a nonnegative integer. +The integer square root of n is defined to be +. + + +
+ +
(isqrt 0) 0
+
+(isqrt 16) 4
+
+(isqrt 16.0) 4.0
+
+(isqrt 20) 4
+
+(isqrt 20.0) 4.0
+
+(isqrt (* 2 (expt 10 20))) 14142135623
+
procedure: (integer-length n)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
The procedure integer-length returns the length in bits of +the smallest two's complement representation for n, with an +assumed leading 1 (sign) bit for negative numbers. +For zero, integer-length returns 0. + +
+ +
(integer-length 0) 0
+
+(integer-length 1) 1
+
+(integer-length 2) 2
+
+(integer-length 3) 2
+
+(integer-length 4) 3
+
+(integer-length #b10000000) 8
+
+(integer-length #b11111111) 8
+
+(integer-length -1) 0
+
+(integer-length -2) 1
+
+(integer-length -3) 2
+
+(integer-length -4) 2
+
procedure: (nonpositive? real)
+
+returns: #t if real is not greater than zero, #f otherwise
+
+libraries: (chezscheme)
+
+
nonpositive? is equivalent to (lambda (x) (<= x 0)). + +
+ +
(nonpositive? 128) #f
+
+(nonpositive? 0.0) #t
+
+(nonpositive? 1.8e-15) #f
+
+(nonpositive? -2/3) #t
+
procedure: (nonnegative? real)
+
+returns: #t if real is not less than zero, #f otherwise
+
+libraries: (chezscheme)
+
+
nonnegative? is equivalent to (lambda (x) (>= x 0)). + +
+ +
(nonnegative? -65) #f
+
+(nonnegative? 0) #t
+
+(nonnegative? -0.0121) #f
+
+(nonnegative? 15/16) #t
+
procedure: (conjugate num)
+
+returns: complex conjugate of num
+
+libraries: (chezscheme)
+
+
The procedure conjugate, when passed a complex argument +a + bi, returns its complex conjugate a + (-b)i. + +
+ +
(conjugate 3.0+4.0i) 3.0-4.0i
+
+(conjugate 1e-20-2e-30i) 1e-20+2e-30i
+
+(conjugate 3) 3
+
procedure: (magnitude-squared num)
+
+returns: magnitude of num squared
+
+libraries: (chezscheme)
+
+
The procedure magnitude-squared, when passed a complex +argument a + bi returns its magnitude squared, +i.e., a2 + b2. + +
+ +
(magnitude-squared 3.0-4.0i) 25.0
+
+(magnitude-squared 3.0) 9.0
+
procedure: (sinh num)
+
procedure: (cosh num)
+
procedure: (tanh num)
+
+returns: the hyperbolic sine, cosine, or tangent of num
+
+libraries: (chezscheme)
+
+
+
(sinh 0.0) 0.0
+
+(cosh 0.0) 1.0
+
+(tanh -0.0) -0.0
+
procedure: (asinh num)
+
procedure: (acosh num)
+
procedure: (atanh num)
+
+returns: the hyperbolic arc sine, arc cosine, or arc tangent of num
+
+libraries: (chezscheme)
+
+
+
(acosh 0.0) 0.0+1.5707963267948966i
+
+(acosh 1.0) 0.0
+
+(atanh -1.0) -inf.0
+
procedure: (string->number string)
+
procedure: (string->number string radix)
+
+returns: the number represented by string, or #f
+
+libraries: (chezscheme)
+
+
This procedure is identical to the Revised6 Report version except +that radix may be any exact integer between 2 and 36, inclusive. +The Revised6 Report version requires radix to be in the set +{2,8,10,16}. + +
+ +
(string->number "211012" 3) 559
+
+(string->number "tobeornottobe" 36) 140613689159812836698
+
procedure: (number->string num)
+
procedure: (number->string num radix)
+
procedure: (number->string num radix precision)
+
+returns: an external representation of num as a string
+
+libraries: (chezscheme)
+
+
This procedure is identical to the Revised6 Report version except +that radix may be any exact integer between 2 and 36, inclusive. +The Revised6 Report version requires radix to be in the set +{2,8,10,16}. + +
+ +
(number->string 10000 4) "2130100"
+
+(number->string 10000 27) "DJA"
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/objects.html b/csug10.0/objects.html
new file mode 100644
index 000000000..f3013c566
--- /dev/null
+++ b/csug10.0/objects.html
@@ -0,0 +1,5258 @@
+
+
+
+
+
+This chapter describes operations specific to Chez Scheme on +nonnumeric objects, including standard objects such as pairs and +numbers and Chez Scheme extensions such as boxes and records. +Chapter 8 describes operations on numbers. +See Chapter 6 of The Scheme Programming Language, 4th Edition or the Revised6 Report +on Scheme for a description of standard operations on objects. + +
+ +
+procedure: (enum-set? obj)
+
+returns: #t if obj is an enum set, #f otherwise
+
+libraries: (chezscheme)
+
+
This predicate is not defined by the Revised6 Report, but should be. + +
+procedure: (record-constructor-descriptor? obj)
+
+returns: #t if obj is a record constructor descriptor, #f otherwise
+
+libraries: (chezscheme)
+
+
This predicate is not defined by the Revised6 Report, but should be. + + +
+ +
+procedure: (atom? obj)
+
+returns: #t if obj is not a pair, #f otherwise
+
+libraries: (chezscheme)
+
+
atom? is equivalent to (lambda (x) (not (pair? x))). + +
+ +
(atom? '(a b c)) #f
+
+(atom? '(3 . 4)) #f
+
+(atom? '()) #t
+
+(atom? 3) #t
+
procedure: (list-head list n)
+
+returns: a list of the first n elements of list
+
+libraries: (chezscheme)
+
+
n must be an exact nonnegative integer less than or equal to +the length of list. + +
+list-head and the standard Scheme procedure list-tail +may be used together to split a list into two separate lists. +While list-tail performs no allocation but instead returns a +sublist of the original list, list-head always returns a copy +of the first portion of the list. + +
+list-head may be defined as follows. + +
+ +
(define list-head
+
+ (lambda (ls n)
+
+ (if (= n 0)
+
+ '()
+
+ (cons (car ls) (list-head (cdr ls) (- n 1))))))
+
+
+(list-head '(a b c) 0) ()
+
+(list-head '(a b c) 2) (a b)
+
+(list-head '(a b c) 3) (a b c)
+
+(list-head '(a b c . d) 2) (a b)
+
+(list-head '(a b c . d) 3) (a b c)
+
+(list-head '#1=(a . #1#) 5) (a a a a a)
+
procedure: (last-pair list)
+
+returns: the last pair of a list
+
+libraries: (chezscheme)
+
+
list must not be empty. +last-pair returns the last pair (not the last element) of list. +list may be an improper list, in which case the last pair is the +pair containing the last element and the terminating object. + +
+ +
(last-pair '(a b c d)) (d)
+
+(last-pair '(a b c . d)) (c . d)
+
procedure: (list-assuming-immutable? v)
+
+returns: a boolean
+
+libraries: (chezscheme)
+
+
Like list?, but on the assumption that any pairs traversed while +computing the result are never mutated further, the result is produced in amoritized +constant time. + +
+ +
(list-assuming-immutable? '(a b c d)) #t
+
+(list-assuming-immutable? '(a b c . d)) #f
+
procedure: (list-copy list)
+
+returns: a copy of list
+
+libraries: (chezscheme)
+
+
list-copy returns a list equal? to list, using new pairs +to reform the top-level list structure. + +
+ +
(list-copy '(a b c)) (a b c)
+
+
+(let ([ls '(a b c)])
+
+ (equal? ls (list-copy ls))) #t
+
+
+(let ([ls '(a b c)])
+
+ (let ([ls-copy (list-copy ls)])
+
+ (or (eq? ls-copy ls)
+
+ (eq? (cdr ls-copy) (cdr ls))
+
+ (eq? (cddr ls-copy) (cddr ls))))) #f
+
procedure: (list* obj ... final-obj)
+
+returns: a list of obj ... terminated by final-obj
+
+libraries: (chezscheme)
+
+
list* is identical to the Revised6 Report cons*. + + +
+procedure: (make-list n)
+
procedure: (make-list n obj)
+
+returns: a list of n objs
+
+libraries: (chezscheme)
+
+
n must be a nonnegative integer. +If obj is omitted, the elements of the list are unspecified. + +
+ +
(make-list 0 '()) ()
+
+(make-list 3 0) (0 0 0)
+
+(make-list 2 "hi") ("hi" "hi")
+
procedure: (iota n)
+
+returns: a list of integers from 0 (inclusive) to n (exclusive)
+
+libraries: (chezscheme)
+
+
n must be an exact nonnegative integer. + +
+ +
(iota 0) ()
+
+(iota 5) (0 1 2 3 4)
+
procedure: (enumerate ls)
+
+returns: a list of integers from 0 (inclusive) to the length of ls (exclusive)
+
+libraries: (chezscheme)
+
+
+
(enumerate '()) ()
+
+(enumerate '(a b c)) (0 1 2)
+
+(let ([ls '(a b c)])
+
+ (map cons ls (enumerate ls))) ((a . 0) (b . 1) (c . 2))
+
procedure: (remq! obj list)
+
procedure: (remv! obj list)
+
procedure: (remove! obj list)
+
+returns: a list containing the elements of list with all occurrences of obj removed
+
+libraries: (chezscheme)
+
+
These procedures are similar to the Revised6 Report +remq, remv, and remove procedures, except +remq!, remv! and remove! use pairs from the +input list to build the output list. +They perform less allocation but are not +necessarily faster than their nondestructive counterparts. +Their use can easily lead to confusing or incorrect results if used +indiscriminately. + +
+ +
(remq! 'a '(a b a c a d)) (b c d)
+
+
+(remv! #\a '(#\a #\b #\c)) (#\b #\c)
+
+
+(remove! '(c) '((a) (b) (c))) ((a) (b))
+
procedure: (substq new old tree)
+
procedure: (substv new old tree)
+
procedure: (subst new old tree)
+
procedure: (substq! new old tree)
+
procedure: (substv! new old tree)
+
procedure: (subst! new old tree)
+
+returns: a tree with new substituted for occurrences of old in tree
+
+libraries: (chezscheme)
+
+
These procedures traverse tree, replacing all objects equivalent to +the object old with the object new. + +
+The equivalence test for substq and substq! is eq?, +for substv and substv! is eqv?, +and for subst and subst! is equal?. + +
+substq!, substv!, and subst! perform the +substitutions destructively. +They perform less allocation but are not +necessarily faster than their nondestructive counterparts. +Their use can easily lead to confusing or incorrect results if used +indiscriminately. + + +
+ +
(substq 'a 'b '((b c) b a)) ((a c) a a)
+
+
+(substv 2 1 '((1 . 2) (1 . 4) . 1)) ((2 . 2) (2 . 4) . 2)
+
+
+(subst 'a
+
+ '(a . b)
+
+ '((a . b) (c a . b) . c)) (a (c . a) . c)
+
+
+(let ([tr '((b c) b a)])
+
+ (substq! 'a 'b tr)
+
+ tr) ((a c) a a)
+
procedure: (reverse! list)
+
+returns: a list containing the elements of list in reverse order
+
+libraries: (chezscheme)
+
+
reverse! destructively reverses list +by reversing its links. +Using reverse! in place of reverse reduces allocation but is not +necessarily faster than reverse. +Its use can easily lead to confusing or incorrect results if used +indiscriminately. + +
+ +
(reverse! '()) ()
+
+(reverse! '(a b c)) (c b a)
+
+
+(let ([x '(a b c)])
+
+ (reverse! x)
+
+ x) (a)
+
+
+(let ([x '(a b c)])
+
+ (set! x (reverse! x))
+
+ x) (c b a)
+
procedure: (append! list ...)
+
+returns: the concatenation of the input lists
+
+libraries: (chezscheme)
+
+
Like append, +append! returns a new list consisting of the elements of the first +list followed by the elements of the second list, the elements of the +third list, and so on. +Unlike append, +append! reuses the pairs in all of the +arguments in forming the new list. +That is, the last cdr of each list argument but the last is changed to +point to the next list argument. +If any argument but the last is the empty list, it is essentially ignored. +The final argument (which need not be a list) is not altered. + +
+append! performs less allocation than append but is not +necessarily faster. +Its use can easily lead to confusing or incorrect results if used +indiscriminately. + +
+ +
(append! '(a b) '(c d)) (a b c d)
+
+
+(let ([x '(a b)])
+
+ (append! x '(c d))
+
+ x) (a b c d)
+
+
+Chez Scheme extends the syntax of characters in two ways. +First, a #\ prefix followed by exactly three octal digits is read +as a character whose numeric code is the octal value of the three digits, +e.g., #\044 is read as #\$. +Second, it recognizes several nonstandard named characters: +#\rubout (which is the same as #\delete), +#\bel (which is the same as #\alarm), +#\vt (which is the same as #\vtab), +#\nel (the Unicode NEL character), and +#\ls (the Unicode LS character). +The set of nonstandard character names may be changed via the procedure +char-name (page 9.14). + +
+These extensions are disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + +
+procedure: (char=? char1 char2 ...)
+
procedure: (char<? char1 char2 ...)
+
procedure: (char>? char1 char2 ...)
+
procedure: (char<=? char1 char2 ...)
+
procedure: (char>=? char1 char2 ...)
+
procedure: (char-ci=? char1 char2 ...)
+
procedure: (char-ci<? char1 char2 ...)
+
procedure: (char-ci>? char1 char2 ...)
+
procedure: (char-ci<=? char1 char2 ...)
+
procedure: (char-ci>=? char1 char2 ...)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
These predicates are identical to the Revised6 Report counterparts, +except they are extended to accept one or more rather than two or more +arguments. +When passed one argument, each of these predicates returns #t. + +
+ +
(char>? #\a) #t
+
+(char<? #\a) #t
+
+(char-ci=? #\a) #t
+
procedure: (char- char1 char2)
+
+returns: the integer difference between char1 and char2
+
+libraries: (chezscheme)
+
+
char- subtracts the integer value of char2 from the +integer value of char1 and returns the difference. +The following examples assume that the integer representation is the +ASCII code for the character. + +
+ +
(char- #\f #\e) 1
+
+
+(define digit-value
+
+ ; returns the digit value of the base-r digit c, or #f if c
+
+ ; is not a valid digit
+
+ (lambda (c r)
+
+ (let ([v (cond
+
+ [(char<=? #\0 c #\9) (char- c #\0)]
+
+ [(char<=? #\A c #\Z) (char- c #\7)]
+
+ [(char<=? #\a c #\z) (char- c #\W)]
+
+ [else 36])])
+
+ (and (fx< v r) v))))
+
+(digit-value #\8 10) 8
+
+(digit-value #\z 10) #f
+
+(digit-value #\z 36) 35
+
char- might be defined as follows. + +
+ +
(define char-
+
+ (lambda (c1 c2)
+
+ (- (char->integer c1) (char->integer c2))))
+
procedure: (char-grapheme-step char state)
+
+returns: two values: a boolean indicating whether a cluster terminated and a new state
+
+libraries: (chezscheme)
+
+
char must be a character, and state must be a fixnum. + +
+char-grapheme-step encodes a state machine for +Unicode's grapheme specification on a sequence of code points. +It accepts a character for the next code point in a sequence, and it +returns two values: whether a (single) grapheme cluster has terminated +since the most recently reported termination (or the start of the +stream), and a new state to be used with +char-grapheme-step and the next character. + +
+A state is represented by a fixnum. A value of 0 for +state represents the initial state or a state where no +characters are pending toward a new boundary. Thus, if a sequence of +characters is exhausted and state is not 0, then the +end of the stream creates one last grapheme boundary. + +
+char-grapheme-step will produce a result for any +fixnum state, but the meaning of a non-0 state is +specified only in that providing such a state produced by +char-grapheme-step in another call to +char-grapheme-step continues detecting +grapheme boundaries in the sequence. + +
+procedure: (char-grapheme-break-property char)
+
+returns: a symbol
+
+libraries: (chezscheme)
+
+
char-grapheme-break-property reports the grapheme-break +property of char, one of Other, CR, +LF, Control, Extend, ZWJ, +Regional_Indicator, Prepend, SpacingMark, +L, V, T, LV, or LVT. +This function is used in the implementation of +char-grapheme-step. + +
+ +
(char-grapheme-break-property #\a) Other
+
+(char-grapheme-break-property #\x300) Extend
+
procedure: (char-extended-pictographic? char)
+
+returns: a boolean
+
+libraries: (chezscheme)
+
+
char-extended-pictographic? reports whether char has +the Unicode Extended_Pictographic property. This function is used in +the implementation of char-grapheme-step. + +
+ +
(char-extended-pictographic? #\a) #f
+
+(char-extended-pictographic? #\xA9) #t
+
+
+Chez Scheme extends the standard string syntax with two character +escapes: \', which produces the single quote character, and +\nnn, i.e., backslash followed by 3 octal digits, +which produces the character equivalent of the octal value of +the 3 digits. +These extensions are disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + +
+All strings are mutable by default, including constants. +A program can create immutable strings via +string->immutable-string +or string-append-immutable. +Any attempt to modify an immutable string causes an exception to be raised. + +
+The length and indices of a string in Chez Scheme are always fixnums. + + +
+procedure: (string=? string1 string2 string3 ...)
+
procedure: (string<? string1 string2 string3 ...)
+
procedure: (string>? string1 string2 string3 ...)
+
procedure: (string<=? string1 string2 string3 ...)
+
procedure: (string>=? string1 string2 string3 ...)
+
procedure: (string-ci=? string1 string2 string3 ...)
+
procedure: (string-ci<? string1 string2 string3 ...)
+
procedure: (string-ci>? string1 string2 string3 ...)
+
procedure: (string-ci<=? string1 string2 string3 ...)
+
procedure: (string-ci>=? string1 string2 string3 ...)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
These predicates are identical to the Revised6 Report counterparts, +except they are extended to accept one or more rather than two or more +arguments. +When passed one argument, each of these predicates returns #t. + +
+ +
(string>? "a") #t
+
+(string<? "a") #t
+
+(string-ci=? "a") #t
+
procedure: (string-copy! src src-start dst dst-start n)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
src and dst must be strings, and dst must be mutable. +src-start, dst-start, and n must be exact nonnegative +integers. +The sum of src-start and n must not exceed the length of src, +and the sum of dst-start and n must not exceed the length of dst. + +
+string-copy! overwrites the n bytes of dst +starting at dst-start with the n bytes of dst +starting at src-start. +This works even if dst is the same string as src and the +source and destination locations overlap. +That is, the destination is filled with the characters that appeared at the +source before the operation began. + +
+ +
(define s1 "to boldly go")
+
+(define s2 (make-string 10 #\-))
+
+
+(string-copy! s1 3 s2 1 3)
+
+s2 "-bol------"
+
+
+
+(string-copy! s1 7 s2 4 2)
+
+s2 "-bolly----"
+
+
+
+(string-copy! s2 2 s2 5 4)
+
+s2 "-bollolly-"
+
procedure: (substring-fill! string start end char)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
string must be mutable. +The characters of string from start (inclusive) to end +(exclusive) are set to char. +start and end must be nonnegative integers; start +must be strictly less than the length of string, while end may +be less than or equal to the length of string. +If end ≤ start, the string is left unchanged. + +
+ +
(let ([str (string-copy "a tpyo typo")])
+
+ (substring-fill! str 2 6 #\X)
+
+ str) "a XXXX typo"
+
procedure: (string-truncate! string n)
+
+returns: string or the empty string
+
+libraries: (chezscheme)
+
+
string must be mutable. +n must be an exact nonnegative fixnum not greater than the length of +string. +If n is zero, string-truncate! returns the empty string. +Otherwise, string-truncate! destructively truncates string to +its first n characters and returns string. + +
+ +
(define s (make-string 7 #\$))
+
+(string-truncate! s 0) ""
+
+s "$$$$$$$"
+
+(string-truncate! s 3) "$$$"
+
+s "$$$"
+
procedure: (mutable-string? obj)
+
+returns: #t if obj is a mutable string, #f otherwise
+
procedure: (immutable-string? obj)
+
+returns: #t if obj is an immutable string, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(mutable-string? (string #\a #\b #\c)) #t
+
+(mutable-string? (string->immutable-string "abc")) #f
+
+(immutable-string? (string #\a #\b #\c)) #f
+
+(immutable-string? (string->immutable-string "abc")) #t
+
+(immutable-string? (cons 3 4)) #f
+
procedure: (string->immutable-string string)
+
+returns: an immutable string equal to string
+
+libraries: (chezscheme)
+
+
The result is string itself if string +is immutable; otherwise, the result is an immutable string with the same content as string. + +
+ +
(define s (string->immutable-string (string #\x #\y #\z)))
+
+(string-set! s 0 #\a) exception: not mutable
+
procedure: (string-append-immutable string ...)
+
+returns: an immutable string that appends the argument strings
+
+libraries: (chezscheme)
+
+
Like string-append, but produces an immutable string. + +
+procedure: (string-grapheme-span string start)
+
procedure: (string-grapheme-span string start end)
+
+returns: the number of characters in a grapheme cluster at the given start
+
+libraries: (chezscheme)
+
+
start and end must indicate a valid range in the string as +for substring, where the length of the string is used if +end is not supplied. + +
+The result is the number of characters (i.e., code points) in the +string that form a Unicode grapheme cluster starting at start, +assuming that start is the start of a grapheme cluster and +extending no further than the character before end. The result +is 0 if start equals end. + +
+ +
(string-grapheme-span (string #\a) 0) 1
+
+(string-grapheme-span (string #\a #\x300) 0) 2
+
+(string-grapheme-span (string #\a #\x300 #\a) 0) 2
+
+(string-grapheme-span (string #\a #\x300 #\a) 0 1) 1
+
procedure: (string-grapheme-count string)
+
procedure: (string-grapheme-count string start)
+
procedure: (string-grapheme-count string start end)
+
+returns: the number of Unicode grapheme clusters (see below)
+
+libraries: (chezscheme)
+
+
start and end must indicate a valid range in the string as +for substring, where 0 is used if start is not +provided, and the length of the string is used if end is not +supplied. + +
+The result is the number of Unicode grapheme clusters in the substring +of string selected by start and end. + +
+ +
(string-grapheme-count (string #\a) 0) 1
+
+(string-grapheme-count (string #\a #\x300) 0) 1
+
+(string-grapheme-count (string #\a #\x300 #\a) 0) 2
+
+(string-grapheme-count (string #\a #\x300 #\a) 0 1) 1
+
+
+Chez Scheme extends the syntax of vectors to allow the length of the +vector to be specified between the # and open parenthesis, e.g., +#3(a b c). +If fewer elements are supplied in the syntax than the specified length, +each element after the last printed element is the same as the last +printed element. +This extension is disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + +
+The length and indices of a vector in Chez Scheme are always fixnums. + +
+All vectors are mutable by default, including constants. +A program can create immutable vectors via +vector->immutable-vector. +Any attempt to modify an immutable vector causes an exception to be raised. + +
+procedure: (vector-copy vector)
+
+returns: a copy of vector
+
+libraries: (chezscheme)
+
+
vector-copy creates a new vector of the same length and contents +as vector. +The elements themselves are not copied. + +
+ +
(vector-copy '#(a b c)) #(a b c)
+
+
+(let ([v '#(a b c)])
+
+ (eq? v (vector-copy v))) #f
+
procedure: (vector-set-fixnum! vector n fixnum)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
vector must be mutable. +vector-set-fixnum! changes the nth element of vector to fixnum. +n must be an exact nonnegative integer strictly less than +the length of vector. + +
+It is faster to store a fixnum than an arbitrary value, +since for arbitrary values, the system has to record potential assignments from older to +younger objects to support generational garbage collection. +Care must be taken to ensure that the argument is indeed a fixnum, however; +otherwise, the collector may not properly track the assignment. +The primitive performs a fixnum check on the argument except at +optimization level 3. + +
+See also the description of fixnum-only vectors (fxvectors) below. + +
+ +
(let ([v (vector 1 2 3 4 5)])
+
+ (vector-set-fixnum! v 2 73)
+
+ v) #(1 2 73 4 5)
+
procedure: (vector-cas! vector n old-obj new-obj)
+
+returns: #t if vector is changed, #f otherwise
+
+libraries: (chezscheme)
+
+
vector must be mutable. +vector-cas! atomically changes the nth element of vector to new-obj +if the replaced nth element is eq? to old-obj. +If the nth element of vector that would be replaced +is not eq? to old-obj, then +vector is unchanged. + +
+On an architecture with a weak memory model, vector-cas! can +spuriously fail, leaving vector unchanged and returning +#f even if the current value of element n is +old-obj. On success, no memory ordering is implied, which means +that memory-order-acquire and/or memory-order-release +may be needed to complete an intended synchronization. + +
+ +
(define v (vector 'old0 'old1 'old2))
+
+(vector-cas! v 1 'old1 'new1) #t, assuming no spurious failure
+
+(vector-ref v 1) 'new1
+
+(vector-cas! v 2 'old1 'new2) #f
+
+(vector-ref v 2) 'old2
+
procedure: (mutable-vector? obj)
+
+returns: #t if obj is a mutable vector, #f otherwise
+
procedure: (immutable-vector? obj)
+
+returns: #t if obj is an immutable vector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(mutable-vector? (vector 1 2 3)) #t
+
+(mutable-vector? (vector->immutable-vector (vector 1 2 3))) #f
+
+(immutable-vector? (vector 1 2 3)) #f
+
+(immutable-vector? (vector->immutable-vector (vector 1 2 3))) #t
+
+(immutable-vector? (cons 3 4)) #f
+
procedure: (vector->immutable-vector vector)
+
+returns: an immutable vector equal to vector
+
+libraries: (chezscheme)
+
+
The result is vector itself if vector +is immutable; otherwise, the result is an immutable vector with the same content as vector. + +
+ +
(define v (vector->immutable-vector (vector 1 2 3)))
+
+(vector-set! v 0 0) exception: not mutable
+
thread parameter: self-evaluating-vectors
+
+libraries: (chezscheme)
+
+
The default value of this parameter is #f, meaning that vector literals must be quoted, as +required by the Revised6 Report. +Setting self-evaluating-vectors to a true value may be useful to provide compatibility with +R7RS, as the latter states that vectors are self-evaluating. + +
+ +
#(a b c) exception: invalid syntax
+
+
+(self-evaluating-vectors #t)
+
+#(a b c) #(a b c)
+
+
+Fixnum-only vectors, or "fxvectors," are like vectors but contain +only fixnums. +Fxvectors are written with the #vfx prefix in place of the +# prefix for vectors, e.g., #vfx(1 2 3) or +#10vfx(2). +The fxvector syntax is disabled in an input stream after #!r6rs +has been seen by the reader, unless #!chezscheme has been seen +more recently. + +
+The length and indices of an fxvector are always fixnums. + +
+Updating an fxvector is generally less expensive than updating a vector, +since for vectors, the system records potential assignments from older to +younger objects to support generational garbage collection. +The storage management system also takes advantage of the fact that +fxvectors contain no pointers to place them in an area of memory that +does not have to be traced during collection. + +
+See also vector-set-fixnum! above. + +
+procedure: (fxvector? obj)
+
+returns: #t if obj is an fxvector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(fxvector? #vfx()) #t
+
+(fxvector? #vfx(1 2 3)) #t
+
+(fxvector? (fxvector 1 2 3)) #t
+
+(fxvector? '#(a b c)) #f
+
+(fxvector? '(a b c)) #f
+
+(fxvector? "abc") #f
+
procedure: (fxvector fixnum ...)
+
+returns: an fxvector of the fixnums fixnum ...
+
+libraries: (chezscheme)
+
+
+
+(fxvector) #vfx()
+
+(fxvector 1 3 5) #vfx(1 3 5)
+
procedure: (make-fxvector n)
+
procedure: (make-fxvector n fixnum)
+
+returns: an fxvector of length n
+
+libraries: (chezscheme)
+
+
n must be a fixnum. +If fixnum is supplied, each element of the fxvector is initialized +to fixnum; otherwise, the elements are unspecified. + +
+ +
(make-fxvector 0) #vfx()
+
+(make-fxvector 0 7) #vfx()
+
+(make-fxvector 5 7) #vfx(7 7 7 7 7)
+
procedure: (fxvector-length fxvector)
+
+returns: the number of elements in fxvector
+
+libraries: (chezscheme)
+
+
+
(fxvector-length #vfx()) 0
+
+(fxvector-length #vfx(1 2 3)) 3
+
+(fxvector-length #10vfx(1 2 3)) 10
+
+(fxvector-length (fxvector 1 2 3 4)) 4
+
+(fxvector-length (make-fxvector 300)) 300
+
procedure: (fxvector-ref fxvector n)
+
+returns: the nth element (zero-based) of fxvector
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum strictly less than +the length of fxvector. + +
+ +
(fxvector-ref #vfx(-1 2 4 7) 0) -1
+
+(fxvector-ref #vfx(-1 2 4 7) 1) 2
+
+(fxvector-ref #vfx(-1 2 4 7) 3) 7
+
procedure: (fxvector-set! fxvector n fixnum)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum strictly less than +the length of fxvector. +fxvector-set! changes the nth element of fxvector to fixnum. + +
+ +
(let ([v (fxvector 1 2 3 4 5)])
+
+ (fxvector-set! v 2 (fx- (fxvector-ref v 2)))
+
+ v) #vfx(1 2 -3 4 5)
+
procedure: (fxvector-fill! fxvector fixnum)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
fxvector-fill! replaces each element of fxvector with fixnum. + +
+ +
(let ([v (fxvector 1 2 3)])
+
+ (fxvector-fill! v 0)
+
+ v) #vfx(0 0 0)
+
procedure: (fxvector->list fxvector)
+
+returns: a list of the elements of fxvector
+
+libraries: (chezscheme)
+
+
+
(fxvector->list (fxvector)) ()
+
+(fxvector->list #vfx(7 5 2)) (7 5 2)
+
+
+(let ([v #vfx(1 2 3 4 5)])
+
+ (apply fx* (fxvector->list v))) 120
+
procedure: (list->fxvector list)
+
+returns: an fxvector of the elements of list
+
+libraries: (chezscheme)
+
+
list must consist entirely of fixnums. + +
+ +
(list->fxvector '()) #vfx()
+
+(list->fxvector '(3 5 7)) #vfx(3 5 7)
+
+
+(let ([v #vfx(1 2 3 4 5)])
+
+ (let ([ls (fxvector->list v)])
+
+ (list->fxvector (map fx* ls ls)))) #vfx(1 4 9 16 25)
+
procedure: (fxvector-copy fxvector)
+
+returns: a copy of fxvector
+
+libraries: (chezscheme)
+
+
fxvector-copy creates a new fxvector with the same length and contents +as fxvector. + +
+ +
(fxvector-copy #vfx(3 4 5)) #vfx(3 4 5)
+
+
+(let ([v #vfx(3 4 5)])
+
+ (eq? v (fxvector-copy v))) #f
+
+ +
+Flonum-only vectors, or "flvectors," are like vectors but contain +only flonums. +Flvectors are written with the #vfl prefix in place of the +# prefix for vectors, e.g., #vfl(1.0 2.0 3.0) or +#10vfl(2.0). +The flvector syntax is disabled in an input stream after #!r6rs +has been seen by the reader, unless #!chezscheme has been seen +more recently. + +
+The length and indices of an flvector are always fixnums. + +
+Updating an flvector is generally less expensive than updating a vector, +since for vectors, the system records potential assignments from older to +younger objects to support generational garbage collection. +An flvector stores a flonum's representation directly, instead of a reference to a +flonum, so flonum identity is fresh when it is extracted from an flvector. +The storage management system also takes advantage of the fact that +flvectors contain no pointers to place them in an area of memory that +does not have to be traced during collection. + +
+procedure: (flvector? obj)
+
+returns: #t if obj is an flvector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(flvector? #vfl()) #t
+
+(flvector? #vfl(1.0 2.0 3.0)) #t
+
+(flvector? (flvector 1.0 2.0 3.0)) #t
+
+(flvector? '#(a b c)) #f
+
+(flvector? '(a b c)) #f
+
+(flvector? "abc") #f
+
procedure: (flvector flonum ...)
+
+returns: an flvector of the flonums flonum ...
+
+libraries: (chezscheme)
+
+
+
+(flvector) #vfl()
+
+(flvector 1.0 3.0 5.0) #vfl(1.0 3.0 5.0)
+
procedure: (make-flvector n)
+
procedure: (make-flvector n flonum)
+
+returns: an flvector of length n
+
+libraries: (chezscheme)
+
+
n must be a fixnum. +If flonum is supplied, each element of the flvector is initialized +to flonum; otherwise, the elements are unspecified. + +
+ +
(make-flvector 0) #vfl()
+
+(make-flvector 0 7.0) #vfl()
+
+(make-flvector 5 7.0) #vfl(7.0 7.0 7.0 7.0 7.0)
+
procedure: (flvector-length flvector)
+
+returns: the number of elements in flvector
+
+libraries: (chezscheme)
+
+
+
(flvector-length #vfl()) 0
+
+(flvector-length #vfl(1.0 2.0 3.0)) 3
+
+(flvector-length #10vfl(1.0 2.0 3.0)) 10
+
+(flvector-length (flvector 1.0 2.0 3.0 4.0)) 4
+
+(flvector-length (make-flvector 300)) 300
+
procedure: (flvector-ref flvector n)
+
+returns: the nth element (zero-based) of flvector
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum strictly less than +the length of flvector. + +
+ +
(flvector-ref #vfl(-1.0 2.0 4.0 7.0) 0) -1.0
+
+(flvector-ref #vfl(-1.0 2.0 4.0 7.0) 1) 2.0
+
+(flvector-ref #vfl(-1.0 2.0 4.0 7.0) 3) 7.0
+
procedure: (flvector-set! flvector n flonum)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum strictly less than +the length of flvector. +flvector-set! changes the nth element of flvector to flonum. + +
+ +
(let ([v (flvector 1.0 2.0 3.0 4.0 5.0)])
+
+ (flvector-set! v 2 (fx- (flvector-ref v 2)))
+
+ v) #vfl(1.0 2.0 -3.0 4.0 5.0)
+
procedure: (flvector-fill! flvector flonum)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
flvector-fill! replaces each element of flvector with flonum. + +
+ +
(let ([v (flvector 1.0 2.0 3.0)])
+
+ (flvector-fill! v 0.0)
+
+ v) #vfl(0.0 0.0 0.0)
+
procedure: (flvector->list flvector)
+
+returns: a list of the elements of flvector
+
+libraries: (chezscheme)
+
+
+
(flvector->list (flvector)) ()
+
+(flvector->list #vfl(7.0 5.0 2.0)) (7.0 5.0 2.0)
+
+
+(let ([v #vfl(1.0 2.0 3.0 4.0 5.0)])
+
+ (apply fl* (flvector->list v))) 120.0
+
procedure: (list->flvector list)
+
+returns: an flvector of the elements of list
+
+libraries: (chezscheme)
+
+
list must consist entirely of flonums. + +
+ +
(list->flvector '()) #vfl()
+
+(list->flvector '(3.0 5.0 7.0)) #vfl(3.0 5.0 7.0)
+
+
+(let ([v #vfl(1.0 2.0 3.0 4.0 5.0)])
+
+ (let ([ls (flvector->list v)])
+
+ (list->flvector (map fx* ls ls)))) #vfl(1.0 4.0 9.0 16.0 25.0)
+
procedure: (flvector-copy flvector)
+
+returns: a copy of flvector
+
+libraries: (chezscheme)
+
+
flvector-copy creates a new flvector with the same length and contents +as flvector. + +
+ +
(flvector-copy #vfl(3.0 4.0 5.0)) #vfl(3.0 4.0 5.0)
+
+
+(let ([v #vfl(3.0 4.0 5.0)])
+
+ (eq? v (flvector-copy v))) #f
+
+ +
+As with vectors, Chez Scheme extends the syntax of bytevectors to allow +the length of the vector to be specified between the # and open +parenthesis, e.g., #3vu8(1 105 73). +If fewer elements are supplied in the syntax than the specified length, +each element after the last printed element is the same as the last +printed element. +This extension is disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + +
+Chez Scheme also extends the set of bytevector primitives, including +primitives for loading and storing 3, 5, 6, and 7-byte quantities. + +
+The length and indices of a bytevector in Chez Scheme are always fixnums. + +
+All bytevectors are mutable by default, including constants. +A program can create immutable bytevectors via +bytevector->immutable-bytevector. +Any attempt to modify an immutable bytevector causes an exception to be raised. + +
+procedure: (bytevector fill ...)
+
+returns: a new bytevector containing fill ...
+
+libraries: (chezscheme)
+
+
Each fill value must be an exact integer representing a signed or +unsigned 8-bit value, i.e., +a value in the range -128 to 255 inclusive. +A negative fill value is treated as its two's complement equivalent. + +
+ +
(bytevector) #vu8()
+
+(bytevector 1 3 5) #vu8(1 3 5)
+
+(bytevector -1 -3 -5) #vu8(255 253 251)
+
procedure: (bytevector->s8-list bytevector)
+
+returns: a new list of the 8-bit signed elements of bytevector
+
+libraries: (chezscheme)
+
+
The values in the returned list are exact eight-bit signed integers, +i.e., values in the range -128 to 127 inclusive. +bytevector->s8-list is similar to the Revised6 Report +bytevector->u8-list except the values in the returned list +are signed rather than unsigned. + +
+ +
(bytevector->s8-list (make-bytevector 0)) ()
+
+(bytevector->s8-list #vu8(1 127 128 255)) (1 127 -128 -1)
+
+
+(let ([v #vu8(1 2 3 255)])
+
+ (apply * (bytevector->s8-list v))) -6
+
procedure: (s8-list->bytevector list)
+
+returns: a new bytevector of the elements of list
+
+libraries: (chezscheme)
+
+
list must consist entirely of exact eight-bit signed integers, i.e., +values in the range -128 to 127 inclusive. +s8-list->bytevector is similar to the Revised6 Report +procedure +u8-list->bytevector, except the elements of the input list +are signed rather than unsigned. + +
+ +
(s8-list->bytevector '()) #vu8()
+
+(s8-list->bytevector '(1 127 -128 -1)) #vu8(1 127 128 255)
+
+
+(let ([v #vu8(1 2 3 4 5)])
+
+ (let ([ls (bytevector->s8-list v)])
+
+ (s8-list->bytevector (map - ls)))) #vu8(255 254 253 252 251)
+
procedure: (bytevector-truncate! bytevector n)
+
+returns: bytevector or the empty bytevector
+
+libraries: (chezscheme)
+
+
bytevector must be mutable. +n must be an exact nonnegative fixnum not greater than the length of +bytevector. +If n is zero, bytevector-truncate! returns the empty bytevector. +Otherwise, bytevector-truncate! destructively truncates bytevector to +its first n bytes and returns bytevector. + +
+ +
(define bv (make-bytevector 7 19))
+
+(bytevector-truncate! bv 0) #vu8()
+
+bv #vu8(19 19 19 19 19 19 19)
+
+(bytevector-truncate! bv 3) #vu8(19 19 19)
+
+bv #vu8(19 19 19)
+
procedure: (bytevector-u24-ref bytevector n eness)
+
+returns: the 24-bit unsigned integer at index n (zero-based) of bytevector
+
procedure: (bytevector-s24-ref bytevector n eness)
+
+returns: the 24-bit signed integer at index n (zero-based) of bytevector
+
procedure: (bytevector-u40-ref bytevector n eness)
+
+returns: the 40-bit unsigned integer at index n (zero-based) of bytevector
+
procedure: (bytevector-s40-ref bytevector n eness)
+
+returns: the 40-bit signed integer at index n (zero-based) of bytevector
+
procedure: (bytevector-u48-ref bytevector n eness)
+
+returns: the 48-bit unsigned integer at index n (zero-based) of bytevector
+
procedure: (bytevector-s48-ref bytevector n eness)
+
+returns: the 48-bit signed integer at index n (zero-based) of bytevector
+
procedure: (bytevector-u56-ref bytevector n eness)
+
+returns: the 56-bit unsigned integer at index n (zero-based) of bytevector
+
procedure: (bytevector-s56-ref bytevector n eness)
+
+returns: the 56-bit signed integer at index n (zero-based) of bytevector
+
+libraries: (chezscheme)
+
+
n must be an exact nonnegative integer and +indexes the starting byte of the value. +The sum of n and the number of bytes occupied by the value +(3 for 24-bit values, 5 for 40-bit values, 6 for 48-bit values, +and 7 for 56-bit values) must not exceed the length of bytevector. +eness must be a valid endianness symbol naming the endianness. + +
+The return value is an exact integer in the appropriate range for +the number of bytes occupied by the value. +Signed values are the equivalent of the stored value treated as a two's +complement value. + +
+procedure: (bytevector-u24-set! bytevector n u24 eness)
+
procedure: (bytevector-s24-set! bytevector n s24 eness)
+
procedure: (bytevector-u40-set! bytevector n u40 eness)
+
procedure: (bytevector-s40-set! bytevector n s40 eness)
+
procedure: (bytevector-u48-set! bytevector n u48 eness)
+
procedure: (bytevector-s48-set! bytevector n s48 eness)
+
procedure: (bytevector-u56-set! bytevector n u56 eness)
+
procedure: (bytevector-s56-set! bytevector n s56 eness)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
bytevector must be mutable. +n must be an exact nonnegative integer and +indexes the starting byte of the value. +The sum of n and the number of bytes occupied by the value must +not exceed the length of bytevector. +u24 must be a 24-bit unsigned value, i.e., a value in the range +0 to 224 - 1 inclusive; +s24 must be a 24-bit signed value, i.e., a value in the range +-223 to 223 - 1 inclusive; +u40 must be a 40-bit unsigned value, i.e., a value in the range +0 to 240 - 1 inclusive; +s40 must be a 40-bit signed value, i.e., a value in the range +-239 to 239 - 1 inclusive; +u48 must be a 48-bit unsigned value, i.e., a value in the range +0 to 248 - 1 inclusive; +s48 must be a 48-bit signed value, i.e., a value in the range +-247 to 247 - 1 inclusive; +u56 must be a 56-bit unsigned value, i.e., a value in the range +0 to 256 - 1 inclusive; and +s56 must be a 56-bit signed value, i.e., a value in the range +-255 to 255 - 1 inclusive. +eness must be a valid endianness symbol naming the endianness. + +
+These procedures store the given value in the 3, 5, 6, or 7 bytes starting +at index n (zero-based) of bytevector. +Negative values are stored as their two's complement equivalent. + +
+procedure: (mutable-bytevector? obj)
+
+returns: #t if obj is a mutable bytevector, #f otherwise
+
procedure: (immutable-bytevector? obj)
+
+returns: #t if obj is an immutable bytevector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(mutable-bytevector? (bytevector 1 2 3)) #t
+
+(mutable-bytevector?
+
+ (bytevector->immutable-bytevector (bytevector 1 2 3))) #f
+
+(immutable-bytevector? (bytevector 1 2 3)) #f
+
+(immutable-bytevector?
+
+ (bytevector->immutable-bytevector (bytevector 1 2 3))) #t
+
+(immutable-bytevector? (cons 3 4)) #f
+
procedure: (bytevector->immutable-bytevector bytevector)
+
+returns: an immutable bytevector equal to bytevector
+
+libraries: (chezscheme)
+
+
The result is bytevector itself if bytevector +is immutable; otherwise, the result is an immutable bytevector with the same content as bytevector. + +
+ +
(define bv (bytevector->immutable-bytevector (bytevector 1 2 3)))
+
+(bytevector-u8-set! bv 0 0) exception: not mutable
+
procedure: (bytevector-compress bytevector)
+
+returns: a new bytevector containing compressed content of bytevector
+
+libraries: (chezscheme)
+
+
The result is the raw compressed data with a minimal header to record +the uncompressed size and the compression mode. The result does not include +the header that is written by port-based compression using the +compressed option. The compression format is determined by the +compress-format +parameter, and the compression level is determined by the +compress-level +parameter. + + +
+procedure: (bytevector-uncompress bytevector)
+
+returns: a bytevector containing uncompressed content of bytevector
+
+libraries: (chezscheme)
+
+
Uncompresses a bytevector produced by +bytevector-compress to a new bytevector with the same content +as the original given to bytevector-compress. + + +
+ +
+ +Stencil vectors are like vectors, but also have a mask, accessible +via stencil-vector-mask, which is a fixnum of no more than +(stencil-vector-mask-width) bits. The length of a stencil vector +is exactly the same as the number of bits set in its mask. In other +words, the following expression is true for any stencil vector sv: + +
+(fx= (stencil-vector-length sv) (fxpopcount (stencil-vector-mask sv))) + +
+Since (stencil-vector-mask-width) can be no more than the number +of bits in a fixnum, the maximum size of a stencil vector is limited. + +
+Other than the stencil-vector constructor, the mask is only
+relevant to the
+ stencil-vector-update and
+stencil-vector-truncate! procedures.
+
+
+A stencil vector provides a more compact representation than a vector +with one element dedicated to the mask. It also provides more +efficient functional update through the stencil-vector-update +procedure. A stencil vector is useful, for example, to implement +sparse nodes in a trie. + +
+Stencil vectors are written with the prefix +#, then a mask integer, then vs, and followed by a +parenthesized sequence of elements. Note that the mask integer +determines the length of the stencil vector, and it uses the same +position as the length of a vector, but the mask is not optional. +Also, the number of elements in the parenthesized sequence must match +exactly the number of bits set in the mask. +The stencil vector syntax is disabled in an input stream after +#!r6rs has been seen by the reader, unless +#!chezscheme has been seen more recently. + +
+procedure: (stencil-vector-mask-width)
+
+returns: a fixnum: the number of bits in a stencil vector mask
+
+libraries: (chezscheme)
+
+
The result is always less than (fixnum-width). + +
+procedure: (stencil-vector? obj)
+
+returns: #t if obj is a stencil vector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(stencil-vector? (stencil-vector #b11 'x 'y)) #t
+
+(stencil-vector? '#3vs(x y)) #t
+
+(stencil-vector? '#2(x y)) #f
+
procedure: (stencil-vector mask obj ...)
+
+returns: a stencil vector with the given mask and content
+
+libraries: (chezscheme)
+
+
mask must be a nonnegative fixnum less than +(fxsll 1 (stencil-vector-mask-width)), +and the number of supplied objs must be the +same as (fxpopcount mask). + +
+ +
(stencil-vector #b11 'x 'y) #3vs(x y)
+
+(stencil-vector #b10101 'x 'y 'z) #21vs(x y z)
+
procedure: (stencil-vector-mask stencil-vector)
+
+returns: the mask of stencil-vector
+
+libraries: (chezscheme)
+
+
procedure: (stencil-vector-length stencil-vector)
+
+returns: the length of stencil-vector
+
+libraries: (chezscheme)
+
+
A stencil vector's length is determined by its mask. (I.e., this is +equivalent to (fxpopcount (stencil-vector-mask stencil-vector)).) + +
+ +
(stencil-vector-mask '#0vs()) ;= 0
+
+(stencil-vector-length '#0vs()) ;= 0
+
+(stencil-vector-mask '#21vs(x y z)) ;= 21
+
+(stencil-vector-length '#21vs(x y z)) ;= 3
+
procedure: (stencil-vector-ref stencil-vector n)
+
+returns: the object at position n in stencil-vector
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum that is less than the length of stencil-vector. + +
+Stencil vector elements are accessed by position, unrelated to the +stencil vector's mask (except insofar as the number of valid positions is +determined by the mask). + +
+Conceptually, each stensil vector element corresponds to a bit in the +stencil vector's mask (and vice-versa). To convert a (0-based) bit position bit to an +index, where the lowest set bit corresponds to the first element of +the stencil vector, use the following calculation: + +
+(fxpopcount (fxand (stencil-vector-mask stencil-vector) (fx- (fxsll 1 bit) 1))) + +
+ +
(stencil-vector-ref '#21vs(x y z) 0) ;= x
+
+(stencil-vector-ref '#21vs(x y z) 2) ;= z
+
procedure: (stencil-vector-set! stencil-vector n obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
n must be a nonnegative fixnum that is less than the length of stencil-vector. + +
+Installs obj at position n within stencil-vector. +See stencil-vector-ref for more information about positions +in stencil vectors. + +
+ +
(define sv (stencil-vector #b10101 'x 'y 'z))
+
+(stencil-vector-set! sv 1 'why)
+
+sv #21vs(x why z)
+
procedure: (stencil-vector-update stencil-vector remove-bits add-bits obj ...)
+
+returns: a new stencil vector adapted from stencil-vector
+
+libraries: (chezscheme)
+
+
remove-bits and add-bits must be nonnegative fixnums less
+than
+ (fxsll 1 (stencil-vector-mask-width)). Furthermore, all of
+the following must be true:
+
+
+
+
+
(logand
+
+ (logand (stencil-vector-mask stencil-vector) (lognot remove-bits))
+
+ add-bits)
+
+
+
must be 0. + +
+
+
+ +
+Returns a new stencil vector that has all of the elements of +stencil-vector, except the ones identified by the bits in +remove-bits. The new stencil vector also has the given objs at +positions determined by add-bits. Elements copied from stencil-vector +to the new vector retain their relative positions corresponding to their +bits in the stencil-vector mask. Individual bits in the mask, remove-bits, +and add-bits are mapped to element positions as described in the documentation +of stencil-vector-ref. The mask of the new stencil vector is the mask of +stencil-vector minus remove-bits plus add-bits. + +
+ +
(define st-vec (stencil-vector #b101 'a 'b))
+
+(stencil-vector-update st-vec #b0 #b10 'c) #7vs(a c b)
+
+(stencil-vector-update st-vec #b0 #b1000 'c) #13vs(a b c)
+
+st-vec #5vs(a b)
+
+(stencil-vector-update st-vec #b1 #b1 'c) #5vs(c b)
+
+(stencil-vector-update st-vec #b100 #b100 'c) #5vs(a c)
+
+(stencil-vector-update st-vec #b100 #b0) #1vs(a)
+
procedure: (stencil-vector-truncate! stencil-vector mask)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
mask must be a nonnegative fixnum that does not have more bits set +than bits set in the current mask of stencil-vector. + +
+Changes the mask of stencil-vector to mask, discarding any +elements of the vector beyond the first (fxpopcount mask) elements. +There is no requirement that mask has any bits in common with +the current mask of stencil-vector. + + +
+ +
+Boxes are single-cell objects that are primarily useful for providing +an "extra level of indirection." +This extra level of indirection is typically used to allow more than one body +of code or data structure to share a reference, or pointer, to an object. +For example, boxes may be used to implement call-by-reference semantics +in an interpreter for a language employing this parameter passing discipline. + +
+Boxes are written with +the prefix #& (pronounced "hash-ampersand"). +For example, #&(a b c) is a box holding the list (a b c). +The box syntax is disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + +
+All boxes are mutable by default, including constants. +A program can create immutable boxes via +box-immutable. +Any attempt to modify an immutable box causes an exception to be raised. + +
+procedure: (box? obj)
+
+returns: #t if obj is a box, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(box? '#&a) #t
+
+(box? 'a) #f
+
+(box? (box 3)) #t
+
procedure: (box obj)
+
+returns: a new box containing obj
+
+libraries: (chezscheme)
+
+
+
+(box 'a) #&a
+
+(box (box '(a b c))) #&#&(a b c)
+
procedure: (unbox box)
+
+returns: contents of box
+
+libraries: (chezscheme)
+
+
+
+(unbox #&a) a
+
+(unbox #&#&(a b c)) #&(a b c)
+
+
+(let ([b (box "hi")])
+
+ (unbox b)) "hi"
+
procedure: (set-box! box obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
box must be mutable. +set-box! sets the contents of box to obj. + +
+ +
(let ([b (box 'x)])
+
+ (set-box! b 'y)
+
+ b) #&y
+
+
+(let ([incr!
+
+ (lambda (x)
+
+ (set-box! x (+ (unbox x) 1)))])
+
+ (let ([b (box 3)])
+
+ (incr! b)
+
+ (unbox b))) 4
+
procedure: (box-cas! box old-obj new-obj)
+
+returns: #t if box is changed, #f otherwise
+
+libraries: (chezscheme)
+
+
box must be mutable. +box-cas! atomically changes the content of box to new-obj +if the replaced content is eq? to old-obj. +If the content of box that would be replaced is not eq? to old-obj, then +box is unchanged. + +
+On an architecture with a weak memory model, box-cas! can +spuriously fail, leaving box unchanged and returning +#f even if the current value in box is old-obj. +On success, no memory ordering is implied, which means that +memory-order-acquire and/or memory-order-release may be +needed to complete an intended synchronization. + +
+ +
(define b (box 'old))
+
+(box-cas! b 'old 'new) #t, assuming no spurious failure
+
+(unbox b) 'new
+
+(box-cas! b 'other 'wrong) #f
+
+(unbox b) 'new
+
procedure: (mutable-box? obj)
+
+returns: #t if obj is a mutable box, #f otherwise
+
procedure: (immutable-box? obj)
+
+returns: #t if obj is an immutable box, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(mutable-box? (box 1)) #t
+
+(mutable-box? (box-immutable 1)) #f
+
+(immutable-box? (box 1)) #f
+
+(immutable-box? (box-immutable 1)) #t
+
+(mutable-box? (cons 3 4)) #f
+
procedure: (box-immutable obj)
+
+returns: a new immutable box containing obj
+
+libraries: (chezscheme)
+
+
Boxes are typically intended to support shared, mutable structure, so immutable boxes +are not often useful. + +
+ +
(define b (box-immutable 1))
+
+(set-box! b 0) exception: not mutable
+
+
+Chez Scheme extends the standard symbol syntax in several ways: + +
+
+
+
+
+ +
+The printer always prints symbols using the standard R6RS syntax, so that, +e.g., @abc prints as \x40;abc and 1- prints as +\x31;-. ' + +
+Gensyms are printed +#{ and +} brackets that enclose both the "pretty" and "unique" +names, +e.g., #{g1426 e5g1c94g642dssw-a}. +They may also be printed using the pretty name only with the prefix +#:, e.g., +#:g1426. + +
+These extensions are disabled in an input stream after #!r6rs has +been seen by the reader, unless #!chezscheme has been seen more +recently. + + +
+
+procedure: (gensym)
+
procedure: (gensym pretty-name)
+
procedure: (gensym pretty-name unique-name)
+
+returns: a unique generated symbol
+
+libraries: (chezscheme)
+
+
Each +call to gensym returns a unique generated symbol, or gensym. +Each generated symbol has two names: a "pretty" name and a +"unique" name. + +
+In the first form above, the pretty name is formed (lazily---see +below) by combining an +internal prefix with the value of an internal counter. +After each name is formed, the internal counter is incremented. +The parameters gensym-prefix and +gensym-count, described below, may be used to access and set +the internal prefix and counter. +By default, the prefix is the single-character string "g". +In the second and third forms, the pretty name of the new gensym +is pretty-name, which must be a string. +The pretty name of a gensym is returned by the procedure +symbol->string. + +
+In both the first and second forms, the unique name is an +automatically generated globally unique name. +Globally unique names are constructed (lazily---see below) from the +combination of a universally unique identifier and an internal +counter. +In the third form of gensym, the unique name of the new gensym is +unique-name, which must be a string. +The unique name of a gensym may be obtained via the procedure +gensym->unique-string. + +
+The unique name allows gensyms to be written in such a way that they +can be read back and reliably commonized on input. +The syntax for gensyms +includes both the pretty name and the unique name, as shown in the +example below: + +
+ +
(gensym) #{g0 bcsfg5eq4e9b3h9o-a} +
When the parameter print-gensym is set to pretty, +the printer prints the pretty name only, with a +#: syntax, so + +
+ +
(parameterize ([print-gensym 'pretty])
+
+ (write (gensym)))
+
prints #:g0. + +
+When the reader sees the #: syntax, it produces a gensym with +the given pretty name, but the original unique name is lost. + +
+When the parameter is set to #f, the printer prints just the +pretty name, so + +
+ +
(parameterize ([print-gensym #f])
+
+ (write (gensym)))
+
prints g0. +This is useful only when gensyms do not need to be read back in +as gensyms. + +
+In order to reduce construction and (when threaded) synchronization +overhead when gensyms are frequently created but rarely printed or +stored in an object file, generated pretty and unique names are created +lazily, i.e., not until first requested, either by the printer, fasl +writer, or explicitly by one of the procedures symbol->string +or gensym->unique-string. +In addition, a gensym is not placed into the system's internal symbol +table (the oblist; see page 174) until the unique name +is requested. +This allows a gensym to be reclaimed by the storage manager +if no references to the gensym exist and no unique name exists by which to +access it, even if it has a top-level binding or a nonempty property +list. + +
+ +
(define x (gensym))
+
+x #{g2 bcsfg5eq4e9b3h9o-c}
+
+(symbol->string x) "g2"
+
+(gensym->unique-string x) "bcsfg5eq4e9b3h9o-c"
+
Gensyms subsume the notion of uninterned +symbols supported by earlier versions of Chez Scheme. +For most purposes, the predicate +uninterned-symbol? has been replaced +by gensym?. + +
+thread parameter: gensym-prefix
+
thread parameter: gensym-count
+
+libraries: (chezscheme)
+
+
The parameters gensym-prefix and +gensym-count are used to access and set the internal prefix +and counter from which the pretty name of a gensym +is generated when gensym is not given an explicit string +argument. +gensym-prefix defaults to the string "g" and may be +set to any object. +gensym-count starts at 0 and may be set to any nonnegative +integer. + +
+As described above, Chez Scheme delays the creation +of the pretty name until the name is first requested by the printer or by +an explicit call to symbol->string. +These parameters are not consulted until that time; setting them when +gensym is called thus has no effect on the generated name. + +
+ +
(let ([x (parameterize ([gensym-prefix "genny"]
+
+ [gensym-count 17]
+
+ [print-gensym 'pretty])
+
+ (gensym))])
+
+ (format "~s" x)) "#{g4 bcsfg5eq4e9b3h9o-e}"
+
+(let ([x (gensym)])
+
+ (parameterize ([gensym-prefix "genny"]
+
+ [gensym-count 17]
+
+ [print-gensym #f])
+
+ (format "~s" (gensym)))) "genny17"
+
procedure: (gensym->unique-string gensym)
+
+returns: the unique name of gensym
+
+libraries: (chezscheme)
+
+
+
+(gensym->unique-string (gensym)) "bd3kufa7ypjcuvut-g" +
procedure: (gensym? obj)
+
+returns: #t if obj is a gensym, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(gensym? (string->symbol "z")) #f
+
+(gensym? (gensym "z")) #t
+
+(gensym? 'a) #f
+
+(gensym? 3) #f
+
+(gensym? (gensym)) #t
+
+(gensym? '#{g2 bcsfg5eq4e9b3h9o-c}) #t
+
procedure: (string->uninterned-symbol str)
+
+returns: a fresh uninterned symbol
+
+libraries: (chezscheme)
+
+
str must be a string. + +
+Returns an uninterned symbol that prints the same as a symbol +constructed from str, but which is not eq? to any +other symbol. + +
+When an uninterned symbol is converted by the fasl writer, the fasl +reader will allocate a fresh uninterned symbol each time the fasl +stream is read. Multiple occurrences of the same uninterned symbol in +the fasl writer's argument will become multiple occurrences of the +same new uninterned symbol in the fasl reader's result for the stream. + +
+ +
+(string->uninterned-symbol "z") z
+
+(uninterned-symbol? (string->uninterned-symbol "z")) #t
+
+(symbol? (string->uninterned-symbol "z")) #t
+
+(gensym? (string->uninterned-symbol "z")) #f
+
procedure: (uninterned-symbol? obj)
+
+returns: #t if obj is an uninterned symbol, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(uninterned-symbol? (string->symbol "z")) #f
+
+(uninterned-symbol? (gensym "z")) #f
+
+(uninterned-symbol? (string->uninterned-symbol "z")) #t
+
+procedure: (putprop symbol key value)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Chez Scheme associates a property list with +each symbol, allowing multiple key-value pairs to be stored +directly with the symbol. +New key-value pairs may be placed in the property list or retrieved in +a manner analogous to the use of association lists, using the procedures +putprop and getprop. +Property lists are often used to store information related to the symbol +itself. +For example, a natural language program might use symbols to represent +words, using their property lists to store information about use and +meaning. + +
+putprop associates value with key on the +property list of symbol. +key and value may be any types of object, although key is +typically a symbol. + +
+putprop may be used to establish a new property or to change +an existing property. + +
+See the examples under getprop below. + + +
+procedure: (getprop symbol key)
+
procedure: (getprop symbol key default)
+
+returns: the value associated with key on the property list of symbol
+
+libraries: (chezscheme)
+
+
getprop searches the property list of +symbol for a key identical to key (in the sense of +eq?), and returns the value associated with this key, if any. +If no value is associated with key on the property list of +symbol, getprop returns default, or #f if +the default argument is not supplied. + + +
+ +
(putprop 'fred 'species 'snurd)
+
+(putprop 'fred 'age 4)
+
+(putprop 'fred 'colors '(black white))
+
+
+(getprop 'fred 'species) snurd
+
+(getprop 'fred 'colors) (black white)
+
+(getprop 'fred 'nonkey) #f
+
+(getprop 'fred 'nonkey 'unknown) unknown
+
+
+
+(putprop 'fred 'species #f)
+
+(getprop 'fred 'species 'unknown) #f
+
procedure: (remprop symbol key)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
remprop removes the property with key key from the property +list of symbol, if such a property exists. + +
+ +
(putprop 'fred 'species 'snurd)
+
+(getprop 'fred 'species) snurd
+
+
+(remprop 'fred 'species)
+
+(getprop 'fred 'species 'unknown) unknown
+
procedure: (property-list symbol)
+
+returns: a copy of the internal property list for symbol
+
+libraries: (chezscheme)
+
+
A property list is a list of alternating keys and values, +i.e., (key value ...). + +
+ +
(putprop 'fred 'species 'snurd)
+
+(putprop 'fred 'colors '(black white))
+
+(property-list 'fred) (colors (black white) species snurd)
+
+procedure: (oblist)
+
+returns: a list of interned symbols
+
+libraries: (chezscheme)
+
+
The system maintains an internal symbol table used +to insure that any two occurrences of the same +symbol name resolve to the same symbol object. +The oblist procedure returns a list of the symbols currently in +this symbol table. + +
+The list of interned symbols grows when a new symbol +is introduced into the system or when the unique name of a +gensym (see page 170) is requested. +It shrinks when the garbage collector determines that it is +safe to discard a symbol. +It is safe to discard a symbol only if the symbol is not accessible except +through the oblist, +has no top-level binding, and has no properties on its property +list. + +
+ +
(if (memq 'tiger (oblist)) 'yes 'no) yes
+
+(equal? (oblist) (oblist)) #t
+
+(= (length (oblist)) (length (oblist))) #t or #f
+
The first example above follows from the property that all interned +symbols are in the oblist from the time they are read, which happens +prior to evaluation. +The second example follows from the fact that no symbols can be +removed from the oblist while references to those symbols exist, in +this case, within the list returned by the first call to +oblist (whichever call is performed first). +The expression in the third example can return #f only if a garbage +collection occurs sometime between the two calls to oblist, and only +if one or more symbols are removed from the oblist by that collection. + +
+ +
+Many Scheme operations return an unspecified result. +Chez Scheme typically returns a special void object when the +value returned by an operation is unspecified. +The Chez Scheme void object is not meant to be used as a datum, and +consequently does not have a reader syntax. +As for other objects without a reader syntax, such as procedures and +ports, Chez Scheme output procedures print the void object using a +nonreadable representation, i.e., #<void>. +Since the void object should be returned only by operations that do not +have "interesting" values, the default waiter printer (see +waiter-write) suppresses the printing of the void object. +set!, set-car!, load, and write are examples of Chez Scheme +operations that return the void object. + +
+procedure: (void)
+
+returns: the void object
+
+libraries: (chezscheme)
+
+
void is a procedure of no arguments that returns the void object. +It can be used to force expressions that are used for effect or whose +values are otherwise unspecified to evaluate to a consistent, trivial +value. +Since most Chez Scheme operations that are used for effect +return the void object, however, it is rarely necessary to explicitly +invoke the void procedure. + +
+Since the void object is used explicitly as an "unspecified" value, +it is a bad idea to use it for any other purpose or to count on any +given expression evaluating to the void object. + +
+The default waiter printer suppresses the void object; that is, nothing +is printed for expressions that evaluate to the void object. + +
+ +
(eq? (void) #f) #f
+
+(eq? (void) #t) #f
+
+(eq? (void) '()) #f
+
+
+procedure: (sort predicate list)
+
procedure: (sort! predicate list)
+
+returns: a list containing the elements of list sorted according to predicate
+
+libraries: (chezscheme)
+
+
sort is identical to the Revised6 Report list-sort, +and sort! is a destructive version of sort, i.e., it +reuses pairs from the input list to form the output list. + +
+ +
(sort < '(3 4 2 1 2 5)) (1 2 2 3 4 5)
+
+(sort! < '(3 4 2 1 2 5)) (1 2 2 3 4 5)
+
procedure: (merge predicate list1 list2)
+
procedure: (merge! predicate list1 list2)
+
+returns: list1 merged with list2 in the order specified by predicate
+
+libraries: (chezscheme)
+
+
predicate should be a procedure that expects two arguments and +returns #t if its first argument must precede its second in +the merged list. +It should not have any side effects. +That is, if predicate is applied to two objects x and +y, where x is taken from the second list and y +is taken from the first list, +it should return true only if x should appear before y +in the output list. +If this constraint is met, +merge and merge! are stable, in that items from list1 are +placed in front of equivalent items from list2 in the output list. +Duplicate elements are included in the merged list. + +
+merge! combines the lists destructively, using pairs from the input +lists to form the output list. + +
+ +
(merge char<?
+
+ '(#\a #\c)
+
+ '(#\b #\c #\d)) (#\a #\b #\c #\c #\d)
+
+(merge <
+
+ '(1/2 2/3 3/4)
+
+ '(0.5 0.6 0.7)) (1/2 0.5 0.6 2/3 0.7 3/4)
+
+
+Chez Scheme provides several extensions to the hashtable mechanism, +including a mechanism for directly accessing a key, value pair in a +hashtable, support for weak eq and eqv hashtables, and a set of procedures +specialized to eq and symbol hashtables. + +
+procedure: (hashtable-cell hashtable key default)
+
+returns: a pair (see below)
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable hashtable. +key and default may be any Scheme values. + +
+If no value is associated with key in hashtable, +hashtable-cell modifies hashtable to associate key with +default. +It returns a pair whose car is key and whose cdr is +the associated value. +Changing the cdr of this pair effectively updates the table to +associate key with a new value. +The key in the car field should not be changed. +The advantage of this procedure over the Revised6 Report procedures +for manipulating hashtable entries is that the value associated with +a key may be read or written many times with only a single hashtable +lookup. + +
+ +
(define ht (make-eq-hashtable))
+
+(define v (vector 'a 'b 'c))
+
+(define cell (hashtable-cell ht v 3))
+
+cell (#(a b c) . 3)
+
+(hashtable-ref ht v 0) 3
+
+(set-cdr! cell 4)
+
+(hashtable-ref ht v 0) 4
+
procedure: (hashtable-ref-cell hashtable key)
+
+returns: a pair if key is in hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable hashtable. +key may be any Scheme value. + +
+If key is associated with a value in hashtable, then hashtable-ref-cell returns a pair +whose car is key and whose cdr is the associated value. Changing the cdr of +this pair effectively updates the table to associate key with a new value. +The key in the car field should not be changed. + +
+If key is not in hashtable, then #f is returned. + +
+ +
(define ht (make-eq-hashtable))
+
+(define v (vector 'a 'b 'c))
+
+(hashtable-ref-cell ht v) #f
+
+(hashtable-set! ht v 3)
+
+(define cell (hashtable-ref-cell ht v))
+
+cell ((#a b c) . 3)
+
+(hashtable-ref ht v 0) 3
+
+(set-cdr! cell 4)
+
+(hashtable-ref ht v 0) 4
+
procedure: (hashtable-keys hashtable)
+
procedure: (hashtable-keys hashtable size)
+
+returns: a vector containing the keys in hashtable
+
+libraries: (chezscheme)
+
+
Identical to the Revised6 Report counterpart, but allowing an optional +size argument. +If size is specified, then it must be an exact, nonnegative integer; the +result vector will contain (min size (hashtable-size hashtable)) elements. +Different calls to hashtable-keys +with a size less than (hashtable-size hashtable) +may return different subsets of hashtable's keys. + +
+ +
(define ht (make-eq-hashtable))
+
+(hashtable-set! ht 'a "one")
+
+(hashtable-set! ht 'b "two")
+
+(hashtable-set! ht 'c "three")
+
+(hashtable-keys ht) #(a b c) or any permutation
+
+(hashtable-keys ht 1) #(a) or #(b) or #(c)
+
procedure: (hashtable-values hashtable)
+
procedure: (hashtable-values hashtable size)
+
+returns: a vector containing the values in hashtable
+
+libraries: (chezscheme)
+
+
Each value is the value of one of the keys in hashtable. +Duplicate values are not removed. +The values may appear in any order in the returned vector. +If size is specified, then it must be an exact, nonnegative integer; the +result vector will contain (min size (hashtable-size hashtable)) elements. +Different calls to hashtable-values +with a size less than (hashtable-size hashtable) +may return different subsets of hashtable's values. + +
+ +
(define ht (make-eq-hashtable))
+
+(define p1 (cons 'a 'b))
+
+(define p2 (cons 'a 'b))
+
+(hashtable-set! ht p1 "one")
+
+(hashtable-set! ht p2 "two")
+
+(hashtable-set! ht 'q "two")
+
+(hashtable-values ht) #("one" "two" "two") or any permutation
+
+(hashtable-values ht 1) #("one") or #("two")
+
This procedure is equivalent to calling hashtable-entries and returning only +the second result, but it is more efficient since the separate vector of keys need +not be created. + +
+procedure: (hashtable-entries hashtable)
+
procedure: (hashtable-entries hashtable size)
+
+returns: two vectors containing the keys and values in hashtable
+
+libraries: (chezscheme)
+
+
Identical to the Revised6 Report counterpart, but allowing an optional +size argument. +If size is specified, then it must be an exact, nonnegative integer; the +result vectors will each contain (min size (hashtable-size hashtable)) elements. +Different calls to hashtable-entries +with a size less than (hashtable-size hashtable) +may return different subsets of hashtable's entries. + +
+ +
(define ht (make-eq-hashtable))
+
+(hashtable-set! ht 'a "one")
+
+(hashtable-set! ht 'b "two")
+
+(hashtable-entries ht) #(a b) #("one" "two") or the other permutation
+
+(hashtable-entries ht 1) #(a) #("one") or #(b) #("two")
+
procedure: (hashtable-cells hashtable)
+
procedure: (hashtable-cells hashtable size)
+
+returns: a vector of up to size elements containing the cells of hashtable
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable hashtable. + +
+Each element of the result vector is the value of one of the cells in hashtable. +The cells may appear in any order in the returned vector. +If size is specified, then it must be an exact, nonnegative integer; the +result vector will contain (min size (hashtable-size hashtable)) elements. +If size is not specified, then the result vector has (hashtable-size hashtable) elements. +Different calls to hashtable-cells +with a size less than (hashtable-size hashtable) +may return different subsets of hashtable's cells. + +
+Changing the cdr of a pair in the result vector effectively updates +the table to associate car of the pair with a new value. The car of a +pair in the result vector should not be changed. + +
+ +
(define ht (make-eqv-hashtable))
+
+(hashtable-set! ht 1 'one)
+
+(hashtable-set! ht 2 'two)
+
+(hashtable-cells ht) #((1 . one) (2 . two)) or #((2 . two) (1 . one))
+
+(hashtable-cells ht 1) #((1 . one)) or #((2 . two))
+
+(hashtable-cells ht 0) #()
+
procedure: (make-weak-eq-hashtable)
+
procedure: (make-weak-eq-hashtable size)
+
procedure: (make-weak-eqv-hashtable)
+
procedure: (make-weak-eqv-hashtable size)
+
procedure: (make-weak-hashtable hash equiv?)
+
procedure: (make-weak-hashtable hash equiv? size)
+
+returns: a new weak hashtable
+
+libraries: (chezscheme)
+
+
Like the Revised6 Report procedures make-eq-hashtable, +make-eqv-hashtable, and make-hashtable, +except the keys of the hashtable are held weakly, i.e., they are not +protected from the garbage collector. +Keys reclaimed by the garbage collector are removed from the table, +and their associated values are dropped the next time the table +is modified, if not sooner. + +
+Values in the hashtable are referenced normally as long as the key is +not reclaimed, since keys are paired values using weak pairs. Consequently, +if a value in the hashtable refers to its own key, then +garbage collection is prevented from reclaiming the key. See +make-ephemeron-hashtable and related functions. + +
+A copy of a weak hashtable created by hashtable-copy is +also weak. +If the copy is immutable, inaccessible keys may still be dropped from the +hashtable, even though the contents of the table is otherwise unchanging. +The effect of this can be observed via hashtable-keys and +hashtable-entries. + +
+ +
(define ht1 (make-weak-eq-hashtable))
+
+(define ht2 (make-weak-eq-hashtable 32))
+
procedure: (make-ephemeron-eq-hashtable)
+
procedure: (make-ephemeron-eq-hashtable size)
+
procedure: (make-ephemeron-eqv-hashtable)
+
procedure: (make-ephemeron-eqv-hashtable size)
+
procedure: (make-ephemeron-hashtable hash equiv?)
+
procedure: (make-ephemeron-hashtable hash equiv? size)
+
+returns: a new ephemeron hashtable
+
+libraries: (chezscheme)
+
+
Like make-weak-eq-hashtable, +make-weak-eqv-hashtable, and make-weak-hashtable, +but a value in the hashtable can refer to a +key in the hashtable (directly or indirectly) without preventing garbage collection from +reclaiming the key, because keys are paired with values using ephemeron pairs. + +
+A copy of an ephemeron hashtable created by +hashtable-copy is also an ephemeron table, and an inaccessible +key can be dropped from an immutable ephemeron hashtable in the same +way as for an immutable weak hashtable. + +
+ +
(define ht1 (make-ephemeron-eq-hashtable))
+
+(define ht2 (make-ephemeron-eq-hashtable 32))
+
procedure: (hashtable-weak? obj)
+
+returns: #t if obj is a weak hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(define ht1 (make-weak-eq-hashtable))
+
+(define ht2 (hashtable-copy ht1))
+
+(hashtable-weak? ht2) #t
+
procedure: (hashtable-ephemeron? obj)
+
+returns: #t if obj is an ephemeron hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(define ht1 (make-ephemeron-eq-hashtable))
+
+(define ht2 (hashtable-copy ht1))
+
+(hashtable-ephemeron? ht2) #t
+
procedure: (eq-hashtable? obj)
+
+returns: #t if obj is an eq hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(eq-hashtable? (make-eq-hashtable)) #t
+
+(eq-hashtable? '(not a hash table)) #f
+
procedure: (eq-hashtable-weak? hashtable)
+
+returns: #t if hashtable is weak, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be an eq hashtable. + +
+ +
(eq-hashtable-weak? (make-eq-hashtable)) #f
+
+(eq-hashtable-weak? (make-weak-eq-hashtable)) #t
+
procedure: (eq-hashtable-ephemeron? hashtable)
+
+returns: #t if hashtable uses ephemeron pairs, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be an eq hashtable. + +
+ +
(eq-hashtable-ephemeron? (make-eq-hashtable)) #f
+
+(eq-hashtable-ephemeron? (make-ephemeron-eq-hashtable)) #t
+
procedure: (eq-hashtable-set! hashtable key value)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable eq hashtable. +key and value may be any Scheme values. + +
+eq-hashtable-set! associates the value +value with the key key in hashtable. + +
+ +
(define ht (make-eq-hashtable))
+
+(eq-hashtable-set! ht 'a 73)
+
procedure: (eq-hashtable-ref hashtable key default)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
hashtable must be an eq hashtable. +key and default may be any Scheme values. + +
+eq-hashtable-ref returns the value +associated with key in hashtable. +If no value is associated with key in hashtable, +eq-hashtable-ref returns default. + + +
+ +
(define ht (make-eq-hashtable))
+
+(define p1 (cons 'a 'b))
+
+(define p2 (cons 'a 'b))
+
+(eq-hashtable-set! ht p1 73)
+
+(eq-hashtable-ref ht p1 55) 73
+
+(eq-hashtable-ref ht p2 55) 55
+
procedure: (eq-hashtable-contains? hashtable key)
+
+returns: #t if an association for key exists in hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be an eq hashtable. +key may be any Scheme value. + +
+ +
(define ht (make-eq-hashtable))
+
+(define p1 (cons 'a 'b))
+
+(define p2 (cons 'a 'b))
+
+(eq-hashtable-set! ht p1 73)
+
+(eq-hashtable-contains? ht p1) #t
+
+(eq-hashtable-contains? ht p2) #f
+
procedure: (eq-hashtable-update! hashtable key procedure default)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable eq hashtable. +key and default may be any Scheme values. +procedure should accept one argument, should return one value, and +should not modify hashtable. + +
+eq-hashtable-update! applies procedure to the value associated with +key in hashtable, or to default if no value is associated with +key in hashtable. +If procedure returns, eq-hashtable-update! associates key +with the value returned by procedure, replacing the old association, +if any. + +
+A version of eq-hashtable-update! that does not verify that it receives +arguments of the proper type might be defined as follows. + +
+ +
(define eq-hashtable-update!
+
+ (lambda (ht key proc value)
+
+ (eq-hashtable-set! ht key
+
+ (proc (eq-hashtable-ref ht key value)))))
+
An implementation may, however, be able to implement +eq-hashtable-update! more efficiently by avoiding multiple +hash computations and hashtable lookups. + +
+ +
(define ht (make-eq-hashtable))
+
+(eq-hashtable-update! ht 'a
+
+ (lambda (x) (* x 2))
+
+ 55)
+
+(eq-hashtable-ref ht 'a 0) 110
+
+(eq-hashtable-update! ht 'a
+
+ (lambda (x) (* x 2))
+
+ 0)
+
+(eq-hashtable-ref ht 'a 0) 220
+
procedure: (eq-hashtable-cell hashtable key default)
+
+returns: a pair (see below)
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable eq hashtable. +key and default may be any Scheme values. + +
+If no value is associated with key in hashtable, +eq-hashtable-cell modifies hashtable to associate key with +default. +It returns a pair whose car is key and whose cdr is +the associated value. +Changing the cdr of this pair effectively updates the table to +associate key with a new value. +The key should not be changed. + +
+ +
(define ht (make-eq-hashtable))
+
+(define v (vector 'a 'b 'c))
+
+(define cell (eq-hashtable-cell ht v 3))
+
+cell (#(a b c) . 3)
+
+(eq-hashtable-ref ht v 0) 3
+
+(set-cdr! cell 4)
+
+(eq-hashtable-ref ht v 0) 4
+
procedure: (eq-hashtable-try-atomic-cell hashtable key default)
+
+returns: a pair or #f (see below)
+
+libraries: (chezscheme)
+
+
Like eq-hashtable-cell, but safe for use from multiple +threads at the same time as long as only this function, +eq-hashtable-ref, eq-hashtable-ref-cell, +and eq-hashtable-contains? are used on a +particular hash table by any thread. To handle certain forms of +contention, the result may be #f, in which case the operation +might be retried. An even more significant constraint is that the hash +table will not be resized interally as needed to provide constant-time +behavior. Use eq-hashtable-set! or a similar operation from a +single thread (e.g., during a collect-reqest handler) to allow the +opportunity of resizing. + +
+procedure: (eq-hashtable-ref-cell hashtable key)
+
+returns: a pair if key is in hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable eq hashtable. +key may be any Scheme value. + +
+If key is associated with a value in hashtable, then eq-hashtable-ref-cell returns a pair +whose car is key and whose cdr is the associated value. Changing the cdr of +this pair effectively updates the table to associate key with a new value. +The key in the car field should not be changed. + +
+If key is not in hashtable, then #f is returned. + +
+ +
(define ht (make-eq-hashtable))
+
+(define v (vector 'a 'b 'c))
+
+(eq-hashtable-ref-cell ht v) #f
+
+(eq-hashtable-set! ht v 3)
+
+(define cell (eq-hashtable-ref-cell ht v))
+
+cell ((#a b c) . 3)
+
+(eq-hashtable-ref ht v 0) 3
+
+(set-cdr! cell 4)
+
+(eq-hashtable-ref ht v 0) 4
+
procedure: (eq-hashtable-delete! hashtable key)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable eq hashtable. +key may be any Scheme value. + +
+eq-hashtable-delete! drops any association +for key from hashtable. + +
+ +
(define ht (make-eq-hashtable))
+
+(define p1 (cons 'a 'b))
+
+(define p2 (cons 'a 'b))
+
+(eq-hashtable-set! ht p1 73)
+
+(eq-hashtable-contains? ht p1) #t
+
+(eq-hashtable-delete! ht p1)
+
+(eq-hashtable-contains? ht p1) #f
+
+(eq-hashtable-contains? ht p2) #f
+
+(eq-hashtable-delete! ht p2)
+
procedure: (symbol-hashtable? obj)
+
+returns: #t if obj is a symbol hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or +symbol=?. + +
+ +
(symbol-hashtable? (make-hashtable symbol-hash eq?)) #t
+
+(symbol-hashtable? (make-eq-hashtable)) #f
+
procedure: (symbol-hashtable-set! hashtable key value)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol, and value may be any Scheme value. + +
+symbol-hashtable-set! associates the value +value with the key key in hashtable. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(symbol-hashtable-ref ht 'a #f) #f
+
+(symbol-hashtable-set! ht 'a 73)
+
+(symbol-hashtable-ref ht 'a #f) 73
+
procedure: (symbol-hashtable-ref hashtable key default)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
hashtable must be a symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol, and default may be any Scheme value. + +
+symbol-hashtable-ref returns the value +associated with key in hashtable. +If no value is associated with key in hashtable, +symbol-hashtable-ref returns default. + + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(define k1 'abcd)
+
+(define k2 'not-abcd)
+
+(symbol-hashtable-set! ht k1 "hi")
+
+(symbol-hashtable-ref ht k1 "bye") "hi"
+
+(symbol-hashtable-ref ht k2 "bye") "bye"
+
procedure: (symbol-hashtable-contains? hashtable key)
+
+returns: #t if an association for key exists in hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be a symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(define k1 'abcd)
+
+(define k2 'not-abcd)
+
+(symbol-hashtable-set! ht k1 "hi")
+
+(symbol-hashtable-contains? ht k1) #t
+
+(symbol-hashtable-contains? ht k2 ) #f
+
procedure: (symbol-hashtable-update! hashtable key procedure default)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol, and default may be any Scheme value. +procedure should accept one argument, should return one value, and +should not modify hashtable. + +
+symbol-hashtable-update! applies procedure to the value associated with +key in hashtable, or to default if no value is associated with +key in hashtable. +If procedure returns, symbol-hashtable-update! associates key +with the value returned by procedure, replacing the old association, +if any. + +
+A version of symbol-hashtable-update! that does not verify that it receives +arguments of the proper type might be defined as follows. + +
+ +
(define symbol-hashtable-update!
+
+ (lambda (ht key proc value)
+
+ (symbol-hashtable-set! ht key
+
+ (proc (symbol-hashtable-ref ht key value)))))
+
An implementation may, however, be able to implement +symbol-hashtable-update! more efficiently by avoiding multiple +hash computations and hashtable lookups. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(symbol-hashtable-update! ht 'a
+
+ (lambda (x) (* x 2))
+
+ 55)
+
+(symbol-hashtable-ref ht 'a 0) 110
+
+(symbol-hashtable-update! ht 'a
+
+ (lambda (x) (* x 2))
+
+ 0)
+
+(symbol-hashtable-ref ht 'a 0) 220
+
procedure: (symbol-hashtable-cell hashtable key default)
+
+returns: a pair (see below)
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol, and default may be any Scheme value. + +
+If no value is associated with key in hashtable, +symbol-hashtable-cell modifies hashtable to associate key with +default. +It returns a pair whose car is key and whose cdr is +the associated value. +Changing the cdr of this pair effectively updates the table to +associate key with a new value. +The key should not be changed. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(define k 'a-key)
+
+(define cell (symbol-hashtable-cell ht k 3))
+
+cell (a-key . 3)
+
+(symbol-hashtable-ref ht k 0) 3
+
+(set-cdr! cell 4)
+
+(symbol-hashtable-ref ht k 0) 4
+
procedure: (symbol-hashtable-ref-cell hashtable key)
+
+returns: a pair if key is in hashtable, #f otherwise
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol. + +
+If key is associated with a value in hashtable, then it returns a pair +whose car is key and whose cdr is the associated value. Changing the cdr of +this pair effectively updates the table to associate key with a new value. +The key in the car field should not be changed. + +
+If key is not in hashtable, then #f is returned. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(define k 'a-key)
+
+(symbol-hashtable-ref-cell ht k) #f
+
+(symbol-hashtable-set! ht k 3)
+
+(define cell (symbol-hashtable-ref-cell ht k))
+
+cell (a-key . 3)
+
+(symbol-hashtable-ref ht k 0) 3
+
+(set-cdr! cell 4)
+
+(symbol-hashtable-ref ht k 0) 4
+
procedure: (symbol-hashtable-delete! hashtable key)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
hashtable must be a mutable symbol hashtable. +(A symbol hashtable is a hashtable created with hash function symbol-hash +and equivalence function eq?, eqv?, equal?, or symbol=?.) +key must be a symbol. + +
+symbol-hashtable-delete! drops any association +for key from hashtable. + +
+ +
(define ht (make-hashtable symbol-hash eq?))
+
+(define k1 (gensym))
+
+(define k2 (gensym))
+
+(symbol-hashtable-set! ht k1 73)
+
+(symbol-hashtable-contains? ht k1) #t
+
+(symbol-hashtable-delete! ht k1)
+
+(symbol-hashtable-contains? ht k1) #f
+
+(symbol-hashtable-contains? ht k2) #f
+
+(symbol-hashtable-delete! ht k2)
+
+
+Chez Scheme extends the Revised6 Report's define-record-type +syntax in one way, which is that it allows a generative record type +to be declared explicitly as such (in a double-negative sort of way) +by including a nongenerative clause with #f as the +uid, i.e.: + +
+ +
(nongenerative #f) +
This can be used in conjunction with the parameter +require-nongenerative-clause to catch the accidental use of +generative record types while avoiding spurious errors for record types +that must be generative. +Generative record types are rarely needed and are generally less +efficient since a run-time representation of the type is created each +time the define-record-clause is evaluated, rather than once +at compile (expansion) time. + +
+thread parameter: require-nongenerative-clause
+
+libraries: (chezscheme)
+
+
This parameter holds a boolean value that determines whether +define-record-type +requires a nongenerative clause. +The default value is #f. +The lead-in above describes why one might want to set this to #t. + +
+ +
+By default, the equal? primitive +compares record instances using eq?, i.e., it distinguishes +non-eq? instances even if they are of the same type and have equal +contents. +A program can override this behavior for instances of a +record type (and its subtypes that do not have their own equality +procedures) by using +record-type-equal-procedure +to associate an equality procedure with the record-type descriptor +(rtd) that describes the record type. + +
+When comparing two eq? instances, equal? always returns +#t. +When comparing two non-eq? instances that share an equality procedure +equal-proc, equal? uses equal-proc to compare +the instances. +Two instances x and y share an equality procedure if +they inherit an equality procedure from the same point in the inheritance +chain, i.e., if +(record-equal-procedure x y) +returns a procedure (equal-proc) rather +than #f. +equal? passes equal-proc three arguments: the two +instances plus a eql? procedure that should be used for +recursive comparison of values within the two instances. +Use of eql? for recursive comparison is necessary to allow +comparison of potentially cyclic structure. +When comparing two non-eq? instances that do not share an equality +procedure, equal? returns #f. + +
+A default equality procedure to be used for all record types (including +opaque types) can be specified via the parameter +default-record-equal-procedure. +The default equality procedure is used only if neither instance's type has or inherits +a type-specific record equality procedure. + +
+Similarly, when the equal-hash +primitive hashes a record instance, it defaults to a value that is +independent of the record type and contents of the instance. +A program can override this behavior for instances of a +record type by using record-type-hash-procedure +to associate a hash procedure with the record-type descriptor (rtd) +that describes the record type. +The procedure record-hash-procedure can be used to find +the hash procedure for a given record instance, following the inheritance +chain. +equal-hash passes the hash procedure two arguments: the +instance plus a hash procedure that should be used for +recursive hashing of values within the instance. +Use of hash for recursive hashing is necessary to allow +hashing of potentially cyclic structure and to make the hashing +of shared structure more efficient. + +
+A default hash procedure to be used for all record types (including +opaque types) can be specified via the parameter +default-record-hash-procedure. +The default hash procedure is used only if an instance's type does not have or inherit +a type-specific hash procedure. + +
+The following example illustrates the setting of equality and hash +procedures. + +
+ +
(define-record-type marble
+
+ (nongenerative)
+
+ (fields color quality))
+
+
+(record-type-equal-procedure (record-type-descriptor marble)) #f
+
+(equal? (make-marble 'blue 'medium) (make-marble 'blue 'medium)) #f
+
+(equal? (make-marble 'blue 'medium) (make-marble 'blue 'high)) #f
+
+
+; Treat marbles as equal when they have the same color
+
+(record-type-equal-procedure (record-type-descriptor marble)
+
+ (lambda (m1 m2 eql?)
+
+ (eql? (marble-color m1) (marble-color m2))))
+
+(record-type-hash-procedure (record-type-descriptor marble)
+
+ (lambda (m hash)
+
+ (hash (marble-color m))))
+
+
+(equal? (make-marble 'blue 'medium) (make-marble 'blue 'high)) #t
+
+(equal? (make-marble 'red 'high) (make-marble 'blue 'high)) #f
+
+
+(define ht (make-hashtable equal-hash equal?))
+
+(hashtable-set! ht (make-marble 'blue 'medium) "glass")
+
+(hashtable-ref ht (make-marble 'blue 'high) #f) "glass"
+
+
+(define-record-type shooter
+
+ (nongenerative)
+
+ (parent marble)
+
+ (fields size))
+
+
+(equal? (make-marble 'blue 'medium) (make-shooter 'blue 'large 17)) #t
+
+(equal? (make-shooter 'blue 'large 17) (make-marble 'blue 'medium)) #t
+
+(hashtable-ref ht (make-shooter 'blue 'high 17) #f) "glass"
+
This example illustrates the application of equality and hash procedures +to cyclic record structures. + +
+ +
(define-record-type node
+
+ (nongenerative)
+
+ (fields (mutable left) (mutable right)))
+
+
+(record-type-equal-procedure (record-type-descriptor node)
+
+ (lambda (x y e?)
+
+ (and
+
+ (e? (node-left x) (node-left y))
+
+ (e? (node-right x) (node-right y)))))
+
+(record-type-hash-procedure (record-type-descriptor node)
+
+ (lambda (x hash)
+
+ (+ (hash (node-left x)) (hash (node-right x)) 23)))
+
+
+(define graph1
+
+ (let ([x (make-node "a" (make-node #f "b"))])
+
+ (node-left-set! (node-right x) x)
+
+ x))
+
+(define graph2
+
+ (let ([x (make-node "a" (make-node (make-node "a" #f) "b"))])
+
+ (node-right-set! (node-left (node-right x)) (node-right x))
+
+ x))
+
+(define graph3
+
+ (let ([x (make-node "a" (make-node #f "c"))])
+
+ (node-left-set! (node-right x) x)
+
+ x))
+
+
+(equal? graph1 graph2) #t
+
+(equal? graph1 graph3) #f
+
+(equal? graph2 graph3) #f
+
+
+(define h (make-hashtable equal-hash equal?))
+
+(hashtable-set! h graph1 #t)
+
+(hashtable-ref h graph1 #f) #t
+
+(hashtable-ref h graph2 #f) #t
+
+(hashtable-ref h graph3 #f) #f
+
procedure: (record-type-equal-procedure rtd equal-proc)
+
+returns: unspecified
+
procedure: (record-type-equal-procedure rtd)
+
+returns: equality procedure associated with rtd, if any, otherwise #f
+
+libraries: (chezscheme)
+
+
In the first form, equal-proc must be a procedure or #f. +If equal-proc is a procedure, a new association between +rtd and equal-proc is established, replacing any existing +such association. +If equal-proc is #f, any existing association between +rtd and an equality procedure is dropped. + +
+In the second form, record-type-equal-procedure returns +the equality procedure associated with rtd, if any, otherwise #f. + +
+When changing a record type's equality procedure, the record type's +hash procedure, if any, should be updated if necessary to maintain +the property that it produces the same hash value for any two +instances the equality procedure considers equal. + +
+procedure: (record-equal-procedure record1 record2)
+
+returns: the shared equality procedure for record1 and record2, if there is one, otherwise #f
+
+libraries: (chezscheme)
+
+
record-equal-procedure traverses the inheritance chains +for both record instances in an attempt to find the most specific +type for each that is associated with an equality procedure, if any. +If such type is found and is the same for both instances, the +equality procedure associated with the type is returned. +Otherwise, #f is returned. + +
+procedure: (record-type-hash-procedure rtd hash-proc)
+
+returns: unspecified
+
procedure: (record-type-hash-procedure rtd)
+
+returns: hash procedure associated with rtd, if any, otherwise #f
+
+libraries: (chezscheme)
+
+
In the first form, hash-proc must be a procedure or #f. +If hash-proc is a procedure, a new association between +rtd and hash-proc is established, replacing any existing +such association. +If hash-proc is #f, any existing association between +rtd and a hash procedure is dropped. + +
+In the second form, record-type-hash-procedure returns +the hash procedure associated with rtd, if any, otherwise #f. + +
+The procedure hash-proc should accept two arguments, the +instance for which it should compute a hash value and a hash procedure +to use to compute hash values for arbitrary fields of the instance, +and it returns a nonnegative exact integer. +A record type's hash procedure should produce the same hash value +for any two instances the record type's equality procedure considers +equal. + +
+procedure: (record-hash-procedure record)
+
+returns: the hash procedure for record, if there is one, otherwise #f
+
+libraries: (chezscheme)
+
+
record-hash-procedure traverses the inheritance chain +for the record instance in an attempt to find the most specific +type that is associated with a hash procedure, if any. +If such type is found, the hash procedure associated with the type +is returned. +Otherwise, #f is returned. + +
+thread parameter: default-record-equal-procedure
+
+libraries: (chezscheme)
+
+
This parameter determines how two record instances are compared by +equal? if neither has a type-specific equality procedure. +When the parameter has the value #f (the default), equal? +compares the instances with eq?, i.e., there is no attempt at +determining structural equivalence. +Otherwise, the parameter's value must be a procedure, and equal? +invokes that procedure to compare the instances, passing it three arguments: +the two instances and a procedure that should be used to recursively +compare arbitrary values within the instances. + +
+thread parameter: default-record-hash-procedure
+
+libraries: (chezscheme)
+
+
This parameter determines the hash procedure used when equal-hash +is called on a record instance and the instance does not have a type-specific +hash procedure. +When the parameter has the value #f (the default), equal-hash +returns a value that is independent of the record type and contents +of the instance. +Otherwise, the parameter's value must be a procedure, and equal-hash +invokes the procedure to compute the instance's hash value, passing it +the record instance and a procedure to invoke to recursively compute +hash values for arbitrary values contained within the record. +The procedure should return a nonnegative exact integer, and the +return value should be the same for any two instances the default +equal procedure considers equivalent. + +
+ +
+In addition to the Revised6 Report record-type creation and definition +mechanisms, which are described in Chapter 9 of The Scheme Programming Language, 4th Edition, +Chez Scheme continues to support pre-R6RS mechanisms for creating new +data types, or record types, with fixed sets of named fields. +Many of the procedures described in this section are available only when +imported from the (chezscheme csv7) library. + +
+Code intended to be portable should use the R6RS mechanism instead. + +
+Records may be defined via the define-record syntactic form or +via the make-record-type procedure. +The underlying representation of records and record-type descriptors is the +same for the Revised6 Report mechanism and the alternative mechanism. +Record types created by one can be used as parent record types for the +other via the procedural mechanisms, though not via the syntactic mechanisms. + + +
+The syntactic (define-record) +interface is the most commonly used interface. +Each define-record form defines a constructor +procedure for records of the new type, a type predicate that returns +true only for records of the new type, an access procedure for each field, +and an assignment procedure for each mutable field. +For example, + +
+ +
(define-record point (x y)) +
creates a new point record type with two fields, x +and y, and defines the following procedures: + +
+
+(make-point x y) | constructor |
+(point? obj) | predicate |
+(point-x p) | accessor for field x |
+(point-y p) | accessor for field y |
+(set-point-x! p obj) | mutator for field x |
+(set-point-y! p obj) | mutator for field y + |
+The names of these procedures follow a regular naming convention by +default, but the programmer can override the defaults if desired. +define-record allows the programmer to control which fields +are arguments to the generated constructor procedure and which +are explicitly initialized by the constructor procedure. +Fields are mutable by default, but may be declared immutable. +Fields can generally contain any Scheme value, but the internal +representation of each field may be specified, which places implicit +constraints on the type of value that may be stored there. +These customization options are covered in the formal description +of define-record later in this section. + +
+The procedural (make-record-type) interface may be used to +implement interpreters that must handle define-record forms. +Each call to make-record-type returns a record-type +descriptor representing the record type. +Using this record-type descriptor, programs may generate constructors, +type predicates, field accessors, and field mutators dynamically. +The following code demonstrates how the procedural interface might +be used to create a similar point record type and associated +definitions. + +
+ +
(define point (make-record-type "point" '(x y)))
+
+(define make-point (record-constructor point))
+
+(define point? (record-predicate point))
+
+(define point-x (record-field-accessor point 'x))
+
+(define point-y (record-field-accessor point 'y))
+
+(define set-point-x! (record-field-mutator point 'x))
+
+(define set-point-y! (record-field-mutator point 'y))
+
The procedural interface is more flexible than the syntactic interface, +but this flexibility can lead to less readable programs and +compromises the compiler's ability to generate efficient code. +Programmers should use the syntactic interface whenever it suffices. + +
+A record-type descriptor may also be extracted from an instance +of a record type, whether the record type was produced by +define-record or make-record-type, and the extracted +descriptor may also be used to produce constructors, predicates, +accessors, and mutators, with a few limitations noted in the description +of record-type-descriptor below. +This is a powerful feature that permits the coding of portable printers +and object inspectors. +For example, the printer employs this feature in its default record +printer, and the inspector uses it to allow inspection and mutation of +system- and user-defined records during debugging. + +
+A parent record +may be specified in the define-record syntax or as an optional +argument to make-record-type. +A new record inherits the parent record's fields, and each instance +of the new record type is considered to be an instance of the parent +type as well, so that accessors and mutators for the parent type may +be used on instances of the new type. + +
+Record +type definitions may be classified as either generative or nongenerative. +A new type results for each generative record definition, +while only one type results for all occurrences of a given +nongenerative record definition. +This distinction is important semantically since record accessors +and setters are applicable only to objects with the same type. + +
+Syntactic (define-record) record definitions are +expand-time generative by default, which means that a new +record is created when the code is expanded. +Expansion happens once for each form prior to compilation or +interpretation, as when it is entered interactively, loaded from source, +or compiled by compile-file. +As a result, multiple evaluations of a single define-record +form, e.g., in the body of a procedure called multiple times, always +produce the same record type. + +
+Separate define-record forms +usually produce different types, even if the forms are textually +identical. +The only exception occurs when the name of a record is specified as +a generated symbol, or gensym (page 170). +Multiple copies of a record definition whose name is given by a gensym +always produce the same record type; i.e., such definitions are +nongenerative. +Each copy of the record definition must contain the same fields and field +modifiers in the same order; an exception is raised with condition-type +&assertion when two differing +record types with the same generated name are loaded into the same +Scheme process. + +
+Procedural (make-record-type) record definitions are +run-time generative by default. +That is, each call to make-record-type usually produces a new +record type. +As with the syntactic interface, +the only exception occurs when the name of the record is specified +as a gensym, in which case the record type is +fully nongenerative. + +
+By default, a record is printed with the syntax + +
+ +
#[type-name field ...] +
where field ... are the printed representations of +the contents of the fields of the record, and +type-name is a generated symbol, or gensym +(page 170), that uniquely identifies the record type. +For nongenerative records, type-name is the gensym +provided by the program. +Otherwise, it is a gensym whose "pretty" name +(page 170) is the name given to the record by +define-record or make-record-type. + +
+The default printing of records of a given type may be overridden +with record-writer. + +
+The default syntax may be used as input to the reader as well, as long +as the corresponding record type has already been defined in the Scheme +session in which the read occurs. +The parameter record-reader may be used to specify a +different name to be recognized by the reader in place of the +generated name. +Specifying a different name in this manner also changes the name used +when the record is printed. +This reader extension is disabled in an input stream after #!r6rs +has been seen by the reader, unless #!chezscheme has been seen +more recently. + +
+The mark (#n=) and reference (#n#) +syntaxes may be used within the record syntax, with the result +of creating shared or cyclic structure as desired. +All cycles must be resolvable, however, without mutation of an +immutable record field. +That is, any cycle must contain at least one pointer through a +mutable field, whether it is a mutable record field or a mutable +field of a built-in object type such as a pair or vector. + +
+When the parameter print-record is set to #f, records +are printed using the simpler syntax + +
+ +
#<record of type name> +
where name is the "pretty" name of the record (not the full +gensym) or the reader name first assigned to the record +type. + + + +
+syntax: (define-record name (fld1 ...) ((fld2 init) ...) (opt ...))
+
syntax: (define-record name parent (fld1 ...) ((fld2 init) ...) (opt ...))
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A define-record form is a definition and may appear anywhere +and only where other definitions may appear. + +
+define-record creates a new record type containing a specified +set of named fields and defines a set of procedures for creating and +manipulating instances of the record type. + +
+name must be an identifier. +If name is a generated symbol (gensym), the record definition is +nongenerative, otherwise it is expand-time generative. +(See the discussion of generativity earlier in this section.) + +
+Each fld must be an identifier field-name, or it must take +the form + +
+ +
(class type field-name) +
where class and type are optional and +field-name is an identifier. +class, if present, must be the keyword immutable +or the keyword mutable. +If the immutable class specifier is present, the field is +immutable; otherwise, the field is mutable. +type, if present, specifies how the field is represented, +as described below. + +
+
+If a type is specified, the field can contain objects only of the +specified type. +If no type is specified, the field is of type ptr, +meaning that it can contain any Scheme object. + +
+The field identifiers name the fields of the record. +The values of the n fields described by fld1 ... are +specified by the n arguments to the generated constructor procedure. +The values of the remaining fields, fld2 ..., are +given by the corresponding expressions, init .... +Each init is evaluated within the scope of the set of field names +given by fld1 ... and each field in +fld2 ... that precedes it, as if within a +let* expression. +Each of these field names is bound to the value of the corresponding field +during initialization. + +
+If +parent is present, the record type named by parent +is the parent of the record. +The new record type inherits each of the parent record's fields, +and records of the new type are considered records of the +parent type. +If parent is not present, the parent record type is +a base record type with no fields. + +
+The following procedures are defined by define-record: + +
+
+
+
+
+ +
+If no parent record type is specified, +the constructor behaves as if defined as + +
+ +
(define make-name
+
+ (lambda (id1 ...)
+
+ (let* ([id2 init] ...)
+
+ body)))
+
where id1 ... are the names of the fields defined by +fld1 ..., +id2 ... are the names of the fields defined by +fld2 ..., +and body builds the record from the values of the identifiers +id1 ... and id2 .... + +
+If a parent record type is specified, the parent arguments appear first, +and the parent fields are inserted into the record before the child +fields. + +
+The options opt ... control the selection of names +of the generated constructor, predicate, accessors, and mutators. + +
+ +
(constructor id)
+
+(predicate id)
+
+(prefix string)
+
The option +(constructor id) causes the generated constructor's name +to be id rather than make-name. +The option (predicate id) likewise causes the generated +predicate's name to be id rather than name?. +The option (prefix string) determines the prefix +to be used in the generated accessor and mutator names in place of +name-. + +
+If no options are needed, the third subexpression, +(opt ...), may be omitted. +If no options and no fields other than those initialized by the arguments +to the +constructor procedure are needed, both the second and third subexpressions +may be omitted. +If options are specified, the second subexpression must be present, +even if it contains no field specifiers. + +
+Here is a simple example with no inheritance and no options. + +
+ +
(define-record marble (color quality))
+
+(define x (make-marble 'blue 'medium))
+
+(marble? x) #t
+
+(pair? x) #f
+
+(vector? x) #f
+
+(marble-color x) blue
+
+(marble-quality x) medium
+
+(set-marble-quality! x 'low)
+
+(marble-quality x) low
+
+
+(define-record marble ((immutable color) (mutable quality))
+
+ (((mutable shape) (if (eq? quality 'high) 'round 'unknown))))
+
+(marble-shape (make-marble 'blue 'high)) round
+
+(marble-shape (make-marble 'blue 'low)) unknown
+
+(define x (make-marble 'blue 'high))
+
+(set-marble-quality! x 'low)
+
+(marble-shape x) round
+
+(set-marble-shape! x 'half-round)
+
+(marble-shape x) half-round
+
The following example illustrates inheritance. + +
+ +
(define-record shape (x y))
+
+(define-record point shape ())
+
+(define-record circle shape (radius))
+
+
+(define a (make-point 7 -3))
+
+(shape? a) #t
+
+(point? a) #t
+
+(circle? a) #f
+
+
+(shape-x a) 7
+
+(set-shape-y! a (- (shape-y a) 1))
+
+(shape-y a) -4
+
+
+(define b (make-circle 7 -3 1))
+
+(shape? b) #t
+
+(point? b) #f
+
+(circle? b) #t
+
+
+(circle-radius b) 1
+
+(circle-radius a) exception: not of type circle
+
+
+(define c (make-shape 0 0))
+
+(shape? c) #t
+
+(point? c) #f
+
+(circle? c) #f
+
This example demonstrates the use of options: + +
+ +
(define-record pair (car cdr)
+
+ ()
+
+ ((constructor cons)
+
+ (prefix "")))
+
+
+(define x (cons 'a 'b))
+
+(car x) a
+
+(cdr x) b
+
+(pair? x) #t
+
+
+(pair? '(a b c)) #f
+
+x #[#{pair bdhavk1bwafxyss1-a} a b]
+
This example illustrates the use a specified reader name, immutable +fields, and the graph mark and reference syntax. + +
+ +
(define-record triple ((immutable x1) (mutable x2) (immutable x3)))
+
+(record-reader 'triple (type-descriptor triple))
+
+
+(let ([t '#[triple #1=(1 2) (3 4) #1#]])
+
+ (eq? (triple-x1 t) (triple-x3 t))) #t
+
+(let ([x '(#1=(1 2) . #[triple #1# b c])])
+
+ (eq? (car x) (triple-x1 (cdr x)))) #t
+
+(let ([t #[triple #1# (3 4) #1=(1 2)]])
+
+ (eq? (triple-x1 t) (triple-x3 t))) #t
+
+(let ([t '#1=#[triple a #1# c]])
+
+ (eq? t (triple-x2 t))) #t
+
+(let ([t '#1=(#[triple #1# b #1#])])
+
+ (and (eq? t (triple-x1 (car t)))
+
+ (eq? t (triple-x1 (car t))))) #t
+
Cycles established with the mark and reference syntax can be +resolved only if a mutable record field or mutable location +of some other object is involved the cycle, as in the last +two examples above. +An exception is raised with condition type &lexical if only +immutable fields are involved. + +
+ +
'#1=#[triple #1# (3 4) #1#] exception +
The following example demonstrates +the use of nongenerative record definitions. + +
+ +
(module A (point-disp)
+
+ (define-record #{point bdhavk1bwafxyss1-b} (x y))
+
+ (define square (lambda (x) (* x x)))
+
+ (define point-disp
+
+ (lambda (p1 p2)
+
+ (sqrt (+ (square (- (point-x p1) (point-x p2)))
+
+ (square (- (point-y p1) (point-y p2))))))))
+
+
+(module B (base-disp)
+
+ (define-record #{point bdhavk1bwafxyss1-b} (x y))
+
+ (import A)
+
+ (define base-disp
+
+ (lambda (p)
+
+ (point-disp (make-point 0 0) p))))
+
+
+(let ()
+
+ (import B)
+
+ (define-record #{point bdhavk1bwafxyss1-b} (x y))
+
+ (base-disp (make-point 3 4))) 5
+
This works even if the different program components are loaded from +different source files or are compiled separately and loaded from +different object files. + +
+syntax: predicate
+
syntax: prefix
+
syntax: constructor
+
+libraries: (chezscheme)
+
+
These identifiers are auxiliary keywords for define-record. +It is a syntax violation to reference these identifiers except in +contexts where they are recognized as auxiliary keywords. +mutable and immutable are also auxiliary keywords for +define-record, shared with the Revised6 Report +define-record-type. + + +
+syntax: (type-descriptor name)
+
+returns: the record-type descriptor associated with name
+
+libraries: (chezscheme)
+
+
name must name a record type defined by define-record +or define-record-type. + +
+This form is equivalent to the Revised6 Report +record-type-descriptor form. + +
+The record-type descriptor is useful for overriding the default +read and write syntax using record-reader and +record-writer and may also be used with the procedural +interface routines described later in this section. + +
+ +
(define-record frob ())
+
+(type-descriptor frob) #<record type frob>
+
procedure: (record-reader name)
+
+returns: the record-type descriptor associated with name
+
procedure: (record-reader rtd)
+
+returns: the first name associated with rtd
+
procedure: (record-reader name rtd)
+
+returns: unspecified
+
procedure: (record-reader name #f)
+
+returns: unspecified
+
procedure: (record-reader rtd #f)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
name must be a symbol, and rtd must be a +record-type descriptor. + +
+With one argument, record-reader is used to retrieve the record +type associated with a name or name associated with a record type. +If no association has been created, record-reader returns +#f + +
+With arguments name and rtd, record-reader registers +rtd as the record-type descriptor to be used whenever the +read procedure encounters a record named by name and +printed in the default record syntax. + +
+With arguments name and #f, record-reader removes +any association for name to a record-type descriptor. +Similarly, with arguments rtd and #f, record-reader +removes any association for rtd to a name. + +
+ +
(define-record marble (color quality))
+
+(define m (make-marble 'blue 'perfect))
+
+m #[#{marble bdhavk1bwafxyss1-c} blue perfect]
+
+
+(record-reader (type-descriptor marble)) #f
+
+(record-reader 'marble) #f
+
+
+(record-reader 'marble (type-descriptor marble))
+
+(marble-color '#[marble red miserable]) red
+
+
+(record-reader (type-descriptor marble)) marble
+
+(record-reader 'marble) #<record type marble>
+
+
+(record-reader (type-descriptor marble) #f)
+
+(record-reader (type-descriptor marble)) #f
+
+(record-reader 'marble) #f
+
+
+(record-reader 'marble (type-descriptor marble))
+
+(record-reader 'marble #f)
+
+(record-reader (type-descriptor marble)) #f
+
+(record-reader 'marble) #f
+
The introduction of a record reader also changes the default +printing of records. +The printer always chooses the reader name first assigned +to the record, if any, in place of the unique record name, as this +continuation of the example above demonstrates. + +
+ +
(record-reader 'marble (type-descriptor marble))
+
+(make-marble 'pink 'splendid) #[marble pink splendid]
+
procedure: (record-writer rtd)
+
+returns: the record writer associated with rtd
+
procedure: (record-writer rtd procedure)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
rtd must be a record-type descriptor, and procedure should +accept three arguments, as described below. + +
+When passed only one argument, record-writer returns the +record writer associated with rtd, which is initially the +default record writer for all records. +The default print method prints all records in a uniform syntax that +includes the generated name for the record +and the values of each of the fields, as described in the introduction +to this section. + +
+When passed two arguments, record-writer establishes a +new association between rtd and procedure so that +procedure will be used by the printer in place of the default +printer for records of the given type. +The printer passes procedure three arguments: +the record r, a port p, and a procedure wr that +should be used to write out the values of arbitrary Scheme objects that +the print method chooses to include in the printed representation of the +record, e.g., values of the record's fields. + +
+ +
(define-record marble (color quality))
+
+(define m (make-marble 'blue 'medium))
+
+
+m #[#{marble bdhavk1bwafxyss1-d} blue medium]
+
+
+(record-writer (type-descriptor marble)
+
+ (lambda (r p wr)
+
+ (display "#<" p)
+
+ (wr (marble-quality r) p)
+
+ (display " quality " p)
+
+ (wr (marble-color r) p)
+
+ (display " marble>" p)))
+
+
+m #<medium quality blue marble>
+
The record writer is used only when print-record is true +(the default). +When the parameter print-record is set to #f, records +are printed using a compressed syntax that identifies only the type +of record. + +
+ +
(parameterize ([print-record #f])
+
+ (format "~s" m)) "#<record of type marble>"
+
A print method may be called more than once during the printing of a +single record to support cycle detection and graph printing +(see print-graph), +so print +methods that perform side effects other than printing to the given +port are discouraged. +Whenever a print method is called more than once during the printing +of a single record, in all but one call, a generic "bit sink" port +is used to suppress output automatically so that only one copy of +the object appears on the actual port. +In order to avoid confusing the cycle detection and graph printing +algorithms, a print method should always produce the same printed +representation for each object. +Furthermore, a print method should normally use the supplied procedure +wr to print subobjects, though atomic values, such as strings +or numbers, may be printed by direct calls to display or +write or by other means. + +
+ +
(let ()
+
+ (define-record ref () ((contents 'nothing)))
+
+ (record-writer (type-descriptor ref)
+
+ (lambda (r p wr)
+
+ (display "<" p)
+
+ (wr (ref-contents r) p)
+
+ (display ">" p)))
+
+ (let ([ref-lexive (make-ref)])
+
+ (set-ref-contents! ref-lexive ref-lexive)
+
+ ref-lexive)) #0=<#0#>
+
Print methods need not be concerned with handling nonfalse values of +the parameters +print-level. +The printer handles print-level automatically even when +user-defined print procedures are used. +Since records typically contain a small, fixed number of fields, it +is usually possible to ignore nonfalse values of +print-length as well. + +
+ +
(print-level 3)
+
+(let ()
+
+ (define-record ref () ((contents 'nothing)))
+
+ (record-writer (type-descriptor ref)
+
+ (lambda (r p wr)
+
+ (display "<" p)
+
+ (wr (ref-contents r) p)
+
+ (display ">" p)))
+
+ (let ([ref-lexive (make-ref)])
+
+ (set-ref-contents! ref-lexive ref-lexive)
+
+ ref-lexive)) <<<<#[...]>>>>
+
thread parameter: print-record
+
+libraries: (chezscheme)
+
+
This parameter controls the printing of records. +If set to true (the default) the record writer associated with a +record type is used to print records of that type. +If set to false, all records are printed with the syntax +#<record of type name>, where name is the +name of the record type as returned by record-type-name. + + +
+procedure: (make-record-type type-name fields)
+
procedure: (make-record-type parent-rtd type-name fields)
+
+returns: a record-type descriptor for a new record type
+
+libraries: (chezscheme)
+
+
make-record-type creates a new data type and returns a +record-type descriptor, a value representing the new data type. +The new type is disjoint from all others. + +
+If present, parent-rtd must be a record-type descriptor. + +
+type-name must be a string or gensym. +If type-name is a string, a new record type is generated. +If type-name is a gensym, a new record type is generated only +if one with the same gensym has not already been defined. +If one has already been defined, the parent and fields must be identical +to those of the existing record type, and the +existing record type is used. +If the parent and fields are not identical, an exception is raised with +condition-type &assertion. + +
+fields must be a list of field descriptors, each of which +describes one field of instances of the new record type. +A field descriptor is either a symbol or a list in the following form: + +
+ +
(class type field-name) +
where class and type are optional. +field-name must be a symbol. +class, if present, must be the symbol immutable or +the symbol mutable. +If the immutable class-specifier is present, the field is +immutable; otherwise, the field is mutable. +type, if present, specifies how the field is represented. +The types are the same as those given in the description +of define-record on page 195. + +
+If a type is specified, the field can contain objects only of the +specified type. +If no type is specified, the field is of type ptr, +meaning that it can contain any Scheme object. + +
+The behavior of a program that modifies the string type-name +or the list fields or any of its sublists is unspecified. + +
+The record-type descriptor may be passed as an argument to any of the +Revised6 Report procedures + +
+
+ +
+or to the Chez Scheme variants + +
+
+ +
+to obtain procedures for creating and manipulating records of the +new type. + +
+ +
(define marble
+
+ (make-record-type "marble"
+
+ '(color quality)
+
+ (lambda (r p wr)
+
+ (display "#<" p)
+
+ (wr (marble-quality r) p)
+
+ (display " quality " p)
+
+ (wr (marble-color r) p)
+
+ (display " marble>" p))))
+
+(define make-marble
+
+ (record-constructor marble))
+
+(define marble?
+
+ (record-predicate marble))
+
+(define marble-color
+
+ (record-field-accessor marble 'color))
+
+(define marble-quality
+
+ (record-field-accessor marble 'quality))
+
+(define set-marble-quality!
+
+ (record-field-mutator marble 'quality))
+
+(define x (make-marble 'blue 'high))
+
+(marble? x) #t
+
+(marble-quality x) high
+
+(set-marble-quality! x 'low)
+
+(marble-quality x) low
+
+x #<low quality blue marble>
+
The order in which the fields appear in fields is important. +While field names are generally distinct, it is permissible for one field +name to be the same as another in the list of fields or the same as +an inherited name. +In this case, field ordinals +must be used to select fields in calls to record-field-accessor +and record-field-mutator. +Ordinals range from zero through one less than the number of fields. +Parent fields come first, if any, followed by the fields in +fields, in the order given. + +
+ +
(define r1 (make-record-type "r1" '(t t)))
+
+(define r2 (make-record-type r1 "r2" '(t)))
+
+(define r3 (make-record-type r2 "r3" '(t t t)))
+
+
+(define x ((record-constructor r3) 'a 'b 'c 'd 'e 'f))
+
+((record-field-accessor r3 0) x) a
+
+((record-field-accessor r3 2) x) c
+
+((record-field-accessor r3 4) x) e
+
+((record-field-accessor r3 't) x) unspecified
+
procedure: (record-constructor rcd)
+
procedure: (record-constructor rtd)
+
+returns: a constructor for records of the type represented by rtd
+
+libraries: (chezscheme)
+
+
Like the Revised6 Report version of this procedure, this procedure +may be passed a record-constructor descriptor, rcd, which determines +the behavior of the constructor. +It may also be passed a record-type descriptor, rtd, in which +case the constructor accepts as many arguments as there are fields in the +record; these arguments are the initial values of the fields in the +order given when the record-type descriptor was created. + + +
+procedure: (record-field-accessor rtd field-id)
+
+returns: an accessor for the identified field
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor, field-id must be +a symbol or field ordinal, i.e., a nonnegative exact integer less than +the number of fields of the given record type. +The specified field must be accessible. + +
+The generated accessor expects one argument, which must be a record of +the type represented by rtd. +It returns the contents of the specified field of the record. + + +
+procedure: (record-field-accessible? rtd field-id)
+
+returns: #t if the specified field is accessible, otherwise #f
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor, field-id must be +a symbol or field ordinal, i.e., a nonnegative exact integer less than +the number of fields of the given record type. + +
+The compiler is free to eliminate a record field if it can prove that +the field is not accessed. +In making this determination, the compiler is free to ignore the +possibility that an accessor might be created from a record-type +descriptor obtained by calling record-type-descriptor on an +instance of the record type. + + +
+procedure: (record-field-mutator rtd field-id)
+
+returns: a mutator for the identified field
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor, field-id must be +a symbol or field ordinal, i.e., a nonnegative exact integer less than +the number of fields of the given record type. +The specified field must be mutable. + +
+The mutator expects two arguments, r and obj. +r must be a record of the type represented by rtd. +obj must be a value that is compatible with the type declared for +the specified field when the record-type descriptor was created. +obj is stored in the specified field of the record. + + +
+procedure: (record-field-mutable? rtd field-id)
+
+returns: #t if the specified field is mutable, otherwise #f
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor, field-id must be +a symbol or field ordinal, i.e., a nonnegative exact integer less than +the number of fields of the given record type. + +
+Any field declared immutable is immutable. +In addition, +the compiler is free to treat a field as immutable if it can prove that +the field is never assigned. +In making this determination, the compiler is free to ignore the +possibility that a mutator might be created from a record-type +descriptor obtained by calling record-type-descriptor on an +instance of the record type. + + +
+procedure: (record-type-name rtd)
+
+returns: the name of the record-type represented by rtd
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor. + +
+The name is a always a string. +If a gensym is provided as the record-type name in a +define-record form or make-record-type call, the result +is the "pretty" name of the gensym (see 7.11). + +
+ +
(record-type-name (make-record-type "empty" '())) "empty"
+
+
+(define-record #{point bdhavk1bwafxyss1-b} (x y))
+
+(define p (type-descriptor #{point bdhavk1bwafxyss1-b}))
+
+(record-type-name p) "point"
+
procedure: (record-type-symbol rtd)
+
+returns: the generated symbol associated with rtd
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor. + +
+ +
(define e (make-record-type "empty" '()))
+
+(record-type-symbol e) #{empty bdhavk1bwafxyss1-e}
+
+
+(define-record #{point bdhavk1bwafxyss1-b} (x y))
+
+(define p (type-descriptor #{point bdhavk1bwafxyss1-b}))
+
+(record-type-symbol p) #{point bdhavk1bwafxyss1-b}
+
procedure: (record-type-field-names rtd)
+
+returns: a list of field names of the type represented by rtd
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor. +The field names are symbols. + +
+See also the Revised6 Report version of this prodecure (exported from +the (chezscheme) library) which returns a vector. + +
+ +
(define-record triple ((immutable x1) (mutable x2) (immutable x3)))
+
+(record-type-field-names (type-descriptor triple)) (x1 x2 x3)
+
procedure: (record-type-field-decls rtd)
+
+returns: a list of field declarations of the type represented by rtd
+
+libraries: (chezscheme csv7)
+
+
rtd must be a record-type descriptor. +Each field declaration has the following form: + +
+ +
(class type field-name) +
where class, type, and field-name are as described +under make-record-type. + +
+ +
(define-record shape (x y))
+
+(define-record circle shape (radius))
+
+
+(record-type-field-decls
+
+ (type-descriptor circle)) ((mutable ptr x)
+
+ (mutable ptr y)
+
+ (mutable ptr radius))
+
procedure: (record? obj)
+
+returns: #t if obj is a record, otherwise #f
+
procedure: (record? obj rtd)
+
+returns: #t if obj is a record of the given type, otherwise #f
+
+libraries: (chezscheme)
+
+
If present, rtd must be a record-type descriptor. + +
+A record is "of the given type" if it is an instance of the record +type or one of its ancestors. +The predicate generated by record-predicate for a +record-type descriptor rtd is equivalent to the following. + +
+ +
(lambda (x) (record? x rtd)) +
procedure: (record-instance? obj rtd)
+
+returns: #t if obj is a record of the given type, otherwise #f
+
+libraries: (chezscheme)
+
+
obj must be a record, and rtd must be a record-type descriptor. + +
+The result is the same as for a two-argument record? call, +but obj is constrained to be a record. In unsafe mode, +record-instance? might be faster than record?. + +
+procedure: (record-type-descriptor rec)
+
+returns: the record-type descriptor of rec
+
+libraries: (chezscheme csv7)
+
+
rec must be a record. +This procedure is intended for use in the definition of portable printers +and debuggers. +For records created with make-record-type, +it may not be the same as the descriptor returned by +make-record-type. +See the comments about field accessibility and mutability under +record-field-accessible? and +record-field-mutable? above. + +
+This procedure is equivalent to the Revised6 Report record-rtd +procedure. + +
+ +
(define rtd (make-record-type "frob" '(blit blat)))
+
+rtd #<record type frob>
+
+(define x ((record-constructor rtd) 1 2))
+
+(record-type-descriptor x) #<record type frob>
+
+(eq? (record-type-descriptor x) rtd) unspecified
+
procedure: (make-record-type-descriptor name parent uid s? o? fields)
+
+returns: a record-type descriptor for a new record type
+
+libraries: (chezscheme)
+
+
Like the Revised6 Report version of this procedure, but fields +is also allowed to be a pair of non-negative integers, in which case the +new record type has anonymous fields. The car of fields +is a field count, and it is added to any fields present in +parent to determine the record type's total number of fields. +The cdr of fields must be an exact non-negative integer +that is treated as a bit array; a 1 bit indicates the the +corresponding field among new fields is mutable. The total number of +fields in a record type must be a fixnum. + +
+If parent is a record type descriptor, it must also have +anonymous fields. The resulting anonymous-field record type can only +be the parent of a record type with anonymous fields. + +
+When a function like record-type-field-names is applied to an +anonymous-field record type, the field names are all reported as +field. + +
+procedure: (record-type-has-named-fields? rtd)
+
+returns: a boolean indicating whether rtd has named fields
+
+libraries: (chezscheme)
+
+
rtd must be a record-type descriptor. + + +
+ +
+procedure: (procedure-arity-mask proc)
+
+returns: an exact integer bitmask identifying the accepted argument counts of proc
+
+libraries: (chezscheme)
+
+
The bitmask is represented as two's complement number with the bit +at each index n set if and only if proc accepts n +arguments. + +
+The two's complement encoding implies that if proc accepts +n or more arguments, the encoding is a negative number, +since all the bits from n and up are set. For example, if +proc accepts any number of arguments, the two's complement +encoding of all bits set is -1. + +
+ +
(procedure-arity-mask (lambda () 'none)) 1
+
+(procedure-arity-mask car) 2
+
+(procedure-arity-mask (case-lambda [() 'none] [(x) x])) 3
+
+(procedure-arity-mask (lambda x x)) -1
+
+(procedure-arity-mask (case-lambda [() 'none] [(x y . z) x])) -3
+
+(procedure-arity-mask (case-lambda)) 0
+
+(logbit? 1 (procedure-arity-mask pair?)) #t
+
+(logbit? 2 (procedure-arity-mask pair?)) #f
+
+(logbit? 2 (procedure-arity-mask cons)) #t
+
procedure: (make-wrapper-procedure proc arity-mask data)
+
procedure: (make-arity-wrapper-procedure proc arity-mask data)
+
+returns: a procedure that behaves like proc, but with the given arity-mask
+
+libraries: (chezscheme)
+
+
proc must be a procedure, and arity-mask must be an exact +integer representing an arity mask in the sense of procedure-arity-mask. + +
+The resulting procedure behaves the same as proc, except that +procedure-arity-mask on the result procedure returns +arity-mask. When the result of make-arity-wrapper-procedure +is called, the given arguments are compared to the given arity mask, and an error is reported +if the argument count does not match. The result of make-wrapper-procedure, +in contrast, does not enforce the given arity mask. + +
+The data argument can be any value, and it can be retrieved from +the result procedure with wrapper-procedure-data. + +
+ +
(define vector3 (make-wrapper-procedure vector 8 #f))
+
+(procedure-arity-mask vector) ; => -1
+
+(procedure-arity-mask vector3) ; => 8
+
+(vector3 1 2 3) #(1 2 3)
+
+(vector3 1 2) #(1 2)
+
+(define vector3/check (make-arity-wrapper-procedure vector 8 #f))
+
+(vector3/check 1 2 3) #(1 2 3)
+
+(vector3/check 1 2) exception
+
procedure: (wrapper-procedure? obj)
+
+returns: #t if obj is a wrapper procedure, #f otherwise
+
+libraries: (chezscheme)
+
+
Determines whether obj is a wrapper procedure produced by either +make-wrapper-procedure or make-arity-wrapper-procedure. + +
+ +
(wrapper-procedure? vector) ; => #f
+
+(define vector3 (make-wrapper-procedure vector 8 #f))
+
+(wrapper-procedure? vector3) ; => #t
+
procedure: (wrapper-procedure-procedure w-proc)
+
+returns: the procedure wrapped by the wrapper procedure proc
+
+libraries: (chezscheme)
+
+
w-proc must be a wrapper procedure produced by either +make-wrapper-procedure or make-arity-wrapper-procedure. + + +
+ +
(define vector3 (make-wrapper-procedure vector 8 'my-data))
+
+(wrapper-procedure-procedure vector3) ; => #<procedure vector>
+
procedure: (wrapper-procedure-data w-proc)
+
+returns: the data stored with the wrapper procedure proc
+
+libraries: (chezscheme)
+
+
w-proc must be a wrapper procedure produced by either +make-wrapper-procedure or make-arity-wrapper-procedure. + + +
+ +
(define vector3 (make-wrapper-procedure vector 8 'my-data))
+
+(wrapper-procedure-data vector3) ; => 'my-data
+
procedure: (set-wrapper-procedure-data! w-proc data)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
w-proc must be a wrapper procedure produced by either +make-wrapper-procedure or make-arity-wrapper-procedure. + +
+Changes the data stored in w-proc to data. + +
+ +
(define vector3 (make-wrapper-procedure vector 8 'my-data))
+
+(wrapper-procedure-data vector3) ; => 'my-data
+
+(set-wrapper-procedure-data! vector3 'my-new-data)
+
+(wrapper-procedure-data vector3) ; => 'my-new-data
+
procedure: (set-wrapper-procedure-procedure! w-proc proc)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
w-proc must be a wrapper procedure produced by either +make-wrapper-procedure or +make-arity-wrapper-procedure, and proc must be +a procedure. + +
+Changes w-proc so that it behaves the same as proc, leaving the
+results of
+ (procedure-arity-mask w-proc) and
+(wrapper-procedure-data w-proc) unchanged.
+
+
+
+ +
(define vector3 (make-wrapper-procedure vector 8 'my-data))
+
+(vector3 1 2 3) ; => #(1 2 3)
+
+(set-wrapper-procedure-procedure! vector3 list)
+
+(vector3 1 2 3) ; => (1 2 3)
+
procedure: (procedure-known-single-valued? proc)
+
+returns: a boolean indicating whether proc is known to always produce a single value
+
+libraries: (chezscheme)
+
+
Returns an approximate classification of proc as always having a +single result value or not. The result may be #f for a procedure +that always returns a single value, but with an implementation that was too +complex for the compiler to prove that fact. The result is #t only +for a procedure that always produces a single result value. + + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/preface.html b/csug10.0/preface.html
new file mode 100644
index 000000000..4fd0b87bf
--- /dev/null
+++ b/csug10.0/preface.html
@@ -0,0 +1,112 @@
+
+
+
+
+
+Chez Scheme is both a general-purpose programming language and +an implementation of that language, with supporting tools and +documentation. +As a superset of the language described in the Revised6 Report +on Scheme (R6RS), Chez Scheme supports all standard features of +Scheme, including first-class procedures, proper treatment of tail +calls, continuations, user-defined records, libraries, exceptions, +and hygienic macro expansion. +Chez Scheme supports numerous non-R6RS features. +A few of these are local and top-level modules, +local import, foreign datatypes and procedures, nonblocking I/O, +an interactive top-level, compile-time values and properties, +pretty-printing, and formatted output. + +
+The implementation includes a compiler that generates native code +for each processor upon which it runs along with a run-time system +that provides automatic storage management, foreign-language +interfaces, source-level debugging, profiling support, and an +extensive run-time library. + +
+The threaded versions of Chez Scheme support native threads, allowing +Scheme programs to take advantage of multiprocessor or multiple-core +systems. +Nonthreaded versions are also available and are faster for +single-threaded applications. +Both 32-bit and 64-bit versions are available for some platforms. +The 64-bit versions support larger heaps, while the 32-bit versions +are faster for some applications. + +
+Chez Scheme's interactive programming system includes an expression +editor that, like many shells, supports command-line editing, a history +mechanism, and command completion. +Unlike most shells that support command-line editing, the expression +editor properly supports multiline expressions. + +
+Chez Scheme is intended to be as reliable and efficient as possible, +with reliability taking precedence over efficiency if necessary. +Reliability means behaving as designed and documented. +While a Chez Scheme program can always fail to work properly +because of a bug in the program, it should never fail because of a +bug in the Chez Scheme implementation. +Efficiency means performing at a high level, consuming minimal CPU +time and memory. +Performance should be balanced across features, across run time and +compile time, and across programs and data of different sizes. +These principles guide Chez Scheme language and tool design as +well as choice of implementation technique; for example, a language +feature or debugging hook might not exist in Chez Scheme because +its presence would reduce reliability, efficiency, or both. + +
+The compiler has been rewritten for Version 9 and generates +substantially faster code than the earlier compiler at the cost of +greater compile time. +This is the primary difference between Versions 8 and 9. + +
+This book (CSUG) is a companion to The Scheme Programming +Language, 4th Edition (TSPL4). +TSPL4 serves as an introduction to and reference for R6RS, while +CSUG describes Chez Scheme features and tools that are not part +of R6RS. +For the reader's convenience, the summary of forms and index at the back +of this book contain entries from both books, with each entry from TSPL4 +marked with a "t" in front of its page number. +In the online version, the page numbers given in the summary of forms and +index double as direct links into one of the documents or the other. + +
+Additional documentation for Chez Scheme includes release notes, a +manual page, and a number of published papers and articles that describe +various aspects of the system's design and implementation. + +
+Thank you for using Chez Scheme. + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/smgmt.html b/csug10.0/smgmt.html
new file mode 100644
index 000000000..232b4001f
--- /dev/null
+++ b/csug10.0/smgmt.html
@@ -0,0 +1,1364 @@
+
+
+
+
+
+This chapter describes aspects of the storage management system and +procedures that may be used to control its operation. + +
+ +
+Scheme objects such as pairs, strings, procedures, and user-defined +records are never explicitly deallocated by a Scheme program. +Instead, the storage management system +automatically reclaims the +storage associated with an object once it proves the object is no longer +accessible. +In order to reclaim this storage, Chez Scheme employs a +garbage +collector which runs periodically as a program runs. +Starting from a set of known roots, e.g., the machine registers, +the garbage collector locates all accessible objects, +copies them (in most cases) in order to eliminate fragmentation +between accessible objects, and reclaims storage occupied by +inaccessible objects. + +
+Collections are triggered automatically by the default collect-request +handler, which is invoked via a collect-request interrupt that occurs +after approximately n bytes of storage have been allocated, where n is +the value of the parameter +collect-trip-bytes. +The default collect-request handler causes a collection by calling the +procedure collect without arguments. +The collect-request handler can be redefined by changing the value of the +parameter +collect-request-handler. +A program can also cause a collection to occur between collect-request +interrupts by calling collect directly either without or with +arguments. + +
+Chez Scheme's collector is a generation-based collector. +It segregates objects based on their age (roughly speaking, the +number of collections survived) and collects older objects less +frequently than younger objects. +Since younger objects tend to become inaccessible more quickly than +older objects, the result is that most collections take little +time. +The system also maintains a +static generation from +which storage is never reclaimed. +Objects are placed into the static generation only +when a heap is compacted (see +Scompact_heap in +Section 4.9) or when an explicitly specified +target-generation is the symbol static. +This is primarily useful after an application's permanent code and data +structures have been loaded and initialized, to reduce the overhead of +subsequent collections. + +
+Nonstatic generations are numbered starting at zero for the youngest +generation up through the current value of +collect-maximum-generation. +The storage manager places newly allocated objects into generation 0. + +
+When collect is invoked without arguments, generation 0 +objects that survive collection move to generation 1, generation 1 +objects that survive move to generation 2, and so on, except that +objects are never moved past the maximum nonstatic generation. +Objects in the maximum nonstatic generation are collected back into +the maximum nonstatic generation. +While generation 0 is collected during each collection, older +generations are collected less frequently. +An internal counter, gc-trip, is maintained to control when each +generation is collected. +Each time collect is called without arguments (as from the default +collect-request handler), gc-trip is incremented by one, and the set of +generations to be collected is determined from the current value of +gc-trip and the value of +collect-generation-radix: +with a collect-generation radix of r, the maximum collected generation +is the highest numbered generation g for which gc-trip is a +multiple of rg. +If collect-generation-radix is set to 4, the system thus +collects generation 0 every time, generation 1 every 4 times, +generation 2 every 16 times, and so on. + +
+The maximum generation mg is collected on the gc-trip schedule only +if the total amount of allocated memory before collection is k times +the total amount of allocated memory after the previous collection of +mg, where the k is the value of +collect-maximum-generation-threshold-factor. +If a collection of mg is skipped by this rule, then gc-trip is +rewound to the previous value that is a multiple of rmg-1 (so +that the next time to collect mg - 1 is potentially also a time to +collect mg). The intent of this k factor is to avoid unnecessary +traversal of long-lived objects when rapidly allocating short-lived +objects; for objects that will live until the end of a process, promoting +them to the static generation can be even more effective, but +promotion requires additional reasoning to ensure that an object is +not retained inappropriately, while the +collect-maximum-generation-threshold-factor parameter allows +the collector to adapt more automatically. + +
+When collect is invoked with arguments, the generations to be +collected and their target generations are determined by the arguments. +In addition, the first argument cg affects the value of gc-trip; +that is, gc-trip is advanced to the next rcg boundary, but +not past the next rcg+1 boundary, where r is the +value of collect-generation-radix. + +
+It is possible to make substantial adjustments in the collector's behavior +by setting the parameters described in this section. +It is even possible to completely override the collector's default strategy for +determining when each generation is collected by redefining the +collect-request handler to call collect with arguments. +For example, the programmer can redefine the handler to treat the +maximum nonstatic generation as a static generation over a long +period of time by calling collect with arguments that +prevent the maximum nonstatic generation from being collected during +that period of time. + +
+Additional information on Chez Scheme's collector can be found in the +report "Don't stop the BiBOP: Flexible and efficient +storage management for dynamically typed languages" [13]. + + +
+procedure: (collect)
+
procedure: (collect cg)
+
procedure: (collect cg max-tg)
+
procedure: (collect cg min-tg max-tg)
+
procedure: (collect cg min-tg max-tg objs)
+
+returns: a list if objs is a list, unspecified otherwise
+
+libraries: (chezscheme)
+
+
This procedure causes the storage manager to perform a garbage +collection. +collect is invoked periodically without arguments by the +default collect-request handler, but it may also be called explicitly, +e.g., from a custom collect-request handler, between phases of a +computation when collection is most likely to be successful, or +before timing a computation. +In the threaded versions of Chez Scheme, the thread that invokes +collect must be the only active thread. + +
+When called without arguments, the system determines automatically +which generations to collect and the target generation for each +collected generation as described in the lead-in to this section. + +
+When called with arguments, the system collects all and only objects +in generations less than or equal to cg (the maximum collected +generation) into the target generation or generations determined +by min-tg (the minimum target generation) and max-tg +(the maximum target generation). +Specifically, the target generation for any object in a collected +generation g is +, where +static is taken to have the value one greater +than the maximum nonstatic generation. + +
+If present, cg must be a nonnegative fixnum no greater than +the maximum nonstatic generation, i.e., the current value of the +parameter collect-maximum-generation. + +
+If present, max-tg must be a nonnegative fixnum or the symbol +static and either equal to cg or one greater than +cg, again treating static as having the value one +greater than the maximum nonstatic generation. +If max-tg is not present (but cg is), it defaults to +cg if cg is equal to the maximum target generation and +to one more than cg otherwise. + +
+If present, min-tg must be a nonnegative fixnum or the symbol +static and no greater than max-tg, again treating +static as having the value one greater than the maximum +nonstatic generation. +Unless max-cg is the same as cg, min-tg must also +be greater than cg. +If min-tg is not present (but cg is), it defaults to +the same value as max-tg. + +
+If present, objs must be either #f or a list. +If objs is a list, the collection is combined with counting as +in compute-size-increments. Counting looks through all +generations, as when 'static is the second argument to +compute-size-increments, but the returned sizes from +collect do not include any objects in a generation older than +g. Another difference is that an object later in objs is +treated as unreachable by earlier objects in objs only when the +later object is a record, thread, or procedure (including +continuations). Finally, if an object is included in objs using +a weak pair, then the object's result size is 0 unless it is reachable +from earlier objects; if the object is not reachable at all, it can be +collected. + +
+procedure: (collect-rendezvous)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Requests a garbage collection in the same way as when the system +determines that a collection should occur. All running threads are +coordinated so that one of them calls the collect-request handler, while +the other threads pause until the handler returns. If the initial +thread is active at the time of the rendezvous, it is used to call +the collect-request handler. + +
+Note that if the collect-request handler (see +collect-request-handler) does not call collect, then +collect-rendezvous does not actually perform a garbage +collection. + + +
+global parameter: collect-notify
+
+libraries: (chezscheme)
+
+
If collect-notify is set to a true value, the collector prints +a message whenever a collection is run. +collect-notify is set to #f by default. + + +
+global parameter: collect-trip-bytes
+
+libraries: (chezscheme)
+
+
This parameter determines the approximate amount of storage that is +allowed to be allocated between garbage collections. +Its value must be a positive fixnum. + +
+Chez Scheme allocates memory internally in large chunks and +subdivides these chunks via inline operations for efficiency. +The storage manager determines whether to request a collection only +once per large chunk allocated. +Furthermore, some time may elapse between when a collection is +requested by the storage manager and when the collect request is +honored, especially if interrupts are temporarily disabled via +with-interrupts-disabled +or disable-interrupts. +Thus, collect-trip-bytes is an approximate measure only. + + +
+global parameter: collect-generation-radix
+
+libraries: (chezscheme)
+
+
This parameter determines how often each generation is collected +when collect is invoked without arguments, as by the default +collect-request handler. +Its value must be a positive fixnum. +Generations are collected once every rg times a collection occurs, +where r is the +value of collect-generation-radix and g is the generation +number. + +
+Setting collect-generation-radix to one forces all generations +to be collected each time a collection occurs. +Setting collect-generation-radix to a very large number +effectively delays collection of older generations indefinitely. + + +
+global parameter: collect-maximum-generation-threshold-factor
+
+libraries: (chezscheme)
+
+
This parameter determines how often the maximum generation is collected +when collect is invoked without arguments, as by the default +collect-request handler. +Its value must be a nonnegative real number. +The maximum generation is collected only when the total amount of allocated +memory before a collection is k times the amount of memory allocated +after the most recent collection of the maximum generation, where k +is the value of collect-maximum-generation-threshold-factor. + +
+Setting collect-maximum-generation-threshold-factor to zero +causes every regularly scheduled collection of the maximum generation +to take place. Setting the value of +collect-maximum-generation-threshold-factor to a large number +can increase peak memory use by delaying collection of the maximum +generation. + + +
+global parameter: collect-maximum-generation
+
+libraries: (chezscheme)
+
+
This parameter determines the maximum nonstatic generation, hence the +total number of generations, currently in use. +Its value is an exact integer in the range 1 through 6. +When set to 1, only two nonstatic generations are used; when set to 2, +three nonstatic generations are used, and so on. +When set to 6, 7 nonstatic generations are used, plus the single +static generation for a total of 8 generations. +Increasing the number of generations effectively decreases how often old +objects are collected, potentially decreasing collection overhead but +potentially increasing the number of inaccessible objects retained in the +system and thus the total amount of memory required. + + +
+global parameter: collect-request-handler
+
+libraries: (chezscheme)
+
+
The value of collect-request-handler must be a procedure. +The procedure is invoked without arguments whenever the +system determines that a collection should occur, i.e., some time after +an amount of storage determined by the parameter +collect-trip-bytes has been allocated since the last +collection. + +
+By default, collect-request-handler simply invokes +collect without arguments. + +
+Automatic collection may be disabled by setting +collect-request-handler to a procedure that does nothing, +e.g.: + +
+ +
(collect-request-handler void) +
Collection can also be temporarily disabled using +critical-section, which prevents any interrupts from +being handled. + +
+In the threaded versions of Chez Scheme, the collect-request +handler is invoked by a single thread with all other threads +temporarily suspended. + + +
+global parameter: release-minimum-generation
+
+libraries: (chezscheme)
+
+
This parameter's value must be between 0 and the value of +collect-maximum-generation, inclusive, and defaults to the +value of collect-maximum-generation. + +
+As new data is allocated and collections occur, the storage-management +system automatically requests additional virtual memory address space +from the operating system. +Correspondingly, in the event the heap shrinks significantly, the system +attempts to return some of the virtual-memory previously obtained from +the operating system back to the operating system. +By default, the system attempts to do so only after a collection that +targets the maximum nonstatic generation. +The system can be asked to do so after collections +targeting younger generations as well by altering the value +release-minimum-generation to something less than the value +of collect-maximum-generation. +When the generation to which the parameter is set, or any older +generation, is the target generation of a collection, the storage +management system attempts to return unneeded virtual memory to the +operating system following the collection. + +
+When collect-maximum-generation is set to a new value g, +release-minimum-generation is implicitly set to g as well +if (a) the two parameters have the same value before the change, or (b) +release-minimum-generation has a value greater than g. + +
+global parameter: in-place-minimum-generation
+
+libraries: (chezscheme)
+
+
This parameter determines when the storage-management system attempts +to trade long-term space usage for the benefit of collection time and +short-term space usage. When performing a collection at a generation +at least as large as this parameter's value, objects already residing +at the generation are kept in place---unless the objects are in a +memory region where previously keeping them in place resulted in too +much fragmentation. + +
+Typically, the value of in-place-minimum-generation should +match the value of the collect-maximum-generation parameter, +but the value of this parameter can be lower to move objects even less +frequently, or it can be higher to disable attempts to keep otherwise +mobile objects in place. + +
+global parameter: heap-reserve-ratio
+
+libraries: (chezscheme)
+
+
This parameter determines the approximate amount of memory reserved (not +returned to the O/S as described in the entry for release-minimum-generation) +in proportion to the amount currently occupied, excluding areas +of memory that have been made static. +Its value must be an inexact nonnegative flonum value; if set to an exact +real value, the exact value is converted to an inexact value. +The default value, 1.0, reserves one page of memory for each currently +occupied nonstatic page. +Setting it to a smaller value may result in a smaller average virtual +memory footprint, while setting it to a larger value may result in fewer +calls into the operating system to request and free memory space. + +
+procedure: (keep-live v)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Ensures that the value produced by v is retained by the store +manager until the keep-live call is performed. This function +can be particularly useful for ensuring that an immobile object +remains in place. + + +
+ +
+Weak pairs allow programs +to maintain weak pointers to objects. +A weak pointer to an object does not prevent the object from being +reclaimed by the storage management system, but it does remain valid as +long as the object is otherwise accessible in the system. + +
+Ephemeron pairs are like weak pairs, but +ephemeron pairs combine two pointers where the second is retained only +as long as the first is retained. + +
+Guardians +allow programs to protect objects from deallocation +by the garbage collector and to determine when the objects would +otherwise have been deallocated. + +
+Weak pairs, ephemeron pairs, and guardians allow programs to retain +information about objects in separate data structures (such as hash +tables) without concern that maintaining this information will cause +the objects to remain indefinitely in the system. Ephemeron pairs +allow such data structures to retain key-value combinations +where a value may refer to its key, but the combination +can be reclaimed if neither must be saved otherwise. +In addition, guardians allow objects to be saved from deallocation +indefinitely so that they can be reused or so that clean-up or other +actions can be performed using the data stored within the objects. + +
+The implementation of guardians and weak pairs used by Chez Scheme +is described in [12]. Ephemerons are described +in [23], but the implementation in Chez Scheme +avoids quadratic-time worst-case behavior. + +
+
+procedure: (weak-cons obj1 obj2)
+
+returns: a new weak pair
+
+libraries: (chezscheme)
+
+
obj1 becomes the car and obj2 becomes the cdr of the +new pair. +Weak pairs are indistinguishable from ordinary pairs in all but two ways: + +
+
+
+ +
+The weak pointer in the car of a weak pair is just like a normal +pointer as long as the object to which it points is accessible through +a normal (nonweak) pointer somewhere in the system. +If at some point the garbage collector recognizes that there are no +nonweak pointers to the object, however, it replaces each weak pointer +to the object with the "broken weak-pointer" object, #!bwp, +and discards the object. + +
+The cdr field of a weak pair is not a weak pointer, so +weak pairs may be used to form lists of weakly held objects. +These lists may be manipulated using ordinary list-processing +operations such as length, map, and assv. +(Procedures like map that produce list structure always +produce lists formed from nonweak pairs, however, even when their input +lists are formed from weak pairs.) +Weak pairs may be altered using set-car! and set-cdr!; after +a set-car! the car field contains a weak pointer to the new +object in place of the old object. +Weak pairs are especially useful for building association pairs +in association lists or hash tables. + +
+Weak pairs are printed in the same manner as ordinary pairs; there +is no reader syntax for weak pairs. +As a result, weak pairs become normal pairs when they are written +and then read. + +
+ +
(define x (cons 'a 'b))
+
+(define p (weak-cons x '()))
+
+(car p) (a . b)
+
+
+(define x (cons 'a 'b))
+
+(define p (weak-cons x '()))
+
+(set! x '*)
+
+(collect)
+
+(car p) #!bwp
+
The latter example above may in fact return (a . b) if a +garbage collection promoting the pair into an older generation occurs +prior to the assignment of x to *. +It may be necessary to force an older generation collection to allow +the object to be reclaimed. +The storage management system guarantees only that the object +will be reclaimed eventually once all nonweak pointers to it are +dropped, but makes no guarantees about when this will occur. + + +
+procedure: (weak-pair? obj)
+
+returns: #t if obj is a weak pair, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(weak-pair? (weak-cons 'a 'b)) #t
+
+(weak-pair? (cons 'a 'b)) #f
+
+(weak-pair? "oops") #f
+
+procedure: (ephemeron-cons obj1 obj2)
+
+returns: a new ephemeron pair
+
+libraries: (chezscheme)
+
+
obj1 becomes the car and obj2 becomes the cdr of the +new pair. +Ephemeron pairs are indistinguishable from ordinary pairs in all but two ways: + +
+
+
+ +
+An ephemeron pair behaves like a weak pair, but the cdr is treated +specially in addition to the car: the cdr of an ephemeron is set to +#!bwp at the same time that the car is set to #!bwp. +Since the car and cdr fields are set to #!bwp at the same +time, then the fact that the car object may be referenced through the +cdr object does not by itself imply that car must be preserved (unlike +a weak pair); instead, the car must be saved for some reason +independent of the cdr object. + +
+Like weak pairs and other pairs, ephemeron pairs may be altered using +set-car! and set-cdr!, and ephemeron pairs are +printed in the same manner as ordinary pairs; there is no reader +syntax for ephemeron pairs. + +
+ +
(define x (cons 'a 'b))
+
+(define p (ephemeron-cons x x))
+
+(car p) (a . b)
+
+(cdr p) (a . b)
+
+
+(define x (cons 'a 'b))
+
+(define p (ephemeron-cons x x))
+
+(set! x '*)
+
+(collect)
+
+(car p) #!bwp
+
+(cdr p) #!bwp
+
+
+(define x (cons 'a 'b))
+
+(define p (weak-cons x x)) ; not an ephemeron pair
+
+(set! x '*)
+
+(collect)
+
+(car p) (a . b)
+
+(cdr p) (a . b)
+
As with weak pairs, the last two expressions of the middle example +above may in fact return (a . b) if a garbage collection +promoting the pair into an older generation occurs prior to the +assignment of x to *. In the last example above, +however, the results of the last two expressions will always be +(a . b), because the cdr of a weak pair holds a non-weak +reference, and that non-weak reference prevents the car field from becoming +#!bwp. + +
+procedure: (ephemeron-pair? obj)
+
+returns: #t if obj is a ephemeron pair, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(ephemeron-pair? (ephemeron-cons 'a 'b)) #t
+
+(ephemeron-pair? (cons 'a 'b)) #f
+
+(ephemeron-pair? (weak-cons 'a 'b)) #f
+
+(ephemeron-pair? "oops") #f
+
procedure: (bwp-object? obj)
+
+returns: #t if obj is the broken weak-pair object, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(bwp-object? #!bwp) #t
+
+(bwp-object? 'bwp) #f
+
+
+(define x (cons 'a 'b))
+
+(define p (weak-cons x '()))
+
+(set! x '*)
+
+(collect (collect-maximum-generation))
+
+(car p) #!bwp
+
+(bwp-object? (car p)) #t
+
procedure: (make-guardian)
+
procedure: (make-guardian ordered?)
+
+returns: a new guardian that is unordered unless ordered? is true
+
+libraries: (chezscheme)
+
+
Guardians are represented by procedures that encapsulate groups of +objects registered for preservation. +When a guardian is created, the group of registered objects is empty. +An object is registered with a guardian by passing the object as an +argument to the guardian: + +
+ +
(define G (make-guardian))
+
+(define x (cons 'aaa 'bbb))
+
+x (aaa . bbb)
+
+(G x)
+
It is also possible to specify a "representative" object when +registering an object. +Continuing the above example: + +
+ +
(define y (cons 'ccc 'ddd))
+
+y (ccc . ddd)
+
+(G y 'rep)
+
The group of registered objects associated with a guardian is logically +subdivided into two disjoint subgroups: a subgroup referred to +as "accessible" objects, and one referred to "inaccessible" objects. +Inaccessible objects are objects that have been proven to be +inaccessible (except through the guardian mechanism itself or through +the car field of a weak or ephemeron pair), and +accessible objects are objects that have not been proven so. +The word "proven" is important here: it may be that some objects in +the accessible group are indeed inaccessible but +that this has not yet been proven. +This proof may not be made in some cases until long after the object +actually becomes inaccessible (in the current implementation, until a +garbage collection of the generation containing the object occurs). + +
+Objects registered with a guardian are initially placed in the accessible +group and are moved into the inaccessible group at some point after they +become inaccessible. +Objects in the inaccessible group are retrieved by invoking the guardian +without arguments. +If there are no objects in the inaccessible group, the guardian returns +#f. +Continuing the above example: + +
+ +
(G) #f
+
+(set! x #f)
+
+(set! y #f)
+
+(collect)
+
+(G) (aaa . bbb) ; this might come out second
+
+(G) rep ; and this first
+
+(G) #f
+
The initial call to G returns #f, since the pairs bound +to x and y are the +only object registered with G, and the pairs are still accessible +through those bindings. +When collect is called, the objects shift into the inaccessible group. +The two calls to G therefore return the pair previously bound to +x and the representative of the pair previously bound to y, +though perhaps in the other order from the one shown. +(As noted above for weak pairs, the call to collect may not actually be +sufficient to prove the object inaccessible, if the object has +migrated into an older generation.) + +
+Although an object registered without a representative and returned from +a guardian has been proven otherwise +inaccessible (except possibly via the car field of a weak or ephemeron pair), it has +not yet been reclaimed by the storage management system and will not be +reclaimed until after the last nonweak pointer to it within or outside +of the guardian system has been dropped. +In fact, objects that have been retrieved from a guardian have no +special status in this or in any other regard. +This feature circumvents the problems that might otherwise arise with +shared or cyclic structure. +A shared or cyclic structure consisting of inaccessible objects is +preserved in its entirety, and each piece registered for preservation +with any unordered guardian is placed in the inaccessible set for that guardian. +The programmer then has complete control over the order in which pieces +of the structure are processed. + +
+An ordered guardian, as created by providing a true value for +ordered?, treats an object as inaccessible only when it is not +accessible from any representative of an object that is in any +usable guardian's inaccessible group and that is distinct from the +object itself. Cycles among objects registered with ordered guardians +can never become inaccessible unless the cycle is broken or some of +the relevant guardians are dropped by the program, and each +registered object's representative (if different from the object) can +contribute to such cycles. If an object is registered to an ordered +guardian with a representative that is different from the object but +that references the object, then the object is in a cycle and will not +become inaccessible unless the reference from the representative to +the object is destroyed. Weak references do not count, so objects that +form a cycle only when counting weak references may still become +inaccessible. + +
+An object may be registered with a guardian more than once, in which +case it will be retrievable more than once: + +
+ +
(define G (make-guardian))
+
+(define x (cons 'aaa 'bbb))
+
+(G x)
+
+(G x)
+
+(set! x #f)
+
+(collect)
+
+(G) (aaa . bbb)
+
+(G) (aaa . bbb)
+
It may also be registered with more than one guardian, and guardians +themselves can be registered with other guardians. If an object +is registered to both an unordered guardian and an ordered guardian +and neither guardian is dropped, the object can become +inaccessible for the ordered guardian only after it has been +determined inaccessible for the unordered guardian and then +retrieved and dropped again by the program. + +
+An object that has been registered with a guardian without a +representative and placed in +the car field of a weak or ephemeron pair remains in the car field of the +weak or ephemeron pair until after it has been returned from the guardian and +dropped by the program or until the guardian itself is dropped. + +
+ +
(define G (make-guardian))
+
+(define x (cons 'aaa 'bbb))
+
+(define p (weak-cons x '()))
+
+(G x)
+
+(set! x #f)
+
+(collect)
+
+(set! y (G))
+
+y (aaa . bbb)
+
+(car p) (aaa . bbb)
+
+(set! y #f)
+
+(collect 1)
+
+(car p) #!bwp
+
(The first collector call above would +promote the object at least into generation 1, requiring the second +collector call to be a generation 1 collection. +This can also be forced by invoking collect several times.) + +
+On the other hand, if a representative (other than the object itself) +is specified, the guarded object is dropped from the car field of the +weak or ephemeron pair at the same time as the representative becomes available +from the guardian. + +
+ +
(define G (make-guardian))
+
+(define x (cons 'aaa 'bbb))
+
+(define p (weak-cons x '()))
+
+(G x 'rep)
+
+(set! x #f)
+
+(collect)
+
+(G) rep
+
+(car p) #!bwp
+
The following example illustrates that the object is deallocated and +the car field of the weak pair set to #!bwp when the guardian +itself is dropped: + +
+ +
(define G (make-guardian))
+
+(define x (cons 'aaa 'bbb))
+
+(define p (weak-cons x '()))
+
+(G x)
+
+(set! x #f)
+
+(set! G #f)
+
+(collect)
+
+(car p) #!bwp
+
The example below demonstrates how guardians might be used to +deallocate external storage, such as storage managed by the C library +"malloc" and "free" operations. + +
+ +
(define malloc
+
+ (let ([malloc-guardian (make-guardian)])
+
+ (lambda (size)
+
+ ; first free any storage that has been dropped. to avoid long
+
+ ; delays, it might be better to deallocate no more than, say,
+
+ ; ten objects for each one allocated
+
+ (let f ()
+
+ (let ([x (malloc-guardian)])
+
+ (when x
+
+ (do-free x)
+
+ (f))))
+
+ ; then allocate and register the new storage
+
+ (let ([x (do-malloc size)])
+
+ (malloc-guardian x)
+
+ x))))
+
do-malloc must return a Scheme object "header" encapsulating a pointer to the +external storage (perhaps as an unsigned integer), and all access to the +external storage must be made through this header. +In particular, care must be taken that no pointers to the external storage +exist outside of Scheme after the corresponding header has been +dropped. +do-free must deallocate the external storage using the encapsulated +pointer. +Both primitives can be defined in terms of foreign-alloc +and foreign-free or the C-library "malloc" and "free" +operators, imported as foreign procedures. (See +Chapter 4.) + +
+If it is undesirable to wait until malloc is called to free dropped +storage previously allocated by malloc, a collect-request handler +can be used instead to check for and free dropped storage, as shown below. + +
+ +
(define malloc)
+
+(let ([malloc-guardian (make-guardian)])
+
+ (set! malloc
+
+ (lambda (size)
+
+ ; allocate and register the new storage
+
+ (let ([x (do-malloc size)])
+
+ (malloc-guardian x)
+
+ x)))
+
+ (collect-request-handler
+
+ (lambda ()
+
+ ; first, invoke the collector
+
+ (collect)
+
+ ; then free any storage that has been dropped
+
+ (let f ()
+
+ (let ([x (malloc-guardian)])
+
+ (when x
+
+ (do-free x)
+
+ (f)))))))
+
With a bit of refactoring, it would be possible to register +the encapsulated foreign address as a representative with +each header, in which do-free would take just the +foreign address as an argument. +This would allow the header to be dropped from the Scheme +heap as soon as it becomes inaccessible. + +
+Guardians can also be created via +ftype-guardian, which +supports reference counting of foreign objects. + +
+procedure: (guardian? obj)
+
+returns: #t if obj is a guardian, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(guardian? (make-guardian)) #t
+
+(guardian? (ftype-guardian iptr)) #t
+
+(guardian? (lambda x x)) #f
+
+(guardian? "oops") #f
+
procedure: (unregister-guardian guardian)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
unregister-guardian unregisters the +as-yet unresurrected objects currently registered with the guardian, +with one caveat. + +
+The caveat, which applies only to threaded versions of Chez Scheme, +is that objects registered with the guardian by other threads since +the last garbage collection might not be unregistered. +To ensure that all objects are unregistered in a multithreaded +application, a single thread can be used both to register and +unregister objects. +Alternatively, an application can arrange to define a +collect-request +handler that calls unregister-guardian after it calls +collect. + +
+In any case, unregister-guardian returns a list containing each object +(or its representative, if specified) that it unregisters, with +duplicates as appropriate if the same object is registered more +than once with the guardian. +Objects already resurrected but not yet retrieved from the guardian +are not included in the list but remain retrievable from the +guardian. + +
+In the current implementation, unregister-guardian takes time proportional +to the number of unresurrected objects currently registered with +all guardians rather than those registered just with +the corresponding guardian. + +
+The example below assumes no collections occur except for those resulting from +explicit calls to collect. + +
+ +
(define g (make-guardian))
+
+(define x (cons 'a 'b))
+
+(define y (cons 'c 'd))
+
+(g x)
+
+(g x)
+
+(g y)
+
+(g y)
+
+(set! y #f)
+
+(collect 0 0)
+
+(unregister-guardian g) ((a . b) (a . b))
+
+(g) (c . d)
+
+(g) (c . d)
+
+(g) #f
+
unregister-guardian can also be used to unregister ftype +pointers registered with guardians created by +ftype-guardian +(Section 15.6). + + +
+ +
+All pointers from C variables or data structures to Scheme objects +should generally be discarded before entry (or reentry) into Scheme. +When this guideline cannot be followed, the object may be +locked via lock-object or via the equivalent +C library procedure Slock_object +(Section 4.9). + +
+procedure: (lock-object obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Locking an object prevents the storage manager from reclaiming or +relocating the object. +Locking should be used sparingly, as it introduces memory fragmentation +and increases storage management overhead. + +
+Locking can also lead to accidental retention of storage if objects +are not unlocked. +Objects may be unlocked via unlock-object or the equivalent +C library procedure +Sunlock_object. + +
+Locking immediate values, such as fixnums, booleans, and characters, +or objects that have been made static is unnecessary but harmless. + + +
+procedure: (unlock-object obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
An object may be locked more than once by successive calls to +lock-object, Slock_object, or both, in which case it must +be unlocked by an equal number of calls to +unlock-object or Sunlock_object before it is +truly unlocked. + +
+An object contained within a locked object, such as an object in the +car of a locked pair, need not also be locked unless a separate C +pointer to the object exists. +That is, if the inner object is accessed only via an indirection of the +outer object, it should be left unlocked so that the collector is free +to relocate it during collection. + +
+Unlocking immediate values, such as fixnums, booleans, and characters, +or objects that have been made static is unnecessary and ineffective but harmless. + + +
+procedure: (locked-object? obj)
+
+returns: #t if obj is locked, immediate, or static
+
+libraries: (chezscheme)
+
+
This predicate returns true if obj cannot be relocated or reclaimed +by the collector, including immediate values, such as fixnums, +booleans, and characters, and objects that have been made static. + + +
+ +
+Like a locked object, an immobile object will not be relocated by +the storage manager. Unlike a locked object, and immobile object will +be reclaimed by the storage manager if it is unreachable. +Foreign-callable code objects are immobile, as are objects allocated +by functions that specifically create immobile objects. + +
+procedure: (box-immobile obj)
+
+returns: a box
+
+libraries: (chezscheme)
+
+
Like box, but creates a box that will not be relocated in memory +by the storage management system until it is reclaimed. + + +
+procedure: (make-immobile-vector n)
+
procedure: (make-immobile-vector n obj)
+
+returns: a vector
+
+libraries: (chezscheme)
+
+
Like make-vector, but creates a vector that will not be relocated +in memory by the storage management system until it is reclaimed. + + +
+procedure: (make-immobile-bytevector n)
+
procedure: (make-immobile-bytevector n byte)
+
+returns: a vector
+
+libraries: (chezscheme)
+
+
Like make-bytevector, but creates a bytevector that will not be relocated +in memory by the storage management system until it is reclaimed. + + + +
+ +
+A phantom bytevector represents +memory that is allocated outside of the Scheme stroage management +system. A phantom bytevector itself uses a small amount of space, but +it contains a length that reflects external allocation. Representing +external allocation can be useful for reflecting memory consumption +and triggering garbage-collection heuristics based on consumption. For +example, for a program that allocates external objects and frees +through a guardian, representing the external object's memory use can +trigger earlier garbage collections when the external objects are +large. A phantom bytevector can also reflect external allocation to +tools like compute-size, since the length of a phantom +bytevector is included in the result of compute-size for the +phantom bytevector. + +
+procedure: (make-phantom-bytevector n)
+
+returns: a phantom bytevector
+
+libraries: (chezscheme)
+
+
n must be an exact nonnegative integer. + +
+Creates a phantom bytevector that reflects n bytes of external +allocation. + +
+The value n must reflect actual allocation in the sense of +consuming a portion of the process's address space. Claiming +significantly more bytes than are actually allocated introduces the +possibility of overflow within the storage management system's +calculations. + +
+procedure: (phantom-bytevector? obj)
+
+returns: #t if obj is a phantom bytevector, #f otherwise
+
+libraries: (chezscheme)
+
+
+
(phantom-bytevector? (make-phantom-bytevector 1024)) #t +
procedure: (phantom-bytevector-length pbv)
+
+returns: the length of the phantom bytevector
+
+libraries: (chezscheme)
+
+
pbv must be a phantom bytevector. + +
+Returns the number of bytes of external allocation that pbv +represents. + +
+ +
(phantom-bytevector-length (make-phantom-bytevector 1024)) 1024 +
procedure: (set-phantom-bytevector-length! pbv n)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
pbv must be a phantom bytevector, and n must be an exact nonnegative integer. + +
+Adjusts the allocation represented by pbv to n bytes. For +example, when an externally allocated object represented by pbv +is deallocated, then pbv's length should be set to 0. + +
+ +
(define pbv (make-phantom-bytevector 1024))
+
+(phantom-bytevector-length pbv) 1024
+
+(set-phantom-bytevector-length! pbv 1)
+
+(phantom-bytevector-length pbv) 1
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/summary.html b/csug10.0/summary.html
new file mode 100644
index 000000000..2fe3c0ba2
--- /dev/null
+++ b/csug10.0/summary.html
@@ -0,0 +1,2047 @@
+
+
+
+
+
+The table that follows summarizes the syntactic forms and procedures +described in this book along with standard Scheme syntactic forms and +procedures. +It shows each item's category and the page number where it is defined. +Page numbers prefixed by "t" refer to +The +Scheme Programming Language, 4th Edition (TSPL4). + +
+All page numbers appearing here refer to the printed version of these +books and also serve as hypertext links to the corresponding locations +in the electronic versions of these books. + + +
+ + + +
+
Form | Category | Page |
---|---|---|
'obj | syntax | 141 |
`obj | syntax | 142 |
,obj | syntax | 142 |
,@obj | syntax | 142 |
=> | syntax | 112 |
_ | syntax | 297 |
... | syntax | 297 |
#'template | syntax | 300 |
#`template | syntax | 305 |
#,template | syntax | 305 |
#,@template | syntax | 305 |
#%variable | syntax | 390 |
#2%variable | syntax | 390 |
#3%variable | syntax | 390 |
($primitive variable) | syntax | 390 |
($primitive 2 variable) | syntax | 390 |
($primitive 3 variable) | syntax | 390 |
$system | module | 339 |
&assertion | syntax | 366 |
&condition | syntax | 362 |
&continuation | syntax | 355 |
&error | syntax | 367 |
&format | syntax | 354 |
&i/o | syntax | 371 |
&i/o-decoding | syntax | 375 |
&i/o-encoding | syntax | 376 |
&i/o-file-already-exists | syntax | 374 |
&i/o-file-does-not-exist | syntax | 374 |
&i/o-file-is-read-only | syntax | 374 |
&i/o-file-protection | syntax | 373 |
&i/o-filename | syntax | 373 |
&i/o-invalid-position | syntax | 372 |
&i/o-port | syntax | 375 |
&i/o-read | syntax | 372 |
&i/o-write | syntax | 372 |
&implementation-restriction | syntax | 369 |
&irritants | syntax | 368 |
&lexical | syntax | 370 |
&message | syntax | 368 |
&no-infinities | syntax | 376 |
&no-nans | syntax | 377 |
&non-continuable | syntax | 369 |
&serious | syntax | 366 |
&source | syntax | 354 |
&syntax | syntax | 370 |
&undefined | syntax | 371 |
&violation | syntax | 366 |
&warning | syntax | 367 |
&who | syntax | 369 |
(* num ...) | procedure | 172 |
(+ num ...) | procedure | 171 |
(- num) | procedure | 172 |
(- num1 num2 num3 ...) | procedure | 172 |
(-1+ num) | procedure | 235 |
(/ num) | procedure | 172 |
(/ num1 num2 num3 ...) | procedure | 172 |
(1+ num) | procedure | 235 |
(1- num) | procedure | 235 |
(< real1 real2 real3 ...) | procedure | 235 |
(< real1 real2 real3 ...) | procedure | 170 |
(<= real1 real2 real3 ...) | procedure | 235 |
(<= real1 real2 real3 ...) | procedure | 170 |
(= num1 num2 num3 ...) | procedure | 235 |
(= num1 num2 num3 ...) | procedure | 170 |
(> real1 real2 real3 ...) | procedure | 235 |
(> real1 real2 real3 ...) | procedure | 170 |
(>= real1 real2 real3 ...) | procedure | 235 |
(>= real1 real2 real3 ...) | procedure | 170 |
(abort) | procedure | 410 |
(abort obj) | procedure | 410 |
abort-handler | thread param | 410 |
(abs real) | procedure | 178 |
(acos num) | procedure | 185 |
(acosh num) | procedure | 238 |
(add-duration time timed) | procedure | 416 |
(add-duration! time timed) | procedure | 416 |
add-prefix | syntax | 338 |
(add1 num) | procedure | 235 |
alias | syntax | 338 |
(alias id1 id2) | syntax | 342 |
(and expr ...) | syntax | 110 |
(andmap procedure list1 list2 ...) | procedure | 129 |
(angle num) | procedure | 183 |
(annotation-expression annotation) | procedure | 345 |
(annotation-option-set annotation) | procedure | 346 |
(annotation-options symbol ...) | syntax | 348 |
(annotation-source annotation) | procedure | 346 |
(annotation-stripped annotation) | procedure | 346 |
(annotation? obj) | procedure | 345 |
(append) | procedure | 160 |
(append list ... obj) | procedure | 160 |
(append! list ...) | procedure | 147 |
(apply procedure obj ... list) | procedure | 107 |
(apropos s) | procedure | 364 |
(apropos s env) | procedure | 364 |
(apropos-list s) | procedure | 363 |
(apropos-list s env) | procedure | 363 |
(ash int count) | procedure | 228 |
(asin num) | procedure | 185 |
(asinh num) | procedure | 238 |
(assert expression) | syntax | 359 |
(assert-unreachable) | procedure | 357 |
(assertion-violation who msg irritant ...) | procedure | 358 |
(assertion-violation? obj) | procedure | 366 |
(assertion-violationf who msg irritant ...) | procedure | 354 |
(assoc obj alist) | procedure | 165 |
(assp procedure alist) | procedure | 166 |
(assq obj alist) | procedure | 165 |
(assv obj alist) | procedure | 165 |
(atan num) | procedure | 185 |
(atan real1 real2) | procedure | 185 |
(atanh num) | procedure | 238 |
(atom? obj) | procedure | 143 |
base-exception-handler | thread param | 356 |
(begin expr1 expr2 ...) | syntax | 108 |
(bignum? obj) | procedure | 214 |
(binary-port-input-buffer binary-input-port) | procedure | 246 |
(binary-port-input-count binary-input-port) | procedure | 247 |
(binary-port-input-index binary-input-port) | procedure | 246 |
(binary-port-input-size binary-input-port) | procedure | 246 |
(binary-port-output-buffer output-port) | procedure | 247 |
(binary-port-output-count binary-output-port) | procedure | 248 |
(binary-port-output-index output-port) | procedure | 247 |
(binary-port-output-size output-port) | procedure | 247 |
(binary-port? obj) | procedure | 270 |
(bitwise-and exint ...) | procedure | 186 |
(bitwise-arithmetic-shift exint1 exint2) | procedure | 190 |
(bitwise-arithmetic-shift-left exint1 exint2) | procedure | 189 |
(bitwise-arithmetic-shift-right exint1 exint2) | procedure | 189 |
(bitwise-bit-count exint) | procedure | 187 |
(bitwise-bit-field exint1 exint2 exint3) | procedure | 189 |
(bitwise-bit-set? exint1 exint2) | procedure | 188 |
(bitwise-copy-bit exint1 exint2 exint3) | procedure | 188 |
(bitwise-copy-bit-field exint1 exint2 exint3 exint4) | procedure | 189 |
(bitwise-first-bit-set exint) | procedure | 187 |
(bitwise-if exint1 exint2 exint3) | procedure | 186 |
(bitwise-ior exint ...) | procedure | 186 |
(bitwise-length exint) | procedure | 187 |
(bitwise-not exint) | procedure | 186 |
(bitwise-reverse-bit-field exint1 exint2 exint3) | procedure | 191 |
(bitwise-rotate-bit-field exint1 exint2 exint3 exint4) | procedure | 190 |
(bitwise-xor exint ...) | procedure | 186 |
(block-read textual-input-port string) | procedure | 262 |
(block-read textual-input-port string count) | procedure | 262 |
(block-write textual-output-port string) | procedure | 269 |
(block-write textual-output-port string count) | procedure | 269 |
(boolean=? boolean1 boolean2) | procedure | 243 |
(boolean? obj) | procedure | 150 |
(bound-identifier=? identifier1 identifier2) | procedure | 302 |
(box obj) | procedure | 168 |
(box-cas! box old-obj new-obj) | procedure | 169 |
(box-immobile obj) | procedure | 452 |
(box-immutable obj) | procedure | 170 |
(box? obj) | procedure | 168 |
(break who msg irritant ...) | procedure | 358 |
(break who) | procedure | 358 |
(break) | procedure | 358 |
break-handler | thread param | 358 |
(buffer-mode symbol) | syntax | 261 |
(buffer-mode? obj) | syntax | 262 |
(bwp-object? obj) | procedure | 445 |
(bytes-allocated) | procedure | 422 |
(bytes-allocated g) | procedure | 422 |
(bytes-deallocated) | procedure | 422 |
(bytes-finalized) | procedure | 422 |
(bytevector fill ...) | procedure | 161 |
(bytevector->immutable-bytevector bytevector) | procedure | 164 |
(bytevector->s8-list bytevector) | procedure | 161 |
(bytevector->sint-list bytevector eness size) | procedure | 238 |
(bytevector->string bytevector transcoder) | procedure | 286 |
(bytevector->u8-list bytevector) | procedure | 232 |
(bytevector->uint-list bytevector eness size) | procedure | 238 |
(bytevector-compress bytevector) | procedure | 164 |
(bytevector-copy bytevector) | procedure | 229 |
(bytevector-copy! src src-start dst dst-start n) | procedure | 230 |
(bytevector-fill! bytevector fill) | procedure | 229 |
(bytevector-ieee-double-native-ref bytevector n) | procedure | 239 |
(bytevector-ieee-double-native-set! bytevector n x) | procedure | 239 |
(bytevector-ieee-double-ref bytevector n eness) | procedure | 240 |
(bytevector-ieee-double-set! bytevector n x eness) | procedure | 240 |
(bytevector-ieee-single-native-ref bytevector n) | procedure | 239 |
(bytevector-ieee-single-native-set! bytevector n x) | procedure | 239 |
(bytevector-ieee-single-ref bytevector n eness) | procedure | 240 |
(bytevector-ieee-single-set! bytevector n x eness) | procedure | 240 |
(bytevector-length bytevector) | procedure | 229 |
(bytevector-reference*-ref bytevector n) | procedure | 92 |
(bytevector-reference-ref bytevector n) | procedure | 91 |
(bytevector-reference-set! bytevector n obj) | procedure | 91 |
(bytevector-s16-native-ref bytevector n) | procedure | 232 |
(bytevector-s16-native-set! bytevector n s16) | procedure | 233 |
(bytevector-s16-ref bytevector n eness) | procedure | 235 |
(bytevector-s16-set! bytevector n s16 eness) | procedure | 236 |
(bytevector-s24-ref bytevector n eness) | procedure | 163 |
(bytevector-s24-set! bytevector n s24 eness) | procedure | 163 |
(bytevector-s32-native-ref bytevector n) | procedure | 232 |
(bytevector-s32-native-set! bytevector n s32) | procedure | 233 |
(bytevector-s32-ref bytevector n eness) | procedure | 235 |
(bytevector-s32-set! bytevector n s32 eness) | procedure | 236 |
(bytevector-s40-ref bytevector n eness) | procedure | 163 |
(bytevector-s40-set! bytevector n s40 eness) | procedure | 163 |
(bytevector-s48-ref bytevector n eness) | procedure | 163 |
(bytevector-s48-set! bytevector n s48 eness) | procedure | 163 |
(bytevector-s56-ref bytevector n eness) | procedure | 163 |
(bytevector-s56-set! bytevector n s56 eness) | procedure | 163 |
(bytevector-s64-native-ref bytevector n) | procedure | 232 |
(bytevector-s64-native-set! bytevector n s64) | procedure | 233 |
(bytevector-s64-ref bytevector n eness) | procedure | 235 |
(bytevector-s64-set! bytevector n s64 eness) | procedure | 236 |
(bytevector-s8-ref bytevector n) | procedure | 231 |
(bytevector-s8-set! bytevector n s8) | procedure | 231 |
(bytevector-sint-ref bytevector n eness size) | procedure | 237 |
(bytevector-sint-set! bytevector n sint eness size) | procedure | 238 |
(bytevector-truncate! bytevector n) | procedure | 162 |
(bytevector-u16-native-ref bytevector n) | procedure | 232 |
(bytevector-u16-native-set! bytevector n u16) | procedure | 233 |
(bytevector-u16-ref bytevector n eness) | procedure | 235 |
(bytevector-u16-set! bytevector n u16 eness) | procedure | 236 |
(bytevector-u24-ref bytevector n eness) | procedure | 163 |
(bytevector-u24-set! bytevector n u24 eness) | procedure | 163 |
(bytevector-u32-native-ref bytevector n) | procedure | 232 |
(bytevector-u32-native-set! bytevector n u32) | procedure | 233 |
(bytevector-u32-ref bytevector n eness) | procedure | 235 |
(bytevector-u32-set! bytevector n u32 eness) | procedure | 236 |
(bytevector-u40-ref bytevector n eness) | procedure | 163 |
(bytevector-u40-set! bytevector n u40 eness) | procedure | 163 |
(bytevector-u48-ref bytevector n eness) | procedure | 163 |
(bytevector-u48-set! bytevector n u48 eness) | procedure | 163 |
(bytevector-u56-ref bytevector n eness) | procedure | 163 |
(bytevector-u56-set! bytevector n u56 eness) | procedure | 163 |
(bytevector-u64-native-ref bytevector n) | procedure | 232 |
(bytevector-u64-native-set! bytevector n u64) | procedure | 233 |
(bytevector-u64-ref bytevector n eness) | procedure | 235 |
(bytevector-u64-set! bytevector n u64 eness) | procedure | 236 |
(bytevector-u8-ref bytevector n) | procedure | 230 |
(bytevector-u8-set! bytevector n u8) | procedure | 231 |
(bytevector-uint-ref bytevector n eness size) | procedure | 237 |
(bytevector-uint-set! bytevector n uint eness size) | procedure | 238 |
(bytevector-uncompress bytevector) | procedure | 164 |
(bytevector=? bytevector1 bytevector2) | procedure | 229 |
(bytevector? obj) | procedure | 155 |
(caaaar pair) | procedure | 157 |
(caaadr pair) | procedure | 157 |
(caaar pair) | procedure | 157 |
(caadar pair) | procedure | 157 |
(caaddr pair) | procedure | 157 |
(caadr pair) | procedure | 157 |
(caar pair) | procedure | 157 |
(cadaar pair) | procedure | 157 |
(cadadr pair) | procedure | 157 |
(cadar pair) | procedure | 157 |
(caddar pair) | procedure | 157 |
(cadddr pair) | procedure | 157 |
(caddr pair) | procedure | 157 |
(cadr pair) | procedure | 157 |
(call-in-continuation continuation procedure) | procedure | 135 |
(call-in-continuation continuation marks procedure) | procedure | 135 |
(call-with-bytevector-output-port procedure) | procedure | 266 |
(call-with-bytevector-output-port procedure ?transcoder) | procedure | 266 |
(call-with-current-continuation procedure) | procedure | 123 |
(call-with-immediate-continuation-mark key proc) | procedure | 135 |
(call-with-immediate-continuation-mark key none-val proc) | procedure | 135 |
(call-with-input-file path procedure) | procedure | 258 |
(call-with-input-file path procedure options) | procedure | 258 |
(call-with-input-file path procedure) | procedure | 281 |
(call-with-output-file path procedure) | procedure | 266 |
(call-with-output-file path procedure options) | procedure | 266 |
(call-with-output-file path procedure) | procedure | 282 |
(call-with-port port procedure) | procedure | 272 |
(call-with-string-output-port procedure) | procedure | 267 |
(call-with-values producer consumer) | procedure | 131 |
(call/1cc procedure) | procedure | 130 |
(call/cc procedure) | procedure | 123 |
(car pair) | procedure | 156 |
(case expr0 clause1 clause2 ...) | syntax | 127 |
(case expr0 clause1 clause2 ...) | syntax | 113 |
(case-lambda clause ...) | syntax | 94 |
case-sensitive | thread param | 279 |
cd | global param | 288 |
(cdaaar pair) | procedure | 157 |
(cdaadr pair) | procedure | 157 |
(cdaar pair) | procedure | 157 |
(cdadar pair) | procedure | 157 |
(cdaddr pair) | procedure | 157 |
(cdadr pair) | procedure | 157 |
(cdar pair) | procedure | 157 |
(cddaar pair) | procedure | 157 |
(cddadr pair) | procedure | 157 |
(cddar pair) | procedure | 157 |
(cdddar pair) | procedure | 157 |
(cddddr pair) | procedure | 157 |
(cdddr pair) | procedure | 157 |
(cddr pair) | procedure | 157 |
(cdr pair) | procedure | 156 |
(ceiling real) | procedure | 177 |
(cfl* cflonum ...) | procedure | 223 |
(cfl+ cflonum ...) | procedure | 223 |
(cfl- cflonum1 cflonum2 ...) | procedure | 223 |
(cfl-conjugate cflonum) | procedure | 223 |
(cfl-imag-part cflonum) | procedure | 222 |
(cfl-magnitude-squared cflonum) | procedure | 224 |
(cfl-real-part cflonum) | procedure | 222 |
(cfl/ cflonum1 cflonum2 ...) | procedure | 223 |
(cfl= cflonum ...) | procedure | 223 |
(cflonum? obj) | procedure | 215 |
(char- char1 char2) | procedure | 148 |
(char->integer char) | procedure | 215 |
(char-alphabetic? char) | procedure | 213 |
(char-ci<=? char1 char2 ...) | procedure | 148 |
(char-ci<=? char1 char2 char3 ...) | procedure | 212 |
(char-ci<? char1 char2 ...) | procedure | 148 |
(char-ci<? char1 char2 char3 ...) | procedure | 212 |
(char-ci=? char1 char2 ...) | procedure | 148 |
(char-ci=? char1 char2 char3 ...) | procedure | 212 |
(char-ci>=? char1 char2 ...) | procedure | 148 |
(char-ci>=? char1 char2 char3 ...) | procedure | 212 |
(char-ci>? char1 char2 ...) | procedure | 148 |
(char-ci>? char1 char2 char3 ...) | procedure | 212 |
(char-downcase char) | procedure | 214 |
(char-extended-pictographic? char) | procedure | 150 |
(char-foldcase char) | procedure | 215 |
(char-general-category char) | procedure | 214 |
(char-grapheme-break-property char) | procedure | 149 |
(char-grapheme-step char state) | procedure | 149 |
(char-lower-case? char) | procedure | 213 |
(char-name obj) | procedure | 278 |
(char-name name char) | procedure | 278 |
(char-numeric? char) | procedure | 213 |
(char-ready?) | procedure | 262 |
(char-ready? textual-input-port) | procedure | 262 |
(char-title-case? char) | procedure | 213 |
(char-titlecase char) | procedure | 214 |
(char-upcase char) | procedure | 214 |
(char-upper-case? char) | procedure | 213 |
(char-whitespace? char) | procedure | 213 |
(char<=? char1 char2 ...) | procedure | 148 |
(char<=? char1 char2 char3 ...) | procedure | 212 |
(char<? char1 char2 ...) | procedure | 148 |
(char<? char1 char2 char3 ...) | procedure | 212 |
(char=? char1 char2 ...) | procedure | 148 |
(char=? char1 char2 char3 ...) | procedure | 212 |
(char>=? char1 char2 ...) | procedure | 148 |
(char>=? char1 char2 char3 ...) | procedure | 212 |
(char>? char1 char2 ...) | procedure | 148 |
(char>? char1 char2 char3 ...) | procedure | 212 |
(char? obj) | procedure | 154 |
(chmod path mode) | procedure | 291 |
(clear-input-port) | procedure | 252 |
(clear-input-port input-port) | procedure | 252 |
(clear-output-port) | procedure | 253 |
(clear-output-port output-port) | procedure | 253 |
(close-input-port input-port) | procedure | 285 |
(close-output-port output-port) | procedure | 285 |
(close-port port) | procedure | 270 |
(collect) | procedure | 439 |
(collect cg) | procedure | 439 |
(collect cg max-tg) | procedure | 439 |
(collect cg min-tg max-tg) | procedure | 439 |
(collect cg min-tg max-tg objs) | procedure | 439 |
collect-generation-radix | global param | 440 |
collect-maximum-generation | global param | 441 |
collect-maximum-generation-threshold-factor | global param | 440 |
collect-notify | global param | 440 |
(collect-rendezvous) | procedure | 440 |
collect-request-handler | global param | 441 |
collect-trip-bytes | global param | 440 |
(collections) | procedure | 423 |
command-line | global param | 412 |
(command-line) | procedure | 350 |
command-line-arguments | global param | 412 |
commonization-level | thread param | 395 |
(compile obj) | procedure | 365 |
(compile obj env) | procedure | 365 |
(compile-file input-filename) | procedure | 369 |
(compile-file input-filename output-filename) | procedure | 369 |
compile-file-message | thread param | 393 |
compile-imported-libraries | thread param | 316 |
compile-interpret-simple | thread param | 391 |
(compile-library input-filename) | procedure | 371 |
(compile-library input-filename output-filename) | procedure | 371 |
compile-library-handler | thread param | 372 |
compile-omit-concatenate-support | thread param | 388 |
(compile-port input-port output-port) | procedure | 374 |
(compile-port input-port output-port sfd) | procedure | 374 |
(compile-port input-port output-port sfd wpo-port) | procedure | 374 |
(compile-port input-port output-port sfd wpo-port covop) | procedure | 374 |
compile-procedure-realm | thread param | 378 |
compile-profile | thread param | 401 |
(compile-program input-filename) | procedure | 371 |
(compile-program input-filename output-filename) | procedure | 371 |
compile-program-handler | thread param | 372 |
(compile-script input-filename) | procedure | 370 |
(compile-script input-filename output-filename) | procedure | 370 |
(compile-time-value-value ctv) | procedure | 330 |
(compile-time-value? obj) | procedure | 330 |
(compile-to-file obj-list output-file) | procedure | 376 |
(compile-to-file obj-list output-file sfd) | procedure | 376 |
(compile-to-port objs op) | procedure | 375 |
(compile-to-port objs op sfd) | procedure | 375 |
(compile-to-port objs op sfd wpoop) | procedure | 375 |
(compile-to-port objs op sfd wpoop covop) | procedure | 375 |
(compile-to-port objs op sfd wpoop covop mach) | procedure | 375 |
(compile-to-port objs op sfd wpoop covop mach hostop) | procedure | 375 |
(compile-to-port objs op sfd wpoop covop mach hostop ext) | procedure | 375 |
(compile-to-port objs op sfd wpoop covop mach hostop ext nortds?) | procedure | 375 |
(compile-whole-library input-filename output-filename) | procedure | 374 |
(compile-whole-program input-filename output-filename) | procedure | 373 |
(compile-whole-program input-filename output-filename libs-visible?) | procedure | 373 |
(complex? obj) | procedure | 151 |
compress-format | thread param | 253 |
compress-level | thread param | 254 |
(compute-composition object) | procedure | 55 |
(compute-composition object generation) | procedure | 55 |
(compute-size object) | procedure | 54 |
(compute-size object generation) | procedure | 54 |
(compute-size-increments list) | procedure | 56 |
(compute-size-increments list generation) | procedure | 56 |
(concatenate-object-files out-file in-file1 in-file2 ...) | procedure | 376 |
(cond clause1 clause2 ...) | syntax | 111 |
(condition condition ...) | procedure | 362 |
(condition-accessor rtd procedure) | procedure | 365 |
(condition-broadcast cond) | procedure | 471 |
(condition-continuation condition) | procedure | 355 |
(condition-irritants condition) | procedure | 368 |
(condition-message condition) | procedure | 368 |
(condition-name condition) | procedure | 471 |
(condition-predicate rtd) | procedure | 365 |
(condition-signal cond) | procedure | 471 |
(condition-wait cond mutex) | procedure | 470 |
(condition-wait cond mutex timeout) | procedure | 470 |
(condition-who condition) | procedure | 369 |
(condition? obj) | procedure | 362 |
(conjugate num) | procedure | 237 |
(cons obj1 obj2) | procedure | 156 |
(cons* obj ... final-obj) | procedure | 158 |
console-error-port | thread param | 265 |
console-input-port | global param | 256 |
console-output-port | global param | 264 |
constant | syntax | 141 |
constructor | syntax | 199 |
(continuation-condition? obj) | procedure | 355 |
(continuation-marks->iterator marks key-vector) | procedure | 134 |
(continuation-marks->iterator marks key-vector none-val) | procedure | 134 |
(continuation-marks->list marks key) | procedure | 133 |
(continuation-marks-first marks key) | procedure | 133 |
(continuation-marks-first marks key none-val) | procedure | 133 |
(continuation-marks? obj) | procedure | 132 |
(continuation-next-marks cont) | procedure | 132 |
(copy-environment env) | procedure | 363 |
(copy-environment env mutable?) | procedure | 363 |
(copy-environment env mutable? syms) | procedure | 363 |
(copy-time time) | procedure | 416 |
(cos num) | procedure | 185 |
(cosh num) | procedure | 238 |
(cost-center-allocation-count cost-center) | procedure | 428 |
(cost-center-instruction-count cost-center) | procedure | 428 |
(cost-center-time cost-center) | procedure | 428 |
(cost-center? obj) | procedure | 428 |
cp0-effort-limit | thread param | 393 |
cp0-outer-unroll-limit | thread param | 393 |
cp0-score-limit | thread param | 393 |
(cpu-time) | procedure | 421 |
(create-exception-state) | procedure | 357 |
(create-exception-state handler) | procedure | 357 |
(critical-section body1 body2 ...) | syntax | 360 |
(current-continuation-marks) | procedure | 132 |
(current-date) | procedure | 417 |
(current-date offset) | procedure | 417 |
current-directory | global param | 288 |
current-error-port | thread param | 265 |
(current-error-port) | procedure | 263 |
current-eval | thread param | 365 |
current-exception-state | thread param | 356 |
current-expand | thread param | 379 |
current-generate-id | thread param | 386 |
current-input-port | thread param | 257 |
(current-input-port) | procedure | 263 |
current-locate-source-object-source | thread param | 349 |
current-make-source-object | thread param | 347 |
(current-memory-bytes) | procedure | 422 |
current-output-port | thread param | 264 |
(current-output-port) | procedure | 263 |
(current-time) | procedure | 414 |
(current-time time-type) | procedure | 414 |
current-transcoder | thread param | 244 |
custom-port-buffer-size | thread param | 256 |
(date->time-utc date) | procedure | 420 |
(date-and-time) | procedure | 420 |
(date-and-time date) | procedure | 420 |
(date-day date) | procedure | 418 |
(date-dst? date) | procedure | 419 |
(date-hour date) | procedure | 418 |
(date-minute date) | procedure | 418 |
(date-month date) | procedure | 418 |
(date-nanosecond date) | procedure | 418 |
(date-second date) | procedure | 418 |
(date-week-day date) | procedure | 419 |
(date-year date) | procedure | 418 |
(date-year-day date) | procedure | 419 |
(date-zone-name date) | procedure | 419 |
(date-zone-offset date) | procedure | 418 |
(date? obj) | procedure | 418 |
(datum template) | syntax | 325 |
(datum->syntax template-identifier obj) | procedure | 308 |
(datum->syntax-object template-identifier obj) | procedure | 325 |
(debug) | procedure | 41 |
debug-condition | thread param | 356 |
debug-level | thread param | 390 |
debug-on-exception | global param | 356 |
(decode-float x) | procedure | 221 |
(default-exception-handler obj) | procedure | 355 |
(default-library-search-handler who library directories extensions) | procedure | 317 |
(default-prompt-and-read level) | procedure | 409 |
default-record-equal-procedure | thread param | 191 |
default-record-hash-procedure | thread param | 192 |
(define var expr) | syntax | 100 |
(define var) | syntax | 100 |
(define (var0 var1 ...) body1 body2 ...) | syntax | 100 |
(define (var0 . varr) body1 body2 ...) | syntax | 100 |
(define (var0 var1 var2 ... . varr) body1 body2 ...) | syntax | 100 |
(define-condition-type name parent constructor pred field ...) | syntax | 364 |
(define-enumeration name (symbol ...) constructor) | syntax | 250 |
(define-ftype ftype-name ftype) | syntax | 77 |
(define-ftype (ftype-name ftype) ...) | syntax | 77 |
(define-property id key expr) | syntax | 330 |
(define-record name (fld1 ...) ((fld2 init) ...) (opt ...)) | syntax | 195 |
(define-record name parent (fld1 ...) ((fld2 init) ...) (opt ...)) | syntax | 195 |
(define-record-type record-name clause ...) | syntax | 328 |
(define-record-type (record-name constructor pred) clause ...) | syntax | 328 |
(define-structure (name id1 ...) ((id2 expr) ...)) | syntax | 489 |
(define-syntax keyword expr) | syntax | 292 |
(define-top-level-syntax symbol obj) | procedure | 123 |
(define-top-level-syntax symbol obj env) | procedure | 123 |
(define-top-level-value symbol obj) | procedure | 121 |
(define-top-level-value symbol obj env) | procedure | 121 |
(define-values formals expr) | syntax | 118 |
(delay expr) | syntax | 128 |
(delete-directory path) | procedure | 291 |
(delete-directory path error?) | procedure | 291 |
(delete-file path) | procedure | 290 |
(delete-file path error?) | procedure | 290 |
(delete-file path) | procedure | 286 |
(denominator rat) | procedure | 181 |
(directory-list path) | procedure | 288 |
(directory-separator) | procedure | 292 |
(directory-separator? char) | procedure | 292 |
(disable-interrupts) | procedure | 359 |
(display obj) | procedure | 285 |
(display obj textual-output-port) | procedure | 285 |
(display-condition obj) | procedure | 355 |
(display-condition obj textual-output-port) | procedure | 355 |
(display-statistics) | procedure | 421 |
(display-statistics textual-output-port) | procedure | 421 |
(display-string string) | procedure | 269 |
(display-string string textual-output-port) | procedure | 269 |
(div x1 x2) | procedure | 175 |
(div-and-mod x1 x2) | procedure | 175 |
(div0 x1 x2) | procedure | 176 |
(div0-and-mod0 x1 x2) | procedure | 176 |
(do ((var init update) ...) (test result ...) expr ...) | syntax | 115 |
drop-prefix | syntax | 338 |
(dynamic-wind in body out) | procedure | 131 |
(dynamic-wind critical? in body out) | procedure | 131 |
(dynamic-wind in body out) | procedure | 124 |
ee-auto-indent | global param | 455 |
ee-auto-paren-balance | global param | 456 |
(ee-bind-key key procedure) | procedure | 457 |
ee-common-identifiers | global param | 456 |
(ee-compose ecmd ...) | procedure | 465 |
ee-default-repeat | global param | 456 |
ee-flash-parens | global param | 456 |
ee-history-limit | global param | 456 |
ee-noisy | global param | 456 |
ee-paren-flash-delay | global param | 456 |
ee-standard-indent | global param | 455 |
(ee-string-macro string) | procedure | 465 |
else | syntax | 112 |
enable-arithmetic-left-associative | thread param | 392 |
enable-cross-library-optimization | thread param | 392 |
enable-error-source-expression | thread param | 392 |
(enable-interrupts) | procedure | 359 |
enable-object-backreferences | global param | 426 |
enable-object-counts | global param | 425 |
enable-type-recovery | thread param | 395 |
enable-unsafe-application | thread param | 392 |
enable-unsafe-variable-reference | thread param | 392 |
(endianness symbol) | syntax | 228 |
(engine-block) | procedure | 140 |
(engine-return obj ...) | procedure | 141 |
(enum-set->list enum-set) | procedure | 252 |
(enum-set-complement enum-set) | procedure | 254 |
(enum-set-constructor enum-set) | procedure | 251 |
(enum-set-difference enum-set1 enum-set2) | procedure | 253 |
(enum-set-indexer enum-set) | procedure | 254 |
(enum-set-intersection enum-set1 enum-set2) | procedure | 253 |
(enum-set-member? symbol enum-set) | procedure | 253 |
(enum-set-projection enum-set1 enum-set2) | procedure | 254 |
(enum-set-subset? enum-set1 enum-set2) | procedure | 252 |
(enum-set-union enum-set1 enum-set2) | procedure | 253 |
(enum-set-universe enum-set) | procedure | 252 |
(enum-set=? enum-set1 enum-set2) | procedure | 252 |
(enum-set? obj) | procedure | 143 |
(enumerate ls) | procedure | 145 |
(environment import-spec ...) | procedure | 137 |
(environment-mutable? env) | procedure | 361 |
(environment-symbols env) | procedure | 363 |
(environment? obj) | procedure | 361 |
(eof-object) | procedure | 273 |
(eof-object? obj) | procedure | 273 |
(eol-style symbol) | syntax | 259 |
(ephemeron-cons obj1 obj2) | procedure | 444 |
(ephemeron-pair? obj) | procedure | 445 |
(eq-hashtable-cell hashtable key default) | procedure | 183 |
(eq-hashtable-contains? hashtable key) | procedure | 182 |
(eq-hashtable-delete! hashtable key) | procedure | 184 |
(eq-hashtable-ephemeron? hashtable) | procedure | 181 |
(eq-hashtable-ref hashtable key default) | procedure | 181 |
(eq-hashtable-ref-cell hashtable key) | procedure | 183 |
(eq-hashtable-set! hashtable key value) | procedure | 181 |
(eq-hashtable-try-atomic-cell hashtable key default) | procedure | 183 |
(eq-hashtable-update! hashtable key procedure default) | procedure | 182 |
(eq-hashtable-weak? hashtable) | procedure | 181 |
(eq-hashtable? obj) | procedure | 181 |
(eq? obj1 obj2) | procedure | 143 |
(equal-hash obj) | procedure | 245 |
(equal? obj1 obj2) | procedure | 148 |
(eqv? obj1 obj2) | procedure | 146 |
(error who msg irritant ...) | procedure | 358 |
(error-handling-mode symbol) | syntax | 260 |
(error? obj) | procedure | 367 |
(errorf who msg irritant ...) | procedure | 354 |
(eval obj) | procedure | 364 |
(eval obj env) | procedure | 364 |
(eval obj environment) | procedure | 136 |
eval-syntax-expanders-when | thread param | 385 |
(eval-when situations form1 form2 ...) | syntax | 381 |
(even? int) | procedure | 174 |
(exact num) | procedure | 180 |
(exact->inexact num) | procedure | 181 |
(exact-integer-sqrt n) | procedure | 184 |
(exact? num) | procedure | 170 |
except | syntax | 338 |
(exclusive-cond clause1 clause2 ...) | syntax | 127 |
(exists procedure list1 list2 ...) | procedure | 119 |
(exit obj ...) | procedure | 410 |
(exit) | procedure | 350 |
(exit obj) | procedure | 350 |
exit-handler | thread param | 410 |
(exp num) | procedure | 184 |
(expand obj) | procedure | 379 |
(expand obj env) | procedure | 379 |
expand-omit-library-invocations | thread param | 387 |
expand-output | thread param | 396 |
(expand/optimize obj) | procedure | 380 |
(expand/optimize obj env) | procedure | 380 |
expand/optimize-output | thread param | 396 |
(export export-spec ...) | syntax | 312 |
expression-editor | module | 455 |
(expt num1 num2) | procedure | 179 |
(expt-mod int1 int2 int3) | procedure | 236 |
(extend-syntax (name key ...) (pat fender template) ...) | syntax | 483 |
fasl-compressed | thread param | 288 |
(fasl-file ifn ofn) | procedure | 288 |
(fasl-read binary-input-port) | procedure | 287 |
(fasl-read binary-input-port situation) | procedure | 287 |
(fasl-read binary-input-port situation externals) | procedure | 287 |
(fasl-strip-options symbol ...) | syntax | 377 |
(fasl-write obj binary-output-port) | procedure | 286 |
(fasl-write obj binary-output-port external-pred) | procedure | 286 |
(fasl-write obj binary-output-port external-pred omit-rtds?) | procedure | 286 |
fields | syntax | 331 |
(file-access-time path/port) | procedure | 290 |
(file-access-time path/port follow?) | procedure | 290 |
file-buffer-size | thread param | 256 |
(file-change-time path/port) | procedure | 290 |
(file-change-time path/port follow?) | procedure | 290 |
(file-directory? path) | procedure | 289 |
(file-directory? path follow?) | procedure | 289 |
(file-exists? path) | procedure | 289 |
(file-exists? path follow?) | procedure | 289 |
(file-exists? path) | procedure | 286 |
(file-length port) | procedure | 250 |
(file-modification-time path/port) | procedure | 290 |
(file-modification-time path/port follow?) | procedure | 290 |
(file-options symbol ...) | syntax | 261 |
(file-port? port) | procedure | 256 |
(file-position port) | procedure | 252 |
(file-position port pos) | procedure | 252 |
(file-regular? path) | procedure | 289 |
(file-regular? path follow?) | procedure | 289 |
(file-symbolic-link? path) | procedure | 289 |
(filter procedure list) | procedure | 164 |
(find procedure list) | procedure | 165 |
(finite? real) | procedure | 174 |
(fixnum->flonum fx) | procedure | 211 |
(fixnum-width) | procedure | 193 |
(fixnum? obj) | procedure | 193 |
(fl* fl ...) | procedure | 207 |
(fl+ fl ...) | procedure | 206 |
(fl- fl) | procedure | 206 |
(fl- fl1 fl2 fl3 ...) | procedure | 206 |
(fl-make-rectangular flonum1 flonum2) | procedure | 222 |
(fl/ fl) | procedure | 207 |
(fl/ fl1 fl2 fl3 ...) | procedure | 207 |
(fl< flonum1 flonum2 ...) | procedure | 220 |
(fl<= flonum1 flonum2 ...) | procedure | 220 |
(fl<=? fl1 fl2 fl3 ...) | procedure | 203 |
(fl<? fl1 fl2 fl3 ...) | procedure | 203 |
(fl= flonum1 flonum2 ...) | procedure | 220 |
(fl=? fl1 fl2 fl3 ...) | procedure | 203 |
(fl> flonum1 flonum2 ...) | procedure | 220 |
(fl>= flonum1 flonum2 ...) | procedure | 220 |
(fl>=? fl1 fl2 fl3 ...) | procedure | 203 |
(fl>? fl1 fl2 fl3 ...) | procedure | 203 |
(flabs fl) | procedure | 209 |
(flacos fl) | procedure | 210 |
(flasin fl) | procedure | 210 |
(flatan fl) | procedure | 210 |
(flatan fl1 fl2) | procedure | 210 |
(flceiling fl) | procedure | 208 |
(flcos fl) | procedure | 210 |
(fldenominator fl) | procedure | 209 |
(fldiv fl1 fl2) | procedure | 207 |
(fldiv-and-mod fl1 fl2) | procedure | 207 |
(fldiv0 fl1 fl2) | procedure | 208 |
(fldiv0-and-mod0 fl1 fl2) | procedure | 208 |
(fleven? fl-int) | procedure | 205 |
(flexp fl) | procedure | 209 |
(flexpt fl1 fl2) | procedure | 210 |
(flfinite? fl) | procedure | 205 |
(flfloor fl) | procedure | 208 |
(flinfinite? fl) | procedure | 205 |
(flinteger? fl) | procedure | 204 |
(fllog fl) | procedure | 209 |
(fllog fl1 fl2) | procedure | 209 |
(fllp flonum) | procedure | 221 |
(flmax fl1 fl2 ...) | procedure | 205 |
(flmin fl1 fl2 ...) | procedure | 205 |
(flmod fl1 fl2) | procedure | 207 |
(flmod0 fl1 fl2) | procedure | 208 |
(flnan? fl) | procedure | 205 |
(flnegative? fl) | procedure | 204 |
(flnonnegative? fl) | procedure | 220 |
(flnonpositive? fl) | procedure | 220 |
(flnumerator fl) | procedure | 209 |
(flodd? fl-int) | procedure | 205 |
(flonum->fixnum flonum) | procedure | 219 |
(flonum? obj) | procedure | 203 |
(floor real) | procedure | 177 |
(flpositive? fl) | procedure | 204 |
(flround fl) | procedure | 208 |
(flsin fl) | procedure | 210 |
(flsingle fl) | procedure | 221 |
(flsqrt fl) | procedure | 210 |
(fltan fl) | procedure | 210 |
(fltruncate fl) | procedure | 208 |
(fluid-let ((var expr) ...) body1 body2 ...) | syntax | 120 |
(fluid-let-syntax ((keyword expr) ...) form1 form2 ...) | syntax | 321 |
(flush-output-port) | procedure | 253 |
(flush-output-port output-port) | procedure | 253 |
(flush-output-port output-port) | procedure | 280 |
(flvector flonum ...) | procedure | 158 |
(flvector->list flvector) | procedure | 160 |
(flvector-copy flvector) | procedure | 160 |
(flvector-fill! flvector flonum) | procedure | 160 |
(flvector-length flvector) | procedure | 159 |
(flvector-ref flvector n) | procedure | 159 |
(flvector-set! flvector n flonum) | procedure | 159 |
(flvector? obj) | procedure | 158 |
(flzero? fl) | procedure | 204 |
(fold-left procedure obj list1 list2 ...) | procedure | 120 |
(fold-right procedure obj list1 list2 ...) | procedure | 121 |
(for-all procedure list1 list2 ...) | procedure | 119 |
(for-each procedure list1 list2 ...) | procedure | 118 |
(force promise) | procedure | 128 |
(foreign-address-name address) | procedure | 94 |
(foreign-alignof type) | procedure | 77 |
(foreign-alloc n) | procedure | 75 |
(foreign-callable conv ... proc-exp (param-type ...) res-type) | syntax | 70 |
(foreign-callable-code-object address) | procedure | 73 |
(foreign-callable-entry-point code) | procedure | 73 |
(foreign-entry entry-name) | procedure | 93 |
(foreign-entry? entry-name) | procedure | 93 |
(foreign-free address) | procedure | 75 |
(foreign-procedure conv ... entry-exp (param-type ...) res-type) | syntax | 59 |
(foreign-ref type address offset) | procedure | 75 |
(foreign-set! type address offset value) | procedure | 77 |
(foreign-sizeof type) | procedure | 77 |
(fork-thread thunk) | procedure | 468 |
(format format-string obj ...) | procedure | 275 |
(format #f format-string obj ...) | procedure | 275 |
(format #t format-string obj ...) | procedure | 275 |
(format textual-output-port format-string obj ...) | procedure | 275 |
(format-condition? obj) | procedure | 354 |
(fprintf textual-output-port format-string obj ...) | procedure | 277 |
(free-identifier=? identifier1 identifier2) | procedure | 302 |
(fresh-line) | procedure | 270 |
(fresh-line textual-output-port) | procedure | 270 |
(ftype-&ref ftype-name (a ...) fptr-expr) | syntax | 85 |
(ftype-&ref ftype-name (a ...) fptr-expr index) | syntax | 85 |
(ftype-guardian ftype-name) | syntax | 474 |
(ftype-init-lock! ftype-name (a ...) fptr-expr) | syntax | 472 |
(ftype-init-lock! ftype-name (a ...) fptr-expr index) | syntax | 472 |
(ftype-lock! ftype-name (a ...) fptr-expr) | syntax | 472 |
(ftype-lock! ftype-name (a ...) fptr-expr index) | syntax | 472 |
(ftype-locked-decr! ftype-name (a ...) fptr-expr) | syntax | 473 |
(ftype-locked-decr! ftype-name (a ...) fptr-expr index) | syntax | 473 |
(ftype-locked-incr! ftype-name (a ...) fptr-expr) | syntax | 473 |
(ftype-locked-incr! ftype-name (a ...) fptr-expr index) | syntax | 473 |
(ftype-pointer->sexpr fptr) | procedure | 89 |
(ftype-pointer-address fptr) | procedure | 84 |
(ftype-pointer-ftype fptr) | procedure | 88 |
(ftype-pointer-null? fptr) | syntax | 85 |
(ftype-pointer=? fptr1 fptr2) | syntax | 85 |
(ftype-pointer? obj) | syntax | 84 |
(ftype-pointer? ftype-name obj) | syntax | 84 |
(ftype-ref ftype-name (a ...) fptr-expr) | syntax | 86 |
(ftype-ref ftype-name (a ...) fptr-expr index) | syntax | 86 |
(ftype-set! ftype-name (a ...) fptr-expr val-expr) | syntax | 86 |
(ftype-set! ftype-name (a ...) fptr-expr index val-expr) | syntax | 86 |
(ftype-sizeof ftype-name) | syntax | 82 |
(ftype-spin-lock! ftype-name (a ...) fptr-expr) | syntax | 472 |
(ftype-spin-lock! ftype-name (a ...) fptr-expr index) | syntax | 472 |
(ftype-unlock! ftype-name (a ...) fptr-expr) | syntax | 472 |
(ftype-unlock! ftype-name (a ...) fptr-expr index) | syntax | 472 |
(fx* fixnum ...) | procedure | 217 |
(fx* fx1 fx2) | procedure | 195 |
(fx*/carry fx1 fx2 fx3) | procedure | 197 |
(fx*/wraparound fixnum ...) | procedure | 218 |
(fx+ fixnum ...) | procedure | 216 |
(fx+ fx1 fx2) | procedure | 195 |
(fx+/carry fx1 fx2 fx3) | procedure | 197 |
(fx+/wraparound fixnum ...) | procedure | 218 |
(fx- fixnum1 fixnum2 ...) | procedure | 217 |
(fx- fx) | procedure | 195 |
(fx- fx1 fx2) | procedure | 195 |
(fx-/carry fx1 fx2 fx3) | procedure | 197 |
(fx-/wraparound fixnum ...) | procedure | 218 |
(fx/ fixnum1 fixnum2 ...) | procedure | 217 |
(fx1+ fixnum) | procedure | 218 |
(fx1- fixnum) | procedure | 218 |
(fx< fixnum1 fixnum2 ...) | procedure | 215 |
(fx<= fixnum1 fixnum2 ...) | procedure | 215 |
(fx<=? fx1 fx2 fx3 ...) | procedure | 193 |
(fx<? fx1 fx2 fx3 ...) | procedure | 193 |
(fx= fixnum1 fixnum2 ...) | procedure | 215 |
(fx=? fx1 fx2 fx3 ...) | procedure | 193 |
(fx> fixnum1 fixnum2 ...) | procedure | 215 |
(fx>= fixnum1 fixnum2 ...) | procedure | 215 |
(fx>=? fx1 fx2 fx3 ...) | procedure | 193 |
(fx>? fx1 fx2 fx3 ...) | procedure | 193 |
(fxabs fixnum) | procedure | 219 |
(fxand fx ...) | procedure | 197 |
(fxarithmetic-shift fx1 fx2) | procedure | 201 |
(fxarithmetic-shift-left fx1 fx2) | procedure | 201 |
(fxarithmetic-shift-right fx1 fx2) | procedure | 201 |
(fxbit-count fx) | procedure | 198 |
(fxbit-field fx1 fx2 fx3) | procedure | 200 |
(fxbit-set? fx1 fx2) | procedure | 199 |
(fxcopy-bit fx1 fx2 fx3) | procedure | 200 |
(fxcopy-bit-field fx1 fx2 fx3 fx4) | procedure | 200 |
(fxdiv fx1 fx2) | procedure | 196 |
(fxdiv-and-mod fx1 fx2) | procedure | 196 |
(fxdiv0 fx1 fx2) | procedure | 196 |
(fxdiv0-and-mod0 fx1 fx2) | procedure | 196 |
(fxeven? fx) | procedure | 194 |
(fxfirst-bit-set fx) | procedure | 199 |
(fxif fx1 fx2 fx3) | procedure | 198 |
(fxior fx ...) | procedure | 197 |
(fxlength fx) | procedure | 198 |
(fxlogand fixnum ...) | procedure | 228 |
(fxlogbit0 index fixnum) | procedure | 231 |
(fxlogbit1 index fixnum) | procedure | 231 |
(fxlogbit? index fixnum) | procedure | 230 |
(fxlogior fixnum ...) | procedure | 229 |
(fxlognot fixnum) | procedure | 229 |
(fxlogor fixnum ...) | procedure | 229 |
(fxlogtest fixnum1 fixnum2) | procedure | 230 |
(fxlogxor fixnum ...) | procedure | 229 |
(fxmax fx1 fx2 ...) | procedure | 195 |
(fxmin fx1 fx2 ...) | procedure | 195 |
(fxmod fx1 fx2) | procedure | 196 |
(fxmod0 fx1 fx2) | procedure | 196 |
(fxmodulo fixnum1 fixnum2) | procedure | 219 |
(fxnegative? fx) | procedure | 194 |
(fxnonnegative? fixnum) | procedure | 216 |
(fxnonpositive? fixnum) | procedure | 216 |
(fxnot fx) | procedure | 197 |
(fxodd? fx) | procedure | 194 |
(fxpopcount fixnum) | procedure | 232 |
(fxpopcount16 fixnum) | procedure | 232 |
(fxpopcount32 fixnum) | procedure | 232 |
(fxpositive? fx) | procedure | 194 |
(fxquotient fixnum1 fixnum2 ...) | procedure | 218 |
(fxremainder fixnum1 fixnum2) | procedure | 218 |
(fxreverse-bit-field fx1 fx2 fx3) | procedure | 202 |
(fxrotate-bit-field fx1 fx2 fx3 fx4) | procedure | 201 |
(fxsll fixnum count) | procedure | 231 |
(fxsll/wraparound fixnum ...) | procedure | 218 |
(fxsra fixnum count) | procedure | 232 |
(fxsrl fixnum count) | procedure | 232 |
(fxvector fixnum ...) | procedure | 156 |
(fxvector->list fxvector) | procedure | 157 |
(fxvector-copy fxvector) | procedure | 158 |
(fxvector-fill! fxvector fixnum) | procedure | 157 |
(fxvector-length fxvector) | procedure | 156 |
(fxvector-ref fxvector n) | procedure | 156 |
(fxvector-set! fxvector n fixnum) | procedure | 157 |
(fxvector? obj) | procedure | 155 |
(fxxor fx ...) | procedure | 197 |
(fxzero? fx) | procedure | 194 |
(gcd int ...) | procedure | 179 |
generate-allocation-counts | thread param | 427 |
generate-covin-files | thread param | 402 |
generate-inspector-information | thread param | 391 |
generate-instruction-counts | thread param | 427 |
generate-interrupt-trap | thread param | 390 |
generate-procedure-source-information | thread param | 391 |
(generate-profile-forms) | thread param | 402 |
(generate-temporaries list) | procedure | 310 |
generate-wpo-files | thread param | 392 |
(gensym) | procedure | 170 |
(gensym pretty-name) | procedure | 170 |
(gensym pretty-name unique-name) | procedure | 170 |
(gensym->unique-string gensym) | procedure | 172 |
gensym-count | thread param | 172 |
gensym-prefix | thread param | 172 |
(gensym? obj) | procedure | 172 |
(get-bytevector-all binary-input-port) | procedure | 275 |
(get-bytevector-n binary-input-port n) | procedure | 274 |
(get-bytevector-n! binary-input-port bytevector start n) | procedure | 274 |
(get-bytevector-some binary-input-port) | procedure | 275 |
(get-bytevector-some! binary-input-port bytevector start n) | procedure | 260 |
(get-char textual-input-port) | procedure | 275 |
(get-datum textual-input-port) | procedure | 278 |
(get-datum/annotations textual-input-port sfd bfp) | procedure | 348 |
(get-hash-table ht k d) | procedure | 482 |
(get-initial-thread) | procedure | 468 |
(get-line textual-input-port) | procedure | 277 |
(get-mode path) | procedure | 291 |
(get-mode path follow?) | procedure | 291 |
(get-output-string string-output-port) | procedure | 255 |
(get-process-id) | procedure | 434 |
(get-registry key) | procedure | 434 |
(get-source-table! textual-input-port source-table) | procedure | 351 |
(get-source-table! textual-input-port source-table combine) | procedure | 351 |
(get-string-all textual-input-port) | procedure | 277 |
(get-string-n textual-input-port n) | procedure | 276 |
(get-string-n! textual-input-port string start n) | procedure | 276 |
(get-string-some textual-input-port) | procedure | 259 |
(get-string-some! textual-input-port string start n) | procedure | 259 |
(get-thread-id) | procedure | 468 |
(get-u8 binary-input-port) | procedure | 274 |
(getenv key) | procedure | 434 |
(getprop symbol key) | procedure | 173 |
(getprop symbol key default) | procedure | 173 |
(greatest-fixnum) | procedure | 193 |
(guard (var clause1 clause2 ...) b1 b2 ...) | syntax | 361 |
(guardian? obj) | procedure | 450 |
(hash-table-for-each ht p) | procedure | 482 |
(hash-table-map ht p) | procedure | 482 |
(hash-table? obj) | procedure | 481 |
(hashtable-cell hashtable key default) | procedure | 176 |
(hashtable-cells hashtable) | procedure | 179 |
(hashtable-cells hashtable size) | procedure | 179 |
(hashtable-clear! hashtable) | procedure | 249 |
(hashtable-clear! hashtable size) | procedure | 249 |
(hashtable-contains? hashtable key) | procedure | 246 |
(hashtable-copy hashtable) | procedure | 248 |
(hashtable-copy hashtable mutable?) | procedure | 248 |
(hashtable-delete! hashtable key) | procedure | 248 |
(hashtable-entries hashtable) | procedure | 178 |
(hashtable-entries hashtable size) | procedure | 178 |
(hashtable-entries hashtable) | procedure | 250 |
(hashtable-ephemeron? obj) | procedure | 180 |
(hashtable-equivalence-function hashtable) | procedure | 245 |
(hashtable-hash-function hashtable) | procedure | 245 |
(hashtable-keys hashtable) | procedure | 177 |
(hashtable-keys hashtable size) | procedure | 177 |
(hashtable-keys hashtable) | procedure | 249 |
(hashtable-mutable? hashtable) | procedure | 245 |
(hashtable-ref hashtable key default) | procedure | 246 |
(hashtable-ref-cell hashtable key) | procedure | 177 |
(hashtable-set! hashtable key obj) | procedure | 246 |
(hashtable-size hashtable) | procedure | 248 |
(hashtable-update! hashtable key procedure default) | procedure | 247 |
(hashtable-values hashtable) | procedure | 178 |
(hashtable-values hashtable size) | procedure | 178 |
(hashtable-weak? obj) | procedure | 180 |
(hashtable? obj) | procedure | 155 |
heap-reserve-ratio | global param | 442 |
(i/o-decoding-error? obj) | procedure | 375 |
(i/o-encoding-error-char condition) | procedure | 376 |
(i/o-encoding-error? obj) | procedure | 376 |
(i/o-error-filename condition) | procedure | 373 |
(i/o-error-port condition) | procedure | 375 |
(i/o-error-position condition) | procedure | 372 |
(i/o-error? obj) | procedure | 371 |
(i/o-file-already-exists-error? obj) | procedure | 374 |
(i/o-file-does-not-exist-error? obj) | procedure | 374 |
(i/o-file-is-read-only-error? obj) | procedure | 374 |
(i/o-file-protection-error? obj) | procedure | 373 |
(i/o-filename-error? obj) | procedure | 373 |
(i/o-invalid-position-error? obj) | procedure | 372 |
(i/o-port-error? obj) | procedure | 375 |
(i/o-read-error? obj) | procedure | 372 |
(i/o-write-error? obj) | procedure | 372 |
(iconv-codec code-page) | procedure | 244 |
(identifier-syntax tmpl) | syntax | 297 |
(identifier-syntax (id1 tmpl1) ((set! id2 e2) tmpl2)) | syntax | 297 |
(identifier? obj) | procedure | 301 |
ieee | module | 339 |
(ieee-environment) | procedure | 362 |
(if test consequent alternative) | syntax | 109 |
(if test consequent) | syntax | 109 |
(imag-part num) | procedure | 182 |
immutable | syntax | 331 |
(immutable-box? obj) | procedure | 169 |
(immutable-bytevector? obj) | procedure | 164 |
(immutable-string? obj) | procedure | 152 |
(immutable-vector? obj) | procedure | 154 |
(implementation-restriction-violation? obj) | procedure | 369 |
(implicit-exports #t) | syntax | 314 |
(implicit-exports #f) | syntax | 314 |
(import import-spec ...) | syntax | 308 |
import-notify | thread param | 317 |
(import-only import-spec ...) | syntax | 308 |
in-place-minimum-generation | global param | 442 |
(include path) | syntax | 326 |
(indirect-export id indirect-id ...) | syntax | 313 |
(inexact num) | procedure | 180 |
(inexact->exact num) | procedure | 181 |
(inexact? num) | procedure | 170 |
(infinite? real) | procedure | 174 |
(initial-bytes-allocated) | procedure | 422 |
(input-port-ready? input-port) | procedure | 261 |
(input-port? obj) | procedure | 270 |
(inspect obj) | procedure | 42 |
(inspect/object object) | procedure | 47 |
(integer->char n) | procedure | 215 |
(integer-length n) | procedure | 236 |
(integer-valued? obj) | procedure | 153 |
(integer? obj) | procedure | 151 |
interaction-environment | thread param | 362 |
(interactive?) | procedure | 433 |
internal-defines-as-letrec* | thread param | 118 |
(interpret obj) | procedure | 365 |
(interpret obj env) | procedure | 365 |
(invoke-library libref) | procedure | 315 |
(iota n) | procedure | 145 |
(irritants-condition? obj) | procedure | 368 |
(isqrt n) | procedure | 236 |
(keep-live v) | procedure | 442 |
keyboard-interrupt-handler | thread param | 358 |
(lambda formals body1 body2 ...) | syntax | 92 |
(last-pair list) | procedure | 144 |
(latin-1-codec) | procedure | 259 |
(lcm int ...) | procedure | 179 |
(least-fixnum) | procedure | 193 |
(length list) | procedure | 159 |
(let ((var expr) ...) body1 body2 ...) | syntax | 95 |
(let name ((var expr) ...) body1 body2 ...) | syntax | 114 |
(let* ((var expr) ...) body1 body2 ...) | syntax | 96 |
(let*-values ((formals expr) ...) body1 body2 ...) | syntax | 99 |
(let-syntax ((keyword expr) ...) form1 form2 ...) | syntax | 293 |
(let-values ((formals expr) ...) body1 body2 ...) | syntax | 99 |
(letrec ((var expr) ...) body1 body2 ...) | syntax | 97 |
(letrec* ((var expr) ...) body1 body2 ...) | syntax | 98 |
(letrec-syntax ((keyword expr) ...) form1 form2 ...) | syntax | 293 |
(lexical-violation? obj) | procedure | 370 |
(library name exports imports library-body) | syntax | 306 |
library-directories | thread param | 316 |
(library-exports libref) | procedure | 318 |
library-extensions | thread param | 316 |
(library-list) | procedure | 318 |
(library-object-filename libref) | procedure | 318 |
(library-requirements libref) | procedure | 318 |
(library-requirements libref options) | procedure | 318 |
(library-requirements-options symbol ...) | syntax | 319 |
library-search-handler | thread param | 317 |
library-timstamp-mode | thread param | 317 |
(library-version libref) | procedure | 318 |
(list obj ...) | procedure | 158 |
(list* obj ... final-obj) | procedure | 145 |
(list->flvector list) | procedure | 160 |
(list->fxvector list) | procedure | 157 |
(list->string list) | procedure | 223 |
(list->vector list) | procedure | 226 |
(list-assuming-immutable? v) | procedure | 144 |
(list-copy list) | procedure | 145 |
(list-head list n) | procedure | 144 |
(list-ref list n) | procedure | 159 |
(list-sort predicate list) | procedure | 167 |
(list-tail list n) | procedure | 160 |
(list? obj) | procedure | 158 |
(literal-identifier=? identifier1 identifier2) | procedure | 328 |
(load path) | procedure | 366 |
(load path eval-proc) | procedure | 366 |
(load-compiled-from-port input-port) | procedure | 368 |
(load-compiled-from-port input-port externals) | procedure | 368 |
(load-library path) | procedure | 366 |
(load-library path eval-proc) | procedure | 366 |
(load-program path) | procedure | 367 |
(load-program path eval-proc) | procedure | 367 |
(load-shared-object path) | procedure | 94 |
(locate-source sfd pos) | procedure | 348 |
(locate-source sfd pos use-cache?) | procedure | 348 |
(locate-source-object-source source-object get-start? use-cache?) | procedure | 349 |
(lock-object obj) | procedure | 451 |
(locked-object? obj) | procedure | 452 |
(log num) | procedure | 184 |
(log num1 num2) | procedure | 184 |
(logand int ...) | procedure | 224 |
(logbit0 index int) | procedure | 227 |
(logbit1 index int) | procedure | 228 |
(logbit? index int) | procedure | 226 |
(logior int ...) | procedure | 225 |
(lognot int) | procedure | 226 |
(logor int ...) | procedure | 225 |
(logtest int1 int2) | procedure | 227 |
(logxor int ...) | procedure | 225 |
(lookahead-char textual-input-port) | procedure | 275 |
(lookahead-u8 binary-input-port) | procedure | 274 |
(machine-type) | procedure | 378 |
(magnitude num) | procedure | 183 |
(magnitude-squared num) | procedure | 237 |
(make-annotation obj source-object stripped-obj) | procedure | 345 |
(make-annotation obj source-object stripped-obj options) | procedure | 345 |
(make-arity-wrapper-procedure proc arity-mask data) | procedure | 209 |
(make-assertion-violation) | procedure | 366 |
(make-boot-file output-filename base-boot-list input-filename ...) | procedure | 376 |
(make-boot-header output-filename base-boot1 base-boot2...) | procedure | 377 |
(make-bytevector n) | procedure | 228 |
(make-bytevector n fill) | procedure | 228 |
make-codec-buffer | thread param | 245 |
(make-compile-time-value obj) | procedure | 328 |
(make-condition) | procedure | 470 |
(make-condition name) | procedure | 470 |
(make-continuation-condition continuation) | procedure | 355 |
(make-cost-center) | procedure | 428 |
(make-custom-binary-input-port id r! gp sp! close) | procedure | 267 |
(make-custom-binary-input/output-port id r! w! gp sp! close) | procedure | 267 |
(make-custom-binary-output-port id w! gp sp! close) | procedure | 267 |
(make-custom-textual-input-port id r! gp sp! close) | procedure | 268 |
(make-custom-textual-input/output-port id r! w! gp sp! close) | procedure | 268 |
(make-custom-textual-output-port id w! gp sp! close) | procedure | 268 |
(make-date nsec sec min hour day mon year) | procedure | 417 |
(make-date nsec sec min hour day mon year offset) | procedure | 417 |
(make-engine thunk) | procedure | 136 |
(make-enumeration symbol-list) | procedure | 251 |
(make-ephemeron-eq-hashtable) | procedure | 180 |
(make-ephemeron-eq-hashtable size) | procedure | 180 |
(make-ephemeron-eqv-hashtable) | procedure | 180 |
(make-ephemeron-eqv-hashtable size) | procedure | 180 |
(make-ephemeron-hashtable hash equiv?) | procedure | 180 |
(make-ephemeron-hashtable hash equiv? size) | procedure | 180 |
(make-eq-hashtable) | procedure | 243 |
(make-eq-hashtable size) | procedure | 243 |
(make-eqv-hashtable) | procedure | 244 |
(make-eqv-hashtable size) | procedure | 244 |
(make-error) | procedure | 367 |
(make-flvector n) | procedure | 159 |
(make-flvector n flonum) | procedure | 159 |
(make-format-condition) | procedure | 354 |
(make-ftype-pointer ftype-name expr) | syntax | 82 |
(make-fxvector n) | procedure | 156 |
(make-fxvector n fixnum) | procedure | 156 |
(make-guardian) | procedure | 446 |
(make-guardian ordered?) | procedure | 446 |
(make-hash-table) | procedure | 481 |
(make-hash-table weak?) | procedure | 481 |
(make-hashtable hash equiv?) | procedure | 244 |
(make-hashtable hash equiv? size) | procedure | 244 |
(make-i/o-decoding-error pobj) | procedure | 375 |
(make-i/o-encoding-error pobj cobj) | procedure | 376 |
(make-i/o-error) | procedure | 371 |
(make-i/o-file-already-exists-error filename) | procedure | 374 |
(make-i/o-file-does-not-exist-error filename) | procedure | 374 |
(make-i/o-file-is-read-only-error filename) | procedure | 374 |
(make-i/o-file-protection-error filename) | procedure | 373 |
(make-i/o-filename-error filename) | procedure | 373 |
(make-i/o-invalid-position-error position) | procedure | 372 |
(make-i/o-port-error pobj) | procedure | 375 |
(make-i/o-read-error) | procedure | 372 |
(make-i/o-write-error) | procedure | 372 |
(make-immobile-bytevector n) | procedure | 452 |
(make-immobile-bytevector n byte) | procedure | 452 |
(make-immobile-reference-bytevector n) | procedure | 91 |
(make-immobile-vector n) | procedure | 452 |
(make-immobile-vector n obj) | procedure | 452 |
(make-implementation-restriction-violation) | procedure | 369 |
(make-input-port handler input-buffer) | procedure | 245 |
(make-input/output-port handler input-buffer output-buffer) | procedure | 245 |
(make-irritants-condition irritants) | procedure | 368 |
(make-lexical-violation) | procedure | 370 |
(make-list n) | procedure | 145 |
(make-list n obj) | procedure | 145 |
(make-message-condition message) | procedure | 368 |
(make-mutex) | procedure | 469 |
(make-mutex name) | procedure | 469 |
(make-no-infinities-violation) | procedure | 376 |
(make-no-nans-violation) | procedure | 377 |
(make-non-continuable-violation) | procedure | 369 |
(make-object-finder pred) | procedure | 53 |
(make-object-finder pred g) | procedure | 53 |
(make-object-finder pred x g) | procedure | 53 |
(make-output-port handler output-buffer) | procedure | 245 |
(make-parameter object) | procedure | 429 |
(make-parameter object procedure) | procedure | 429 |
(make-phantom-bytevector n) | procedure | 453 |
(make-polar real1 real2) | procedure | 183 |
(make-pseudo-random-generator) | procedure | 233 |
(make-record-constructor-descriptor rtd parent-rcd protocol) | procedure | 332 |
(make-record-type type-name fields) | procedure | 203 |
(make-record-type parent-rtd type-name fields) | procedure | 203 |
(make-record-type-descriptor name parent uid s? o? fields) | procedure | 208 |
(make-record-type-descriptor name parent uid s? o? fields) | procedure | 331 |
(make-rectangular real1 real2) | procedure | 182 |
(make-reference-bytevector n) | procedure | 91 |
(make-serious-condition) | procedure | 366 |
(make-source-condition form) | procedure | 354 |
(make-source-file-descriptor obj binary-input-port) | procedure | 347 |
(make-source-file-descriptor obj binary-input-port reset?) | procedure | 347 |
(make-source-object sfd bfp efp) | procedure | 346 |
(make-source-object sfd bfp efp line column) | procedure | 346 |
(make-source-table) | procedure | 349 |
(make-sstats cpu real bytes gc-count gc-cpu gc-real gc-bytes) | procedure | 424 |
(make-string n) | procedure | 218 |
(make-string n char) | procedure | 218 |
(make-syntax-violation form subform) | procedure | 370 |
(make-thread-parameter object) | procedure | 476 |
(make-thread-parameter object procedure) | procedure | 476 |
(make-time type nsec sec) | procedure | 414 |
(make-transcoder codec) | procedure | 259 |
(make-transcoder codec eol-style) | procedure | 259 |
(make-transcoder codec eol-style error-handling-mode) | procedure | 259 |
(make-undefined-violation) | procedure | 371 |
(make-variable-transformer procedure) | procedure | 306 |
(make-vector n) | procedure | 224 |
(make-vector n obj) | procedure | 224 |
(make-violation) | procedure | 366 |
(make-warning) | procedure | 367 |
(make-weak-eq-hashtable) | procedure | 179 |
(make-weak-eq-hashtable size) | procedure | 179 |
(make-weak-eqv-hashtable) | procedure | 179 |
(make-weak-eqv-hashtable size) | procedure | 179 |
(make-weak-hashtable hash equiv?) | procedure | 179 |
(make-weak-hashtable hash equiv? size) | procedure | 179 |
(make-who-condition who) | procedure | 369 |
(make-wrapper-procedure proc arity-mask data) | procedure | 209 |
(map procedure list1 list2 ...) | procedure | 117 |
(mark-port-closed! port) | procedure | 249 |
(max real1 real2 ...) | procedure | 178 |
(maximum-memory-bytes) | procedure | 423 |
(maybe-compile-file input-filename) | procedure | 372 |
(maybe-compile-file input-filename output-filename) | procedure | 372 |
(maybe-compile-library input-filename) | procedure | 372 |
(maybe-compile-library input-filename output-filename) | procedure | 372 |
(maybe-compile-program input-filename) | procedure | 372 |
(maybe-compile-program input-filename output-filename) | procedure | 372 |
(member obj list) | procedure | 161 |
(memory-order-acquire) | procedure | 476 |
(memory-order-release) | procedure | 476 |
(memp procedure list) | procedure | 163 |
(memq obj list) | procedure | 161 |
(memv obj list) | procedure | 161 |
(merge predicate list1 list2) | procedure | 176 |
(merge! predicate list1 list2) | procedure | 176 |
(message-condition? obj) | procedure | 368 |
(meta . definition) | syntax | 340 |
(meta-cond clause1 clause2 ...) | syntax | 341 |
(min real1 real2 ...) | procedure | 178 |
(mkdir path) | procedure | 290 |
(mkdir path mode) | procedure | 290 |
(mod x1 x2) | procedure | 175 |
(mod0 x1 x2) | procedure | 176 |
(module name interface defn ... init ...) | syntax | 333 |
(module interface defn ... init ...) | syntax | 333 |
(modulo int1 int2) | procedure | 175 |
(most-negative-fixnum) | procedure | 215 |
(most-positive-fixnum) | procedure | 215 |
(multibyte->string code-page bytevector) | procedure | 271 |
mutable | syntax | 331 |
(mutable-box? obj) | procedure | 169 |
(mutable-bytevector? obj) | procedure | 164 |
(mutable-string? obj) | procedure | 152 |
(mutable-vector? obj) | procedure | 154 |
(mutex-acquire mutex) | procedure | 469 |
(mutex-acquire mutex block?) | procedure | 469 |
(mutex-name mutex) | procedure | 470 |
(mutex-release mutex) | procedure | 469 |
(mutex? obj) | procedure | 469 |
(nan? real) | procedure | 174 |
(native-endianness) | procedure | 228 |
(native-eol-style) | procedure | 260 |
(native-transcoder) | procedure | 259 |
(negative? real) | procedure | 173 |
(new-cafe) | procedure | 407 |
(new-cafe eval-proc) | procedure | 407 |
(newline) | procedure | 285 |
(newline textual-output-port) | procedure | 285 |
(no-infinities-violation? obj) | procedure | 376 |
(no-nans-violation? obj) | procedure | 377 |
(non-continuable-violation? obj) | procedure | 369 |
nongenerative | syntax | 331 |
(nonnegative? real) | procedure | 237 |
(nonpositive? real) | procedure | 237 |
(not obj) | procedure | 110 |
(null-environment version) | procedure | 137 |
(null? obj) | procedure | 151 |
(number->string num) | procedure | 238 |
(number->string num radix) | procedure | 238 |
(number->string num radix precision) | procedure | 238 |
(number->string num) | procedure | 191 |
(number->string num radix) | procedure | 191 |
(number->string num radix precision) | procedure | 191 |
(number? obj) | procedure | 151 |
(numerator rat) | procedure | 181 |
(object->reference-address obj) | procedure | 92 |
(object-backreferences) | procedure | 426 |
(object-counts) | procedure | 425 |
(oblist) | procedure | 174 |
(odd? int) | procedure | 174 |
only | syntax | 338 |
opaque | syntax | 331 |
(open-bytevector-input-port bytevector) | procedure | 264 |
(open-bytevector-input-port bytevector ?transcoder) | procedure | 264 |
(open-bytevector-output-port) | procedure | 265 |
(open-bytevector-output-port ?transcoder) | procedure | 265 |
(open-fd-input-port fd) | procedure | 258 |
(open-fd-input-port fd b-mode) | procedure | 258 |
(open-fd-input-port fd b-mode ?transcoder) | procedure | 258 |
(open-fd-input/output-port fd) | procedure | 270 |
(open-fd-input/output-port fd b-mode) | procedure | 270 |
(open-fd-input/output-port fd b-mode ?transcoder) | procedure | 270 |
(open-fd-output-port fd) | procedure | 267 |
(open-fd-output-port fd b-mode) | procedure | 267 |
(open-fd-output-port fd b-mode ?transcoder) | procedure | 267 |
(open-file-input-port path) | procedure | 262 |
(open-file-input-port path options) | procedure | 262 |
(open-file-input-port path options b-mode) | procedure | 262 |
(open-file-input-port path options b-mode ?transcoder) | procedure | 262 |
(open-file-input/output-port path) | procedure | 263 |
(open-file-input/output-port path options) | procedure | 263 |
(open-file-input/output-port path options b-mode) | procedure | 263 |
(open-file-input/output-port path options b-mode ?transcoder) | procedure | 263 |
(open-file-output-port path) | procedure | 262 |
(open-file-output-port path options) | procedure | 262 |
(open-file-output-port path options b-mode) | procedure | 262 |
(open-file-output-port path options b-mode ?transcoder) | procedure | 262 |
(open-input-file path) | procedure | 257 |
(open-input-file path options) | procedure | 257 |
(open-input-file path) | procedure | 280 |
(open-input-output-file path) | procedure | 270 |
(open-input-output-file path options) | procedure | 270 |
(open-input-string string) | procedure | 254 |
(open-output-file path) | procedure | 265 |
(open-output-file path options) | procedure | 265 |
(open-output-file path) | procedure | 281 |
(open-output-string) | procedure | 255 |
(open-process-ports command) | procedure | 58 |
(open-process-ports command b-mode) | procedure | 58 |
(open-process-ports command b-mode ?transcoder) | procedure | 58 |
(open-source-file sfd) | procedure | 348 |
(open-string-input-port string) | procedure | 265 |
(open-string-output-port) | procedure | 266 |
optimize-level | thread param | 389 |
(or expr ...) | syntax | 110 |
(ormap procedure list1 list2 ...) | procedure | 129 |
(output-port-buffer-mode port) | procedure | 273 |
(output-port? obj) | procedure | 270 |
(pair? obj) | procedure | 151 |
(parameterize ((param expr) ...) body1 body2 ...) | syntax | 430 |
parent | syntax | 331 |
parent-rtd | syntax | 331 |
(pariah expr1 expr2 ...) | syntax | 397 |
(partition procedure list) | procedure | 164 |
(path-absolute? path) | procedure | 292 |
(path-build dir-path path) | procedure | 292 |
(path-extension path) | procedure | 292 |
(path-first path) | procedure | 292 |
(path-last path) | procedure | 292 |
(path-parent path) | procedure | 292 |
(path-rest path) | procedure | 292 |
(path-root path) | procedure | 292 |
(pbchunk-convert-file in-path out-path c-paths c-names start-index) | procedure | 378 |
(peek-char) | procedure | 284 |
(peek-char textual-input-port) | procedure | 284 |
(petite?) | procedure | 433 |
(phantom-bytevector-length pbv) | procedure | 453 |
(phantom-bytevector? obj) | procedure | 453 |
(port-bol? port) | procedure | 249 |
(port-closed? port) | procedure | 249 |
(port-eof? input-port) | procedure | 278 |
(port-file-compressed! port) | procedure | 253 |
(port-file-descriptor port) | procedure | 256 |
(port-handler port) | procedure | 245 |
(port-has-port-length? port) | procedure | 250 |
(port-has-port-nonblocking?? port) | procedure | 251 |
(port-has-port-position? port) | procedure | 271 |
(port-has-set-port-length!? port) | procedure | 251 |
(port-has-set-port-nonblocking!? port) | procedure | 251 |
(port-has-set-port-position!? port) | procedure | 272 |
(port-input-buffer input-port) | procedure | 246 |
(port-input-count input-port) | procedure | 247 |
(port-input-empty? input-port) | procedure | 247 |
(port-input-index input-port) | procedure | 246 |
(port-input-size input-port) | procedure | 246 |
(port-length port) | procedure | 250 |
(port-name port) | procedure | 250 |
(port-nonblocking? port) | procedure | 251 |
(port-output-buffer output-port) | procedure | 247 |
(port-output-count output-port) | procedure | 248 |
(port-output-full? output-port) | procedure | 248 |
(port-output-index output-port) | procedure | 247 |
(port-output-size output-port) | procedure | 247 |
(port-position port) | procedure | 271 |
(port-transcoder port) | procedure | 271 |
(port? obj) | procedure | 270 |
(positive? real) | procedure | 173 |
predicate | syntax | 199 |
prefix | syntax | 199 |
(pretty-file ifn ofn) | procedure | 272 |
(pretty-format sym) | procedure | 272 |
(pretty-format sym fmt) | procedure | 272 |
pretty-initial-indent | thread param | 274 |
pretty-line-length | thread param | 274 |
pretty-maximum-lines | thread param | 275 |
pretty-one-line-limit | thread param | 274 |
(pretty-print obj) | procedure | 271 |
(pretty-print obj textual-output-port) | procedure | 271 |
pretty-standard-indent | thread param | 275 |
print-brackets | thread param | 282 |
print-char-name | thread param | 279 |
print-extended-identifiers | thread param | 283 |
print-gensym | thread param | 282 |
print-graph | thread param | 280 |
print-length | thread param | 280 |
print-level | thread param | 280 |
print-positive-exponent-sign | thread param | 285 |
print-precision | thread param | 284 |
print-radix | thread param | 281 |
print-record | thread param | 203 |
print-select-flonum-exponential-format | thread param | 285 |
print-subnormal-precision | thread param | 284 |
print-unicode | thread param | 285 |
print-vector-length | thread param | 284 |
(printf format-string obj ...) | procedure | 277 |
(expr0 expr1 ...) | syntax | 107 |
(procedure-arity-mask proc) | procedure | 208 |
(procedure-known-single-valued? proc) | procedure | 211 |
(procedure? obj) | procedure | 155 |
(process command) | procedure | 58 |
(profile source-object) | syntax | 402 |
(profile-clear) | procedure | 402 |
(profile-clear-database) | procedure | 407 |
(profile-dump) | procedure | 403 |
(profile-dump-data path) | procedure | 406 |
(profile-dump-data path dump) | procedure | 406 |
(profile-dump-html) | procedure | 404 |
(profile-dump-html prefix) | procedure | 404 |
(profile-dump-html prefix dump) | procedure | 404 |
(profile-dump-list) | procedure | 405 |
(profile-dump-list warn?) | procedure | 405 |
(profile-dump-list warn? dump) | procedure | 405 |
(profile-line-number-color) | thread param | 405 |
(profile-load-data path ...) | procedure | 406 |
(profile-palette) | thread param | 404 |
(profile-query-weight obj) | procedure | 407 |
(profile-release-counters) | procedure | 403 |
(property-list symbol) | procedure | 174 |
protocol | syntax | 331 |
(pseudo-random-generator->vector prgen) | procedure | 234 |
(pseudo-random-generator-next! prgen) | procedure | 234 |
(pseudo-random-generator-next! prgen below-int) | procedure | 234 |
(pseudo-random-generator-seed! prgen seed-int) | procedure | 234 |
(pseudo-random-generator? val) | procedure | 233 |
(put-bytevector binary-output-port bytevector) | procedure | 279 |
(put-bytevector binary-output-port bytevector start) | procedure | 279 |
(put-bytevector binary-output-port bytevector start n) | procedure | 279 |
(put-bytevector-some binary-output-port bytevector) | procedure | 268 |
(put-bytevector-some binary-output-port bytevector start) | procedure | 268 |
(put-bytevector-some binary-output-port bytevector start n) | procedure | 268 |
(put-char textual-output-port char) | procedure | 279 |
(put-datum textual-output-port obj) | procedure | 279 |
(put-hash-table! ht k v) | procedure | 482 |
(put-registry! key val) | procedure | 434 |
(put-source-table textual-output-port source-table) | procedure | 351 |
(put-string textual-output-port string) | procedure | 279 |
(put-string textual-output-port string start) | procedure | 279 |
(put-string textual-output-port string start n) | procedure | 279 |
(put-string-some textual-output-port string) | procedure | 268 |
(put-string-some textual-output-port string start) | procedure | 268 |
(put-string-some textual-output-port string start n) | procedure | 268 |
(put-u8 binary-output-port octet) | procedure | 278 |
(putenv key value) | procedure | 434 |
(putprop symbol key value) | procedure | 173 |
(quasiquote obj ...) | syntax | 142 |
(quasisyntax template ...) | syntax | 305 |
(quote obj) | syntax | 141 |
(quotient int1 int2) | procedure | 175 |
r5rs | module | 339 |
r5rs-syntax | module | 339 |
(raise obj) | procedure | 357 |
(raise-continuable obj) | procedure | 357 |
(random real) | procedure | 233 |
random-seed | thread param | 233 |
(rational-valued? obj) | procedure | 153 |
(rational? obj) | procedure | 151 |
(rationalize real1 real2) | procedure | 181 |
(ratnum? obj) | procedure | 215 |
(read) | procedure | 284 |
(read textual-input-port) | procedure | 284 |
(read-char) | procedure | 284 |
(read-char textual-input-port) | procedure | 284 |
(read-token) | procedure | 262 |
(read-token textual-input-port) | procedure | 262 |
(read-token textual-input-port sfd bfp) | procedure | 262 |
(real->flonum real) | procedure | 211 |
(real-part num) | procedure | 182 |
(real-time) | procedure | 421 |
(real-valued? obj) | procedure | 153 |
(real? obj) | procedure | 151 |
(rec var expr) | syntax | 119 |
(record-accessor rtd idx) | procedure | 334 |
(record-case expr clause1 clause2 ...) | syntax | 128 |
(record-constructor rcd) | procedure | 205 |
(record-constructor rtd) | procedure | 205 |
(record-constructor rcd) | procedure | 333 |
(record-constructor-descriptor record-name) | syntax | 333 |
(record-constructor-descriptor? obj) | procedure | 143 |
(record-equal-procedure record1 record2) | procedure | 191 |
(record-field-accessible? rtd field-id) | procedure | 205 |
(record-field-accessor rtd field-id) | procedure | 205 |
(record-field-mutable? rtd field-id) | procedure | 206 |
(record-field-mutable? rtd idx) | procedure | 338 |
(record-field-mutator rtd field-id) | procedure | 205 |
(record-hash-procedure record) | procedure | 191 |
(record-instance? obj rtd) | procedure | 207 |
(record-mutator rtd idx) | procedure | 334 |
(record-predicate rtd) | procedure | 333 |
(record-reader name) | procedure | 200 |
(record-reader rtd) | procedure | 200 |
(record-reader name rtd) | procedure | 200 |
(record-reader name #f) | procedure | 200 |
(record-reader rtd #f) | procedure | 200 |
(record-rtd record) | procedure | 338 |
(record-type-descriptor rec) | procedure | 208 |
(record-type-descriptor record-name) | syntax | 333 |
(record-type-descriptor? obj) | procedure | 332 |
(record-type-equal-procedure rtd equal-proc) | procedure | 190 |
(record-type-equal-procedure rtd) | procedure | 190 |
(record-type-field-decls rtd) | procedure | 207 |
(record-type-field-names rtd) | procedure | 206 |
(record-type-field-names rtd) | procedure | 337 |
(record-type-generative? rtd) | procedure | 337 |
(record-type-has-named-fields? rtd) | procedure | 208 |
(record-type-hash-procedure rtd hash-proc) | procedure | 191 |
(record-type-hash-procedure rtd) | procedure | 191 |
(record-type-name rtd) | procedure | 206 |
(record-type-name rtd) | procedure | 336 |
(record-type-opaque? rtd) | procedure | 337 |
(record-type-parent rtd) | procedure | 336 |
(record-type-sealed? rtd) | procedure | 337 |
(record-type-symbol rtd) | procedure | 206 |
(record-type-uid rtd) | procedure | 336 |
(record-writer rtd) | procedure | 201 |
(record-writer rtd procedure) | procedure | 201 |
(record? obj) | procedure | 207 |
(record? obj rtd) | procedure | 207 |
(record? obj) | procedure | 338 |
(reference*-address->object addr) | procedure | 92 |
(reference-address->object addr) | procedure | 92 |
(reference-bytevector? obj) | procedure | 91 |
(register-signal-handler sig procedure) | procedure | 360 |
release-minimum-generation | global param | 441 |
(remainder int1 int2) | procedure | 175 |
(remove obj list) | procedure | 163 |
(remove! obj list) | procedure | 146 |
(remove-foreign-entry entry-name) | procedure | 96 |
(remove-hash-table! ht k) | procedure | 482 |
(remove-registry! key) | procedure | 434 |
(remp procedure list) | procedure | 163 |
(remprop symbol key) | procedure | 174 |
(remq obj list) | procedure | 163 |
(remq! obj list) | procedure | 146 |
(remv obj list) | procedure | 163 |
(remv! obj list) | procedure | 146 |
rename | syntax | 338 |
(rename-file old-pathname new-pathname) | procedure | 291 |
require-nongenerative-clause | thread param | 188 |
(reset) | procedure | 410 |
(reset-cost-center! cost-center) | procedure | 429 |
reset-handler | thread param | 410 |
(reset-maximum-memory-bytes!) | procedure | 423 |
(reverse list) | procedure | 161 |
(reverse! list) | procedure | 147 |
(revisit path) | procedure | 369 |
(revisit-compiled-from-port input-port) | procedure | 368 |
(round real) | procedure | 178 |
run-cp0 | thread param | 393 |
(s8-list->bytevector list) | procedure | 162 |
(sc-expand obj) | procedure | 379 |
(sc-expand obj env) | procedure | 379 |
scheme | module | 339 |
(scheme-environment) | procedure | 362 |
(scheme-pre-release) | procedure | 433 |
scheme-program | global param | 411 |
(scheme-report-environment version) | procedure | 137 |
scheme-script | global param | 411 |
scheme-start | global param | 411 |
(scheme-version) | procedure | 432 |
(scheme-version show-pre-release?) | procedure | 432 |
(scheme-version-number) | procedure | 433 |
sealed | syntax | 331 |
self-evaluating-vectors | thread param | 155 |
(serious-condition? obj) | procedure | 366 |
(set! var expr) | syntax | 102 |
(set-binary-port-input-buffer! binary-input-port bytevector) | procedure | 246 |
(set-binary-port-input-index! binary-input-port n) | procedure | 246 |
(set-binary-port-input-size! binary-input-port n) | procedure | 246 |
(set-binary-port-output-buffer! binary-output-port bytevector) | procedure | 248 |
(set-binary-port-output-index! output-port n) | procedure | 248 |
(set-binary-port-output-size! output-port n) | procedure | 248 |
(set-box! box obj) | procedure | 169 |
(set-car! pair obj) | procedure | 157 |
(set-cdr! pair obj) | procedure | 157 |
(set-phantom-bytevector-length! pbv n) | procedure | 453 |
(set-port-bol! output-port obj) | procedure | 249 |
(set-port-eof! input-port obj) | procedure | 249 |
(set-port-input-buffer! input-port x) | procedure | 246 |
(set-port-input-index! input-port n) | procedure | 246 |
(set-port-input-size! input-port n) | procedure | 246 |
(set-port-length! port len) | procedure | 251 |
(set-port-name! port obj) | procedure | 250 |
(set-port-nonblocking! port obj) | procedure | 251 |
(set-port-output-buffer! output-port x) | procedure | 248 |
(set-port-output-index! output-port n) | procedure | 248 |
(set-port-output-size! output-port n) | procedure | 248 |
(set-port-position! port pos) | procedure | 272 |
(set-sstats-bytes! s new-value) | procedure | 424 |
(set-sstats-cpu! s new-value) | procedure | 424 |
(set-sstats-gc-bytes! s new-value) | procedure | 424 |
(set-sstats-gc-count! s new-value) | procedure | 424 |
(set-sstats-gc-cpu! s new-value) | procedure | 424 |
(set-sstats-gc-real! s new-value) | procedure | 424 |
(set-sstats-real! s new-value) | procedure | 424 |
(set-textual-port-input-buffer! textual-input-port string) | procedure | 246 |
(set-textual-port-input-index! textual-input-port n) | procedure | 246 |
(set-textual-port-input-size! textual-input-port n) | procedure | 246 |
(set-textual-port-output-buffer! textual-output-port string) | procedure | 248 |
(set-textual-port-output-index! textual-output-port n) | procedure | 248 |
(set-textual-port-output-size! textual-output-port n) | procedure | 248 |
(set-time-nanosecond! time nsec) | procedure | 415 |
(set-time-second! time sec) | procedure | 415 |
(set-time-type! time type) | procedure | 415 |
(set-timer n) | procedure | 359 |
(set-top-level-value! symbol obj) | procedure | 122 |
(set-top-level-value! symbol obj env) | procedure | 122 |
(set-virtual-register! k x) | procedure | 432 |
(set-wrapper-procedure-data! w-proc data) | procedure | 210 |
(set-wrapper-procedure-procedure! w-proc proc) | procedure | 210 |
(simple-conditions condition) | procedure | 363 |
(sin num) | procedure | 185 |
(sinh num) | procedure | 238 |
(sint-list->bytevector list eness size) | procedure | 239 |
(sleep time) | procedure | 420 |
(sort predicate list) | procedure | 176 |
(sort! predicate list) | procedure | 176 |
(source-condition-form condition) | procedure | 354 |
(source-condition? obj) | procedure | 354 |
source-directories | global param | 388 |
(source-file-descriptor path checksum) | procedure | 347 |
(source-file-descriptor-checksum sfd) | procedure | 347 |
(source-file-descriptor-path sfd) | procedure | 347 |
(source-file-descriptor? obj) | procedure | 347 |
(source-object-bfp source-object) | procedure | 346 |
(source-object-column source-object) | procedure | 347 |
(source-object-efp source-object) | procedure | 346 |
(source-object-line source-object) | procedure | 346 |
(source-object-sfd source-object) | procedure | 346 |
(source-object? obj) | procedure | 346 |
(source-table-cell source-table source-object default) | procedure | 350 |
(source-table-contains? source-table source-object) | procedure | 350 |
(source-table-delete! source-table source-object) | procedure | 350 |
(source-table-dump source-table) | procedure | 404 |
(source-table-ref source-table source-object default) | procedure | 350 |
(source-table-set! source-table source-object obj) | procedure | 350 |
(source-table-size source-table) | procedure | 351 |
(source-table? obj) | procedure | 350 |
(sqrt num) | procedure | 183 |
(sstats-bytes s) | procedure | 424 |
(sstats-cpu s) | procedure | 424 |
(sstats-difference s1 s2) | procedure | 425 |
(sstats-gc-bytes s) | procedure | 424 |
(sstats-gc-count s) | procedure | 424 |
(sstats-gc-cpu s) | procedure | 424 |
(sstats-gc-real s) | procedure | 424 |
(sstats-print s) | procedure | 425 |
(sstats-print s textual-output-port) | procedure | 425 |
(sstats-real s) | procedure | 424 |
(sstats? obj) | procedure | 424 |
(standard-error-port) | procedure | 268 |
(standard-error-port b-mode) | procedure | 268 |
(standard-error-port b-mode ?transcoder) | procedure | 268 |
(standard-error-port) | procedure | 264 |
(standard-input-port) | procedure | 259 |
(standard-input-port b-mode) | procedure | 259 |
(standard-input-port b-mode ?transcoder) | procedure | 259 |
(standard-input-port) | procedure | 264 |
(standard-output-port) | procedure | 267 |
(standard-output-port b-mode) | procedure | 267 |
(standard-output-port b-mode ?transcoder) | procedure | 267 |
(standard-output-port) | procedure | 264 |
(statistics) | procedure | 423 |
(stencil-vector mask obj ...) | procedure | 165 |
(stencil-vector-length stencil-vector) | procedure | 166 |
(stencil-vector-mask stencil-vector) | procedure | 166 |
(stencil-vector-mask-width) | procedure | 165 |
(stencil-vector-ref stencil-vector n) | procedure | 166 |
(stencil-vector-set! stencil-vector n obj) | procedure | 166 |
(stencil-vector-truncate! stencil-vector mask) | procedure | 167 |
(stencil-vector-update stencil-vector remove-bits add-bits obj ...) | procedure | 167 |
(stencil-vector? obj) | procedure | 165 |
(string char ...) | procedure | 218 |
(string->bytevector string transcoder) | procedure | 287 |
(string->immutable-string string) | procedure | 152 |
(string->list string) | procedure | 222 |
(string->multibyte code-page string) | procedure | 271 |
(string->number string) | procedure | 238 |
(string->number string radix) | procedure | 238 |
(string->number string) | procedure | 191 |
(string->number string radix) | procedure | 191 |
(string->symbol string) | procedure | 242 |
(string->uninterned-symbol str) | procedure | 172 |
(string->utf16 string) | procedure | 287 |
(string->utf16 string endianness) | procedure | 287 |
(string->utf32 string) | procedure | 287 |
(string->utf32 string endianness) | procedure | 287 |
(string->utf8 string) | procedure | 287 |
(string-append string ...) | procedure | 219 |
(string-append-immutable string ...) | procedure | 152 |
(string-ci-hash string) | procedure | 245 |
(string-ci<=? string1 string2 string3 ...) | procedure | 150 |
(string-ci<=? string1 string2 string3 ...) | procedure | 217 |
(string-ci<? string1 string2 string3 ...) | procedure | 150 |
(string-ci<? string1 string2 string3 ...) | procedure | 217 |
(string-ci=? string1 string2 string3 ...) | procedure | 150 |
(string-ci=? string1 string2 string3 ...) | procedure | 217 |
(string-ci>=? string1 string2 string3 ...) | procedure | 150 |
(string-ci>=? string1 string2 string3 ...) | procedure | 217 |
(string-ci>? string1 string2 string3 ...) | procedure | 150 |
(string-ci>? string1 string2 string3 ...) | procedure | 217 |
(string-copy string) | procedure | 219 |
(string-copy! src src-start dst dst-start n) | procedure | 151 |
(string-downcase string) | procedure | 221 |
(string-fill! string char) | procedure | 220 |
(string-foldcase string) | procedure | 221 |
(string-for-each procedure string1 string2 ...) | procedure | 122 |
(string-grapheme-count string) | procedure | 153 |
(string-grapheme-count string start) | procedure | 153 |
(string-grapheme-count string start end) | procedure | 153 |
(string-grapheme-span string start) | procedure | 152 |
(string-grapheme-span string start end) | procedure | 152 |
(string-hash string) | procedure | 245 |
(string-length string) | procedure | 218 |
(string-normalize-nfc string) | procedure | 222 |
(string-normalize-nfd string) | procedure | 222 |
(string-normalize-nfkc string) | procedure | 222 |
(string-normalize-nfkd string) | procedure | 222 |
(string-ref string n) | procedure | 218 |
(string-set! string n char) | procedure | 219 |
(string-titlecase string) | procedure | 221 |
(string-truncate! string n) | procedure | 151 |
(string-upcase string) | procedure | 221 |
(string<=? string1 string2 string3 ...) | procedure | 150 |
(string<=? string1 string2 string3 ...) | procedure | 216 |
(string<? string1 string2 string3 ...) | procedure | 150 |
(string<? string1 string2 string3 ...) | procedure | 216 |
(string=? string1 string2 string3 ...) | procedure | 150 |
(string=? string1 string2 string3 ...) | procedure | 216 |
(string>=? string1 string2 string3 ...) | procedure | 150 |
(string>=? string1 string2 string3 ...) | procedure | 216 |
(string>? string1 string2 string3 ...) | procedure | 150 |
(string>? string1 string2 string3 ...) | procedure | 216 |
(string? obj) | procedure | 154 |
(strip-fasl-file input-path output-path options) | procedure | 377 |
(sub1 num) | procedure | 235 |
subset-mode | thread param | 435 |
(subst new old tree) | procedure | 146 |
(subst! new old tree) | procedure | 146 |
(substq new old tree) | procedure | 146 |
(substq! new old tree) | procedure | 146 |
(substring string start end) | procedure | 220 |
(substring-fill! string start end char) | procedure | 151 |
(substv new old tree) | procedure | 146 |
(substv! new old tree) | procedure | 146 |
(subtract-duration time timed) | procedure | 416 |
(subtract-duration! time timed) | procedure | 416 |
suppress-greeting | global param | 412 |
(symbol->string symbol) | procedure | 242 |
(symbol-hash symbol) | procedure | 245 |
(symbol-hashtable-cell hashtable key default) | procedure | 186 |
(symbol-hashtable-contains? hashtable key) | procedure | 185 |
(symbol-hashtable-delete! hashtable key) | procedure | 187 |
(symbol-hashtable-ref hashtable key default) | procedure | 185 |
(symbol-hashtable-ref-cell hashtable key) | procedure | 187 |
(symbol-hashtable-set! hashtable key value) | procedure | 184 |
(symbol-hashtable-update! hashtable key procedure default) | procedure | 185 |
(symbol-hashtable? obj) | procedure | 184 |
(symbol=? symbol1 symbol2) | procedure | 242 |
(symbol? obj) | procedure | 154 |
(syntax template) | syntax | 300 |
(syntax->annotation obj) | procedure | 348 |
(syntax->datum obj) | procedure | 308 |
(syntax->list syntax-object) | procedure | 323 |
(syntax->vector syntax-object) | procedure | 324 |
(syntax-case expr (literal ...) clause ...) | syntax | 299 |
(syntax-error obj string ...) | procedure | 327 |
(syntax-object->datum obj) | procedure | 324 |
(syntax-rules (literal ...) clause ...) | syntax | 323 |
(syntax-rules (literal ...) clause ...) | syntax | 294 |
(syntax-violation who msg form) | procedure | 359 |
(syntax-violation who msg form subform) | procedure | 359 |
(syntax-violation-form condition) | procedure | 370 |
(syntax-violation-subform condition) | procedure | 370 |
(syntax-violation? obj) | procedure | 370 |
(system command) | procedure | 57 |
(tan num) | procedure | 185 |
(tanh num) | procedure | 238 |
(textual-port-input-buffer textual-input-port) | procedure | 246 |
(textual-port-input-count textual-input-port) | procedure | 247 |
(textual-port-input-index textual-input-port) | procedure | 246 |
(textual-port-input-size textual-input-port) | procedure | 246 |
(textual-port-output-buffer output-port) | procedure | 247 |
(textual-port-output-count textual-output-port) | procedure | 248 |
(textual-port-output-index output-port) | procedure | 247 |
(textual-port-output-size output-port) | procedure | 247 |
(textual-port? obj) | procedure | 270 |
(thread-condition? obj) | procedure | 470 |
(thread-join thread) | procedure | 468 |
(thread-preserve-ownership!) | procedure | 468 |
(thread-preserve-ownership! thread) | procedure | 468 |
(thread? obj) | procedure | 468 |
(threaded?) | procedure | 433 |
(time expr) | syntax | 421 |
(time-difference time1 time2) | procedure | 416 |
(time-difference! time1 time2) | procedure | 416 |
(time-nanosecond time) | procedure | 415 |
(time-second time) | procedure | 415 |
(time-type time) | procedure | 415 |
(time-utc->date time) | procedure | 420 |
(time-utc->date time offset) | procedure | 420 |
(time<=? time1 time2) | procedure | 416 |
(time<? time1 time2) | procedure | 416 |
(time=? time1 time2) | procedure | 416 |
(time>=? time1 time2) | procedure | 416 |
(time>? time1 time2) | procedure | 416 |
(time? obj) | procedure | 415 |
timer-interrupt-handler | thread param | 359 |
(top-level-bound? symbol) | procedure | 122 |
(top-level-bound? symbol env) | procedure | 122 |
(top-level-mutable? symbol) | procedure | 123 |
(top-level-mutable? symbol env) | procedure | 123 |
(top-level-program imports body) | syntax | 307 |
(top-level-syntax symbol) | procedure | 124 |
(top-level-syntax symbol env) | procedure | 124 |
(top-level-syntax? symbol) | procedure | 125 |
(top-level-syntax? symbol env) | procedure | 125 |
(top-level-value symbol) | procedure | 122 |
(top-level-value symbol env) | procedure | 122 |
(trace var1 var2 ...) | syntax | 36 |
(trace) | syntax | 36 |
(trace-case-lambda name clause ...) | syntax | 34 |
(trace-define var expr) | syntax | 38 |
(trace-define (var . idspec) body1 body2 ...) | syntax | 38 |
(trace-define-syntax keyword expr) | syntax | 39 |
(trace-do ((var init update) ...) (test result ...) expr ...) | syntax | 35 |
(trace-lambda name formals body1 body2 ...) | syntax | 33 |
(trace-let name ((var expr) ...) body1 body2 ...) | syntax | 34 |
trace-output-port | thread param | 38 |
trace-print | thread param | 38 |
(transcoded-port binary-port transcoder) | procedure | 271 |
transcoded-port-buffer-size | thread param | 244 |
(transcoder-codec transcoder) | procedure | 259 |
(transcoder-eol-style transcoder) | procedure | 259 |
(transcoder-error-handling-mode transcoder) | procedure | 259 |
(transcoder? obj) | procedure | 244 |
(transcript-cafe path) | procedure | 413 |
(transcript-off) | procedure | 413 |
(transcript-on path) | procedure | 413 |
(truncate real) | procedure | 177 |
(truncate-file output-port) | procedure | 269 |
(truncate-file output-port pos) | procedure | 269 |
(truncate-port output-port) | procedure | 269 |
(truncate-port output-port pos) | procedure | 269 |
(type-descriptor name) | syntax | 200 |
(u8-list->bytevector list) | procedure | 232 |
(uint-list->bytevector list eness size) | procedure | 239 |
(unbox box) | procedure | 168 |
undefined-variable-warnings | thread param | 396 |
(undefined-violation? obj) | procedure | 371 |
(unget-char textual-input-port char) | procedure | 260 |
(unget-u8 binary-input-port octet) | procedure | 261 |
(uninterned-symbol? obj) | procedure | 173 |
(unless test-expr expr1 expr2 ...) | syntax | 112 |
(unlock-object obj) | procedure | 451 |
(unquote obj ...) | syntax | 142 |
(unquote-splicing obj ...) | syntax | 142 |
(unread-char char) | procedure | 260 |
(unread-char char textual-input-port) | procedure | 260 |
(unregister-guardian guardian) | procedure | 450 |
(unsyntax template ...) | syntax | 305 |
(unsyntax-splicing template ...) | syntax | 305 |
(untrace var1 var2 ...) | syntax | 37 |
(untrace) | syntax | 37 |
(utf-16-codec) | procedure | 243 |
(utf-16-codec endianness) | procedure | 243 |
(utf-16-codec) | procedure | 259 |
(utf-16be-codec) | procedure | 243 |
(utf-16le-codec) | procedure | 243 |
(utf-8-codec) | procedure | 259 |
(utf16->string bytevector endianness) | procedure | 288 |
(utf16->string bytevector endianness endianness-mandatory?) | procedure | 288 |
(utf32->string bytevector endianness) | procedure | 288 |
(utf32->string bytevector endianness endianness-mandatory?) | procedure | 288 |
(utf8->string bytevector) | procedure | 287 |
(values obj ...) | procedure | 131 |
variable | syntax | 91 |
(vector obj ...) | procedure | 224 |
(vector->immutable-vector vector) | procedure | 155 |
(vector->list vector) | procedure | 225 |
(vector->pseudo-random-generator vec) | procedure | 234 |
(vector->pseudo-random-generator! prgen vec) | procedure | 234 |
(vector-cas! vector n old-obj new-obj) | procedure | 154 |
(vector-copy vector) | procedure | 153 |
(vector-fill! vector obj) | procedure | 225 |
(vector-for-each procedure vector1 vector2 ...) | procedure | 122 |
(vector-length vector) | procedure | 224 |
(vector-map procedure vector1 vector1 ...) | procedure | 121 |
(vector-ref vector n) | procedure | 224 |
(vector-set! vector n obj) | procedure | 225 |
(vector-set-fixnum! vector n fixnum) | procedure | 154 |
(vector-sort predicate vector) | procedure | 226 |
(vector-sort! predicate vector) | procedure | 226 |
(vector? obj) | procedure | 154 |
(verify-loadability situation input ...) | procedure | 367 |
(vfasl-convert-file input-path output-path base-boots) | procedure | 378 |
(violation? obj) | procedure | 366 |
(virtual-register k) | procedure | 432 |
(virtual-register-count) | procedure | 432 |
(visit path) | procedure | 368 |
(visit-compiled-from-port input-port) | procedure | 368 |
(void) | procedure | 175 |
waiter-prompt-and-read | thread param | 409 |
waiter-prompt-string | thread param | 408 |
waiter-write | thread param | 409 |
(warning who msg irritant ...) | procedure | 353 |
(warning? obj) | procedure | 367 |
(warningf who msg irritant ...) | procedure | 354 |
(weak-cons obj1 obj2) | procedure | 443 |
(weak-pair? obj) | procedure | 444 |
(when test-expr expr1 expr2 ...) | syntax | 112 |
(who-condition? obj) | procedure | 369 |
(with ((pat expr) ...) template) | syntax | 485 |
(with-continuation-mark key val body) | syntax | 131 |
(with-cost-center cost-center thunk) | procedure | 428 |
(with-cost-center timed? cost-center thunk) | procedure | 428 |
(with-exception-handler procedure thunk) | procedure | 360 |
(with-implicit (id0 id1 ...) body1 body2 ...) | syntax | 325 |
(with-input-from-file path thunk) | procedure | 258 |
(with-input-from-file path thunk options) | procedure | 258 |
(with-input-from-file path thunk) | procedure | 283 |
(with-input-from-string string thunk) | procedure | 254 |
(with-interrupts-disabled body1 body2 ...) | syntax | 360 |
(with-mutex mutex body1 body2 ...) | syntax | 470 |
(with-output-to-file path thunk) | procedure | 267 |
(with-output-to-file path thunk options) | procedure | 267 |
(with-output-to-file path thunk) | procedure | 283 |
(with-output-to-string thunk) | procedure | 255 |
(with-profile-tracker thunk) | procedure | 403 |
(with-profile-tracker preserve-existing? thunk) | procedure | 403 |
(with-source-path who name procedure) | procedure | 388 |
(with-syntax ((pattern expr) ...) body1 body2 ...) | syntax | 304 |
(wrapper-procedure-data w-proc) | procedure | 210 |
(wrapper-procedure-procedure w-proc) | procedure | 210 |
(wrapper-procedure? obj) | procedure | 209 |
(write obj) | procedure | 284 |
(write obj textual-output-port) | procedure | 284 |
(write-char char) | procedure | 285 |
(write-char char textual-output-port) | procedure | 285 |
(zero? num) | procedure | 173 |
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/syntax.html b/csug10.0/syntax.html
new file mode 100644
index 000000000..e977d847c
--- /dev/null
+++ b/csug10.0/syntax.html
@@ -0,0 +1,2541 @@
+
+
+
+
+
+This chapter describes the Chez Scheme extensions to the +syntax-case syntactic abstraction mechanism now standardized in +the Revised6 Report. +These extensions include +the module system (Section 11.5), +meta definitions (Section 11.8), +conditional expansion (Section 11.9) +syntax-rules fenders, +fluid-let-syntax, +and include. + + +
+ +
+Keyword bindings established via the Revised6 Report +define-syntax, let-syntax, or letrec-syntax +forms may be rebound temporarily with fluid-let-syntax. + +
+syntax: (fluid-let-syntax ((keyword expr) ...) form1 form2 ...)
+
+returns: see explanation
+
+libraries: (chezscheme)
+
+
Each expr must evaluate to a transformer. +fluid-let-syntax is similar to the standard let-syntax, except +that instead of introducing new bindings for the keywords +keyword ..., +fluid-let-syntax temporarily alters the existing bindings +for the keywords during the expansion of its body. +That is, during the expansion of form1 form2 ..., +the visible lexical (or top-level) binding +for each keyword is temporarily replaced by a new association +between the keyword and the corresponding transformer. +This affects any references to the keyword that resolve +to the same lexical (or top-level) binding whether the references occur +in the text of the body or are introduced during its expansion. +In contrast, let-syntax captures only those references that +occur within the text of its body. + +
+The following example shows how fluid-let-syntax +differs from let-syntax. + +
+ +
(let ([f (lambda (x) (+ x 1))])
+
+ (let-syntax ([g (syntax-rules ()
+
+ [(_ x) (f x)])])
+
+ (let-syntax ([f (syntax-rules ()
+
+ [(_ x) x])])
+
+ (g 1)))) 2
+
+
+(let ([f (lambda (x) (+ x 1))])
+
+ (let-syntax ([g (syntax-rules ()
+
+ [(_ x) (f x)])])
+
+ (fluid-let-syntax ([f (syntax-rules ()
+
+ [(_ x) x])])
+
+ (g 1)))) 1
+
The two expressions are identical except that the inner +let-syntax form +in the first expression is a fluid-let-syntax form in the second. +In the first expression, the f occurring in the expansion of +(g 1) refers to +the let-bound variable f, whereas in the second it refers +to the keyword f by virtue of the fluid syntax binding for +f. + +
+The following code employs fluid-let-syntax in the definition +of a define-integrable form that is similar +to define for procedure definitions except that it causes the +code for the procedure to be integrated, or inserted, wherever +a direct call to the procedure is found. +No semantic difference is visible between procedures defined with +define-integrable and those defined with define, except that +a top-level define-integrable form must appear before the first +reference to the defined identifier. +Lexical scoping is preserved, the actual parameters +in an integrated call are evaluated once and at the proper time, +integrable procedures may be used as first-class values, and +recursive procedures do not cause indefinite recursive expansion. + +
+ +
(define-syntax define-integrable
+
+ (syntax-rules (lambda)
+
+ [(_ name (lambda formals form1 form2 ...))
+
+ (begin
+
+ (define xname
+
+ (fluid-let-syntax ([name (identifier-syntax xname)])
+
+ (lambda formals form1 form2 ...)))
+
+ (define-syntax name
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [_ (identifier? x) #'xname]
+
+ [(_ arg (... ...))
+
+ #'((fluid-let-syntax ([name (identifier-syntax xname)])
+
+ (lambda formals form1 form2 ...))
+
+ arg
+
+ (... ...))]))))]))
+
A define-integrable has the following form. + +
+ +
(define-integrable name lambda-expression) +
A define-integrable form expands into a pair of definitions: a syntax +definition of name and a variable definition of xname. +The transformer for name converts apparent calls to +name into direct calls to lambda-expression. +Since the resulting forms are merely direct lambda applications +(the equivalent of let expressions), +the actual parameters are evaluated exactly once and before evaluation +of the procedure's body, as required. +All other references to name are replaced with references to +xname. +The definition of xname binds it to the value of +lambda-expression. +This allows the procedure to be used as a first-class value. +Because xname is introduced by the transformer, the binding for +xname is not visible anywhere except where references to it +are introduced by the transformer for name. + +
+Within lambda-expression, wherever it appears, name +is rebound to a transformer that expands all references into references +to xname. +The use of fluid-let-syntax +for this purpose prevents indefinite +expansion from indirect recursion among integrable procedures. +This allows the procedure to be recursive without causing indefinite +expansion. +Nothing special is done by define-integrable to maintain lexical +scoping, since lexical scoping is maintained automatically by the +expander. + +
+Chez Scheme integrates locally defined procedures automatically when it is +appropriate to do so. +It cannot integrate procedures defined at top-level, +however, since code that assigns top-level variables can be introduced +into the system (via eval or load) at any time. +define-integrable can be used to force the integration of +procedures bound at top-level, even if the integration of locally bound +procedures is left to the compiler. +It can also be used to force the integration of large procedures that +the compiler would not normally integrate. +(The expand/optimize procedure is useful for determining when +integration does or does not take place.) + +
+ +
+Chez Scheme extends syntax-rules to permit clause to include +fenders just like those allowed within syntax-case clauses. + +
+syntax: (syntax-rules (literal ...) clause ...)
+
+returns: a transformer
+
+libraries: (chezscheme)
+
+
Each literal must be an identifier other than +an underscore ( _ ) or ellipsis ( ... ). +Each clause must take the form below. + +
+ +
(pattern template)
+
+(pattern fender template)
+
The first form is the only form supported by the Revised6 Report. + + +
+ +
+Chez Scheme provides several procedures and syntactic forms that may +be used to simplify the coding of certain syntactic abstractions. + +
+procedure: (syntax->list syntax-object)
+
+returns: a list of syntax objects
+
+libraries: (chezscheme)
+
+
This procedure takes a syntax object representing +a list-structured form and returns a list of syntax objects, each representing +the corresponding subform of the input form. + + +
+syntax->list may be defined as follows. + +
+ +
(define syntax->list
+
+ (lambda (ls)
+
+ (syntax-case ls ()
+
+ [() '()]
+
+ [(x . r) (cons #'x (syntax->list #'r))])))
+
+
+#'(a b c) #<syntax (a b c)>
+
+(syntax->list #'(a b c)) (#<syntax a> #<syntax b> #<syntax c>)
+
syntax->list is not required for list structures constructed +from individual pattern variable values or sequences of pattern-variable +values, since such structures are already lists. +For example: + +
+ +
(list? (with-syntax ([x #'a] [y #'b] [z #'c]) #'(x y z)))) #t
+
+(list? (with-syntax ([(x ...) #'(a b c)]) #'(x ...))) #t
+
procedure: (syntax->vector syntax-object)
+
+returns: a vector of syntax objects
+
+libraries: (chezscheme)
+
+
This procedure takes a syntax object representing +a vector-structured form and returns a vector of syntax objects, each representing +the corresponding subform of the input form. + + +
+syntax->vector may be defined as follows. + +
+ +
(define syntax->vector
+
+ (lambda (v)
+
+ (syntax-case v ()
+
+ [#(x ...) (apply vector (syntax->list #'(x ...)))])))
+
+
+#'#(a b c) #<syntax #(a b c)>
+
+(syntax->vector #'#(a b c)) #(#<syntax a> #<syntax b> #<syntax c>)
+
syntax->vector is not required for vector structures constructed +from individual pattern variable values or sequences of pattern-variable +values, since such structures are already vectors. +For example: + +
+ +
(vector? (with-syntax ([x #'a] [y #'b] [z #'c]) #'#(x y z)))) #t
+
+(vector? (with-syntax ([(x ...) #'(a b c)]) #'#(x ...))) #t
+
procedure: (syntax-object->datum obj)
+
+returns: obj stripped of syntactic information
+
+libraries: (chezscheme)
+
+
syntax-object->datum is identical to the Revised6 Report +syntax->datum. + + +
+syntax: (datum template)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
(datum template) is a convenient shorthand syntax for + +
+ +
(syntax->datum (syntax template)) +
datum may be defined simply as follows. + +
+ +
(define-syntax datum
+
+ (syntax-rules ()
+
+ [(_ t) (syntax->datum #'t)]))
+
+
+(with-syntax ((a #'(a b c))) (datum a)) (a b c)
+
procedure: (datum->syntax-object template-identifier obj)
+
+returns: a syntax object
+
+libraries: (chezscheme)
+
+
datum->syntax-object is identical to the Revised6 Report +datum->syntax. + +
+syntax: (with-implicit (id0 id1 ...) body1 body2 ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
This form abstracts over the common usage of datum->syntax +for creating implicit identifiers (see above). +The form + +
+ +
(with-implicit (id0 id1 ...)
+
+ body1 body2 ...)
+
is equivalent to + +
+ +
(with-syntax ([id1 (datum->syntax #'id0 'id1)] ...)
+
+ body1 body2 ...)
+
with-implicit can be defined simply as follows. + +
+ +
(define-syntax with-implicit
+
+ (syntax-rules ()
+
+ [(_ (tid id ...) b1 b2 ...)
+
+ (with-syntax ([id (datum->syntax #'tid 'id)] ...)
+
+ b1 b2 ...)]))
+
We can use with-implicit to simplify the (correct version of) +loop above. + +
+ +
(define-syntax loop
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(k e ...)
+
+ (with-implicit (k break)
+
+ #'(call-with-current-continuation
+
+ (lambda (break)
+
+ (let f () e ... (f)))))])))
+
syntax: (include path)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +include expands into a begin expression containing +the forms found in the file named by path. +For example, if the file f-def.ss contains +(define f (lambda () x)), the expression + +
+ +
(let ([x "okay"])
+
+ (include "f-def.ss")
+
+ (f))
+
evaluates to "okay". +An include form is treated as a definition if it appears within a +sequence of definitions and the forms on the file named by +path are all definitions, as in the above example. +If the file contains expressions instead, the include form is +treated as an expression. + +
+include may be defined portably as follows, although +Chez Scheme uses an implementation-dependent definition that allows +it to capture and maintain source information for included code. + +
+ +
(define-syntax include
+
+ (lambda (x)
+
+ (define read-file
+
+ (lambda (fn k)
+
+ (let ([p (open-input-file fn)])
+
+ (let f ([x (read p)])
+
+ (if (eof-object? x)
+
+ (begin (close-input-port p) '())
+
+ (cons (datum->syntax k x)
+
+ (f (read p))))))))
+
+ (syntax-case x ()
+
+ [(k filename)
+
+ (let ([fn (datum filename)])
+
+ (with-syntax ([(exp ...) (read-file fn #'k)])
+
+ #'(begin exp ...)))])))
+
The definition of include uses datum->syntax to convert +the objects read from the file into syntax objects in the proper +lexical context, so that identifier references and definitions within +those expressions are scoped where the include form appears. + +
+In Chez Scheme's implementation of include, +the parameter source-directories (Section 12.5) +determines the set of directories searched for source files not identified +by absolute path names. + + +
+
+procedure: (syntax-error obj string ...)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
Syntax errors may be reported with syntax-error, which produces +a message by concatenating string ... and a printed +representation of obj. +If no string arguments are provided, the string "invalid syntax" +is used instead. +When obj is a syntax object, the syntax-object wrapper is +stripped (as with syntax->datum) before the printed representation +is created. +If source file information is present in the syntax-object wrapper, +syntax-error incorporates this information into the error +message. + +
+syntax-case and syntax-rules call syntax-error +automatically if the input fails to match one of the clauses. + +
+We can use syntax-error to precisely report the cause +of the errors detected in the following definition of +(unnamed) let. + +
+ +
(define-syntax let
+
+ (lambda (x)
+
+ (define check-ids!
+
+ (lambda (ls)
+
+ (unless (null? ls)
+
+ (unless (identifier? (car ls))
+
+ (syntax-error (car ls) "let cannot bind non-identifier"))
+
+ (check-ids! (cdr ls)))))
+
+ (define check-unique!
+
+ (lambda (ls)
+
+ (unless (null? ls)
+
+ (let ([x (car ls)])
+
+ (when (let mem? ([ls (cdr ls)])
+
+ (and (not (null? ls))
+
+ (or (bound-identifier=? x (car ls))
+
+ (mem? (cdr ls)))))
+
+ (syntax-error x "let cannot bind two occurrences of")))
+
+ (check-unique! (cdr ls)))))
+
+ (syntax-case x ()
+
+ [(_ ((i e) ...) b1 b2 ...)
+
+ (begin
+
+ (check-ids! #'(i ...))
+
+ (check-unique! #'(i ...))
+
+ #'((lambda (i ...) b1 b2 ...) e ...))])))
+
With this change, the expression + +
+ +
(let ([a 3] [a 4]) (+ a a)) +
produces the error message "let cannot bind two occurrences of a." + +
+procedure: (literal-identifier=? identifier1 identifier2)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
This procedure is identical to the Revised6 Report +free-identifier=?, and is provided for backward +compatibility only. + +
+ +
+When defining sets of dependent macros, it is often convenient to attach +information to identifiers in the same compile time environment +that the expander uses to record information about variables, keywords, +module names, etc. +For example, a record-type definition macro, like +define-record-type, might need to attach information to the +record-type name in the compile-time environment for use in handling child +record-type definitions. + +
+Chez Scheme provides two mechanisms for attaching information to +identifiers in the compile-time environment: compile-time values and +compile-time properties. +A compile-time value is a kind of transformer that can be +associated with an identifier via define-syntax, +let-syntax, letrec-syntax, and fluid-let-syntax. +When an identifier is associated with a compile-time value, it cannot +also have any other meaning, and an attempt to reference it as an +ordinary identifier results in a syntax error. +A compile-time property, on the other hand, is maintained alongside +an existing binding, providing additional information about the +binding. +Properties are ignored when ordinary references to an identifier +occur. + +
+The mechanisms used by a macro to obtain compile-time values and +properties are similar. +In both cases, the macro's transformer returns a procedure p +rather than a syntax object. +The expander invokes p with one argument, an environment-lookup +procedure lookup, which p can then use to obtain compile-time +values and properties for one or more identifiers before it constructs the +macro's final output. +lookup accepts one or two identifier arguments. +With one argument, id, lookup returns the compile-time +value of id, or #f if id has no compile-time value. +With two arguments, id and key, lookup returns the +value of id's key property, or #f if id +has no key property. + + +
+procedure: (make-compile-time-value obj)
+
+returns: a compile-time value
+
+libraries: (chezscheme)
+
+
A compile time value is a kind of transformer with which a keyword may +be associated by any of the keyword binding constructs, e.g., define-syntax +or let-syntax. +The transformer encapsulates the supplied obj. +The encapsulated object may be retrieved as described above. + +
+The following example illustrates how this feature might be used to define +a simple syntactic record-definition mechanism where the record type descriptor +is generated at expansion time. + +
+ +
(define-syntax drt
+
+ (lambda (x)
+
+ (define construct-name
+
+ (lambda (template-identifier . args)
+
+ (datum->syntax template-identifier
+
+ (string->symbol
+
+ (apply string-append
+
+ (map (lambda (x)
+
+ (if (string? x)
+
+ x
+
+ (symbol->string (syntax->datum x))))
+
+ args))))))
+
+ (define do-drt
+
+ (lambda (rname fname* prtd)
+
+ (with-syntax ([rname rname]
+
+ [rtd (make-record-type-descriptor
+
+ (syntax->datum rname) prtd #f #f #f
+
+ (list->vector
+
+ (map (lambda (fname)
+
+ `(immutable ,(syntax->datum fname)))
+
+ fname*)))]
+
+ [make-rname (construct-name rname "make-" rname)]
+
+ [rname? (construct-name rname rname "?")]
+
+ [(rname-fname ...)
+
+ (map (lambda (fname)
+
+ (construct-name fname rname "-" fname))
+
+ fname*)]
+
+ [(i ...) (enumerate fname*)])
+
+ #'(begin
+
+ (define-syntax rname (make-compile-time-value 'rtd))
+
+ (define rcd (make-record-constructor-descriptor 'rtd #f #f))
+
+ (define make-rname (record-constructor rcd))
+
+ (define rname? (record-predicate 'rtd))
+
+ (define rname-fname (record-accessor 'rtd i))
+
+ ...))))
+
+ (syntax-case x (parent)
+
+ [(_ rname (fname ...))
+
+ (for-all identifier? #'(rname fname ...))
+
+ (do-drt #'rname #'(fname ...) #f)]
+
+ [(_ rname pname (fname ...))
+
+ (for-all identifier? #'(rname pname fname ...))
+
+ (lambda (lookup)
+
+ (let ([prtd (lookup #'pname)])
+
+ (unless (record-type-descriptor? prtd)
+
+ (syntax-error #'pname "unrecognized parent record type"))
+
+ (do-drt #'rname #'(fname ...) prtd)))])))
+
+
(drt prec (x y))
+
+(drt crec prec (z))
+
+(define r (make-crec 1 2 3))
+
+(prec? r) #t
+
+(prec-x r) 1
+
+(crec-z r) 3
+
+prec exception: invalid syntax prec
+
procedure: (compile-time-value? obj)
+
+returns: #t if obj is a compile-time value; #f otherwise
+
+libraries: (chezscheme)
+
+
+
(define-syntax x (make-compile-time-value "eggs"))
+
+(compile-time-value? (top-level-syntax 'x)) #t
+
procedure: (compile-time-value-value ctv)
+
+returns: the value of a compile-time value
+
+libraries: (chezscheme)
+
+
+
(define-syntax x (make-compile-time-value "eggs"))
+
+(compile-time-value-value (top-level-syntax 'x)) "eggs"
+
syntax: (define-property id key expr)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A define-property form attaches a property to an +existing identifier binding without disturbing the existing meaning +of the identifier in the scope of that binding. +It is typically used by one macro to record information about a binding +for use by another macro. +Both id and key must be identifiers. +The expression expr is evaluated when the define-property +form is expanded, and a new property associating key with the +value of expr is attached to the existing binding of +id, which must have a visible local or top-level binding. + +
+define-property is a definition and can appear anywhere +other definitions can appear. +The scope of a property introduced by define-property is the +entire body in which the define-property form appears or global +if it appears at top level, except +where it is replaced by a property for the same id and +key or where the binding to which it is attached is shadowed. +Any number of properties can be attached to the same binding with +different keys. +Attaching a new property with the same name as an property already +attached to a binding shadows the existing property with the new +property. + +
+The following example defines a macro, get-info, that retrieves +the info property of a binding, defines the variable x, +attaches an info property to the binding of x, retrieves +the property via get-info, references x to show that +its normal binding is still intact, and uses get-info again +within the scope of a different binding of x to show that the +properties are shadowed as well as the outer binding of x. + +
+ +
(define info)
+
+(define-syntax get-info
+
+ (lambda (x)
+
+ (lambda (lookup)
+
+ (syntax-case x ()
+
+ [(_ q)
+
+ (let ([info-value (lookup #'q #'info)])
+
+ #`'#,(datum->syntax #'* info-value))]))))
+
+(define x "x-value")
+
+(define-property x info "x-info")
+
+(get-info x) "x-info"
+
+x "x-value"
+
+(let ([x "inner-x-value"]) (get-info x)) #f
+
For debugging, it is often useful to have a form that retrieves +an arbitrary property, given an identifier and a key. +The get-property macro below does +just that. + +
+ +
(define-syntax get-property
+
+ (lambda (x)
+
+ (lambda (r)
+
+ (syntax-case x ()
+
+ [(_ id key)
+
+ #`'#,(datum->syntax #'* (r #'id #'key))]))))
+
+(get-property x info) "x-info"
+
The bindings for both identifiers must be visible where +get-property is used. + +
+The version of drt defined below is like the one defined using +make-compile-time-value above, except that it defines the +record name as a macro that raises an exception with a more descriptive +message, while attaching the record type descriptor to the binding as a +separate property. +The variable drt-key defined along with drt is used +only as the key for the property that drt attaches to a record +name. +Both drt-key and drt are defined within a module that +exports only the latter, ensuring that the properties used by drt +cannot be accessed or forged. + +
+ +
(library (drt) (export drt) (import (chezscheme))
+
+ (define drt-key)
+
+ (define-syntax drt
+
+ (lambda (x)
+
+ (define construct-name
+
+ (lambda (template-identifier . args)
+
+ (datum->syntax template-identifier
+
+ (string->symbol
+
+ (apply string-append
+
+ (map (lambda (x)
+
+ (if (string? x)
+
+ x
+
+ (symbol->string (syntax->datum x))))
+
+ args))))))
+
+ (define do-drt
+
+ (lambda (rname fname* prtd)
+
+ (with-syntax ([rname rname]
+
+ [rtd (make-record-type-descriptor
+
+ (syntax->datum rname) prtd #f #f #f
+
+ (list->vector
+
+ (map (lambda (fname)
+
+ `(immutable ,(syntax->datum fname)))
+
+ fname*)))]
+
+ [make-rname (construct-name rname "make-" rname)]
+
+ [rname? (construct-name rname rname "?")]
+
+ [(rname-fname ...)
+
+ (map (lambda (fname)
+
+ (construct-name fname rname "-" fname))
+
+ fname*)]
+
+ [(i ...) (enumerate fname*)])
+
+ #'(begin
+
+ (define-syntax rname
+
+ (lambda (x)
+
+ (syntax-error x "invalid use of record name")))
+
+ (define rcd (make-record-constructor-descriptor 'rtd #f #f))
+
+ (define-property rname drt-key 'rtd)
+
+ (define make-rname (record-constructor rcd))
+
+ (define rname? (record-predicate 'rtd))
+
+ (define rname-fname (record-accessor 'rtd i))
+
+ ...))))
+
+ (syntax-case x (parent)
+
+ [(_ rname (fname ...))
+
+ (for-all identifier? #'(rname fname ...))
+
+ (do-drt #'rname #'(fname ...) #f)]
+
+ [(_ rname pname (fname ...))
+
+ (for-all identifier? #'(rname pname fname ...))
+
+ (lambda (lookup)
+
+ (let ([prtd (lookup #'pname #'drt-key)])
+
+ (unless prtd
+
+ (syntax-error #'pname "unrecognized parent record type"))
+
+ (do-drt #'rname #'(fname ...) prtd)))]))))
+
+
(import (drt))
+
+(drt prec (x y))
+
+(drt crec prec (z))
+
+(define r (make-crec 1 2 3))
+
+(prec? r) #t
+
+(prec-x r) 1
+
+(crec-z r) 3
+
+prec exception: invalid use of record name prec
+
+
+Modules are used to help organize programs into separate +parts that interact cleanly via declared interfaces. +Although modular programming is typically used to facilitate the development +of large programs possibly written by many individuals, it may also be +used in Chez Scheme at a "micro-modular" level, since Chez Scheme +module and import forms are definitions and may appear anywhere any other +kind of definition may appear, including within a lambda body +or other local scope. + +
+Modules control visibility of bindings and can be viewed as extending +lexical scoping to allow more precise control over where bindings are +or are not visible. +Modules export identifier bindings, i.e., variable bindings, keyword +bindings, or module name bindings. +Modules may be named or anonymous. +Bindings exported from a named module may be made visible via an import +form wherever the module's name is visible. +Bindings exported from an anonymous module are implicitly imported where +the module form appears. +Anonymous modules are useful for hiding some of a set of bindings while +allowing the remaining bindings in the set to be visible. + +
+Some of the text and examples given in this section are +adapted from the paper +"Extending the scope of syntactic +abstraction" [32], which describes modules and their +implementation in more detail. + +
+syntax: (module name interface defn ... init ...)
+
syntax: (module interface defn ... init ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
name is an identifier, defn ... +are definitions, and init ... are expressions. +interface is a list of exports (export ...), +where each export is either an identifier identifier +or of the form (identifier export ...). + +
+The first syntax for module establishes a named scope that +encapsulates a set of identifier bindings. +The exported bindings may be made visible via import or +import-only (Section 10.4) +anywhere the module name is visible. +The second syntax for module introduces an anonymous module +whose bindings are implicitly imported (as if by import of a +hidden module name) where the module form appears. + +
+A module consists of a (possibly empty) set of +definitions and a (possibly empty) sequence of initialization expressions. +The identifiers defined within a module are visible within the body +of the module and, if exported, within the scope of an import for the +module. +Each identifier listed in a module's interface must be defined within +or imported into that module. +A module form is a definition and can appear anywhere other +definitions can appear, including +at the top level of a program, nested within the bodies of +lambda expressions, nested within library and +top-level program forms, and nested within other modules. +Also, because module names are scoped like other identifiers, +modules and libraries may export module names as well as variables and keywords. + +
+When an interface contains an export of the form +(identifier export ...), only identifier is +visible in the importing context. +The identifiers within export ... are +indirect imports, as if declared via an +indirect-export form (Section 10.4). + +
+Module names occupy the same namespace as other identifiers and follow +the same scoping rules. +Unless exported, identifiers defined within a module are visible only +within that module. + +
+Expressions within a module can reference identifiers bound outside of +the module. + +
+ +
(let ([x 3])
+
+ (module m (plusx)
+
+ (define plusx (lambda (y) (+ x y))))
+
+ (import m)
+
+ (let ([x 4])
+
+ (plusx 5))) 8
+
Similarly, import does not prevent access to identifiers that +are visible where the import form appears, except for those variables +shadowed by the imported identifiers. + +
+ +
(module m (y) (define y 'm-y))
+
+(let ([x 'local-x] [y 'local-y])
+
+ (import m)
+
+ (list x y)) (local-x m-y)
+
On the other hand, use of import-only within a module +establishes an isolated scope in +which the only visible identifiers are those exported by the +imported module. + +
+ +
(module m (y) (define y 'm-y))
+
+(let ([x 'local-x] [y 'local-y])
+
+ (import-only m)
+
+ x) Error: x is not visible
+
This is sometimes desirable for static verification that no +identifiers are used except those explicitly imported into a +module or local scope. + +
+Unless a module imported via import-only exports +import or +import-only and the name of at least one module, subsequent +imports within the scope of the import-only form are not +possible. +To create an isolated scope containing the exports of more than one +module without making import or import-only +visible, all of the modules to be imported must be listed in the +same import-only form. + +
+Another solution is to create a single module that contains +the exports of each of the other modules. + +
+ +
(module m2 (y) (define y 'y))
+
+(module m1 (x) (define x 'x))
+
+(module mega-module (cons x y)
+
+ (import m1)
+
+ (import m2)
+
+ (import scheme))
+
+(let ([y 3])
+
+ (import-only mega-module)
+
+ (cons x y)) (x . y)
+
Before it is compiled, a source program is translated into +a core language program containing no syntactic abstractions, syntactic +definitions, library definitions, module definitions, or import forms. +Translation is performed by a syntax expander that +processes the forms in the source program via recursive descent. + +
+A define-syntax form associates a keyword +with a transformer in a translation-time environment. +When the expander encounters a keyword, it invokes the +associated transformer and reprocesses the resulting form. +A module form associates a module name with an interface. +When the expander encounters an import form, it extracts the +corresponding module interface from the translation-time environment and makes +the exported bindings visible in the scope where the import form +appears. + +
+Internal definitions and definitions within a module +body are processed from left to right so that a module's definition +and import may appear within the same sequence of definitions. +Expressions appearing within a body and the right-hand sides of variable +definitions, however, are translated +only after the entire set of definitions has been processed, allowing +full mutual recursion among variable and syntactic definitions. + +
+Module and import forms affect only the visibility of identifiers in +the source program, not their meanings. +In particular, variables are bound to locations whether defined within or +outside of a module, and import does not introduce new locations. +Local variables are renamed as necessary to preserve the scoping +relationships established by both modules and syntactic abstractions. +Thus, the expression: + +
+ +
(let ([x 1])
+
+ (module m (x setter)
+
+ (define-syntax x (identifier-syntax z))
+
+ (define setter (lambda (x) (set! z x)))
+
+ (define z 5))
+
+ (let ([y x] [z 0])
+
+ (import m)
+
+ (setter 3)
+
+ (+ x y z))) 4
+
is equivalent to the following program +in which identifiers have been consistently renamed as indicated by +subscripts. + +
+ +
(let ([x0 1])
+
+ (define-syntax x1 (identifier-syntax z1))
+
+ (define setter1 (lambda (x2) (set! z1 x2)))
+
+ (define z1 5)
+
+ (let ([y3 x0] [z3 0])
+
+ (setter1 3)
+
+ (+ x1 y3 z3)))
+
Definitions within a top-level begin, lambda, top-level program, +library, or module body +are processed from left to right by the expander at expand time, and the +variable definitions are evaluated from left-to-right at run time. +Initialization expressions appearing within a module body +are evaluated in sequence after the evaluation of the variable +definitions. + +
+Mutually recursive modules can be defined in several ways. +In the following program, a and b are mutually recursive +modules exported by an anonymous module whose local scope is used to +statically link the two. +For example, +the free variable y within module a refers to +the binding for y, provided by importing b, +in the enclosing module. + +
+ +
(module (a b)
+
+ (module a (x) (define x (lambda () y)))
+
+ (module b (y) (define y (lambda () x)))
+
+ (import a)
+
+ (import b))
+
The following syntactic abstraction generalizes this pattern to +permit the definition of multiple mutually recursive modules. + +
+ +
(define-syntax rec-modules
+
+ (syntax-rules (module)
+
+ [(_ (module m (id ...) form ...) ...)
+
+ (module (m ...)
+
+ (module m (id ...) form ...) ...
+
+ (import m) ...)]))
+
Because a module can re-export imported bindings, +it is quite easy to provide multiple views on a single +module, as s and t provide for r +below, or to combine several modules into a compound, +as r does. + +
+ +
(module p (x y)
+
+ (define x 1) (define y 2))
+
+(module q (y z)
+
+ (define y 3) (define z 4))
+
+(module r (a b c d)
+
+ (import* p (a x) (b y))
+
+ (import* q (c y) (d z)))
+
+(module s (a c) (import r))
+
+(module t (b d) (import r))
+
To allow interfaces to be separated from implementations, +the following syntactic abstractions support the definition and use of +named interfaces. + +
+ +
(define-syntax define-interface
+
+ (syntax-rules ()
+
+ [(_ name (export ...))
+
+ (define-syntax name
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(_ n defs)
+
+ (with-implicit (n export ...)
+
+ #'(module n (export ...) .
+
+ defs))])))]))
+
+
+(define-syntax define-module
+
+ (syntax-rules ()
+
+ [(_ name interface defn ...)
+
+ (interface name (defn ...))]))
+
define-interface creates an interface macro that, given a module +name and a list of definitions, expands into a module definition with +a concrete interface. + +
+with-implicit is used to ensure that the introduced +export identifiers are visible in the same scope as the name of +the module in the define-module form. + +
+define-interface and define-module can be used as +follows. + +
+ +
(define-interface simple (a b))
+
+(define-module m simple
+
+ (define-syntax a (identifier-syntax 1))
+
+ (define b (lambda () c))
+
+ (define c 2))
+
+(let () (import m) (+ a (b))) 3
+
The abstract module facility defined below allows a module interface to +be satisfied incrementally when module forms are evaluated. +This permits flexibility in the separation between the interface and +implementation, supports separate compilation of mutually recursive +modules, and permits redefinition of module implementations. + +
+ +
(define-syntax abstract-module
+
+ (syntax-rules ()
+
+ [(_ name (ex ...) (kwd ...) defn ...)
+
+ (module name (ex ... kwd ...)
+
+ (declare ex) ...
+
+ defn ...)]))
+
+
+(define-syntax implement
+
+ (syntax-rules ()
+
+ [(_ name form ...)
+
+ (module () (import name) form ...)]))
+
Within an abstract-module form, +each of the exports in the list ex ... must be +variables. +The values of these variables are supplied by one or more separate +implement forms. +Since keyword bindings must be present at compile time, +they cannot be satisfied incrementally and are instead listed as +separate exports and defined within the abstract module. + +
+Within an implement form, +the sequence of forms form ... is a sequence of +zero or more definitions followed by a sequence of zero or more +expressions. +Since the module used in the expansion of implement does +not export anything, the definitions are all local to the +implement form. +The expressions may be arbitrary expressions, but should include +one satisfy form for each variable whose definition is +supplied by the implement form. +A satisfy form has the syntax + +
+ +
(satisfy variable expr) +
declare and satisfy may simply be the equivalents of +define and set!. + +
+ +
(define-syntax declare (identifier-syntax define))
+
+(define-syntax satisfy (identifier-syntax set!))
+
Alternatively, declare can initialize the declared variable to +the value of a flag known only to declare and satisfy, +and satisfy can verify that this flag is still present to insure +that only one attempt to satisfy the value of a given identifier is +made. + +
+ +
(module ((declare cookie) (satisfy cookie))
+
+ (define cookie "chocolate chip")
+
+ (define-syntax declare
+
+ (syntax-rules () [(_ var) (define var cookie)]))
+
+ (define-syntax satisfy
+
+ (syntax-rules ()
+
+ [(_ var exp)
+
+ (if (eq? var cookie)
+
+ (set! var exp)
+
+ (assertion-violationf 'satisfy
+
+ "value of variable ~s has already been satisfied"
+
+ 'var))])))
+
Using abstract-module and implement, we can define +mutually recursive and separately compilable modules as follows. + +
+ +
(abstract-module e (even?) (pred)
+
+ (define-syntax pred
+
+ (syntax-rules () [(_ exp) (- exp 1)])))
+
+
+(abstract-module o (odd?) ())
+
+
+(implement e
+
+ (import o)
+
+ (satisfy even?
+
+ (lambda (x)
+
+ (or (zero? x) (odd? (pred x))))))
+
+
+(implement o
+
+ (import e)
+
+ (satisfy odd?
+
+ (lambda (x) (not (even? x)))))
+
+
+(let () (import-only e) (even? 38)) #t
+
syntax: only
+
syntax: except
+
syntax: add-prefix
+
syntax: drop-prefix
+
syntax: rename
+
syntax: alias
+
+libraries: (chezscheme)
+
+
These identifiers are auxiliary keywords for import +and import-only. +It is a syntax violation to reference these identifiers except in +contexts where they are recognized as auxiliary keywords. + +
+ +
+The local import and export forms described in +Section 10.4 can be used +equally well for and within modules. + +
+ +
+Five modules are built-in to Chez Scheme: scheme, +r5rs, r5rs-syntax, ieee, and +$system. +Each module is immutable, i.e., the exported bindings cannot be +altered. + +
+module: scheme
+
+libraries: (chezscheme)
+
+
scheme contains all user-visible top-level bindings +(variables, keywords, and module names) built into Chez Scheme. + +
+module: r5rs
+
+libraries: (chezscheme)
+
+
r5rs contains all top-level bindings +(variables and keywords) defined in the +Revised5 Report on Scheme. +The bindings exported from r5rs are precisely those that are +available within an expression evaluated via eval with the +environment specifier returned by +scheme-report-environment. + +
+module: r5rs-syntax
+
+libraries: (chezscheme)
+
+
r5rs-syntax contains all top-level keyword bindings +defined in the Revised5 Report on Scheme. +The bindings exported from r5rs-syntax are precisely those that are +available within an expression evaluated via eval with the +environment specifier returned by +null-environment. + +
+module: ieee
+
+libraries: (chezscheme)
+
+
ieee contains all top-level bindings +(variables and keywords) defined in the +ANSI/IEEE standard for Scheme. +The bindings exported from ieee are precisely those that are +available within an expression evaluated via eval with the +environment specifier returned by +ieee-environment. + + +
+module: $system
+
+libraries: (chezscheme)
+
+
$system contains all user-visible top-level bindings built +into Chez Scheme along with various undocumented system bindings. + + +
+ +
+syntax: (meta . definition)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The meta keyword is actually a prefix that can be placed in +front of any definition keyword, e.g., + +
+ +
(meta define x 3) +
It tells the expander that any variable definition resulting +from the definition is to be an expand-time definition available only +to the right-hand sides of other meta definitions and, most importantly, +transformer expressions. +It is used to define expand-time helpers and other information for use +by one or more syntax-case transformers. + + +
+ +
(module M (helper1 a b)
+
+ (meta define helper1
+
+ (lambda (---)
+
+ ---))
+
+ (meta define helper2
+
+ (lambda (---)
+
+ --- (helper2 ---) ---))
+
+ (define-syntax a
+
+ (lambda (x)
+
+ --- (helper1 ---) ---))
+
+ (define-syntax b
+
+ (lambda (x)
+
+ --- (helper1 ---) ---
+
+ --- (helper2 ---) ---)))
+
The right-hand-side expressions of a syntax definition or meta definition +can refer only to identifiers whose values are already available in the +compile-time environment. +Because of the left-to-right expansion order for library, +module, lambda, and similar bodies, this implies a +semantics similar to let* for a sequence of meta definitions, +in which each right-hand side can refer only to the variables defined +earlier in the sequence. +An exception is that the right-hand side of a meta definition can refer +to its own name as long as the reference is not evaluated until after +the value of the expression has been computed. +This permits meta definitions to be self-recursive but not mutually +recursive. +The right-hand side of a meta definition can, however, build syntax +objects containing occurrences of any identifiers defined in the body +in which the meta definition appears. + +
+Meta definitions propagate through macro expansion, so one can write, +for example: + +
+ +
(module (a)
+
+ (meta define-record foo (x))
+
+ (define-syntax a
+
+ (let ([q (make-foo #''q)])
+
+ (lambda (x) (foo-x q)))))
+
+a q
+
where define-record is a macro that expands into a set of defines. + +
+It is also sometimes convenient to write + +
+ +
(meta begin defn ...) +
or + +
+ +
(meta module {exports} defn ...) +
or + +
+ +
(meta include "path") +
to create groups of meta bindings. + +
+ +
+Expansion-time decisions can be made via meta-cond, which is +similar to cond but evaluates the test expressions at +expansion time and can be used in contexts where definitions are +expected as well as in expression contexts. + +
+syntax: (meta-cond clause1 clause2 ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
Each clause but the last must take the form: + +
+ +
(test expr1 expr2 ...) +
The last may take the same form or be an else clause of the form: + +
+ +
(else expr1 expr2 ...) +
During expansion, the test expressions are evaluated in order until +one evaluates to a true value or until all of the tests have been +evaluated. +If a test evaluates to a true value, the meta-cond form +expands to a begin form containing the corresponding +expressions expr1 expr2 .... +If no test evaluates to a true value and an else clause +is present, the meta-cond form expands to a begin form +containing the expressions expr1 expr2 ... from +the else clause. +Otherwise the meta-cond expression expands into a call to +the void procedure. + +
+meta-cond might be defined as follows. + +
+ +
(define-syntax meta-cond
+
+ (syntax-rules ()
+
+ [(_ [a0 a1 a2 ...] [b0 b1 b2 ...] ...)
+
+ (let-syntax ([expr (cond
+
+ [a0 (identifier-syntax (begin a1 a2 ...))]
+
+ [b0 (identifier-syntax (begin b1 b2 ...))]
+
+ ...)])
+
+ expr)]))
+
meta-cond is used to choose, at expansion time, from among a +set of possible forms. +For example, one might have safe (error-checking) and unsafe +(non-error-checking) versions of a procedure and decide which to +call based on the compile-time optimization level, as shown +below. + +
+ +
(meta-cond
+
+ [(= (optimize-level) 3) (unsafe-frob x)]
+
+ [else (safe-frob x)])
+
+
+syntax: (alias id1 id2)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
alias is a definition and can appear anywhere +other definitions can appear. +It is used to transfer the binding from one identifier to +another. + +
+ +
(let ([x 3]) (alias y x) (set! y 4) (list x y)) (4 4)
+
+
+(module lisp (if)
+
+ (module (scheme:if)
+
+ (import scheme)
+
+ (alias scheme:if if))
+
+ (define-syntax if
+
+ (syntax-rules ()
+
+ [(_ e_1 e_2 e_3)
+
+ (scheme:if (not (memq e_1 '(#f ()))) e_2 e_3)])))
+
+(define (length ls)
+
+ (import lisp)
+
+ (if ls (+ (length (cdr ls)) 1) 0))
+
+(length '(a b c)) 3
+
Because of left-to-right expansion order, aliases should appear after +the definition of the right-hand-side identifier, e.g.: + +
+ +
(let ()
+
+ (import-only (chezscheme))
+
+ (define y 3)
+
+ (alias x y)
+
+ x) 3
+
rather than: + +
+ +
(let ()
+
+ (import-only (chezscheme))
+
+ (alias x y)
+
+ (define y 3)
+
+ x) exception: unbound identifier
+
+
+When source code is read from a file by load, +compile-file, or variants of these, such as +load-library, the reader attaches annotations to each +object read from the file. +These annotations identify the file and the position of the object within +the file. +Annotations are tracked through the compilation process and associated +with compiled code at run time. +The expander and compiler use the annotations to produce syntax errors +and compiler warnings that identify the location of the offending form, +and the inspector uses them to identify the locations of calls and +procedure definitions. +The compiler and run time also use annotations to associate source +positions with profile counts. + +
+While these annotations are usually maintained "behind the scenes," +the programmer can manipulate them directly via a set +of routines for creating and accessing annotations. + +
+Annotations are values of a type distinct from other types and have +four components: an expression, possibly with annotated subexpressions, +a source object, a stripped version of the expression, and +usage options. +Annotations can be created via +make-annotation, which has +three required arguments corresponding to the first three components +and an optional fourth argument corresponding to the fourth component. +The second argument must be a source object, and the third argument should be a +stripped version of the first argument, i.e., equivalent to the first +argument with each annotation replaced by its expression component. +An annotation is essentially equivalent to its stripped component as a +representation of source code, with the source information attached and +available to the expander or evaluator. +The optional fourth argument, if present, must be an enumeration set over +the symbols debug and profile and defaults to an +enumeration set containing both debug and profile. + +
+Annotations marked debug are used for compile-time error +reporting and run-time error reporting and inspection; annotations +marked profile are used for profiling. +Annotations created by the Scheme reader are always marked both +debug and profile, but other readers and parsers +might choose to mark some annotations only debug or only +profile. +In particular, it might be useful to annotate multiple +expressions in the output of a parser with the same source object +for debugging purposes and mark only one of them profile +to avoid duplicate counts. +It might also be useful to mark no expressions profile and +instead introduce explicit profile forms +(Section 12.7) to identify the set of source +locations to be profiled. + +
+Source objects are also values of a type distinct from other types and +also have three or five components: a source-file descriptor (sfd), +a beginning file position (bfp), an ending file position (efp), +an optional beginning line, and an optional beginning +column. The sfd identifies the file from which an expression is read and the +bfp and efp identify the range of character positions occupied by the object +in the file, with the bfp being inclusive and the efp being exclusive. +The line and column are either both numbers or both not present. +A source object can be created via +make-source-object, which +takes either three or five arguments corresponding to these components. +The first argument must be a source-file descriptor, the second and +third must be nonnegative exact integers, the second must not be +greater than the third, and the fourth and fifth (if provided) must +be positive exact integers. + +
+Source-file descriptors are also values of a type distinct +from all other types and have two components: the file's path, +usually represented by a string, and a checksum, represented by a number. +The path might or might not be an absolute path depending on how +the file's path was specified when the source-file descriptor was +created. +The checksum is computed based on the file's length and contents +when the file is created and checked by tools that look for the +source file to make sure that the proper file has been found and +has not been modified. +Source-file descriptors can be created with +make-source-file-descriptor, +which accepts two arguments: an object (usually a string) naming the path and a binary +input port, along with an optional third boolean argument, reset?, +which defaults to false. +make-source-file-descriptor computes a checksum based on +the contents of the port, starting at its current position. +It resets the port, using set-port-position!, after computing +the checksum if reset? is true; otherwise, it leaves the +port at end-of-file. + +
+The procedures that create, check for, and access annotations, +source objects, and source-file descriptors are summarized below +and described in more detail later in this section. + +
+ +
(make-annotation obj source-object obj) annotation
+
+(annotation? obj) boolean
+
+(annotation-expression annotation) obj
+
+(annotation-source annotation) source-object
+
+(annotation-stripped annotation) obj
+
+
+(make-source-object sfd uint uint) source-object
+
+(make-source-object sfd uint uint uint uint) source-object
+
+(source-object? obj) boolean
+
+(source-object-sfd source-object) sfd
+
+(source-object-bfp source-object) uint
+
+(source-object-efp source-object) uint
+
+(source-object-line source-object) uint or #f
+
+(source-object-column source-object) uint or #f
+
+
+(make-source-file-descriptor obj binary-input-port) sfd
+
+(make-source-file-descriptor obj binary-input-port reset?) sfd
+
+(source-file-descriptor obj checksum) sfd
+
+(source-file-descriptor? obj) boolean
+
+(source-file-descriptor-checksum sfd) obj
+
+(source-file-descriptor-path sfd) obj
+
A program might open a source file with +open-file-input-port, create an sfd using +make-source-file-descriptor, +create a textual port from the binary port using transcoded-port, and +create source objects and annotations for each of the objects it reads +from the file. +If a custom reader is not required, the Scheme +reader can be used to read annotations via the +get-datum/annotations +procedure: + +
+ +
(get-datum/annotations textual-input-port sfd uint) obj, uint +
get-datum/annotations is like get-datum but instead of returning +a plain datum, it returns an annotation encapsulating a datum (possibly with nested +annotations), a source object, and the plain (stripped) datum. +It also returns a second value, the position of the first character beyond the +object in the file. +Character positions are accepted and returned by +get-datum/annotations so that the textual port need not support +port-position and need not report positions in characters +if it does support port-position. +(Positions are usually reported in bytes.) +The bfp and efp positions recorded in the annotations returned by +get-datum/annotations are correct only if the positions supplied +to it are correct. + +
+Once read, an annotation can be passed to the expander, interpreter, or +compiler. +The procedures eval, expand, interpret, +and compile all accept annotated or unannotated input. + +
+Two additional procedures complete the set of annotation-related primitives: + +
+ +
(open-source-file sfd) #f or port
+
+(syntax->annotation obj) #f or annotation
+
open-source-file attempts to +locate and open the source file identified by sfd. +It returns a textual input port, positioned at the beginning of the file, +if successful, and #f otherwise. + +
+syntax->annotation accepts +a syntax object. +If the syntax object's expression is annotated, it returns the +annotation; otherwise, it returns #f. +It can be used by a macro to extract source information, when +available, from an input form. + +
+The procedure datum->syntax accepts either an +annotated or unannotated input datum. + +
+procedure: (make-annotation obj source-object stripped-obj)
+
procedure: (make-annotation obj source-object stripped-obj options)
+
+returns: an annotation
+
+libraries: (chezscheme)
+
+
The annotation is formed with obj as its expression component, +source-object as its source-object component, and stripped-obj +as its stripped component. +obj should represent an expression, possibly with embedded +annotations. +stripped-obj should be a stripped version of obj, i.e., +equivalent to obj with each annotation replaced by its +expression component. +options, if present must be an enumeration set over +the symbols debug and profile, and defaults to an +enumeration set containing both debug and profile. +Annotations marked debug are used for compile-time error +reporting and run-time error reporting and inspection; annotations +marked profile are used for profiling. + +
+procedure: (annotation? obj)
+
+returns: #t if obj is an annotation, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (annotation-expression annotation)
+
+returns: the expression component of annotation
+
+libraries: (chezscheme)
+
+
procedure: (annotation-source annotation)
+
+returns: the source-object component of annotation
+
+libraries: (chezscheme)
+
+
procedure: (annotation-stripped annotation)
+
+returns: the stripped component of annotation
+
+libraries: (chezscheme)
+
+
procedure: (annotation-option-set annotation)
+
+returns: the options enumeration set of annotation
+
+libraries: (chezscheme)
+
+
procedure: (make-source-object sfd bfp efp)
+
procedure: (make-source-object sfd bfp efp line column)
+
+returns: a source object
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor. +bfp and efp must be exact nonnegative integers, and bfp +should not be greater than efp. +line and column must be exact positive integers. + +
+procedure: (source-object? obj)
+
+returns: #t if obj is a source object, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (source-object-sfd source-object)
+
+returns: the sfd component of source-object
+
+libraries: (chezscheme)
+
+
procedure: (source-object-bfp source-object)
+
+returns: the bfp component of source-object
+
+libraries: (chezscheme)
+
+
procedure: (source-object-efp source-object)
+
+returns: the efp component of source-object
+
+libraries: (chezscheme)
+
+
procedure: (source-object-line source-object)
+
+returns: the line component of source-object if present, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (source-object-column source-object)
+
+returns: the column component of source-object if present, otherwise #f
+
+libraries: (chezscheme)
+
+
thread parameter: current-make-source-object
+
+libraries: (chezscheme)
+
+
current-make-source-object is used by the reader to construct +a source object for an annotation. current-make-source-object +is initially bound to make-source-object, and the reader always +calls the function bound to the parameter with three arguments. + +
+Adjust this parameter to, for example, eagerly convert a position integer +to a file-position object, instead of delaying the conversion to +locate-source. + +
+procedure: (make-source-file-descriptor obj binary-input-port)
+
procedure: (make-source-file-descriptor obj binary-input-port reset?)
+
+returns: a source-file descriptor
+
+libraries: (chezscheme)
+
+
To compute the checksum encapsulated in the source-file descriptor, +this procedure must read all of the data from +binary-input-port. +If reset? is present and #t, the port is reset to its +original position, as if via port-position. +Otherwise, it is left pointing at end-of-file. + +
+procedure: (source-file-descriptor? obj)
+
+returns: #t if obj is a source-file descriptor, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (source-file-descriptor-checksum sfd)
+
+returns: the checksum component of sfd
+
+libraries: (chezscheme)
+
+
procedure: (source-file-descriptor-path sfd)
+
+returns: the path component of sfd
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor. The result is typically a string, but a +source file descriptor can have any value representing a path. + +
+procedure: (source-file-descriptor path checksum)
+
+returns: a new source-file-descriptor
+
+libraries: (chezscheme)
+
+
checksum must be an exact nonnegative integer. path is usually a string, but +may be any object. +This procedure can be used to construct custom source-file descriptors or to reconstitute +source-file descriptors from the path and checksum components. + +
+syntax: (annotation-options symbol ...)
+
+returns: an annotation-options enumeration set
+
+libraries: (chezscheme)
+
+
Annotation-options enumeration sets may be passed to make-annotation to +control whether the annotation is used for debugging, profiling, both, or neither. +Accordingly, each symbol must be either debug or profile. + +
+procedure: (syntax->annotation obj)
+
+returns: an annotation or #f
+
+libraries: (chezscheme)
+
+
If obj is an annotation or syntax-object encapsulating an annotation, +the annotation is returned. + +
+procedure: (get-datum/annotations textual-input-port sfd bfp)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor. +bfp must be an exact nonnegative integer and should be the +character position of the next character to be read from +textual-input-port. + +
+This procedure returns two values: an annotated object and an ending +file position. +In most cases, bfp should be 0 for the first call +to get-datum/annotation at the start of a file, +and it should be the second return value of the preceding +call to get-datum/annotation for each subsequent +call. +This protocol is necessary to handle files containing multiple-byte +characters, since file positions do not necessarily correspond +to character positions. + +
+procedure: (open-source-file sfd)
+
+returns: a port or #f
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor. +This procedure attempts to locate and open the source file identified +by sfd. +It returns a textual input port, positioned at the beginning of the file, +if successful, and #f otherwise. +It can fail even if a file with the correct name exists in one of +the source directories when the file's checksum does not match the +checksum recorded in sfd. + +
+procedure: (locate-source sfd pos)
+
procedure: (locate-source sfd pos use-cache?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
sfd must be a source-file descriptor, and pos must be an +exact nonnegative integer. + +
+This procedure either uses cached information from a previous +request for sfd (only when use-cache? is provided as true) +or attempts to locate and open the source file identified +by sfd (which can only work when its path is a string). +If successful, it returns three values: a string path, an exact +nonnegative integer line, and an exact nonnegative integer char +representing the absolute pathname, line, and character position within +the line represented by the specified source-file descriptor and file +position. +If unsuccessful, it returns zero values. +It can fail even if a file with the correct name exists in one of +the source directories when the file's checksum does not match the +checksum recorded in sfd. + +
+procedure: (locate-source-object-source source-object get-start? use-cache?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
This procedure is similar to locate-source, but instead of +taking an sfd and a position, it takes a source object plus a request +for either the start or end location. + +
+If get-start? is true and source-object has a line and column, +this procedure returns the path in +source-objects's sfd, source-object's line, and +source-objects's column. + +
+Otherwise, +this procedure calls locate-source on +source-object's sfd, either source-object's bfp or efp +depending on get-start?, and use-cache?. + +
+thread parameter: current-locate-source-object-source
+
+libraries: (chezscheme)
+
+
current-locate-source-object-source determines the +source-location lookup function that is used by the system to report +errors based on source objects. This parameter is initially bound to +locate-source-object-object. + +
+Adjust this parameter to control the way that source locations are +extracted from source objects, possibly using recorded information, +caches, and the filesystem in a way different from +locate-source-object-object. + + +
+ +
+Source tables provide an efficient way to associate information +with source objects both in memory and on disk, such as the coverage information +saved to .covin files when +generate-covin-files is +set to #t +and the profile counts associated with source objects by +with-profile-tracker +(Section 12.7). + +
+Source tables are manipulated via hashtable-like accessors and setters +(Section 7.14, The Scheme Programming Language, 4th Edition Section 6.13), e.g., +source-table-ref and source-table-set!. +They can be saved to files via +put-source-table +and restored via +get-source-table!. + +
+procedure: (make-source-table)
+
+returns: a source table
+
+libraries: (chezscheme)
+
+
A source table contains associations between source objects and arbitrary +values. For purposes of the source-table operations described below, two +source objects are the same if they have the same source-file descriptor, +equal beginning file positions and equal ending file positions. +Two source-file descriptors are the same if they have the same path and +checksum. + +
+procedure: (source-table? obj)
+
+returns: #t if obj is a source-table; #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (source-table-set! source-table source-object obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
source-table-set! associates source-object +with obj in source-table, replacing the +existing association, if any. + + +
+procedure: (source-table-ref source-table source-object default)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
default may be any Scheme value. + +
+source-table-ref returns the value +associated with source-object in source-table. +If no value is associated with source-object in source-table, +source-table-ref returns default. + + +
+procedure: (source-table-contains? source-table source-object)
+
+returns: #t if an association for source-object exists in source-table, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (source-table-cell source-table source-object default)
+
+returns: a pair (see below)
+
+libraries: (chezscheme)
+
+
default may be any Scheme value. + +
+If no value is associated with source-object in source-table, +source-table-cell modifies source-table to associate source-object with +default. +Regardless, it returns a pair whose car is source-object and whose cdr is +the associated value. +Changing the cdr of this pair effectively updates the table to +associate source-object with a new value. +The car field of the pair should not be modified. + + +
+procedure: (source-table-delete! source-table source-object)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
source-table-delete! drops the association +for source-object from source-table, if +one exists. + + +
+procedure: (source-table-size source-table)
+
+returns: the number of entries in source-table
+
+libraries: (chezscheme)
+
+
procedure: (put-source-table textual-output-port source-table)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure writes a representation of the information stored in source-table to the port. + + +
+procedure: (get-source-table! textual-input-port source-table)
+
procedure: (get-source-table! textual-input-port source-table combine)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The port must be positioned at a representation of source-table +information written by some previous call to put-source-table, +which reads the information and merges it into source-table. + +
+If present and non-false, combine must be a procedure and +should accept two arguments. +It is called whenever associations for the same source object are +present both in source-table and in the information read from +the port. +In this case, combine is passed two arguments: the associated +value from source-table and the associated value from the +port (in that order) and must return one value, which is recorded +as the new associated value for the source object in source-table. + +
+If combine is not present, combine is #f, or +no association for a source object read from the port already exists +in source-table, the value read from the port is recorded as +the associated value of the source object in source-table. + +
+ +
(define st (make-source-table))
+
+(call-with-port (open-input-file "profile.out1")
+
+ (lambda (ip) (get-source-table! ip st)))
+
+(call-with-port (open-input-file "profile.out2")
+
+ (lambda (ip) (get-source-table! ip st +)))
+
+ + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/system.html b/csug10.0/system.html
new file mode 100644
index 000000000..87b7edc5e
--- /dev/null
+++ b/csug10.0/system.html
@@ -0,0 +1,6289 @@
+
+
+
+
+
+This chapter describes operations for +handling exceptions, interrupts, environments, +compilation and evaluation, profiling, +controlling the operation of the system, +timing and statistics, +defining and setting parameters, +and +querying the operating system environment. + + + +
+ +
+Chez Scheme provides some extensions to the +Revised6 Report exception-handling mechanism, including mechanisms +for producing formatted error messages, displaying conditions, +and redefining the base exception handler. +These extensions are described in this section. + + +
+procedure: (warning who msg irritant ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
warning raises a continuable exception with condition type +&warning and should be used to describe situations for which the +&warning condition type is appropriate, typically a situation +that should not prevent the program from continuing but might result +in a more serious problem at some later point. + +
+The continuation object with which the exception is raised also includes +a &who condition whose who field is who if who is +not #f, a &message condition whose message field is +msg, and an &irritants condition whose irritants field +is (irritant ...). + +
+who must be a string, a symbol, or #f identifying the procedure +or syntactic form reporting the warning. +It is usually best to identify a procedure the programmer has called rather +than some other procedure the programmer may not be aware is involved in +carrying out the operation. +msg must be a string and should describe the exceptional situation. +The irritants may be any Scheme objects and should include values that may +have caused or been materially involved in the exceptional situation. + + +
+procedure: (assertion-violationf who msg irritant ...)
+
+returns: does not return
+
procedure: (errorf who msg irritant ...)
+
+returns: does not return
+
procedure: (warningf who msg irritant ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
These procedures are like assertion-violation, error, +and warning except +that msg is assumed to be a format string, as if in a call to +format (Section 9.13), with +irritant ... treated as the additional arguments to +format. +This allows programs to control the appearance of the error message, at +least when the default exception handler is in place. + +
+For each of these procedures, the continuation object with which the exception +is raised includes a &format condition to signify that the string +contained in the condition object's &message condition is a +format string and the objects contained in the condition object's +&irritants condition should be treated as the additional +format arguments. + +
+syntax: &format
+
procedure: (make-format-condition)
+
+returns: a condition of type &format
+
procedure: (format-condition? obj)
+
+returns: #t if obj is a condition of type &format, #f otherwise
+
+libraries: (chezscheme)
+
+
+ +
Presence of this condition type within a compound condition indicates +that the string provided by the &message condition, if +present, is a format string and the list of objects provided by +the &irritants condition, if present, should be treated as +additional format arguments. +This condition type might be defined as follows. + +
(define-condition-type &format &condition
+
+ make-format-condition format-condition?)
+
syntax: &source
+
procedure: (make-source-condition form)
+
+returns: a condition of type &source
+
procedure: (source-condition? obj)
+
+returns: #t if obj is a condition of type &source, #f otherwise
+
procedure: (source-condition-form condition)
+
+returns: the contents of condition's form field
+
+libraries: (chezscheme)
+
+
+ +
This condition type can be included within a compound condition when a +source expression can be identified in situations in which a +&syntax condition would be inappropriate, such as when a +run-time assertion violation is detected. +The form argument should be an s-expression or syntax object +representing the source expression. +This condition type might be defined as follows. + +
(define-condition-type &source &condition
+
+ make-source-condition source-condition?
+
+ (form source-condition-form))
+
syntax: &continuation
+
procedure: (make-continuation-condition continuation)
+
+returns: a condition of type &continuation
+
procedure: (continuation-condition? obj)
+
+returns: #t if obj is a condition of type &continuation, #f otherwise
+
procedure: (condition-continuation condition)
+
+returns: the contents of condition's continuation field
+
+libraries: (chezscheme)
+
+
+ +
This condition type can be included within a compound condition to indicate +the current continuation at the point where the exception described by the +condition occurred. +The continuation of a failed assert or a call to +assertion-violation, assertion-violationf, +error, errorf, or syntax-error is now included +via this condition type in the conditions passed to raise. +The continuation argument should be a continuation. +This condition type might be defined as follows. + +
(define-condition-type &continuation &condition
+
+ make-continuation-condition continuation-condition?
+
+ (continuation condition-continuation))
+
procedure: (display-condition obj)
+
procedure: (display-condition obj textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
If textual-output-port is not supplied, it defaults to the current output port. +This procedure displays a message to the effect that an exception +has occurred with value obj. +If obj is a condition (Chapter 11 of +The Scheme Programming Language, 4th Edition), it displays information encapsulated within the condition, +handling messages, who conditions, irritants, source information, +etc., as appropriate. + +
+procedure: (default-exception-handler obj)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure is the default value of the base-exception-handler +parameter called on a condition when no other exception handler has been +defined or when all dynamically established exception handlers have chosen +not to handle the condition. +It first displays obj, as if with display-condition, to the +console error port. +For non-serious warning conditions, it returns immediately after displaying +the condition. + +
+For serious or other non-warning conditions, it +saves the condition in the parameter debug-condition, where +debug (Section 3.2) can retrieve it and +allow it to be inspected. +If the debug-on-exception parameter is set to #f (the +default unless the --debug-on-exception command-line option is provided), the +handler prints a message instructing the user to type (debug) to +enter the debugger, then resets to the current café. +Otherwise, the handler invokes debug directly and resets if +debug returns. + +
+If an I/O exception occurs while attempting to display the condition, +the default exception handler resets (as if by calling reset). +The intent is to avoid an infinite regression (ultimately ending +in exhaustion of memory) in which the process repeatedly recurs +back to the default exception handler trying to write to a console-error +port (typically stderr) that is no longer writable, e.g., due to +the other end of a pipe or socket having been closed. + +
+global parameter: debug-on-exception
+
+libraries: (chezscheme)
+
+
The value of this parameter determines whether the default exception handler +immediately enters the debugger immediately when it receives a serious or +non-warning condition. +If the --debug-on-exception +command-line option (Section 2.1) has been provided, the +initial value of this parameter is #t. +Otherwise, the initial value is #f. + + +
+thread parameter: base-exception-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure, and the procedure +should accept one argument. +The default value of base-exception-handler is +the procedure default-exception-handler. + +
+The value of this parameter is invoked whenever no exception handler +established by a program has chosen to handle an exception. + +
+thread parameter: debug-condition
+
+libraries: (chezscheme)
+
+
This parameter is used by the default exception handler to hold the +last serious or non-warning condition received by the handler, where +it can be inspected via the debug procedure +(Section 3.2). +It can also be invoked by user code to store or retrieve a +condition. + +
+thread parameter: current-exception-state
+
+libraries: (chezscheme)
+
+
current-exception-state may be used to get or set +the current exception state. +When called without arguments, current-exception-state returns +an exception state comprising the current stack of handlers established +by with-exception-handler and guard. +When called with a single argument, which must be an exception state, +current-exception-state sets the exception state. + +
+procedure: (create-exception-state)
+
procedure: (create-exception-state handler)
+
+libraries: (chezscheme)
+
+
create-exception-state creates an exception +state whose stack of exception handlers is empty except for, in effect, +an infinite number of occurrences of handler at its +base. +handler must be a procedure, and should accept one argument. +If not provided, handler defaults to a procedure equivalent +to the value of the following expression. + +
+ +
(lambda (x) ((base-exception-handler) x)) +
procedure: (assert-unreachable)
+
+libraries: (chezscheme)
+
+
assert-unreachable is an assertion with the special property that +at optimize-level 3 the optimizer can assume that the any application of +assert-unreachable is, in fact, not reachable. + +
+In code expanded or compiled at optimize-levels less than 3, invoking +assert-unreachable raises a non-continuable exception with +condition type &assertion. + +
+In code expanded or compiled at optimize-level 3, the behavior of invoking +assert-unreachable is undefined, which gives the compiler liberty to pick +convenient or efficient behavior. For example: + +
+ +
(print-gensym #f)
+
+(optimize-level 3)
+
+(expand/optimize
+
+ '(lambda (x)
+
+ (if (pair? x)
+
+ (car x)
+
+ (assert-unreachable)))))
+
+ (lambda (x) (#3%car x))
+
because choosing to make (assert-unreachable) behave the same +as (#3%car x) makes both branches of the if the +same, and then pair? test can be eliminated (since it has no side +effects). + +
+ +
+Chez Scheme allows programs to control +the action of the Scheme system when various events +occur, including an interrupt from the +keyboard, the expiration of an internal timer set by set-timer, +a breakpoint caused by a call to break, or a request from the +storage manager to initiate a garbage collection. +These mechanisms are described in this section, except for the +collect request mechanism, which is described in Section 13.1. + +
+Timer, keyboard, and collect-request interrupts are supported via a counter +that is decremented approximately once for each call to a nonleaf procedure. +(A leaf procedure is one that does not itself make any calls.) +When no timer is running, this counter is set to a default value (1000 +in Version 9) when a program starts or after an interrupt occurs. +If a timer is set (via set-timer), the counter is set to the +minimum of the default value and the number of ticks to which the timer is +set. +When the counter reaches zero, the system looks to see if the timer +is set and has expired or if a keyboard or collect request interrupt +has occurred. +If so, the current procedure call is pended ("put on hold") while the +appropriate interrupt handler is invoked to handle the interrupt. +When (if) the interrupt handler returns, the pended call takes place. +Thus, timer, keyboard, and collect-request interrupts effectively occur +synchronously with respect to the procedure call mechanism, and +keyboard and collect request interrupts may be delayed by a number +of calls equal to the default timer value. + +
+Calls to the break handler occur immediately +whenever break is called. + +
+procedure: (break who msg irritant ...)
+
procedure: (break who)
+
procedure: (break)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
The arguments to break follow the protocol described above for +errorf. +The default break handler (see break-handler) displays a message and +invokes the debugger. +The format string and objects may be omitted, in which case the +message issued by the default break handler identifies the break +using the who argument but provides no more information +about the break. +If the who argument is omitted as well, no message is generated. +The default break handler returns normally if the debugger +exits normally. + +
+thread parameter: break-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure. +The current break handler is called by break, which passes +along its arguments. +See break for a description of the default break +handler. +The example below shows how to disable breaks. + +
+ +
(break-handler (lambda args (void))) +
thread parameter: keyboard-interrupt-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure. +The keyboard-interrupt handler is called (with no arguments) when +a keyboard interrupt occurs. +The default keyboard-interrupt handler invokes the interactive +debugger. +If the debugger exits normally the interrupted computation is +resumed. +The example below shows how to install a keyboard-interrupt handler +that resets without invoking the debugger. + +
+ +
(keyboard-interrupt-handler
+
+ (lambda ()
+
+ (newline (console-output-port))
+
+ (reset)))
+
+procedure: (set-timer n)
+
+returns: previous current timer value
+
+libraries: (chezscheme)
+
+
n must be a nonnegative integer. +When n is nonzero, set-timer starts an internal timer with +an initial value of n. +When n ticks elapse, a timer interrupt occurs, resulting in +invocation of the timer interrupt handler. +Each tick corresponds roughly to one nonleaf procedure call (see the +introduction to this section); thus, ticks are not +uniform time units but instead depend heavily on how much work is done +by each procedure call. + +
+When n is zero, set-timer turns the timer off. + +
+The value returned in either case is the value of the timer before the +call to set-timer. +A return value of 0 should not be taken to imply that the timer was not on; +the return value may also be 0 if the timer was just about to fire when +the call to set-timer occurred. + +
+The engine mechanism (Section 6.4) is built on top of the +timer interrupt so timer interrupts should not be used with engines. + + +
+thread parameter: timer-interrupt-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure. +The timer interrupt handler is called by the system when the internal timer +(set by set-timer) expires. +The default handler raises an exception with condition type &assertion +to say that the handler has not +been defined; any program that uses the timer should redefine the +handler before setting the timer. + +
+procedure: (disable-interrupts)
+
procedure: (enable-interrupts)
+
+returns: disable count
+
+libraries: (chezscheme)
+
+
disable-interrupts disables the handling of interrupts, +including timer, keyboard, and collect request interrupts. +enable-interrupts re-enables these interrupts. +The system maintains a disable count that starts at zero; when zero, +interrupts are enabled. +Each call to disable-interrupts increments the count, +effectively disabling interrupts. +Each call to enable-interrupts decrements the count, if +not already zero, effectively enabling interrupts. +For example, two calls to disable-interrupts followed by one call to +enable-interrupts leaves interrupts disabled. +Calls to enable-interrupts when the count is already zero +(and interrupts are enabled) have no effect. +The value returned by either procedure is the number of calls to +enable-interrupts required to enable interrupts. + +
+Great care should be exercised when using these procedures, since disabling +interrupts inhibits the normal processing of keyboard interrupts, +timer interrupts, and, perhaps most importantly, collect request interrupts. +Since garbage collection does not happen automatically when interrupts are +disabled, it is possible for the storage allocator to run out of space +unnecessarily should interrupts be disabled for a long period of time. + +
+The with-interrupts-disabled syntactic form should be used instead of +these more primitive procedures whenever possible, +since with-interrupts-disabled ensures that interrupts are re-enabled +whenever a nonlocal exit occurs, such as when an exception is handled by +the default exception handler. + + +
+syntax: (with-interrupts-disabled body1 body2 ...)
+
syntax: (critical-section body1 body2 ...)
+
+returns: the values of the body body1 body2 ...
+
+libraries: (chezscheme)
+
+
with-interrupts-disabled evaluates the body +body1 body2 ... with interrupts disabled. +That is, upon entry, interrupts are disabled, and +upon exit, interrupts are re-enabled. +Thus, with-interrupts-disabled allows the implementation of indivisible +operations in nonthreaded versions of Chez Scheme or within a single thread +in threaded versions of Chez Scheme. +critical-section is the same as with-interrupts-disabled and +is provided for backward compatibility. + +
+with-interrupts-disabled can be defined as follows. + +
+ +
(define-syntax with-interrupts-disabled
+
+ (syntax-rules ()
+
+ [(_ b1 b2 ...)
+
+ (dynamic-wind
+
+ disable-interrupts
+
+ (lambda () b1 b2 ...)
+
+ enable-interrupts)]))
+
The use of dynamic-wind ensures that interrupts are +disabled whenever the body of the with-interrupts-disabled expression +is active and re-enabled whenever it is not. +Since calls to disable-interrupts are counted (see the +discussion under disable-interrupts and +enable-interrupts above), with-interrupts-disabled +expressions may be nested with the desired effect. + + +
+procedure: (register-signal-handler sig procedure)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
register-signal-handler is used to +establish a signal handler for a given low-level signal. +sig must be an exact integer identifying a valid signal, and +procedure should accept one argument. +See your host system's <signal.h> or documentation for a list +of valid signals and their numbers. +After a signal handler for a given signal has been registered, receipt +of the specified signal results in a call to the handler. +The handler is passed the signal number, allowing the same handler to +be used for different signals while differentiating among them. + +
+Signals handled in this fashion are treated like keyboard interrupts in +that the handler is not called immediately when the signal is delivered +to the process, but rather at some procedure call boundary after the +signal is delivered. +It is generally not a good idea, therefore, to establish handlers for +memory faults, illegal instructions, and the like, since the code that +causes the fault or illegal instruction will continue to execute +(presumably erroneously) for some time before the handler is invoked. +A finite amount of storage is used to buffer as-yet unhandled +signals, after which additional signals are dropped. + +
+register-signal-handler is supported only on Unix-based +systems. + + +
+ +
+Environments are first-class objects containing identifier bindings. +They are similar to modules but, unlike modules, may be manipulated +at run time. +Environments may be provided as optional arguments to eval, +expand, and the procedures that define, assign, or +reference top-level values. + +
+There are several built-in environments, and new environments can +be created by copying existing environments or selected bindings +from existing environments. + +
+Environments can be mutable or immutable. +A mutable environment can be extended with new bindings, its +existing bindings can be modified, and its variables can be assigned. +An immutable environment cannot be modified in any of these ways. + +
+procedure: (environment? obj)
+
+returns: #t if obj is an environment, otherwise #f
+
+libraries: (chezscheme)
+
+
+
(environment? (interaction-environment)) #t
+
+(environment? 'interaction-environment) #f
+
+(environment? (copy-environment (scheme-environment))) #t
+
+(environment? (environment '(prefix (rnrs) $rnrs-))) #t
+
procedure: (environment-mutable? env)
+
+returns: #t if env is mutable, otherwise #f
+
+libraries: (chezscheme)
+
+
+
(environment-mutable? (interaction-environment)) #t
+
+(environment-mutable? (scheme-environment)) #f
+
+(environment-mutable? (copy-environment (scheme-environment))) #t
+
+(environment-mutable? (environment '(prefix (rnrs) $rnrs-))) #f
+
procedure: (scheme-environment)
+
+returns: an environment
+
+libraries: (chezscheme)
+
+
scheme-environment returns an environment containing +the initial top-level bindings. +This environment corresponds to the scheme module. + +
+The environment returned by this procedure is immutable. + +
+ +
(define cons 3)
+
+(top-level-value 'cons (scheme-environment)) #<procedure cons>
+
+(set-top-level-value! 'cons 3 (scheme-environment)) exception
+
procedure: (ieee-environment)
+
+returns: an IEEE/ANSI standard compatibility environment
+
+libraries: (chezscheme)
+
+
ieee-environment returns an environment containing +bindings for the keywords and variables whose meanings are +defined by the IEEE/ANSI Standard for Scheme [26]. + +
+The bindings for each of the identifiers in the IEEE environment are those +of the corresponding Revised6 Report library, so this does not provide +full backward compatibility. + +
+The environment returned by this procedure is immutable. + +
+ +
(define cons 3)
+
+(top-level-value 'cons (ieee-environment)) #<procedure cons>
+
+(set-top-level-value! 'cons 3 (ieee-environment)) exception
+
thread parameter: interaction-environment
+
+libraries: (chezscheme)
+
+
The original value of interaction-environment is the default +top-level environment. +It is initially set to a mutable copy of +(scheme-environment) and which may be extended or otherwise +altered by top-level definitions and assignments. +It may be set to any environment, mutable or not, to change the +default top-level evaluation environment. + +
+An expression's top-level bindings resolve to the environment that is +in effect when the expression is expanded, and changing the value +of this parameter has no effect on running code. +Changes affect only code that is subsequently expanded, e.g., as the +result of a call to eval, load, or +compile-file. + +
+ +
(define cons 3)
+
+cons 3
+
+(top-level-value 'cons (interaction-environment)) 3
+
+
+(interaction-environment (scheme-environment))
+
+cons #<procedure cons>
+
+(set! cons 3) exception: attempt to assign immutable variable
+
+(define cons 3) exception: invalid definition in immutable environment
+
procedure: (copy-environment env)
+
procedure: (copy-environment env mutable?)
+
procedure: (copy-environment env mutable? syms)
+
+returns: a new environment
+
+libraries: (chezscheme)
+
+
copy-environment returns a copy of env, i.e., a new +environment that contains the same bindings as env. + +
+The environment is mutable if mutable? is omitted or true; +if mutable? is false, the environment is immutable. + +
+The set of bindings copied from env to the new environment +is determined by syms, which defaults to the value of +(environment-symbols env). +The binding, if any, for each element of syms is copied to the +new environment, and no other bindings are present in the new +environment. + +
+In the current implementation, the storage space used by an environment +is never collected, so repeated use of copy-environment will +eventually cause the system to run out of memory. + +
+ +
(define e (copy-environment (scheme-environment)))
+
+(eval '(define cons +) e)
+
+(eval '(cons 3 4) e) 7
+
+(eval '(cons 3 4) (scheme-environment)) (3 . 4)
+
procedure: (environment-symbols env)
+
+returns: a list of symbols
+
+libraries: (chezscheme)
+
+
This procedure returns a list of symbols representing the identifiers +bound in environment env. +It is primarily useful in building the list of symbols to be copied +from one environment to another. + +
+ +
(define listless-environment
+
+ (copy-environment
+
+ (scheme-environment)
+
+ #t
+
+ (remq 'list (environment-symbols (scheme-environment)))))
+
+(eval '(let ([x (cons 3 4)]) x) listless-environment) (3 . 4)
+
+(eval '(list 3 4) listless-environment) exception
+
procedure: (apropos-list s)
+
procedure: (apropos-list s env)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
This procedure returns a selected list of symbols and pairs. +Each symbol in the list represents an identifier bound in env. +Each pair represents a set of identifiers exported by a +predefined library or a library previously defined or loaded +into the system. +The car of the pair is the library name, and the cdr is a list +of symbols. +If s is a string, only entries whose names have s as a +substring are included, and if s is a symbol, only those whose names +have the name of s as a substring are selected. +If no environment is provided, it defaults to the value of +interaction-environment. + +
+ +
(library (a) (export a-vector-sortof) (import (rnrs))
+
+ (define a-vector-sortof '(vector 1 2 3)))
+
+(apropos-list 'vector-sort)
+
+ (vector-sort vector-sort!
+
+ ((a) a-vector-sortof)
+
+ ((chezscheme) vector-sort vector-sort!)
+
+ ((rnrs) vector-sort vector-sort!)
+
+ ((rnrs sorting) vector-sort vector-sort!)
+
+ ((scheme) vector-sort vector-sort!))
+
procedure: (apropos s)
+
procedure: (apropos s env)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
apropos is like apropos-list except the information is +displayed to the current output port, as shown in the following +transcript. + +
+ +
> (library (a) (export a-vector-sortof) (import (rnrs))
+
+ (define a-vector-sortof '(vector 1 2 3)))
+
+> (apropos 'vector-sort)
+
+interaction environment:
+
+ vector-sort, vector-sort!
+
+(a):
+
+ a-vector-sortof
+
+(chezscheme):
+
+ vector-sort, vector-sort!
+
+(rnrs):
+
+ vector-sort, vector-sort!
+
+(rnrs sorting):
+
+ vector-sort, vector-sort!
+
+(scheme):
+
+ vector-sort, vector-sort!
+
+
+procedure: (eval obj)
+
procedure: (eval obj env)
+
+returns: value of the Scheme form represented by obj
+
+libraries: (chezscheme)
+
+
eval treats obj as the representation of an expression. +It evaluates the expression in environment env and returns +its value. +If no environment is provided, it defaults to the environment +returned by interaction-environment. + +
+Single-argument eval is a Chez Scheme extension. +Chez Scheme also permits obj to be the representation of a +nonexpression form, i.e., a definition, whenever the environment +is mutable. +Chez Scheme further allows obj to be an annotation +(Section 11.11), and the default evaluators +make use of annotations to incorporate source-file +information in error messages and associate source-file +information with compiled code. + +
+In Chez Scheme, eval is actually a wrapper that simply +passes its arguments to the current evaluator. +(See current-eval.) +The default evaluator is compile, which expands the +expression via the current expander (see +current-expand), compiles it, +executes the resulting code, and returns its value. +If the environment argument, env, is present, +compile passes it along to the current expander, +which is sc-expand by default. + + +
+thread parameter: current-eval
+
+libraries: (chezscheme)
+
+
current-eval determines the evaluation procedure used by the +procedures eval, load, and +new-cafe. +current-eval is initially bound to the value of +compile. +(In Petite Chez Scheme, it is initially bound to the value of +interpret.) +The evaluation procedure should expect one or two arguments: an object +to evaluate and an optional environment. +The second argument might be an annotation +(Section 11.11). + +
+ +
(current-eval interpret)
+
+(+ 1 1) 2
+
+
+(current-eval (lambda (x . ignore) x))
+
+(+ 1 1) (+ 1 1)
+
procedure: (compile obj)
+
procedure: (compile obj env)
+
+returns: value of the Scheme form represented by obj
+
+libraries: (chezscheme)
+
+
obj, which can be an annotation (Section 11.11) +or unannotated value, is treated as a Scheme expression, expanded with the +current expander (the value of current-expand) in the specified +environment (or the interaction environment, if no environment +is provided), compiled to machine code, and executed. +compile is the default value of the current-eval +parameter. + + +
+procedure: (interpret obj)
+
procedure: (interpret obj env)
+
+returns: value of the Scheme form represented by obj
+
+libraries: (chezscheme)
+
+
interpret is like compile, except that the expression +is interpreted rather than compiled. +interpret may be used as a replacement for compile, +with the following caveats: + +
+
+
+
+ +
+interpret is sometimes faster than compile when the +form to be evaluated is short running, since it avoids some of the +work done by compile prior to evaluation. + + +
+procedure: (load path)
+
procedure: (load path eval-proc)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +load reads and evaluates the contents of the file specified by +path. +The file may contain source or object code. +By default, load employs eval to evaluate each source +expression found in a source file. +If eval-proc is specified, load uses this procedure instead. +eval-proc must accept one argument, the expression to evaluate. +The expression passed to eval-proc might be an annotation +(Section 11.11) or an unannotated value. + +
+The eval-proc argument +facilitates the implementation of embedded Scheme-like languages +and the use of alternate +evaluation mechanisms to be used for Scheme programs. +eval-proc can be put to other uses as well. +For example, + +
+ +
(load "myfile.ss"
+
+ (lambda (x)
+
+ (pretty-print
+
+ (if (annotation? x)
+
+ (annotation-stripped x)
+
+ x))
+
+ (newline)
+
+ (eval x)))
+
pretty-prints each expression before evaluating it. + +
+The parameter source-directories (Section 12.5) +determines the set of directories searched for source files not identified +by absolute path names or paths that start with ./ (or .\ +under Windows) or ../ (or ..\ under Windows). + +
+procedure: (load-library path)
+
procedure: (load-library path eval-proc)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
load-library is identical to load except +that it treats the input file as if it were prefixed by an implicit +#!r6rs. +This effectively disables any non-R6RS lexical +syntax except where subsequently overridden by #!chezscheme. + + +
+procedure: (load-program path)
+
procedure: (load-program path eval-proc)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +load-program reads and evaluates the contents of the file specified by +path. +The file may contain source or object code. +If it contains source code, load-program wraps +the code in a top-level-program form so that the file's +content is treated as an RNRS top-level program +(Section 10.3 of The Scheme Programming Language, 4th Edition). +By default, load-program employs eval to evaluate each source +expression found in the file. +If eval-proc is specified, load-program uses this procedure instead. +eval-proc must accept one argument, the expression to evaluate. +The expression passed to eval-proc might be an annotation +(Section 11.11) or an unannotated value. + +
+The parameter source-directories (Section 12.5) +determines the set of directories searched for source files not identified +by absolute path names or paths that start with ./ (or .\ +under Windows) or ../ (or ..\ under Windows). + + +
+procedure: (verify-loadability situation input ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
situation must be one of the symbols visit, revisit, or load. +Each input must be a string pathname or a pair of a string pathname and a library search path. +Each of the pathnames should name a file containing object code for a set of libraries and +top-level programs, such as would be produced by +compile-program, +compile-library, +compile-whole-program, +or +compile-whole-library. +A library search path must be a suitable argument for +library-directories. + +
+verify-loadability verifies, without actually loading any +code or defining any libraries, whether the object files named +by the specified pathnames and their library dependencies, direct +or indirect, are present, readable, and mutually compatible. +The type of dependencies for each named object file is determined +by the situation argument: compile-time dependencies for +visit, run-time dependencies for revisit and both for +load. + +
+For each input pathname that is paired with a search path, +the library-directories parameter is parameterized to the +library search path during the recursive search for dependencies +of the programs and libraries found in the object file named by the +pathname. + +
+If verify-loadability finds a problem, such as a missing +library dependency or compilation-instance mismatch, it raises an +exception with an appropriate condition. +Otherwise, it returns an unspecified value. + +
+Since verify-loadability does not load or run any code +from the files it processes, it cannot determine whether errors +unrelated to missing or unreadable files or mutual compatibility +will occur when the files are actually loaded. + + +
+procedure: (load-compiled-from-port input-port)
+
procedure: (load-compiled-from-port input-port externals)
+
+returns: result of the last compiled expression
+
+libraries: (chezscheme)
+
+
load-compiled-from-port reads and evaluates the object-code contents +of input-port as previously created by functions like compile-file, +compile-script, compile-library, and +compile-to-port. + +
+The externals argument, if supplied, must be a vector. It should +cooperate with an ext-pred procedure passed to +compile-to-port, analogous to the way a procedure and vector +cooperate with fasl-write and fasl-read. + +
+The return value is the value of the last expression whose compiled +form is in input-port. If input-port is empty, then the +result value is unspecified. +The port is left at end-of-file but is not closed. + + +
+procedure: (visit-compiled-from-port input-port)
+
+returns: result of the last compiled expression processed
+
+libraries: (chezscheme)
+
+
visit-compiled-from-port reads and evaluates the object-code contents +of input-port as previously created by functions like compile-file, +compile-script, compile-library, and +compile-to-port. In the process, it skips any revisit (run-time-only) code. + +
+The return value is the value of the last expression whose last non-revisit compiled +form is in input-port. If there are no such forms, then the +result value is unspecified. +The port is left at end-of-file but is not closed. + + +
+procedure: (revisit-compiled-from-port input-port)
+
+returns: result of the last compiled expression processed
+
+libraries: (chezscheme)
+
+
revisit-compiled-from-port reads and evaluates the object-code contents +of input-port as previously created by functions like compile-file, +compile-script, compile-library, and +compile-to-port. In the process, it skips any visit (compile-time-only) code. + +
+The return value is the value of the last expression whose last non-visit compiled +form is in input-port. If there are no such forms, then the +result value is unspecified. +The port is left at end-of-file but is not closed. + + +
+procedure: (visit path)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +visit reads the named file, which must contain compiled object +code compatible with the current machine type and version, and it +runs those portions of the compiled object code that +establish compile-time information or correspond to expressions +identified as "visit" time by eval-when forms contained in +the original source file. + +
+For example, assume the file t1.ss contains the following +forms: + +
+ +
(define-syntax a (identifier-syntax 3))
+
+(module m (x) (define x 4))
+
+(define y 5)
+
If t1.ss is compiled to t1.so, applying load +to t1.so has the effect of defining all three identifiers. +Applying visit to t1.so, however, has the effect of +installing the transformer for a, installing the interface for +m (for use by import), and recording y as +a variable. +visit is useful when separately compiling one file that depends +on bindings defined in another without actually loading and evaluating +the code in the supporting file. + +
+The parameter source-directories (Section 12.5) +determines the set of directories searched for source files not identified +by absolute path names or paths that start with ./ (or .\ +under Windows) or ../ (or ..\ under Windows). + +
+procedure: (revisit path)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. +revisit reads the named file, which must contain compiled object +code compatible with the current machine type and version, and it +runs those portions of the compiled object code that compute +run-time values or correspond to expressions identified as "revisit" time by +eval-when forms contained in the original source file. + +
+Continuing the example given for visit above, +applying revisit to the object file, t1.so, has +the effect of establishing the values of the variable x +exported from m and the top-level variable y, +without installing either the interface for m or +the transformer for a. + +
+revisit is useful for loading compiled application code without +loading unnecessary compile-time information. +Care must be taken when using this feature if the application calls +eval or uses top-level-value, +set-top-level-value!, or top-level-syntax to access +top-level bindings at run-time, since these procedures use compile-time +information to resolve top-level bindings. + +
+The parameter source-directories (Section 12.5) +determines the set of directories searched for source files not identified +by absolute path names or paths that start with ./ (or .\ +under Windows) or ../ (or ..\ under Windows). + +
+procedure: (compile-file input-filename)
+
procedure: (compile-file input-filename output-filename)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
input-filename and output-filename must be strings. +input-filename must name an existing, readable file. +It must contain a sequence of zero or more source expressions; +if this is not the case, compile-file raises an exception +with condition type &syntax. + +
+The normal evaluation process proceeds in two steps: compilation and +execution. +compile-file performs the compilation process for an entire source +file, producing an object file. +When the object file is subsequently loaded (see load), the +compilation process is not necessary, and the file typically loads +several times faster. + +
+If the optional output-filename argument is omitted, the +actual input and output filenames are determined as follows. +If input-filename has no extension, the input filename +is input-filename followed by .ss and the +output filename is input-filename followed by .so. +If input-filename has the extension .so, the +input filename is input-filename and the output filename +is input-filename followed by .so. +Otherwise, the input filename is input-filename and the +output filename is input-filename without its extension, +followed by .so. +For example, (compile-file "myfile") produces an object file +with the name "myfile.so" from the source file named +"myfile.ss", (compile-file "myfile.sls") produces an +object file with the name "myfile.so" from the source file named +"myfile.sls", and +(compile-file "myfile1" "myfile2") produces an object file with +the name "myfile2" from the source file name "myfile1". + +
+Before compiling a file, compile-file saves the values of the +following parameters: + +
+ +
optimize-level
+
+debug-level
+
+run-cp0
+
+cp0-effort-limit
+
+cp0-score-limit
+
+cp0-outer-unroll-limit
+
+generate-inspector-information
+
+generate-procedure-source-information
+
+compile-profile
+
+generate-covin-files
+
+generate-interrupt-trap
+
+enable-cross-library-optimization
+
+enable-arithmetic-left-associative
+
+enable-error-source-expression
+
+enable-unsafe-application
+
+enable-type-recovery
+
It restores the values after the file has been compiled. +This allows the programmer to control the values of these parameters on +a per-file basis, e.g., via an eval-when with situation +compile embedded in the source file. +For example, if + +
+ +
(eval-when (compile) (optimize-level 3)) +
appears at the top of a source file, the optimization level is set +to 3 just while the remainder of file is compiled. + +
+procedure: (compile-script input-filename)
+
procedure: (compile-script input-filename output-filename)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
input-filename and output-filename must be strings. + +
+compile-script is like compile-file but differs in +that it copies the leading #! line from the +source-file script into the object file. + +
+compile-script permits compiled script files to be created from +source script to reduce script load time. +As with source-code scripts, compiled scripts may be run with the +--script +command-line option. + +
+procedure: (compile-library input-filename)
+
procedure: (compile-library input-filename output-filename)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
input-filename and output-filename must be strings. + +
+compile-library is identical to compile-file except +that it treats the input file as if it were prefixed by an implicit +#!r6rs. +This effectively disables any non-R6RS lexical +syntax except where subsequently overridden by #!chezscheme. + +
+procedure: (compile-program input-filename)
+
procedure: (compile-program input-filename output-filename)
+
+returns: a list of libraries invoked by the program
+
+libraries: (chezscheme)
+
+
input-filename and output-filename must be strings. + +
+compile-program is like compile-script but differs in +that it implements the semantics of RNRS top-level programs, while +compile-script implements the semantics of the interactive +top-level. +The resulting compiled program will also run faster than if compiled +via compile-file or compile-script. + +
+compile-program returns a list of libraries directly +invoked by the compiled top-level program, excluding built-in +libraries like (rnrs) and (chezscheme). +The procedure library-requirements may be used to determine +the indirect requirements, i.e., additional libraries required by +the directly invoked libraries. +When combined with library-object-filename, this information can +be used to determine the set of files that must be distributed with the +compiled program file. + +
+A program invokes a library only if it references one or more variables +exported from the library. +The set of libraries invoked by a top-level program, and hence +loaded when the program is loaded, might be smaller than the set +imported by the program, and it might be larger than the set +directly imported by the program. + +
+As with source-code top-level programs, compiled top-level programs may be +run with the +--program +command-line option. + +
+procedure: (maybe-compile-file input-filename)
+
procedure: (maybe-compile-file input-filename output-filename)
+
procedure: (maybe-compile-library input-filename)
+
procedure: (maybe-compile-library input-filename output-filename)
+
procedure: (maybe-compile-program input-filename)
+
procedure: (maybe-compile-program input-filename output-filename)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
These procedures are like their non-maybe counterparts but +compile the source file only if the object file is out-of-date. +An object file X is considered out-of-date if it does not exist or +if it is older than the source file or any files included (via include) +when X was created. +When the value of the parameter compile-imported-libraries +is #t, X is also considered out-of-date if the object +file for any library imported when X was compiled is out-of-date. +If maybe-compile-file determines that compilation is necessary, +it compiles the source file by passing compile-file the +input and output filenames. +compile-library does so by similarly invoking the value of the +compile-library-handler parameter, and +compile-program does so by similarly invoking the value of the +compile-program-handler parameter. + +
+When output-filename is not specified, the input and output +filenames are determined in the same manner as for compile-file. + +
+thread parameter: compile-library-handler
+
+libraries: (chezscheme)
+
+
This parameter must be set to a procedure, and the procedure should +accept two string arguments naming a source file and an object file. +The procedure should typically invoke compile-library and +pass it the two arguments, but it can also use one of the other +file or port compilation procedures. +For example, it might read the source file using its own parser and +use compile-to-file to finish +the compilation process. +The procedure can perform other actions as well, such as parameterizing +compilation parameters, establishing guards, or gathering statistics. +The default value of this parameter simply invokes +compile-library on the two string arguments without taking +any other action. + +
+The value of this parameter is called by maybe-compile-library +when the object file is out-of-date. +It is also called by the expander to compile an +imported library when compile-imported-libraries is #t +and the expander determines the object file is out-of-date. + +
+thread parameter: compile-program-handler
+
+libraries: (chezscheme)
+
+
This parameter must be set to a procedure, and the procedure should +accept two string arguments naming a source file and an object file. +The procedure should typically invoke compile-program and +pass it the two arguments, but it can also use one of the other +file or port compilation procedures. +For example, it might read the source file using its own parser and +use compile-to-file to finish +the compilation process. +The procedure can perform other actions as well, such as parameterizing +compilation parameters, establishing guards, or gathering statistics. +The default value of this parameter simply invokes +compile-program on the two string arguments without taking +any other action and returns the list of libraries returned by +compile-program. + +
+The value of this parameter is called by maybe-compile-program +when the object file is out-of-date. + +
+procedure: (compile-whole-program input-filename output-filename)
+
procedure: (compile-whole-program input-filename output-filename libs-visible?)
+
+returns: a list of libraries left to be loaded at run time
+
+libraries: (chezscheme)
+
+
compile-whole-program accepts as input a filename naming +a "whole program optimization" (wpo) file for a top-level program +and produces an object file incorporating the program and each +library upon which it depends, provided that a wpo file for the +library can be found. + +
+If a wpo file for a required library cannot be found, but an object +file for the library can, the library is not incorporated in the +resulting object file. +Such libraries are left to be loaded at run time. +compile-whole-program returns a list of such libraries. +If there are no such libraries, the resulting object file is +self-contained and compile-whole-program returns the empty +list. + +
+The libraries incorporated into the resulting object file are visible (for +use by environment and eval) if the libs-visible? +argument is supplied and non-false. +Any library incorporated into the resulting object file and required by +an object file left to be loaded at run time is also visible, as are any +libraries the object file depends upon, regardless of the value of +libs-visible?. + +
+compile-whole-program linearizes the initialization code for the +set of incorporated libraries in a way that respects static +dependencies among the libraries but not necessary dynamic dependencies +deriving from initialization-time uses of environment +or eval. +Additional static dependencies can be added in most cases to force +an ordering that allows the dynamic imports to succeed, +though not in general since a different order might be required each +time the program is run. +Adding a static dependency of one library on a second requires +adding an import of the second in the first as well as a run-time +reference to one of the variables exported by the second in the +body of the first. + +
+input-filename and output-filename must be strings. +input-filename must identify a wpo file, and a wpo or object +file must also be present for each required library somewhere in +the directories specified by the library-directories +parameter. + +
+To the extent possible given the specified set of visible libraries +and requirements of libraries to be loaded at run time, +compile-whole-program discards unused code and optimizes +across program and library boundaries, potentially reducing program +load time, run time, and memory requirements. +Some optimization also occurs even across the boundaries of libraries +that are not incorporated into the output, though this optimization +is limited in nature. + +
+The procedures compile-file, compile-program, compile-library, +compile-script, and compile-whole-library produce wpo files as well as ordinary +object files when the generate-wpo-files parameter is set +to #t (the default is #f). +compile-port and compile-to-port do so when passed +an optional wpo port. + +
+procedure: (compile-whole-library input-filename output-filename)
+
+returns: a list of libraries left to be loaded at run time
+
+libraries: (chezscheme)
+
+
compile-whole-library is like compile-whole-program, +except input-filename must specify a wpo file for a library, +all libraries are automatically made visible, and a new wpo file is +produced (when generate-wpo-files is #t) as well +as an object file for the resulting combination of libraries. + +
+The comment in the description of compile-whole-program +about the effect of initialization-code linearization on dynamic +dependencies applies to compile-whole-library as well. + +
+procedure: (compile-port input-port output-port)
+
procedure: (compile-port input-port output-port sfd)
+
procedure: (compile-port input-port output-port sfd wpo-port)
+
procedure: (compile-port input-port output-port sfd wpo-port covop)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
input-port must be a textual input port. +output-port and, if present and non-false, wpo-port must be binary output ports. +If present and non-false, sfd must be a source-file descriptor. +If present and non-false, covop must be a textual output port. + +
+compile-port is like compile-file except that it takes +input from an arbitrary textual input port and sends output to an arbitrary +binary output port. +If sfd is supplied, it is passed to the reader so that source information +can be associated with the expressions read from input-port. +It is also used to associate block-profiling information with the input +file name encapsulated within sfd. +If wpo-port is supplied, compile-port sends whole-program optimization information +to wpo-port for use by compile-whole-program, as if +(and regardless of whether) generate-wpo-files is set. +If covop is supplied, compile-port sends coverage information to +covop, as if (and regardless of whether) generate-covin-files is set. + +
+The ports are closed automatically after compilation under the assumption +the program that opens the ports and invokes compile-port +will take care of closing the ports. + +
+procedure: (compile-to-port objs op)
+
procedure: (compile-to-port objs op sfd)
+
procedure: (compile-to-port objs op sfd wpoop)
+
procedure: (compile-to-port objs op sfd wpoop covop)
+
procedure: (compile-to-port objs op sfd wpoop covop mach)
+
procedure: (compile-to-port objs op sfd wpoop covop mach hostop)
+
procedure: (compile-to-port objs op sfd wpoop covop mach hostop ext)
+
procedure: (compile-to-port objs op sfd wpoop covop mach hostop ext nortds?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
objs must be a list containing a sequence of +objects that represent syntactically valid expressions, each possibly +annotated (Section 11.11). +If any of the objects does not represent a syntactically valid +expression, compile-to-port raises an exception with +condition type &syntax. +op and, if present and non-false, wpoop, covop, and hostop must be binary output ports. +If present and non-false, sfd must be a source-file descriptor. +If present and non-false, mach must be a symbol. +If present and non-false, ext must be or a procedure, +but it must be #f if objs does not have exactlty one element. + +
+compile-to-port is like compile-file except that it takes +input from a list of objects and sends output to an arbitrary binary +output port. +sfd is used to associate block-profiling information with the +input file name encapsulated within sfd. +If wpoop is present and not #f, compile-to-port sends whole-program optimization information +to wpoop for use by compile-whole-program, as if +(and regardless of whether) generate-wpo-files is set. +If covop is present and not #f, compile-to-port sends coverage information to +covop, as if (and regardless of whether) generate-covin-files is set. +If mach is present, compile-to-port compiles for the specified machine type. +If hostop is present, compile-to-port compiles for the host machine type +to hostp (in addition to writing for machine to op, whether or not +the machine types are the same). + +
+The ports are not closed automatically after compilation under the assumption +the program that opens the port and invokes compile-to-port +will take care of closing the port. + +
+If ext is present and not #f, it is used like
+the externals-pred predicate supplied to fasl-write. In that case, a
+corresponding vector must be provided to
+
+load-compiled-from-port to load the compiled code, analogous
+to the vector supplied to fasl-read.
+
+
+Similarly, if nortds? is present and true, it is used like the +omit-rtds? argument supplied to fasl-write: Any record types +relevant to the compiled code are not written to the output port. When +the compiled code is later loaded, these record types must already +be declared in the loading context, and the +loading context is assumed to have compatible record-type +registrations using the same unique ID. Behavior if the loading context +has an incompatible record-type registration using the same +(ostensibly unique) ID is undefined. + +
+When objs contains a single list-structured element whose +first-element is the symbol top-level-program, +compile-to-port returns a list of the libraries the top-level +program requires at run time, as with compile-program. +Otherwise, the return value is unspecified. + +
+procedure: (compile-to-file obj-list output-file)
+
procedure: (compile-to-file obj-list output-file sfd)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
obj-list must be a list containing a sequence of +objects that represent syntactically valid expressions, each possibly +annotated (Section 11.11). +If any of the objects does not represent a syntactically valid +expression, compile-to-file raises an exception with +condition type &syntax. +output-file must be a string. +If present, sfd must be a source-file descriptor. + +
+compile-to-file is like compile-file except that it takes +input from a list of objects. +sfd is used to associate block-profiling information with the +input file name encapsulated within sfd. + +
+When obj-list contains a single list-structured element whose +first-element is the symbol top-level-program, +compile-to-file returns a list of the libraries the top-level +program requires at run time, as with compile-program. +Otherwise, the return value is unspecified. + +
+procedure: (concatenate-object-files out-file in-file1 in-file2 ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
out-file and each in-file must be strings. + +
+concatenate-object-files combines the header information +contained in the object files named by each in-file. It then +writes the combined header information to the file named by +out-file, followed by the remaining object code from each +input file in turn. + +
+procedure: (make-boot-file output-filename base-boot-list input-filename ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
output-filename, input-filename, and the elements of +base-boot-list must be strings. + +
+make-boot-file writes a boot header to the file named by +output-filename, followed by the object code for each +input-filename in turn. +If an input file is not already compiled, make-boot-file compiles +the file as it proceeds. + +
+The boot header identifies the elements of base-boot-list as +alternative boot files upon which the new boot file depends. +If the list of strings naming base boot files is empty, the first named +input file should be a base boot file, i.e., petite.boot or some boot file +derived from petite.boot. + +
+Boot files are loaded explicitly via the --boot or -b +command-line options or implicitly based on the name of the executable +(Section 2.9). + +
+See Section 2.8 for more information on boot files +and the use of make-boot-file. + +
+procedure: (make-boot-header output-filename base-boot1 base-boot2...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure has been subsumed by make-boot-file and is provided for +backward compatibility. +The call + +
+ +
(make-boot-header output-filename base-boot1 base-boot2 ...) +
is equivalent to + +
+ +
(make-boot-file output-filename '(base-boot1 base-boot2 ...)) +
procedure: (strip-fasl-file input-path output-path options)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
input-path and output-path must be strings. +input-path must name an existing, readable file containing +object code produced by compile-file, one of the other +file-compiling procedures, or an earlier run of strip-fasl-file. +options must be an enumeration set over the symbols constituting +valid strip options, as described in the fasl-strip-options +entry below. + +
+The new procedure strip-fasl-file allows the removal of +source information of various sorts from a compiled object (fasl) +file produced by compile-file or one of the other file +compiling procedures. +It also allows removal of library visit code from object files +containing compiled libraries. +Visit code is the code for macro transformers and meta definitions +required to compile (but not run) dependent libraries. + +
+On most platforms, the input and output paths can be the same, +in which case the input file is replaced with a new file containing +the stripped object code. +Using the same path will likely fail on Windows file systems, +which do not generally permit an open file to be removed. + +
+If options is empty, the output file is effectively equivalent +to the input file, though it will not necessarily be identical. + +
+syntax: (fasl-strip-options symbol ...)
+
+returns: a fasl-strip-options enumeration set
+
+libraries: (chezscheme)
+
+
Fasl-strip-options enumeration sets are passed to strip-fasl-file +to determine what is stripped. +The available options are described below. + +
+
+
+
+
+thread parameter: compile-procedure-realm
+
+libraries: (chezscheme)
+
+
This parameter can be set to #f or to a symbol. The realm of +a procedure (or, more precisely, a procedure's code object) is +accessible though the inspector. + +
+procedure: (vfasl-convert-file input-path output-path base-boots)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Converts a compiled file to one that may load more quickly, especially +in the case of a boot file. The converted file is a boot file if +base-boots is a list of strings, otherwise base-boots must +be #f to create a non-boot file. + +
+procedure: (pbchunk-convert-file in-path out-path c-paths c-names start-index)
+
+returns: ending index as a nonnegative exact integer
+
+libraries: (chezscheme)
+
+
Converts a compiled file in-path for a pb machine +variant to a compiled file out-path that uses C chunk +functions written to the files in c-paths, where c-paths +is a nonempty list of file names. Chunk code is distributed across the +files to avoid making a single, over-large source C file. The +c-names list provides a list of function names, one for each +output file in c-paths, where each function name is defined as a +function of no arguments to register the file's chunks with the +system. This registration must be performed before the converted +compiled code is run. Every set of chunks registered in this way must +use a distinct index range, where start-index provides the +starting index for this set, and the result value is one more than the +index of the last chunk written to the c-paths sources. + + +
+procedure: (machine-type)
+
+returns: the current machine type
+
+libraries: (chezscheme)
+
+
Consult the release notes for the current version of Chez Scheme +for a list of supported machine types. + + +
+
+procedure: (expand obj)
+
procedure: (expand obj env)
+
+returns: expansion of the Scheme form represented by obj
+
+libraries: (chezscheme)
+
+
expand treats obj as the representation of an expression. +It expands the expression in environment env and returns +an object representing the expanded form. +If no environment is provided, it defaults to the environment +returned by interaction-environment. + +
+obj can be an annotation +(Section 11.11), and the default expander +makes use of annotations to incorporate source-file +information in error messages. + +
+expand actually passes its arguments to the current expander +(see current-expand), initially sc-expand. + +
+See also expand-output (page 396) +which can be used to request that the compiler or interpreter show +expander output. + +
+thread parameter: current-expand
+
+libraries: (chezscheme)
+
+
current-expand determines the expansion procedure used by +the compiler, interpreter, and direct calls to +expand +to expand syntactic extensions. +current-expand is initially bound to the value of +sc-expand. + +
+It may be set another procedure, but since the format of +expanded code expected by the compiler and interpreter is not publicly +documented, only sc-expand produces correct output, so the +other procedure must ultimately be defined in terms of +sc-expand. + +
+The first argument to the expansion procedure represents the input +expression. +It can be an annotation (Section 11.11) or an +unannotated value. +the second argument is an environment. +Additional arguments might be passed to the expansion procedure +by the compiler, interpreter, and expand; their number +and roles are unspecified. + +
+procedure: (sc-expand obj)
+
procedure: (sc-expand obj env)
+
+returns: the expanded form of obj
+
+libraries: (chezscheme)
+
+
The procedure +sc-expand is used to expand programs written using +syntax-case macros. +sc-expand is the default expander, i.e., the initial +value of current-expand. +obj represents the program to be expanded, and +env must be an environment. +obj can be an annotation (Section 11.11) +or unannotated value. +If not provided, env defaults to the environment returned by +interaction-environment. + +
+
+procedure: (expand/optimize obj)
+
procedure: (expand/optimize obj env)
+
+returns: result of expanding and optimizing form represented by obj
+
+libraries: (chezscheme)
+
+
expand/optimize treats obj as the representation of +an expression. +obj can be an annotation (Section 11.11) +or unannotated value. +expand/optimize expands the expression in environment env +and passes the expression through the source optimizer cp0 +and a type-inferring optimizer cptypes +(unless cp0 and cptypes are disabled via run-cp0, +or unless cptypes is disabled via enable-type-recovery). +It also simplifies letrec and letrec* expressions within +the expression and makes their undefined checks explicit. +It returns an object representing the expanded, simplified, and optimized form. +If no environment is provided, it defaults to the environment +returned by interaction-environment. + +
+expand/optimize is primarily useful for understanding what +cp0 plus cptypes does and does not optimize. +Many optimizations are performed later in the compiler, +so expand/optimize does not give a complete picture of +optimizations performed. + +
+ +
(expand/optimize
+
+ '(let ([y '(3 . 4)])
+
+ (+ (car y) (cdr y)))) 7
+
+
+(print-gensym #f)
+
+(expand/optimize
+
+ '(let ([y '(3 . 4)])
+
+ (lambda (x)
+
+ (* (+ (car y) (cdr y)) x)))) (lambda (x) (#2%* 7 x))
+
+
+(expand/optimize
+
+ '(let ([n (expt 2 10)])
+
+ (define even?
+
+ (lambda (x) (or (zero? x) (not (odd? x)))))
+
+ (define odd?
+
+ (lambda (x) (not (even? (- x 1)))))
+
+ (define f
+
+ (lambda (x)
+
+ (lambda (y)
+
+ (lambda (z)
+
+ (if (= z 0) (omega) (+ x y z))))))
+
+ (define omega
+
+ (lambda ()
+
+ ((lambda (x) (x x)) (lambda (x) (x x)))))
+
+ (let ([g (f 1)] [m (f n)])
+
+ (let ([h (if (> ((g 2) 3) 5)
+
+ (lambda (x) (+ x 1))
+
+ odd?)])
+
+ (h n))))) 1025
+
See also expand/optimize-output (page 396) +which can be used to request that the compiler or interpreter show +source-optimizer output. + +
+syntax: (eval-when situations form1 form2 ...)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
situations must be a list containing some combination of the symbols +eval, compile, load, visit, and +revisit. + +
+When source files are loaded (see load), the forms in the file +are read, compiled, and executed sequentially, so that each form in +the file is fully evaluated before the next one is read. +When a source file is compiled (see compile-file), however, the +forms are read and compiled, but not executed, in sequence. +This distinction matters only when the execution of one +form in the file affects the compilation of later forms, e.g., +when the form results in the definition of a module or syntactic form or +sets a compilation parameter such as optimize-level or +case-sensitive. + +
+For example, assume that a file contains the following two forms: + +
+ +
(define-syntax reverse-define
+
+ (syntax-rules ()
+
+ [(_ e x) (define x e)]))
+
+
+(reverse-define 3 three)
+
Loading this from source has the effect of defining +reverse-define as a syntactic form and binding the identifier +three to 3. +The situation may be different if the file is compiled with +compile-file, however. +Unless the system or programmer takes steps to assure that the first +form is fully executed before the second expression is compiled, +the syntax expander will not recognize reverse-define as a syntactic +form and will generate code for a procedure call to reverse-define +instead of generating code to define three to be 3. +When the object file is subsequently loaded, the attempt to reference +either reverse-define or three will fail. + +
+As it happens, when a define-syntax, module, +import, or import-only form appears at top level, as in the +example above, the compiler does indeed arrange to evaluate it before +going on to compile the remainder of the file. +If the compiler encounters a variable definition for an identifier that +was previously something else, it records that fact as well. +The compiler also generates the +appropriate code so that the bindings will be present as well when +the object file is subsequently loaded. +This solves most, but not all, problems of this nature, since most are +related to the use of define-syntax and modules. +Some problems are not so straightforwardly handled, however. +For example, assume that the file contains the following definitions +for nodups? and mvlet. + +
+ +
(define nodups?
+
+ (lambda (ids)
+
+ (define bound-id-member?
+
+ (lambda (id ids)
+
+ (and (not (null? ids))
+
+ (or (bound-identifier=? id (car ids))
+
+ (bound-id-member? id (cdr ids))))))
+
+ (or (null? ids)
+
+ (and (not (bound-id-member? (car ids) (cdr ids)))
+
+ (nodups? (cdr ids))))))
+
+
+(define-syntax mvlet
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(_ ((x ...) expr) b1 b2 ...)
+
+ (and (andmap identifier? #'(x ...))
+
+ (nodups? #'(x ...)))
+
+ #'(call-with-values
+
+ (lambda () expr)
+
+ (lambda (x ...) b1 b2 ...))])))
+
+
+(mvlet ((a b c) (values 1 2 3))
+
+ (list (* a a) (* b b) (* c c)))
+
When loaded directly, this results in the definition of +nodups? as a procedure and mvlet as a syntactic +abstraction before evaluation of the mvlet expression. +Because nodups? is defined before the mvlet +expression is expanded, the call to nodups? during the +expansion of mvlet causes no difficulty. +If instead this file were compiled, using compile-file, the +compiler would arrange to define mvlet before continuing +with the expansion and evaluation of the mvlet expression, +but it would not arrange to define nodups?. +Thus the expansion of the mvlet expression would fail. + +
+In this case it does not help to evaluate the syntactic extension alone. +A solution in this case would be to move the definition of +nodups? inside the definition for mvlet, just as +the definition for bound-id-member? is placed within +nodups?, but this does not work for help routines shared +among several syntactic definitions. +Another solution is to label the nodups? definition a +"meta" definition (see Section 11.8) but this +does not work for helpers that are used both by syntactic +abstractions and by run-time code. + +
+A somewhat simpler problem occurs when setting parameters that affect +compilation, such as optimize-level and +case-sensitive?. +If not set prior to compilation, their settings usually will not have +the desired effect. + +
+eval-when offers a solution to these problems by allowing the +programmer to explicitly control what forms should or should not +be evaluated during compilation. +eval-when is a syntactic form and is handled directly by the +expander. +The action of eval-when depends upon the situations argument +and whether or not the forms form1 form2 ... +are being compiled via compile-file or are being evaluated +directly. +Let's consider each of the possible situation specifiers +eval, compile, load, visit, and +revisit in turn. + +
+
+
+
+
+
+A file is considered "visited" when it is brought in by either +load or visit and "revisited" when it is brought in +by either load or revisit. + +
+Top-level expressions are treated as if they are wrapped in an +eval-when with situations load and eval. +This means that, by default, forms typed at the keyboard or +loaded from a source file are evaluated, and forms appearing in a +file to be compiled are not evaluated directly but are compiled for +execution when the resulting object file is subsequently loaded. + +
+The treatment of top-level definitions is slightly more involved. +All definitions result in changes to the compile-time environment. +For example, an identifier defined by define is recorded +as a variable, and an identifier defined by define-syntax +is recorded as a keyword and associated with the value of its +right-hand-side (transformer) expression. +These changes are made at eval, compile, and load +time as if the definitions were wrapped in an eval-when with +situations eval, load, and compile. +(This behavior can be altered by changing the value of the +parameter eval-syntax-expanders-when.) +Some definitions also result in changes to the run-time environment. +For example, a variable is associated with the value of its +right-hand-side expression. +These changes are made just at evaluation and load time as if the +definitions were wrapped in an eval-when with situations +eval and load. + +
+The treatment of local expressions or definitions (those not at top level) +that are wrapped in an eval-when depends only upon whether the +situation eval is present in the list of situations. +If the situation eval is present, the definitions and expressions +are evaluated as if they were not wrapped in an eval-when form, +i.e., the eval-when form is treated as a begin form. +If the situation eval is not present, the forms are ignored; +in a definition context, the eval-when form is treated as an +empty begin, and in an expression context, the eval-when +form is treated as a constant with an unspecified value. + +
+Since top-level syntax bindings are established, by default, at compile +time as well as eval and load time, top-level variable bindings needed +by syntax transformers should be wrapped in an eval-when form +with situations compile, load, and eval. +We can thus nodups? problem above by enclosing the definition +of nodups? in an eval-when as follows. + +
+ +
(eval-when (compile load eval)
+
+ (define nodups?
+
+ (lambda (ids)
+
+ (define bound-id-member?
+
+ (lambda (id ids)
+
+ (and (not (null? ids))
+
+ (or (bound-identifier=? id (car ids))
+
+ (bound-id-member? id (cdr ids))))))
+
+ (or (null? ids)
+
+ (and (not (bound-id-member? (car ids) (cdr ids)))
+
+ (nodups? (cdr ids)))))))
+
This forces it to be evaluated before it is needed during the expansion +of the mvlet expression. + +
+Just as it is useful to add compile to the default +load and eval situations, omitting options is also +useful. +Omitting one or more of compile, load, and +eval has the effect of preventing the evaluation at the given +time. +Omitting all of the options has the effect of inhibiting evaluation +altogether. + +
+One common combination of situations is (compile eval), which by the +inclusion of compile causes the expression to be evaluated at +compile time, and by the omission of load inhibits the generation +of code by the compiler for execution when the file is subsequently loaded. +This is typically used for the definition of syntactic extensions used only +within the file in which they appear; in this case their presence in the +object file is not necessary. +It is also used to set compilation parameters that are intended to be in +effect whether the file is loaded from source or compiled via +compile-file + +
+ +
(eval-when (compile eval) (case-sensitive #t)) +
Another common situations list is (compile), which might be +used to set compilation options to be used only when the file is +compiled via compile-file. + +
+ +
(eval-when (compile) (optimize-level 3)) +
Finally, one other common combination is (load eval), which might +be useful for inhibiting the double evaluation (during the compilation of +a file and again when the resulting object file is loaded) of syntax +definitions when the syntactic extensions are not needed within +the file in which their definitions appear. + +
+The behavior of eval-when is usually intuitive but can be +understood precisely as follows. +The syntax-case expander, which handles eval-when +forms, maintains two state sets, one for compile-time forms and +one for run-time forms. +The set of possible states in each set are "L" for load, +"C" for compile, "V" for visit, "R" for +revisit, and "E" for eval. + +
+When compiling a file, the compile-time set initially contains "L" +and "C" and the run-time set initially contains only "L." +When not compiling a file (as when a form is evaluated by the +read-eval-print loop or loaded from a source file), both sets +initially contain only "E." +The subforms of an eval-when form at top level are expanded with +new compile- and run-time sets determined by the current sets and +the situations listed in the eval-when form. +Each element of the current set contributes zero or more elements to the +new set depending upon the given situations according to the following +table. + +
+
+ | load | compile | visit | revisit | eval |
+L | L | C | V | R | --- |
+C | --- | --- | --- | --- | C |
+V | V | C | V | --- | --- |
+R | R | C | --- | R | --- |
+E | --- | --- | --- | --- | E |
+ |
+For example, if the current compile-time state set is {L} +and the situations are load and compile, the new compile-time +state set is {L, C}, since L/load +contributes "L" and L/compile contributes "C." + +
+The state sets determine how forms are treated by the expander. +Compile-time forms such as syntax definitions are evaluated at a time +or times determined by the compile-time state set, and run-time forms +are evaluated at a time or times determined by the run-time state set. +A form is evaluated immediately if "C" is in the state set. +Code is generated to evaluate the form at visit or revisit +time if "V" or "R" is present. +If "L" is present in the compile-time set, it is treated as "V;" +likewise, if "L" is present in the run-time set, it is treated as +"R." +If more than one of states is present in the state set, the +form is evaluated at each specified time. + +
+"E" can appear in the state set only when not compiling a file, i.e., +when the expander is invoked from an evaluator such as compile +or interpret. +When it does appear, the expanded form is returned from the expander to be +processed by the evaluator, e.g., compile or interpret, +that invoked the expander. + +
+The value of the parameter eval-syntax-expanders-when actually determines +the initial compile-time state set. +The parameter is bound to a list of situations, which defaults to +(compile load eval). +When compiling a file, compile contributes "C" to the +state set, load contributes "L," visit contributes +"V," revisit contributes "R," and eval +contributes nothing. +When not compiling a file, eval contributes "E" to the +state set, and the other situations contribute nothing. +There is no corresponding parameter for controlling the initial value +of the run-time state set. + +
+For RNRS top-level programs, eval-when is essentially ineffective. +The entire program is treated as a single expression, so eval-when +becomes a local eval-when for which only the eval +situation has any relevance. +As for any local eval-when form, the subforms are ignored if +the eval situation is not present; otherwise, they are treated as +if the eval-when wrapper were absent. + +
+thread parameter: eval-syntax-expanders-when
+
+libraries: (chezscheme)
+
+
This parameter must be set to a list representing a set of +eval-when situations, e.g., a list containing at most one +occurrence of each of the symbols eval, compile, +load, visit, and revisit. +It is used to determine the evaluation time of syntax +definitions, module forms, and import forms are expanded. +(See the discussion of eval-when above.) +The default value is (compile load eval), which causes +compile-time information in a file to be established when the file is +loaded from source, when it is compiled via compile-file, +and when a compiled version of the file is loaded via load +or visit. + +
+thread parameter: current-generate-id
+
+libraries: (chezscheme)
+
+
This parameter must be set to a procedure that accepts one argument, a +symbol, and returns a fresh symbol. This procedure is called by the macro +expander to get symbols to use for a top-level binding, as a record uid, +or to identify a library compilation. The default procedure converts the +symbol to a string and passes it to gensym. + +
+For example, while expanding the following library, the +current-generate-id procedure is called on the symbols +a-lib, a-var, and a-var again. + +
+ +
(library (a-lib)
+
+ (export a-var)
+
+ (import (chezscheme))
+
+ (define a-var 3)
+
+ (define-syntax def
+
+ (syntax-rules ()
+
+ [(_) (define a-var 'other)]))
+
+ (def))
+
The procedure held by the current-generate-id parameter is called on a-lib +to generate a symbol that identifies this particular library +compilation, as opposed to the compilation of a different library +named (a-lib). It is called on a-var the first time +to select a distinct symbol to hold the value of the a-var +defininion, since a-var itself should not be defined directly +at the top level. Finally, the current-generate-id procedure +is called on a-var to select a name for the macro-introduced +definiton of a-var in the expansion of (def)---which +turns out to be completely inaccessible since no reference is +introduced by the same expansion step. + +
+Setting the parameter to a particular, deterministic generator can +cause symbols in the expansion of the library to be always the +same. That determinism can be helpful if the expansion semantically +matches an earlier expansion, so that uses of an earlier compilation +remain compatible with the new one. Of course, reusing a symbol runs +the risk of creating collisions that the macro and library system +normally prevents via distinct symbols, and compiler optimizations may +rely on the expectation of distinct symbols for distinct compilations. +Configure current-generate-id at your own risk. + +
+As a further example, suppose that the following two forms are +compiled separately: + +
+ +
;; Compile this x.ss to x.so
+
+(library (x)
+
+ (export x)
+
+ (import (chezscheme))
+
+ (define x '(x)))
+
+
+;; Compile this y.ss to y.so
+
+(top-level-program
+
+ (import (chezscheme)
+
+ (y))
+
+ (printf "~s\n" x))
+
If x.ss is modified and recompiled, loading the new +x.so and the old y.so will correctly report an error +that the compiled y.so requires a different compilation +instance that the one already loaded. + +
+Suppose, however, that you're willing to live dangerously to avoid +recompiling y.ss by generating the same symbols for every +compilation of x.ss. While compiling x.ss, you could +set current-generate-id to the result of +make-x-generator: + +
+ +
(define (make-x-generator)
+
+ (let ([x-uid "gf91a5b83ujz3mogjdaij7-x"]
+
+ [counter-ht (make-eq-hashtable)])
+
+ (lambda (sym)
+
+ (let* ([n (eq-hashtable-ref counter-ht sym 0)]
+
+ [s ((if (gensym? sym) gensym->unique-string symbol->string) sym)]
+
+ [g (gensym (symbol->string sym) (format "~a-~a-~a" x-uid s n))])
+
+ (eq-hashtable-set! counter-ht sym (+ n 1))
+
+ g))))
+
As long as the first and second compilations of x.ss use the +result of make-x-generator, the first compilation of +y.ss might work with the second compilation of x.ss, +even if the change adds, removes, or reorders definitions of variables +other than x. + +
+Beware that if the variable x is originally defined as +(define x 1), then the compilation of y.ss likely +inlines the value 1 in place of its reference to the variable +x, so changing x.ss will have no effect without +recompiling y.ss. Similarly, if the change to x.ss +deletes the definition of x or introduces a macro-generated +definition of x before the direct definition, then the +previously compiled y.ss is unlikely to refer to the correct +definition of x in the new compilation of x.ss. +Configure current-generate-id this way only in situations where +the potential for unspecified failure is more tolerable than +recompilation. + +
+thread parameter: expand-omit-library-invocations
+
+libraries: (chezscheme)
+
+
This boolean-valued parameter determines whether library uses are +recorded in macro expansion. Normally, when an expression expands to a +reference to a library-defined identifier, the expansion is prefixed +with a check to ensure that the exporting library is defined and +invoked. If expand-omit-library-invocations is set to true, +the prefix is omitted. + +
+Setting expand-omit-library-invocations to true makes sense +only when evaluating many small expressions in a context where all +referenced libraries are known to be present and already invoked, and +only when it's worth saving the small overhead of representing and +running the check. + +
+thread parameter: compile-omit-concatenate-support
+
+libraries: (chezscheme)
+
+
This boolean-valued parameter determines whether code compiled to a +file or port includes information needed to support +concatenate-object-files. Omitting the information can +provide minor space and load-time savings for small compiled objects. + + +
+ +
+global parameter: source-directories
+
+libraries: (chezscheme)
+
+
The value of source-directories must be a list of strings, each +of which names a directory path. +source-directories determines the set of directories searched +for source or object files when a file is loaded via load, load-library, +load-program, include, +visit, or revisit, +when a syntax error occurs, or when a source +file is opened in the interactive inspector. + +
+The default value is the list ("."), which means source files +will be found only in or relative to the current directory, unless named +with an absolute path or a path that starts with ./ (or .\ +under Windows) or ../ (or ..\ under Windows). + +
+This parameter is never altered by the system, with one exception. +The expander temporarily adds (via parameterize) the directory +in which a library file resides to the front of the source-directories +list when it compiles (when compile-imported-libraries is true) or loads the library from source, which it does +only if the library is not already defined. + +
+procedure: (with-source-path who name procedure)
+
+libraries: (chezscheme)
+
+
The procedure with-source-path searches through the current +source-directories path, in order, for a file with the specified +name and invokes procedure on the result. +If no such file is found, an exception is raised with condition types +&assertion and &who with who as +who value. + +
+If name is an absolute pathname or one beginning with ./ +(or .\ under Windows) or ../ (or ..\ under +Windows), or if the list of source directories +contains only ".", the default, or "", which is +equivalent to ".", no searching is performed and name is +returned. + +
+who must be a symbol, name must be a string, and +procedure should accept one argument. + +
+The following examples assumes that the file "pie" exists +in the directory "../spam" but not in "../ham" or the current +directory. + +
+ +
(define find-file
+
+ (lambda (fn)
+
+ (with-source-path 'find-file fn values)))
+
+
+(find-file "pie") "pie"
+
+
+(source-directories '("." "../ham"))
+
+(find-file "pie") exception in find-file: pie not found
+
+
+(source-directories '("." "../spam"))
+
+(find-file "pie") "../spam/pie"
+
+
+(source-directories '("." "../ham"))
+
+(find-file "/pie") "/pie"
+
+
+(source-directories '("." "../ham"))
+
+(find-file "./pie") "./pie"
+
+
+(source-directories '("." "../spam"))
+
+(find-file "../pie") "../ham/pie"
+
+
+thread parameter: optimize-level
+
+libraries: (chezscheme)
+
+
This parameter can take on one of the four values 0, 1, 2, and 3. + +
+In theory, this parameter controls the amount of optimization +performed by the compiler. +In practice, it does so only indirectly, and the only difference +is between optimize level 3, at which the compiler generates +"unsafe" code, and optimize levels 0-2, at which the compiler +generates "safe" code. +Safe code performs full type and bounds checking so that, for example, +an attempt to apply a non-procedure, an attempt to take the car of a +non-pair, or an attempt to reference beyond the end of a vector each +result in an exception being raised. +With unsafe code, the same situations may result in invalid memory +references, corruption of the Scheme heap (which may cause +seemingly unrelated problems later), system crashes, or other undesirable +behaviors. +Unsafe code is typically faster, but optimize-level 3 should be used with +caution and only on sections of well-tested code that must run as quickly +as possible. + +
+While the compiler produces the same code for optimize levels 0-2, +user-defined macro transformers can differentiate among the different +levels if desired. + +
+One way to use optimize levels is on a per-file +basis, using eval-when to force the use of a particular +optimize level at compile time. +For example, placing: + +
+ +
(eval-when (compile) (optimize-level 3)) +
at the front of a file will cause all of the forms in the file to be +compiled at optimize level 3 when the file is compiled (using +compile-file) but does not affect the optimize level used +when the file is loaded from source. +Since compile-file parameterizes optimize-level (see parameterize), +the above +expression does not permanently alter the optimize level in the +system in which the compile-file is performed. + +
+The optimize level can also be set via the +--optimize-level +command-line option (Section 2.9). +This option is particularly useful for running RNRS top-level programs +at optimize-level 3 via the +--program command-line option, +since eval-when is ineffective for RNRS top-level programs as described +on page 385. + + +
+
+syntax: ($primitive variable)
+
syntax: #%variable
+
syntax: ($primitive 2 variable)
+
syntax: #2%variable
+
syntax: ($primitive 3 variable)
+
syntax: #3%variable
+
+returns: the primitive value for variable
+
+libraries: (chezscheme)
+
+
variable must name a primitive procedure. +The $primitive syntactic form allows control over the +optimize level at the granularity of individual primitive references, +and it can be used to access the original value +of a primitive, regardless of the lexical context or the current +top-level binding for the variable originally bound to the primitive. + +
+The expression ($primitive variable) may +be abbreviated as #%variable. +The reader expands #% followed by an object +into a $primitive expression, much as it expands 'object +into a quote expression. + +
+If a 2 or 3 appears in the form or between the +# and % in the abbreviated form, the compiler treats +an application of the primitive as if it were compiled +at the corresponding optimize level (see the optimize-level +parameter). +If no number appears in the form, an application of the primitive is +treated as an optimize-level 3 application if the current optimize +level is 3; +otherwise, it is treated as an optimize-level 2 application. + +
+ +
(#%car '(a b c)) a
+
+(let ([car cdr]) (car '(a b c))) (b c)
+
+(let ([car cdr]) (#%car '(a b c))) a
+
+(begin (set! car cdr) (#%car '(a b c))) a
+
thread parameter: debug-level
+
+libraries: (chezscheme)
+
+
This parameter can take on one of the four values 0, 1, 2, and 3. +It is used to tell the compiler how important the preservation of +debugging information is, with 0 being least important and 3 being +most important. +The default value is 1. +As of Version 9.0, it is used solely to determine whether an +error-causing call encountered in nontail position is treated as +if it were in tail position (thus causing the caller's frame not +to appear in a stack backtrace); this occurs at debug levels below 2. + +
+thread parameter: generate-interrupt-trap
+
+libraries: (chezscheme)
+
+
To support interrupts, including keyboard, timer, and collect request +interrupts, the compiler inserts a short sequence of instructions at the +entry to each nonleaf procedure (Section 12.2). +This small overhead may be eliminated by setting +generate-interrupt-trap to #f. +The default value of this parameter is #t. + +
+It is rarely a good idea to compile code without interrupt trap +generation, since a tight loop in the generated code may completely +prevent interrupts from being serviced, including the collect request +interrupt that causes garbage collections to occur automatically. +Disabling trap generation may be useful, however, for routines that act +simply as "wrappers" for other routines for which code is presumably +generated with interrupt trap generation enabled. +It may also be useful for short performance-critical routines with +embedded loops or recursions that are known to be short running and +that make no other calls. + + +
+thread parameter: compile-interpret-simple
+
+libraries: (chezscheme)
+
+
At all optimize levels, when the value of +compile-interpret-simple is set to a true value (the default), +compile interprets simple +expressions. +A simple expression is one that creates no procedures. +This can save a significant amount of time over the course of many +calls to compile or eval (with current-eval +set to compile, its default value). +When set to false, compile compiles all expressions. + + +
+
+thread parameter: generate-inspector-information
+
+libraries: (chezscheme)
+
+
When this parameter is set to a true value (the default), information +about the source and contents of procedures and continuations is +generated during compilation and retained in tables associated with +each code segment. +This information allows the inspector to provide more complete +information, at the expense of using more memory and producing +larger object files (via compile-file). +Although compilation and loading may be slower when inspector +information is generated, the speed of the compiled code is not +affected. +If this parameter is changed during the compilation of a file, the +original value will be restored. +For example, if: + +
+ +
(eval-when (compile) (generate-inspector-information #f)) +
is included in a file, generation of inspector information will be +disabled only for the remainder of that particular file. + +
+
+thread parameter: generate-procedure-source-information
+
+libraries: (chezscheme)
+
+
When generate-inspector-information is set to #f and +this parameter is set to #t, then a source location is preserved +for a procedure, even though other inspector information is not preserved. +Source information provides a small amount of debugging support at a +much lower cost in memory and object-file size than full inspector information. +If this parameter is changed during the compilation of a file, the +original value will be restored. + +
+thread parameter: enable-cross-library-optimization
+
+libraries: (chezscheme)
+
+
This parameter controls whether information is included with the +object code for a compiled library to enable propagation of constants +and inlining of procedures defined in the library into dependent +libraries. +When set to #t (the default), this information is included; +when set to #f, the information is not included. +Setting the parameter to #f potentially reduces the sizes +of the resulting object files and the exposure of near-source +information via the object file. + +
+thread parameter: enable-arithmetic-left-associative
+
+libraries: (chezscheme)
+
+
This parameter controls whether the compiler is constrained to +implement +, fx+, fl+, cfl+, +*, fx*, fl*, and cfl* as +left-associative operations when given more than two arguments. +The default is #f. + +
+thread parameter: enable-error-source-expression
+
+libraries: (chezscheme)
+
+
This parameter controls whether the compiler can convert erroneous +expressions into a call to an error function that shows the expression +as an S-expression. The default is #t. + +
+thread parameter: enable-unsafe-application
+
+libraries: (chezscheme)
+
+
This parameter controls whether application forms are compiled as +unsafe (i.e., no check whether the target is a procedure), even when +the value of optimize-level is less than 3. The +default is #f. + +
+thread parameter: enable-unsafe-variable-reference
+
+libraries: (chezscheme)
+
+
This parameter controls whether references to letrec-bound +variables are compiled unsafe (i.e., no check whether the variable has +a value), even when the value of optimize-level is less than +3. The default is #f. + +
+thread parameter: generate-wpo-files
+
+libraries: (chezscheme)
+
+
When this parameter is set to #t (the default is #f), +compile-file, compile-library, compile-program, +and compile-script produce whole-program optimization (wpo) +files for use by compile-whole-program. +The name of the wpo file is derived from the output-file +name by replacing the object-file extension (normally .so) +with .wpo, or adding the extension .wpo if the +object filename has no extension or has the extension .wpo. + +
+thread parameter: compile-file-message
+
+libraries: (chezscheme)
+
+
When this parameter is set to true, the default, compile-file, +compile-library, compile-program, and +compile-script print a message of the form: + +
+ +
compiling input-path with output to output-path +
When the parameter is set to #f, the message is not printed. + +
+
+thread parameter: run-cp0
+
thread parameter: cp0-effort-limit
+
thread parameter: cp0-score-limit
+
thread parameter: cp0-outer-unroll-limit
+
+libraries: (chezscheme)
+
+
These parameters control the operation of cp0 plus cptypes, source +optimization passes that run after macro expansion and prior +to most other compiler passes. + +
+cp0 performs procedure inlining, in which the code of one +procedure is inlined at points where it is called by other procedures, +as well as copy propagation, constant folding, useless code +elimination, and several related optimizations. +The algorithm used by the optimizer is described in detail in the paper +"Fast and effective procedure inlining" [31]. + +
+cptypes performs additional optimizations based on type +information about primitives, such as the fact that + always +returns a number; since it primarily removes unnecessary run-time +checks, cptypes primarily benefits compilation in safe mode. +The cptypes pass can be independently disabled through the +enable-type-recovery parameter. + +
+When cp0 is enabled, the programmer can count on the compiler +to fold constants, eliminate unnecessary let bindings, and +eliminate unnecessary and inaccessible code. +This is particularly useful when writing macros, since the programmer +can usually handle only the general case and let the compiler simplify +the code when possible. +For example, the programmer can define case as follows: + +
+ +
(define-syntax case
+
+ (syntax-rules ()
+
+ [(_ e [(k ...) a1 a2 ...] ... [else b1 b2 ...])
+
+ (let ([t e])
+
+ (cond
+
+ [(memv t '(k ...)) a1 a2 ...]
+
+ ...
+
+ [else b1 b2 ...]))]
+
+ [(_ e [(k ...) a1 a2 ...] ...)
+
+ (let ([t e])
+
+ (cond
+
+ [(memv t '(k ...)) a1 a2 ...]
+
+ ...))]))
+
and count on the introduce let expression to be eliminated +if e turns out to be an unassigned variable, and count on +the entire case expression to be folded if e turns +out to be a constant. + +
+It is possible to see what cp0 plus cptypes does with an expression +via the procedure expand/optimize, +which expands its argument and passes the result through cp0 and cptypes, as +illustrated by the following transcript. + +
+ +
> (print-gensym #f)
+
+> (expand/optimize
+
+ '(lambda (x)
+
+ (case x [(a) 1] [(b c) 2] [(d) 3] [else 4])))
+
+(lambda (x)
+
+ (if (#2%member x '(a))
+
+ 1
+
+ (if (#2%member x '(b c)) 2 (if (#2%member x '(d)) 3 4))))
+
+> (expand/optimize
+
+ '(+ (let ([f (lambda (x)
+
+ (case x [(a) 1] [(b c) 2] [(d) 3] [else 4]))])
+
+ (f 'b))
+
+ 15))
+
+17
+
In the first example, the let expression produced by case +is eliminated, and in the second, the entire expression is optimized down +to the constant 17. +Although not shown by expand/optimize, the member calls +in the output code for the first example will be replaced by calls to the +less expensive eq? by a later pass of the compiler. +Additional examples are given in the description +of expand/optimize. + +
+The value of run-cp0 must be a procedure. +Whenever the compiler is invoked on a Scheme form, the value p +of this parameter is called to determine whether and how +cp0 and cptypes are run. +p receives two arguments: cp0, the entry point into the +cp0 plus cptypes passes, and x, the form being compiled. +The default value of run-cp0 simply invokes cp0 on +x, then cp0 again on the result. +The second run is useful in some cases because the first run +may not eliminate bindings for certain variables that appear to be +referenced but are not actually referenced after inlining. +The marginal benefit of the second run is usually minimal, but so is the +cost. + +
+Interesting variants include + +
+ +
(run-cp0 (lambda (cp0 x) x)) +
which bypasses (disables) cp0, and + +
+ +
(run-cp0 (lambda (cp0 x) (cp0 x))) +
which runs cp0 just once. + +
+The value of cp0-effort-limit determines the maximum amount +of effort spent on each inlining attempt. +The time spent optimizing a program is a linear function of this limit and the +number of calls in the program's source, so small values for this parameter +enforce a tighter bound on compile time. +When set to zero, inlining is disabled except when the name of a procedure +is referenced only once. +The value of cp0-score-limit determines the maximum amount of +code produced per inlining attempt. +Small values for this parameter limit the amount of overall code expansion. +These parameters must be set to nonnegative fixnum values. + +
+The parameter cp0-outer-unroll-limit +controls the amount of inlining performed by the optimizer for +recursive procedures. +With the parameter's value set to the default value of 0, recursive +procedures are not inlined. +A nonzero value for the outer unroll limit allows calls external to +a recursive procedure to be inlined. +For example, the expression + +
+ +
(letrec ([fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1)))))])
+
+ (fact 10))
+
would be left unchanged with the outer unroll limit set to zero, but would +be converted into + +
+ +
(letrec ([fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1)))))])
+
+ (* 10 (fact 9)))
+
with the outer unroll limit set to one. + +
+Interesting effects can be had by varying several of these parameters at +once. +For example, setting the +effort and outer unroll limits to large values and the score limit +to 1 has the effect of inlining even complex recursive procedures +whose values turn out to be constant at compile time without risking +any code expansion. +For example, + +
+ +
(letrec ([fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1)))))])
+
+ (fact 10))
+
would be reduced to 3628800, but + +
+ +
(letrec ([fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1)))))])
+
+ (fact z))
+
would be left unchanged, although the optimizer may take a while to +reach this decision if the effort and outer unroll limits are large. + +
+thread parameter: enable-type-recovery
+
+libraries: (chezscheme)
+
+
A parameter that controls whether the compiler attempts to optimize +programs by performing a pass similar to type inference, which can +avoid more checks and statically resolve more predicates than +cp0 by itself, but at the cost of extra compile time. The +default is #t. + +
+thread parameter: commonization-level
+
+libraries: (chezscheme)
+
+
After running the main source optimization pass (cp0) for the last time, the +compiler optionally runs a commonization pass. +The pass commonizes the code for lambda expressions that have +identical structure by abstracting differences at certain leaves +of the program, namely constants, references to unassigned variables, +and references to primitives. +The parameter commonization-level controls whether commonization +is run and, if so, how aggressive it is. +Its value must be a nonnegative exact integer ranging from 0 through 9. +When the parameter is set to 0, the default, commonization is not run. +Otherwise, higher values result in more commonization. + +
+Commonization can undo some of the effects of cp0's inlining, can +add run-time overhead, and can complicate debugging, particularly +at higher commonization levels, which is why it is disabled by +default. +On the other hand, for macros or other meta programs that can +generate large, mostly similar lambda expressions, enabling +commonization can result in significant savings in object-code size +and even reduce run-time overhead by making more efficient use of +instruction caches. + +
+thread parameter: undefined-variable-warnings
+
+libraries: (chezscheme)
+
+
When undefined-variable-warnings is set to #t, the +compiler issues a warning message whenever it cannot determine that +a variable bound by letrec, letrec*, or an internal +definition will not be referenced before it is defined. +The default value is #f. + +
+Regardless of the setting of this parameter, the compiler inserts code +to check for the error, except at optimize level 3. +The check is fairly inexpensive and does not typically inhibit inlining +or other optimizations. +In code that must be carefully tuned, however, it is sometimes useful +to reorder bindings or make other changes to eliminate the checks. +Enabling undefined-variable warnings can facilitate this process. + +
+The checks are also visible in the output of expand/optimize. + +
+
+thread parameter: expand-output
+
thread parameter: expand/optimize-output
+
+libraries: (chezscheme)
+
+
The parameters expand-output and expand/optimize-output +can be used to request that the compiler and interpreter print +expander and source-optimizer output produced during the compilation or +interpretation process. +Each parameter must be set to either #f (the default) or a +textual output port. + +
+When expand-output is set to a textual output port, the output +of the expander is printed to the port as a side effect of running +compile, interpret, or any of the file compiling +primitives, e.g., compile-file or compile-library. +Similarly, when expand/optimize-output is set to a textual +output port, the output of the source optimizer is printed. + +
+See also expand (page 379) and +expand-optimize (page 380), which +can be used to run the expander or the expander and source optimizer +directly on an individual form. + +
+syntax: (pariah expr1 expr2 ...)
+
+returns: the values of the last subexpression
+
+libraries: (chezscheme)
+
+
A pariah expression is just like a begin expression +except that it informs the compiler that the code is expected to +be executed infrequently. +The compiler uses this information to optimize code layout, register +assignments, and other aspects of the generated code. +The pariah form can be used in performance-critical code +to mark the branches of a conditional (e.g., if, cond, +or case) that are less likely to be executed than the +others. + + +
+ +
+ChezScheme supports two forms of profiling: source profiling and +block profiling. +With source profiling enabled, the compiler instruments the code +it produces to count the number of times each source-code expression +is executed. +This information can be +displayed in HTML format, or it can be packaged in a list or +source table for arbitrary user-defined processing. +It can also be dumped to a file to be loaded subsequently into the +compiler's database of profile information for use in source-level +optimizations, such as reordering the clauses of a case +or exclusive-cond form. +In connection with coverage-information (covin) files generated by the +compiler when +generate-covin-files +is #t, profile information can also be used to gauge coverage +of a source-code base by a set of tests. + +
+The association between source-code expressions and profile counts +is usually established via annotations produced by the reader and +present in the input to the expander (Section 11.11). +It is also possible to explicitly identify source positions +to be assigned profile counts via profile expressions. +A profile expression has one subform, a source object, and +returns an unspecified value. +Its only effect is to cause the number of times the expression is +executed to be accounted to the source object. + +
+In cases where source positions explicitly identified by profile +forms are the only ones whose execution counts should be tracked, +the parameter generate-profile-forms can be set to #f +to inhibit the expander's implicit generation of profile forms +for all annotated source expressions. +It is also possible to obtain finer control over implicit generation of +profile forms by marking which annotations should and +should not be used for profiling (Section 11.11). + +
+With block profiling enabled, the compiler similarly instruments the +code it produces to count the number of times each "basic block" +in the code it produces is executed. +Basic blocks are the building blocks of the code produced by many +compilers, including Chez Scheme's compiler, and are sequences +of straight-line code entered only at the top and exited only at +the bottom. +Counting the number of times each basic block is executed is +equivalent to counting the number of times each instruction is +executed, but more efficient. +Block-profile information cannot be viewed, but it can be dumped +to a file to be loaded subsequently into the compiler's database of +profile information for use in block- and instruction-level +optimizations. +These optimizations include reordering blocks to push less frequently +used sequences of code out-of-line, so they will not occupy space +in the instruction cache, and giving registers to variables that are +used in more frequently executed instructions. + +
+Source profiling involves at least the following steps: + +
+
+ +
+Source profiling is enabled by setting the parameter +compile-profile to the symbol source +or to the boolean value #t. +The profile information can be dumped via: + +
+
+If the information is intended to be fed back into the compiler for +optimization, the following additional steps are required, either +in the same or a different Scheme process: + +
+
+ +
+Profile information dumped by profile-dump-data is loaded +into the compiler's profile database via profile-load-data. +Profiling information is not available to the compiler unless +it is explicitly dumped via profile-dump-data and loaded +via profile-load-data. + +
+When block-profile information is to be used for optimization, +the steps are similar: + +
+
+ +
+Block profiling is enabled by setting the parameter +compile-profile to the symbol block +or to the boolean value #t. +The profile information must be dumped via profile-dump-data +and loaded via profile-load-data. +As with source profile information, block profile information can be +loaded in the same or in a different Scheme process as the one that +dumped the information. + +
+For block optimization, the code to be recompiled must be identical. +In general, this means the files involved must not have been modified, +and nothing else can change that indirectly affects the code produced +by the compiler, e.g., settings for compiler parameters such as +optimize-level or the contents of configuration files read +by macros at compile time. +Otherwise, the set of blocks or the instructions within them might +be different, in which case the block profile information will not +line up properly and the compiler will raise an exception. + +
+For the same reason, when both source profiling and block profiling +information is to be used for optimization, the source information +must be gathered first and loaded before both the first and second +compilation runs involved in block profiling. +That is, the following steps must be used: + +
+
+ +
+The numbers labeling each step indicate both the order of the steps +and those that must be performed in the same Scheme process. +(All of the steps can be performed in the same Scheme process, if +desired.) + +
+Both source and block profiling are disabled when compile-profile +is set to #f, its default value. + +
+The following example highlights the use of source profiling for +identifying hot spots in the code. +Let's assume that the file /tmp/fatfib/fatfib.ss contains the +following source code. + +
+ +
(define fat+
+
+ (lambda (x y)
+
+ (if (zero? y)
+
+ x
+
+ (fat+ (1+ x) (1- y)))))
+
+
+(define fatfib
+
+ (lambda (x)
+
+ (if (< x 2)
+
+ 1
+
+ (fat+ (fatfib (1- x)) (fatfib (1- (1- x)))))))
+
We can load fatfib.ss with profiling enabled as follows. + +
+ +
(parameterize ([compile-profile 'source])
+
+ (load "/tmp/fatfib/fatfib.ss"))
+
We then run the application as usual. + +
+ +
(fatfib 20) 10946 +
After the run (or multiple runs), we +dump the profile information as a set of html files using +profile-dump-html. + +
+ +
(profile-dump-html) +
This creates a file named profile.html containing a summary of the profile +information gathered during the run. +If we view this file in a browser, we should see something like the +following. + +
+ + + + +
+The most frequently executed code is highlighted in colors closer to +red in the visible spectrum, while +the least frequently executed code is highlighted in colors closer to +violet. +Each of the entries in the lists of files and hot spots are links into +additional generated files, one per source file (provided +profile-dump-html was able to locate an unmodified copy of +the source file). +In this case, there is only one, fatfib.ss.html. +If we move to that file, we should see something like this: + +
+ + + + +
+As in the summary, the code is color-coded according to frequency +of execution. +Hovering over a color-coded section of code should cause a pop-up +box to appear with the starting position and count of the source +expression. +If a portion of source code is not color-coded or is identified +via the starting position as having inherited its color from some +enclosing expression, it may have been recognized as dead code by +the compiler or garbage collector and discarded, or the expander +might not have been able to track it through the macro-expansion +process. + +
+profile-dump and profile-dump-list may be used to +generate a list of profile entries, which may then be analyzed manually +or via a custom profile-viewing application. + +
+thread parameter: compile-profile
+
+libraries: (chezscheme)
+
+
When this parameter is set to the symbol source or the +boolean value #t, the compiler instruments the code it +generates with instructions that count the number of times each +section of source code is executed. +When set to the symbol block, the compiler similarly +instruments the code it generates with instructions that count the +number of times each block of code is executed. +When set to #f (the default), the compiler does not insert +these instructions. + +
+The general description of profiling above describes how the source +and block profile information can be viewed or used for optimization. + +
+The code generated when compile-profile is non-false is +larger and less efficient, so this parameter should be set only +when profile information is needed. + +
+The profile counters for code compiled when profile instrumentation +is enabled are retained indefinitely, even if the code with which +they are associated is reclaimed by the garbage collector. +This results in more complete and accurate profile data but can lead +to space leaks in programs that dynamically generate or load code. +Such programs can avoid the potential space leak by releasing the +counters explicitly via the procedure +profile-release-counters. + + +
+thread parameter: generate-covin-files
+
+libraries: (chezscheme)
+
+
When this parameter is set to #t, the compiler generates +"coverage-information" (covin) files that can be used in connection with +profile information to measure coverage of a source-code base by a +set of tests. +One covin file is created for each object file, with the object-file +extension replaced by the extension .covin. +Each covin file contains the printed representation of a source table +(Section 11.12), compressed using the compression +format and level specified by compress-format and +compress-level. +This information can be read via +get-source-table! and used +as a universe of source expressions to identify source expressions +that are not evaluated during the running of a set of tests. + + +
+syntax: (profile source-object)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
A profile form has the effect of accounting to the source +position identified by source-object the number of times the +profile form is executed. +Profile forms are generated implicitly by the expander for source +expressions in annotated input, e.g., input read by the compiler or +interpreter from a Scheme source file, so this form is typically +useful only when unannotated source code is produced by the front +end for some language that targets Scheme. + +
+thread parameter: (generate-profile-forms)
+
+libraries: (chezscheme)
+
+
When this parameter is set to #t, the default, the expander +implicitly introduces profile forms for each annotated input +expression, unless the annotation has not been marked for use in +profiling (Section 11.11). +It can be set to #f to inhibit the expander's implicit +generation of profile forms, typically when explicit +profile forms are already present for all source positions +that should be profiled. + +
+procedure: (profile-clear)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Calling this procedure causes profile information to be cleared, i.e., +the counts associated with each section of code are set to zero. + +
+procedure: (profile-release-counters)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Calling this procedure causes profile information associated with reclaimed +code objects to be dropped. + +
+procedure: (profile-dump)
+
+returns: a list of pairs of source-object and count
+
+libraries: (chezscheme)
+
+
This procedure produces a dump of all +profile information gathered since startup or the last call to +profile-clear. +It returns a list of pairs, where the car of each pair +is a source object (Section 11.11) and the +cdr is an exact nonnegative integer count. + +
+The list might contain more than one entry per source object due +to macro expansion and procedure inlining, and it might contain +more than one (non-eq) source object per file and source position +due to separate compilation. +In such cases, the counts are not overlapping and can be summed +together to obtain the full count. + +
+The advantage of profile-dump over profile-dump-list +is that profile-dump performs only minimal processing and +preserves complete source objects, including their embedded source-file +descriptors. +It might be used, for example, to dump profile information to a +fasl file on one machine for subsequent processing on another. + +
+with-profile-tracker +can be used to obtain the same set of counts as a source table. + + +
+procedure: (with-profile-tracker thunk)
+
procedure: (with-profile-tracker preserve-existing? thunk)
+
+returns: a source table and the values returned by thunk
+
+libraries: (chezscheme)
+
+
thunk must be a procedure and should accept zero arguments. +It may return any number of values. + +
+with-profile-tracker invokes thunk without arguments. +If thunk returns n values x1, x2, ..., xn, with-profile-tracker +returns n + 1 values st, x1, x2, ..., xn, where st is a +source table associating source objects with profile counts. +If preserve-existing? is absent or #f, each count +represents the number of times the source expression represented +by the associated source object is evaluated during the invocation +of thunk. +Otherwise, each count represents the number of times the source +expression represented by the associated source object is evaluated +before or during the invocation of thunk. + +
+Profile data otherwise cleared by a call to +profile-clear or +profile-release-counters +during the invocation of thunk is included in the +resulting table. +That is, invoking these procedures while thunk is running has +no effect on the resulting counts. +On the other hand, profile data cleared before with-profile-tracker +is invoked is not included in the resulting table. + +
+The idiom (with-profile-tracker #t values) can be used to obtain +the current set of profile counts as a source table. + + +
+procedure: (source-table-dump source-table)
+
+returns: a list of pairs of source objects and their associated values in source-table
+
+libraries: (chezscheme)
+
+
This procedure can be used to convert a source-table produced by +with-profile-tracker or some other mechanism into the form returned +by profile-dump for use as an argument to +profile-dump-html, +profile-dump-list, +or +profile-dump-data. + +
+procedure: (profile-dump-html)
+
procedure: (profile-dump-html prefix)
+
procedure: (profile-dump-html prefix dump)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure produces one or more HTML files, including +profile.html, which contains color-coded summary information, +and one file source.html for each source +file source containing a color-coded copy of the +source code, as described in the lead-in to this section. +If prefix is specified, it must be a string and is prepended +to the names of the generated HTML files. +For example, if prefix is "/tmp/", the generated +files are placed in the directory /tmp. +The raw profile information is obtained from dump, which +defaults to the value returned by profile-dump. + +
+thread parameter: (profile-palette)
+
+libraries: (chezscheme)
+
+
This value of this parameter must be a nonempty vector of at least +three pairs. +The car of each pair is a background color and the cdr is a foreground +(text) color. +Each color must be a string, and each string should contain an HTML +cascading style sheet (CSS) color specifier. +The first pair is used for unprofiled code, and the second is used +for unexecuted profiled code. +The third is used for code that is executed least frequently, the fourth +for code executed next-least frequently, and so on, with the last +being used for code that is executed most frequently. +Programmers may wish to supply their own palette to enhance visibility +or to change the number of colors used. + +
+By default, a black background is used for unprofiled code, and a gray +background is used for unexecuted profiled code. +Background colors ranging from purple to red are used for executed +profiled code, depending on frequency of execution, with red for the most +frequently executed code. + +
+ +
(profile-palette)
+
+ #(("#111111" . "white") ("#607D8B" . "white")
+
+ ("#9C27B0" . "black") ("#673AB7" . "white")
+
+ ("#3F51B5" . "white") ("#2196F3" . "black")
+
+ ("#00BCD4" . "black") ("#4CAF50" . "black")
+
+ ("#CDDC39" . "black") ("#FFEB3B" . "black")
+
+ ("#FFC107" . "black") ("#FF9800" . "black")
+
+ ("#F44336" . "white"))
+
+(profile-palette
+
+ ; set palette with rainbow colors and black text
+
+ ; for all but unprofiled or unexecuted code
+
+ '#(("#000000" . "white") ; black
+
+ ("#666666" . "white") ; gray
+
+ ("#8B00FF" . "black") ; violet
+
+ ("#6600FF" . "black") ; indigo
+
+ ("#0000FF" . "black") ; blue
+
+ ("#00FF00" . "black") ; green
+
+ ("#FFFF00" . "black") ; yellow
+
+ ("#FF7F00" . "black") ; orange
+
+ ("#FF0000" . "black"))) ; red
+
thread parameter: (profile-line-number-color)
+
+libraries: (chezscheme)
+
+
This value of this parameter must be a string or #f. +If it is a string, the string should contain an HTML cascading style sheet (CSS) +color specifier. +If the parameter is set to a string, profile-dump-html includes line numbers +in its html rendering of each source file, using the specified color. +If the parameter is set to #f, no line numbers are included. + +
+procedure: (profile-dump-list)
+
procedure: (profile-dump-list warn?)
+
procedure: (profile-dump-list warn? dump)
+
+returns: a list of profile entries (see below)
+
+libraries: (chezscheme)
+
+
This procedure produces a dump of all +profile information present in dump, which defaults to +the value returned by profile-dump. +It returns a list of entries, each of which is itself a list containing the +following elements identifying one block of code and how many times it +has been executed. + +
+
+ +
+profile-dump-list may be unable to locate an unmodified copy +of the file in the current source directories +or at the absolute address, if an absolute address was used when +the file was compiled or loaded. +If this happens, the line number and character position of the beginning +file position are #f and the pathname is the pathname originally +used. +A warning is also issued (an exception with condition type +&warning is raised) unless the warn? argument is provided +and is false. + +
+Otherwise, the pathname is the path to an unmodified copy of the source +and the line and character positions are set to exact nonnegative integers. + +
+In either case, the execution count, beginning file position, and ending +file position are all exact nonnegative integers, and the pathname is a string. + +
+For source positions in files that cannot be found, the list might +contain more than one entry per position due to macro expansion, +procedure inlining, and separate compilation. +In such cases, the counts are not overlapping and can be summed +together to obtain the full count. + +
+The information returned by profile-dump-list can be used to +implement a custom viewer or used as input for offline analysis of +profile information. + +
+The advantage of profile-dump-list over profile-dump +is that it attempts to determine the line number and character +position for each source point and, if successful, aggregates +multiple counts for the source point into a single entry. + +
+procedure: (profile-dump-data path)
+
procedure: (profile-dump-data path dump)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. + +
+This procedure writes, in a machine-readable form consumable by +profile-load-data, profile counts represented by dump +to the file named by path, replacing the file if it already exists. +dump defaults to the value returned by profile-dump. + +
+procedure: (profile-load-data path ...)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Each path must be a string. + +
+This procedure reads profile information from the files named by +path ... and stores it in the compiler's internal +database of profile information. +The contents of the files must have been created originally by +profile-dump-data using the same version of Chez Scheme. + +
+The database stores a weight for each source expression or block +rather than the actual count. +When a single file is loaded into the database, the weight is the +proportion of the actual count over the maximum count for all +expressions or blocks represented in the file. +When more than one file is loaded, either by one or multiple calls +to profile-load-data, the weights are averaged. + +
+procedure: (profile-query-weight obj)
+
+returns: obj's profile weight, or #f if obj is not in the database
+
+libraries: (chezscheme)
+
+
The compiler's profile database maps source objects +(Section 11.11) to weights. +If obj is a source object, the profile-query-weight returns +the weight associated with the source object or #f if the database +does not have a weight recorded for the source object. +obj can also be an annotation or syntax object, in which case +profile-query-weight first extracts the source object, if any, +using syntax->annotation and annotation-source, +returning #f if no source-object is found. + +
+A weight is a flonum in the range 0.0 to 1.0, inclusive, and denotes the +ratio of the actual count to the maximum count as described in the +description of profile-load-data. + +
+profile-query-weight can be used by a macro to determine +the relative frequency with which its subexpressions were executed +in the run or runs that generated the information in the database. +This information can be used to guide the generation of code that +is likely to be more efficient. +For example, the case macro uses profile information, when +available, to order the clauses so that those whose keys matched +more frequently are tested before those whose keys matched less +frequently. + +
+procedure: (profile-clear-database)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure clears the compiler's profile database. +It has no impact on the counts associated with individual sections +of instrumented code; profile-clear can be used to reset +those counts. + +
+ +
+procedure: (new-cafe)
+
procedure: (new-cafe eval-proc)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
Chez Scheme interacts with the user +through a waiter, or read-eval-print loop (REPL). +The waiter operates within a context called a café. +When the system starts up, the user is placed in a café and +given a waiter. +new-cafe opens a new Scheme café, stacked on top of the old one. +In addition to starting the waiter, new-cafe sets up the café's +reset and exit handlers (see reset-handler and exit-handler). +Exiting a café resumes the continuation of the call +to new-cafe that created the café. +Exiting from the initial café leaves Scheme altogether. +A café may be exited from either by an explicit call to exit or +by receipt of end-of-file ("control-D" on Unix systems) in response +to the waiter's prompt. +In the former case, any values passed to exit are returned from +new-cafe. + +
+If the optional eval-proc argument is specified, eval-proc +is used to evaluate forms entered from the console. +Otherwise, the value of the parameter current-eval is used. +eval-proc must accept one argument, the expression to evaluate. + +
+Interesting values for eval-proc include expand, +which causes the macro expanded value of each expression entered to +be printed and (lambda (x) x), which simply causes each expression +entered to be printed. +An arbitrary procedure of one argument may be used to facilitate +testing of a program on a series of input values. + +
+ +
> (new-cafe (lambda (x) x))
+
+>> 3
+
+3
+
+>> (a . (b . (c . ())))
+
+(a b c)
+
+
(define sum
+
+ (lambda (ls)
+
+ (if (null? ls)
+
+ 0
+
+ (+ (car ls) (sum (cdr ls))))))
+
+> (new-cafe sum)
+
+>> (1 2 3)
+
+6
+
The default waiter reader (see waiter-prompt-and-read) displays +the current waiter prompt (see waiter-prompt-string) +to the current value of console-output-port and +reads +from the current value of console-input-port. +The default waiter printer (see waiter-write) sends output +to the current value of console-output-port. +These parameters, along with current-eval, +can be modified to change the behavior of the waiter. + +
+thread parameter: waiter-prompt-string
+
+libraries: (chezscheme)
+
+
The value of waiter-prompt-string must be a string. +It is used by the default waiter prompter (see the parameter +waiter-prompt-and-read) to print a prompt. +Nested cafés +are marked by repeating the prompt string once for each nesting level. + +
+ +
> (waiter-prompt-string)
+
+">"
+
+> (waiter-prompt-string "%")
+
+% (waiter-prompt-string)
+
+"%"
+
+% (new-cafe)
+
+%% (waiter-prompt-string)
+
+"%"
+
thread parameter: waiter-prompt-and-read
+
+libraries: (chezscheme)
+
+
waiter-prompt-and-read must be set to a procedure. +It is used by the waiter to +print a prompt and read an expression. +The value of waiter-prompt-and-read is called by the waiter with a +positive integer that indicates the café nesting level. +It should return an expression to be evaluated by the current +evaluator (see new-cafe and current-eval). + +
+procedure: (default-prompt-and-read level)
+
+libraries: (chezscheme)
+
+
level must be a positive integer indicating the cafeé nesting +level as described above. + +
+This procedure is the default value of the waiter-prompt-and-read +parameter whenever the expression editor +(Section 2.2, Chapter 14) is +not enabled. +It might be defined as follows. + +
+ +
(define default-prompt-and-read
+
+ (lambda (n)
+
+ (unless (and (integer? n) (>= n 0))
+
+ (assertion-violationf 'default-prompt-and-read
+
+ "~s is not a nonnegative integer"
+
+ n))
+
+ (let ([prompt (waiter-prompt-string)])
+
+ (unless (string=? prompt "")
+
+ (do ([n n (- n 1)])
+
+ ((= n 0)
+
+ (write-char #\space (console-output-port))
+
+ (flush-output-port (console-output-port)))
+
+ (display prompt (console-output-port))))
+
+ (let ([x (read (console-input-port))])
+
+ (when (and (eof-object? x) (not (string=? prompt "")))
+
+ (newline (console-output-port))
+
+ (flush-output-port (console-output-port)))
+
+ x))))
+
thread parameter: waiter-write
+
+libraries: (chezscheme)
+
+
The value of waiter-write must be a procedure. +The waiter uses the value of waiter-write to print the results +of each expression read and evaluated by the waiter. +The following example installs a procedure equivalent to the default +waiter-write: + +
+ +
(waiter-write
+
+ (lambda (x)
+
+ (unless (eq? x (void))
+
+ (pretty-print x (console-output-port)))
+
+ (flush-output-port (console-output-port))))
+
procedure: (reset)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
reset invokes the current reset handler (see reset-handler) +without arguments. + + +
+thread parameter: reset-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure and should accept zero +arguments. +The current reset handler is called by reset. +The default reset handler resets to the current café. + + +
+procedure: (exit obj ...)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
exit invokes the current exit handler (see +exit-handler), passing along its arguments, if any. + + +
+thread parameter: exit-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure and should accept any +number of arguments. +The current exit handler is called by exit. + +
+The default exit handler exits from the current café, +returning its arguments as the values of the call to +new-cafe that created the current café. +If the current café is the original café, or if exit +is called from a script, exit exits from Scheme. +In this case, the exit code for the Scheme process is 0 if +no arguments were supplied or if the first argument is void, +the value of the first argument cast to a C int if +it is an exact integer of the host machine's bit width, and 1 otherwise. + +
+procedure: (abort)
+
procedure: (abort obj)
+
+returns: does not return
+
+libraries: (chezscheme)
+
+
abort invokes the current abort handler (see abort-handler), +passing along its argument, if any. + + +
+thread parameter: abort-handler
+
+libraries: (chezscheme)
+
+
The value of this parameter must be a procedure and should accept either +zero arguments or one argument. +The current abort handler is called by abort. + +
+The default abort handler exits the Scheme process. +The exit code for the Scheme process is -1 if no arguments were supplied, +0 if the first argument is void, the value of the first argument if it is +a 32-bit exact integer, and -1 otherwise. + + +
+global parameter: scheme-start
+
+libraries: (chezscheme)
+
+
The value of scheme-start is a procedure that determines the +system's action upon start-up. +The procedure receives zero or more arguments, which are strings +representing the file names (or command-line arguments not recognized +by the Scheme executable) after given on the command line. +The default value first loads the files named by the arguments, then +starts up the initial café: + +
+ +
(lambda fns
+
+ (for-each load fns)
+
+ (new-cafe))
+
scheme-start may be altered to start up an application or to +perform customization prior to normal system start-up. + +
+To have any effect, this parameter must be set within a boot file. +(See Chapter 2.) + +
+global parameter: scheme-script
+
+libraries: (chezscheme)
+
+
The value of scheme-script is a procedure that determines the +system's action upon start-up, +when the --script option is used. +The procedure receives one or more arguments. +The first is a string identifying the script filename and the remainder +are strings representing the remaining file names (or command-line +arguments not recognized by the Scheme executable) given on the command +line. +The default value of this parameter is a procedure that sets the +command-line and command-line-arguments parameters, +loads the script using load, and returns void, which is +translated into a 0 exit status for the script process. + +
+ +
(lambda (fn . fns)
+
+ (command-line (cons fn fns))
+
+ (command-line-arguments fns)
+
+ (load fn))
+
scheme-script may be altered to start up an application or to +perform customization prior to normal system start-up. + +
+To have any effect, this parameter must be set within a boot file. +(See Chapter 2.) + + +
+global parameter: scheme-program
+
+libraries: (chezscheme)
+
+
The value of scheme-program is a procedure that determines the +system's action upon start-up +when the --program (RNRS top-level program) option is used. +The procedure receives one or more arguments. +The first is a string identifying the program filename and the remainder +are strings representing the remaining file names (or command-line +arguments not recognized by the Scheme executable) given on the command +line. +The default value of this parameter is a procedure that sets the +command-line and command-line-arguments parameters, +loads the program using load-program, and returns void, which is +translated into a 0 exit status for the script process. + +
+ +
(lambda (fn . fns)
+
+ (command-line (cons fn fns))
+
+ (command-line-arguments fns)
+
+ (load-program fn))
+
scheme-program may be altered to start up an application or to +perform customization prior to normal system start-up. + +
+To have any effect, this parameter must be set within a boot file. +(See Chapter 2.) + + +
+global parameter: command-line
+
+libraries: (chezscheme)
+
+
This parameter is set by the default values of scheme-script +and scheme-program +to a list representing the command line, with the script name followed +by the command-line arguments, when the --script or +--program option is used on system startup. + +
+global parameter: command-line-arguments
+
+libraries: (chezscheme)
+
+
This parameter is set by the default values of scheme-script +and scheme-program +to a list of the command-line arguments when the --script +or --program option is used on system startup. + +
+global parameter: suppress-greeting
+
+libraries: (chezscheme)
+
+
The value of suppress-greeting is a boolean value that determines +whether Chez Scheme prints an identifying banner and copyright notice. +The parameter defaults to #f but may be set to #t for +use in batch processing applications where the banner would be disruptive. + +
+To have any effect, this parameter must be set within a boot file. +(See Chapter 2.) + + +
+ +
+A transcript file is a record of an interactive session. +It is also useful as a "quick-and-dirty" alternative to opening an +output file and using explicit output operations. + + +
+
+procedure: (transcript-on path)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
path must be a string. + +
+transcript-on opens the file named by path for output, +and it copies to this file all input from the current input port and +all output to the current output port. +An exception is raised with condition-type i/o-filename if the +file cannot be opened for output. + + +
+procedure: (transcript-off)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
transcript-off ends transcription and closes the transcript file. + + +
+procedure: (transcript-cafe path)
+
+libraries: (chezscheme)
+
+
path must be a string. +transcript-cafe opens a transcript file as with +transcript-on and +enters a new café; exiting +from this café (see exit) also ends transcription and closes the +transcript file. +Invoking transcript-off while in a transcript café ends transcription +and closes the transcript file but does not cause an exit from the +café. + + +
+ +
+This section documents procedures for handling times and dates. Most of +the procedures described here are proposed in +SRFI 19: +Time Data Types and Procedures, by Will Fitzgerald. + +
+Times are represented by time objects. +Time objects record the nanosecond and second of a particular time +or duration, along with a time type that identifies the nature +of the time object. +The time type is one of the following symbols: + +
+
+
+
+
+
+
+
+A time-object second is an exact integer (possibly negative), +and a nanosecond is an exact nonnegative integer less than 109. +The second and nanosecond of a time object may be converted to +an aggregate nanosecond value by scaling the +seconds by 109 and adding the nanoseconds. +Thus, if the second and nanosecond of a time object are 5 and 10, +the time object represents 5000000010 nanoseconds (5.000000010 seconds). +If the second and nanosecond are -5 and 10, the time object +represents -4999999990 nanoseconds (-4.999999990 seconds). + +
+Dates are represented by date objects. +A date object records the nanosecond, second, minute, hour, day, month, +and year of a particular date, along with an offset that identifies the +time zone. + +
+As for time objects, a nanosecond is an exact integer less than 109. +A date-object second is, however, an exact nonnegative integer +less than 62. +(The values 61 and 62 allow for leap seconds.) +A minute is an exact nonnegative integer less than 60, and +an hour is an exact nonnegative integer less than 24. +A day is an exact nonnegative integer in ranging from 1 representing +the first day of the month to n, where n is the number of +days in the date's month and year. +A month is an exact nonnegative integer ranging from 1 through 12, +where 1 represents January, 2 represents February, and so on. +A year must be an exact integer. +Years less than 1970 or greater than 2038 may not be supported +depending on limitations of the underlying implementation. +A time-zone offset represents the time-zone offset, in seconds, from UTC. +It is an exact integer in the range -86400 to +86400, inclusive. +For example, Eastern Standard Time (EST), which is 5 hours east, has +offset 5 × 3600 = -18000. +The offset for Eastern Daylight Time (EDT) is -14400. +UTC is represented by offset zero. + +
+procedure: (current-time)
+
procedure: (current-time time-type)
+
+returns: a time object representing the current time
+
+libraries: (chezscheme)
+
+
time-type must be one of the time-type symbols listed above +and defaults to time-utc. + +
+ +
(current-time) #<time-utc 1198815722.473668000>
+
+(current-time 'time-process) #<time-process 0.120534264>
+
procedure: (make-time type nsec sec)
+
+returns: a time object
+
+libraries: (chezscheme)
+
+
type must be one of the time-type symbols listed above. +nsec represents nanoseconds and must be an exact nonnegative +integer less than 109. +sec represents seconds and must be an exact integer. + +
+ +
(make-time 'time-utc 787511000 1198783214)
+
+(make-time 'time-duration 10 5)
+
+(make-time 'time-duration 10 -5)
+
procedure: (time? obj)
+
+returns: #t if obj is a time object, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(time? (current-time)) #t
+
+(time? (make-time 'time-utc 0 0)) #t
+
+(time? "1400 hours") #f
+
procedure: (time-type time)
+
+returns: the time type of time
+
procedure: (time-nanosecond time)
+
+returns: the nanosecond of time
+
procedure: (time-second time)
+
+returns: the second of time
+
+libraries: (chezscheme)
+
+
time must be a time object. + +
+ +
(time-type (current-time)) time-utc
+
+(time-type (current-time 'time-process)) time-process
+
+(time-type (make-time 'time-duration 0 50)) time-duration
+
+(time-second (current-time)) 1198816497
+
+(time-nanosecond (current-time)) 2399000
+
+(time-second (make-time 'time-duration 10 -5)) -5
+
+(time-nanosecond (make-time 'time-duration 10 -5)) 10
+
procedure: (set-time-type! time type)
+
+returns: unspecified
+
procedure: (set-time-nanosecond! time nsec)
+
+returns: unspecified
+
procedure: (set-time-second! time sec)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
time must be a time object. +type must be one of the time-type symbols listed above. +nsec represents nanoseconds and must be an exact nonnegative +integer less than 109. +sec represents seconds and must be an exact integer. + +
+Each of these procedures modifies the time object, changing one aspect +while leaving the others unaffected. +For example, set-time-nanosecond! changes the nanosecond of +time without changing the second or type. +In particular, no conversion of values is performed when the type of a time +object is changed. + +
+procedure: (time=? time1 time2)
+
procedure: (time<? time1 time2)
+
procedure: (time<=? time1 time2)
+
procedure: (time>=? time1 time2)
+
procedure: (time>? time1 time2)
+
+returns: #t if the relation holds, #f otherwise
+
+libraries: (chezscheme)
+
+
time1 and time2 must be time objects and must have +the same type. + +
+ +
(let ([t (current-time)])
+
+ (time=? t t)) #t
+
+(let ([t (current-time)])
+
+ (let loop ()
+
+ (when (time=? (current-time) t))
+
+ (loop))
+
+ (time>? (current-time) t)) #t
+
procedure: (copy-time time)
+
+returns: a copy of time
+
+libraries: (chezscheme)
+
+
+
(define t1 (current-time))
+
+(define t2 (copy-time t1))
+
+(eq? t2 t1) #f
+
+(eqv? (time-second t2) (time-second t1)) #t
+
+(eqv? (time-nanosecond t2) (time-nanosecond t1)) #t
+
procedure: (time-difference time1 time2)
+
+returns: the result of subtracting time2 from time1
+
procedure: (time-difference! time1 time2)
+
+returns: the result of subtracting time2 from time1
+
procedure: (add-duration time timed)
+
+returns: the result of adding timed to time
+
procedure: (add-duration! time timed)
+
+returns: the result of adding timed to time
+
procedure: (subtract-duration time timed)
+
+returns: the result of subtracting timed from time
+
procedure: (subtract-duration! time timed)
+
+returns: the result of subtracting timed from time
+
+libraries: (chezscheme)
+
+
For time-difference, time1 and time2 must +have the same time type, and the result is a time object with +time type time-duration. +For add-duration, add-duration!, +subtract-duration, and subtract-duration!, +timed must have time type time-duration, +and the result is a time object with the same time type as +time. +time-difference!, add-duration!, and +subtract-duration! are potentially destructive, i.e., each +might modify and return its first argument, or it might allocate a +new time object. + +
+ +
(let ([delay (make-time 'time-duration 0 1)])
+
+ (let ([t1 (current-time 'time-monotonic)])
+
+ (sleep delay)
+
+ (let ([t2 (current-time 'time-monotonic)])
+
+ (let ([t3 (time-difference t2 t1)])
+
+ (and
+
+ (eq? (time-type t3) 'time-duration)
+
+ (time>=? t3 delay)
+
+ (time=? (add-duration t1 t3) t2)
+
+ (time=? (subtract-duration t2 t3) t1)))))) #t
+
procedure: (current-date)
+
procedure: (current-date offset)
+
+returns: a date object representing the current date
+
+libraries: (chezscheme)
+
+
offset represents the time-zone offset in seconds east of UTC, +as described above. +It must be an exact integer in the range -86400 to ++86400, inclusive and defaults to the local time-zone offset. +UTC may be obtained by passing an offset of zero. + +
+If offset is not provided, then the current time zone's offset +is used, and date-dst? and date-zone-name report +information about the time zone. If offset is provided, then +date-dst? and date-zone-name on the resulting date +object produce #f. + +
+The following examples assume the local time zone is EST. + +
+ +
(current-date) #<date Thu Dec 27 23:23:20 2007>
+
+(current-date 0) #<date Fri Dec 28 04:23:20 2007>
+
+
+(date-zone-name (current-date)) "EST" or other system-provided string
+
+(date-zone-name (current-date 0)) #f
+
procedure: (make-date nsec sec min hour day mon year)
+
procedure: (make-date nsec sec min hour day mon year offset)
+
+returns: a date object
+
+libraries: (chezscheme)
+
+
nsec represents nanoseconds and must be an exact nonnegative integer +less than 109. +sec represents seconds and must be an exact nonnegative integer +less than 62. +min represents minutes and must be an exact nonnegative integer +less than 60. +hour must be an exact nonnegative integer less than 24. +day must be an exact integer, 1 ≤ day ≤ 31. +(The actual upper limit may be less depending on the month and year.) +mon represents the month must be an exact integer, 1 ≤ mon ≤ 12. +year must be an exact integer. +It should be at least 1970. +offset represents the time-zone offset in seconds east of UTC, +as described above. +It must be an exact integer in the range -86400 to +86400, inclusive. +UTC may be specified by passing an offset of zero. + +
+If offset is not provided, then the current time zone's offset +is used, and date-dst? and date-zone-name report +information about the time zone. If offset is provided, then +date-dst? and date-zone-name on the resulting date +object produce #f. + +
+ +
(make-date 0 0 0 0 1 1 1970 0) #<date Thu Jan 1 00:00:00 1970>
+
+(make-date 0 30 7 9 23 9 2007 -14400) #<date Sun Sep 23 09:07:30 2007>
+
+
+(date-zone-name (make-date 0 30 7 9 23 9 2007 -14400)) #f
+
+(string? (date-zone-name (make-date 0 30 7 9 23 9 2007))) #t
+
procedure: (date? obj)
+
+returns: #t if obj is a date object, #f otherwise
+
+libraries: (chezscheme)
+
+
+
+(date? (current-date))
+
+(date? (make-date 0 30 7 9 23 9 2007 -14400))
+
+(date? "Sun Sep 23 09:07:30 2007") #f
+
procedure: (date-nanosecond date)
+
+returns: the nanosecond of date
+
procedure: (date-second date)
+
+returns: the second of date
+
procedure: (date-minute date)
+
+returns: the minute of date
+
procedure: (date-hour date)
+
+returns: the hour of date
+
procedure: (date-day date)
+
+returns: the day of date
+
procedure: (date-month date)
+
+returns: the month of date
+
procedure: (date-year date)
+
+returns: the year of date
+
procedure: (date-zone-offset date)
+
+returns: the time-zone offset of date
+
+libraries: (chezscheme)
+
+
date must be a date object. + +
+ +
(define d (make-date 0 30 7 9 23 9 2007 -14400))
+
+(date-nanosecond d) 0
+
+(date-second d) 30
+
+(date-minute d) 7
+
+(date-hour d) 9
+
+(date-day d) 23
+
+(date-month d) 9
+
+(date-year d) 2007
+
+(date-zone-offset d) -14400
+
procedure: (date-week-day date)
+
+returns: the week-day of date
+
procedure: (date-year-day date)
+
+returns: the year-day of date
+
+libraries: (chezscheme)
+
+
These procedures allow the day-of-week or day-of-year to be determined for +the date represented by date. +A week-day is an exact nonnegative integer less than 7, where +0 represents Sunday, 1 represents Monday, and so on. +A year-day is an exact nonnegative integer less than 367, where +0 represents the first day of the year (January 1), 1 the +second day, 2 the third, and so on. + +
+ +
(define d1 (make-date 0 0 0 0 1 1 1970 -18000))
+
+d1 #<date Thu Jan 1 00:00:00 1970>
+
+(date-week-day d1) 4
+
+(date-year-day d1) 0
+
+
+(define d2 (make-date 0 30 7 9 23 9 2007 -14400))
+
+d2 #<date Sun Sep 23 09:07:30 2007>
+
+(date-week-day d2) 0
+
+(date-year-day d2) 265
+
procedure: (date-dst? date)
+
+returns: whether date is in Daylight Saving Time
+
procedure: (date-zone-name date)
+
+returns: #f or a string naming the time zone of date
+
+libraries: (chezscheme)
+
+
These procedures report time-zone information for +the date represented by date for a date object that +is constructed without an explicit time-zone offset. When +a date object is created instead with explicit time-zone offset, +these procedures produce #f. + +
+Daylight Saving Time status for the current time zone and a name +string for the time zone are computed using platform-specific routines. +In particular, the format of the zone name is platform-specific. + +
+ +
(define d (make-date 0 30 7 9 23 9 2007))
+
+(date-zone-offset d) -14400 assuming Eastern U.S. time zone
+
+(date-dst? d) #t
+
+(date-zone-name d) "EDT" or some system-provided string
+
procedure: (time-utc->date time)
+
procedure: (time-utc->date time offset)
+
+returns: a date object corresponding to time
+
procedure: (date->time-utc date)
+
+returns: a time object corresponding to date
+
+libraries: (chezscheme)
+
+
These procedures are used to convert between time and date objects. +The time argument to time-utc->date must have time-type +utc, and date->time-utc always returns a time +object with time-type utc. + +
+For time-utc->date, +offset represents the time-zone offset in seconds east of UTC, +as described at the beginning of this section. +It must be an exact integer in the range -86400 to ++86400, inclusive and defaults to the local time-zone offset. +UTC may be obtained by passing an offset of zero. + +
+If offset is not provided to time-utc->date, then the current time zone's offset +is used, and date-dst? and date-zone-name report +information about the time zone. If offset is provided, then +date-dst? and date-zone-name on the resulting date +object produce #f. + +
+ +
(define d (make-date 0 30 7 9 23 9 2007 -14400))
+
+(date->time-utc d) #<time-utc 1190552850.000000000>
+
+(define t (make-time 'time-utc 0 1190552850))
+
+(time-utc->date t) #<date Sun Sep 23 09:07:30 2007>
+
+(time-utc->date t 0) #<date Sun Sep 23 13:07:30 2007>
+
procedure: (date-and-time)
+
procedure: (date-and-time date)
+
+returns: a string giving the current date and time
+
+libraries: (chezscheme)
+
+
The string is always in the format illustrated by the examples below and +always has length 24. + +
+ +
(date-and-time) "Fri Jul 13 13:13:13 2001"
+
+(define d (make-date 0 0 0 0 1 1 2007 0))
+
+(date-and-time d) "Mon Jan 01 00:00:00 2007"
+
procedure: (sleep time)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
time must be a time object with type time-duration. +sleep causes the invoking thread to suspend operation for +approximately the amount of time indicated by the time object, unless +the process receives a signal that interrupts the sleep operation. +The actual time slept depends on the granularity of the system clock +and how busy the system is running other threads and processes. + + +
+ +
+This section documents procedures for timing computations. +The current-time procedure described in +Section 12.10 may also be used to +time computations. + +
+syntax: (time expr)
+
+returns: the values of expr
+
+libraries: (chezscheme)
+
+
time evaluates expr and, as a side-effect, prints (to the +console-output port) the amount of cpu time, the amount of real time, +the number of bytes allocated, and the amount of collection overhead +associated with evaluating expr. + +
+ +
> (time (collect))
+
+(time (collect))
+
+ 1 collection
+
+ 1 ms elapsed cpu time, including 1 ms collecting
+
+ 1 ms elapsed real time, including 1 ms collecting
+
+ 160 bytes allocated, including 8184 bytes reclaimed
+
procedure: (display-statistics)
+
procedure: (display-statistics textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure displays a running total of the amount of +cpu time, real time, bytes allocated, and collection overhead. +If textual-output-port is not supplied, it defaults to the current output port. + + +
+procedure: (cpu-time)
+
+returns: the amount of cpu time consumed since system start-up
+
+libraries: (chezscheme)
+
+
The amount is in milliseconds. +The amount includes "system" as well as "user" time, i.e., time +spent in the kernel on behalf of the process as well as time spent in +the process itself. + +
+See also current-time, which returns more precise information. + + +
+procedure: (real-time)
+
+returns: the amount of real time that has elapsed since system start-up
+
+libraries: (chezscheme)
+
+
The amount is in milliseconds. + +
+See also current-time, which returns more precise information. + + +
+procedure: (bytes-allocated)
+
procedure: (bytes-allocated g)
+
+returns: the number of bytes currently allocated
+
+libraries: (chezscheme)
+
+
If g is supplied, bytes-allocated returns the number of +bytes currently allocated for Scheme objects in the specified generation +plus externally allocated bytes as represented by phantom bytevectors in +the generation. +g must be a nonnegative exact integer no greater than the +maximum nonstatic generation, i.e., the +value returned by collect-maximum-generation, or the symbol +static. +If g is not supplied, bytes-allocated returns the total +number of bytes allocated in all generations. + +
+procedure: (initial-bytes-allocated)
+
+returns: the total number of bytes allocated after loading boot files
+
+libraries: (chezscheme)
+
+
procedure: (bytes-deallocated)
+
+returns: the total number of bytes deallocated by the garbage collector
+
+libraries: (chezscheme)
+
+
The total number of bytes allocated by the current process, whether +still in use or not, can be obtained by summing +(bytes-deallocated) and (bytes-allocated) +and possibly subtracting (initial-bytes-allocated). + +
+procedure: (bytes-finalized)
+
+returns: the number of bytes queued in guardians
+
+libraries: (chezscheme)
+
+
The number of bytes associated with objects that were registered in +guardians as otherwise inaccessible (including the bytes for objects +reachable only through registered objects) during the most recent +garbage collection. + +
+procedure: (current-memory-bytes)
+
+returns: the total number of bytes currently allocated, including overhead
+
+libraries: (chezscheme)
+
+
current-memory-bytes returns the total size of the heap +in bytes, including not only the bytes occupied for Scheme objects +but also various forms of overhead, including fragmentation and +reserved but not currently occupied memory, and is thus an accurate +measure of the amount of heap memory currently reserved from the +operating system for the current process. The result is only for +Scheme's storage management, however, so it does not include sizes +for externally allocated objects (even those that are represented by phantom bytevectors). + +
+procedure: (maximum-memory-bytes)
+
+returns: the maximum number of bytes ever allocated, including overhead
+
+libraries: (chezscheme)
+
+
maximum-memory-bytes returns the maximum size of the heap +in bytes, i.e., the maximum value that current-memory-bytes +returned or could have returned, since the last call to +reset-maximum-memory-bytes! or, if there has been no such +call, since the process started. + +
+procedure: (reset-maximum-memory-bytes!)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
reset-maximum-memory-bytes! resets the maximum recorded size +of the heap to the current size of the heap. + +
+procedure: (collections)
+
+returns: the number garbage collections so far
+
+libraries: (chezscheme)
+
+
procedure: (statistics)
+
+returns: a sstats record containing current statistics
+
+libraries: (chezscheme)
+
+
statistics packages together various timing and allocation +statistics into a single sstats record. +A sstats record has the following fields: + +
+
+All values are computed since system start-up. +The time values are time objects (Section 12.10), +and the bytes and count values are exact integers. + +
+statistics might be defined as follows: + +
+ +
(define statistics
+
+ (lambda ()
+
+ (make-sstats
+
+ (current-time 'time-thread)
+
+ (current-time 'time-monotonic)
+
+ (- (+ (bytes-allocated) (bytes-deallocated))
+
+ (initial-bytes-allocated))
+
+ (collections)
+
+ (current-time 'time-collector-cpu)
+
+ (current-time 'time-collector-real)
+
+ (bytes-deallocated))))
+
procedure: (make-sstats cpu real bytes gc-count gc-cpu gc-real gc-bytes)
+
+returns: a sstats record
+
+libraries: (chezscheme)
+
+
The time arguments (cpu, real, gc-cpu, and gc-real) must be time objects. +The other arguments must be exact integers. + + +
+procedure: (sstats? obj)
+
+returns: #t if obj is a sstats record, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (sstats-cpu s)
+
procedure: (sstats-real s)
+
procedure: (sstats-bytes s)
+
procedure: (sstats-gc-count s)
+
procedure: (sstats-gc-cpu s)
+
procedure: (sstats-gc-real s)
+
procedure: (sstats-gc-bytes s)
+
+returns: the value of the corresponding field of s
+
+libraries: (chezscheme)
+
+
s must be a sstats record. + +
+procedure: (set-sstats-cpu! s new-value)
+
procedure: (set-sstats-real! s new-value)
+
procedure: (set-sstats-bytes! s new-value)
+
procedure: (set-sstats-gc-count! s new-value)
+
procedure: (set-sstats-gc-cpu! s new-value)
+
procedure: (set-sstats-gc-real! s new-value)
+
procedure: (set-sstats-gc-bytes! s new-value)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
s must be a sstats record, the new-value arguments for the time fields +(cpu, real, gc-cpu, and gc-real) +must be time objects, and +the other new-value arguments must be exact integers. +Each procedure sets the value of the corresponding field of s to +new-value. + + +
+procedure: (sstats-difference s1 s2)
+
+returns: a sstats record representing the difference between s1 and s2
+
+libraries: (chezscheme)
+
+
s1 and s2 must be sstats records. +sstats-difference subtracts each field of s2 from the +corresponding field of s1 to produce the resulting sstats +record. + +
+procedure: (sstats-print s)
+
procedure: (sstats-print s textual-output-port)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
s must be a sstats record. +If textual-output-port is not supplied, it defaults to the current output port. +sstats-print displays the fields of s in a manner similar +to display-statistics and time. + + +
+global parameter: enable-object-counts
+
+libraries: (chezscheme)
+
+
The value of enable-object-counts is a boolean value that +determines whether the collector records object counts as it runs and +hence whether the object counts returned by the procedure +object-counts are accurate. +The parameter is set to #f by default, since enabling object +counts adds overhead to collection. + +
+Counts for the static generation are always correct. +Counts for a nonstatic generation n are correct immediately after a +collection of generation m ≥ n (regardless of whether the target +generation is m or m + 1) if enable-object-counts +was set to #t during the collection. + +
+One strategy for collecting object counts with minimal overhead is +to enable object counts only while collecting the maximum nonstatic +generation and to obtain the object counts immediately after that +collection. + +
+procedure: (object-counts)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
The procedure object-counts returns a nested association list +representing object counts and bytes allocated for each heap-allocated +primitive type and record type with at least one live instance in one +or more generations. +(Heap-allocated primitive types include, e.g., pairs and vectors, but +not, e.g., fixnums or characters.) +Object counts are gathered by the collector only when +enable-object-counts is #t. +The description of enable-object-counts details the +circumstances under which the counts are accurate. + +
+The association list returned by object-counts has the following +structure: + +
+ +
((type (generation count . bytes) ...) ...) +
type is either the name of a primitive type, represented as a +symbol, e.g., pair, or a record-type descriptor (rtd). +generation is a nonnegative fixnum between 0 and the value +of (collect-maximum-generation), inclusive, or the symbol +static representing the static generation. +count and bytes are nonnegative fixnums. + +
+ +
(collect-request-handler void)
+
+(enable-object-counts #t)
+
+(define-record-type frob (fields x))
+
+(define x (make-frob (make-frob #f)))
+
+(collect 3 3)
+
+(cdr (assoc 3
+
+ (cdr (assoc (record-type-descriptor frob)
+
+ (object-counts))))) (2 . 16)
+
global parameter: enable-object-backreferences
+
+libraries: (chezscheme)
+
+
The value of enable-object-backreferences is a boolean value that +determines whether the collector records information about which other object +caused an object to be retained and +hence whether the backreferences reported by the procedure +object-backreferences are accurate. +The parameter is set to #f by default, since backreference recording +adds overhead to collection. + +
+Beware that backreference recording can have small performance effects +even after it is disabled---at least until the next collection over +the same generations---since backreference records constrain the way +that the collector stores some objects. + +
+procedure: (object-backreferences)
+
+returns: a list of list of pairs
+
+libraries: (chezscheme)
+
+
The procedure object-backreferences returns a list of +backreference lists. Each backreference list is a list of pairs, where +the car of the pair is a referenced object, and the +cdr of the pair is either #f or a value that caused +the car's value or be retained during collection. The +cdr of a backreference pair is #f if the object in +the car is retained by a root reference within the system's +implementation or static generation. By locating the cdr of +one pair as the car of another, chains of objects as +discovered by the collector can be traced back to roots. + +
+The list returned by object-backreferences contains one +backreference list for each nonstatic generation (in order, starting +with generation 0). An object is recorded in a backreference +list for the destination generation to which it is moved by +collection. The collector records backreference information only when +enable-object-backreferences is set to a true value, and only +for objects that start in generations that are collected. + +
+For example, assuming that backreferences have not been previously +enabled, the result of + +
(collect-request-handler void)
+
+(enable-object-backreferences #t)
+
+(collect 0)
+
+(enable-object-backreferences #f)
+
+(object-backreferences)
+
will have a non-empty backreference list only for the second +list in the result (i.e., the list for generation 1). + +
+Although object-backreferences reports generation-specific +information to reflect its cooperation with generational collection, +backreference information is most useful after a collection of all +generations up to the maximum nonstatic generation. In that case, +backreference information can be used to discover why a particular +value or kind of value remains allocated or remains in a weak pair +after garbage collection. + +
+ +
(collect-request-handler void)
+
+(enable-object-backreferences #t)
+
+(define b (box "hello"))
+
+(collect 0)
+
+(assq (unbox b) (cadr (object-backreferences))) ("hello" . #&"hello")
+
+
+Cost centers are used to track the bytes allocated, instructions executed, +and/or cpu time elapsed while evaluating selected sections of code. +Cost centers are created via the procedure make-cost-center, and +costs are tracked via the procedure with-cost-center. + +
+Allocation and instruction counts are tracked only for code instrumented +for that purpose. +This instrumentation is controlled by two parameters: generate-allocation-counts +and generate-instruction-counts. +Instrumentation is disabled by default. +Built in procedures are not instrumented, nor is interpreted code or +non-Scheme code. +Elapsed time is tracked only when the optional timed? argument to +with-cost-center is provided and is not false. + +
+The with-cost-center procedure accurately tracks costs, subject +to the caveats above, even when reentered with the same cost center, used +simultaneously in multiple threads, and exited or reentered one or more +times via continuation invocation. + +
+thread parameter: generate-allocation-counts
+
+libraries: (chezscheme)
+
+
When this parameter has a true value, the compiler inserts a short sequence of +instructions at each allocation point in generated code to track the amount of +allocation that occurs. +This parameter is initially false. + +
+thread parameter: generate-instruction-counts
+
+libraries: (chezscheme)
+
+
When this parameter has a true value, the compiler inserts a short +sequence of instructions in each block of generated code to track the +number of instructions executed by that block. +This parameter is initially false. + +
+procedure: (make-cost-center)
+
+returns: a new cost center
+
+libraries: (chezscheme)
+
+
The recorded costs of the new cost center are initialized to zero. + +
+procedure: (cost-center? obj)
+
+returns: #t if obj is a cost center, otherwise #f
+
+libraries: (chezscheme)
+
+
procedure: (with-cost-center cost-center thunk)
+
procedure: (with-cost-center timed? cost-center thunk)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
thunk must be a procedure that accepts zero arguments. +with-cost-center invokes thunk without arguments and +returns its values. +It also tracks, dynamically, the bytes allocated, instructions executed, +and cpu time elapsed while evaluating the invocation of thunk and +adds the tracked costs to the cost center's running record of these costs. + +
+As described above, allocation counts are tracked only for code +compiled with the parameter generate-allocation-counts set +to true, and instruction counts are tracked only for code compiled +with generate-instruction-counts set to true. +Cpu time is tracked only if timed? is provided and not false and +includes cpu time spent in instrumented, uninstrumented, and non-Scheme +code. + +
+procedure: (cost-center-instruction-count cost-center)
+
+returns: the number of instructions tracked by cost-center
+
+libraries: (chezscheme)
+
+
procedure: (cost-center-allocation-count cost-center)
+
+returns: the number of allocated bytes tracked by cost-center
+
+libraries: (chezscheme)
+
+
procedure: (cost-center-time cost-center)
+
+returns: the cpu time tracked by cost-center
+
+libraries: (chezscheme)
+
+
The cpu time is returned as a time object with time-type time-duration. + +
+procedure: (reset-cost-center! cost-center)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
This procedure resets the costs recorded by cost-center to zero. + + +
+ +
+This section describes mechanisms for creating and manipulating parameters. +New parameters may be created conveniently with make-parameter. +Nothing distinguishes parameters from other +procedures, however, except for their behavior. +If more complicated actions must be taken when a parameter is invoked +than can be accommodated easily through the make-parameter mechanism, +the parameter may be defined directly with case-lambda. + + +
+procedure: (make-parameter object)
+
procedure: (make-parameter object procedure)
+
+returns: a parameter (procedure)
+
+libraries: (chezscheme)
+
+
make-parameter accepts one or two arguments. +The first argument is the initial value of the internal variable, and +the second, if present, is a filter applied to the initial value +and all subsequent values. +The filter should accept one argument. +If the value is not appropriate, the filter should raise an exception or +convert the value into a more appropriate form. + +
+For example, the default value of print-length is defined as +follows: + +
+ +
(define print-length
+
+ (make-parameter
+
+ #f
+
+ (lambda (x)
+
+ (unless (or (not x) (and (fixnum? x) (fx>= x 0)))
+
+ (assertion-violationf 'print-length
+
+ "~s is not a positive fixnum or #f"
+
+ x))
+
+ x)))
+
+
(print-length) #f
+
+(print-length 3)
+
+(print-length) 3
+
+(format "~s" '(1 2 3 4 5 6)) "(1 2 3 ...)"
+
+(print-length #f)
+
+(format "~s" '(1 2 3 4 5 6)) "(1 2 3 4 5 6)"
+
The definition of make-parameter is straightforward using +case-lambda: + +
+ +
(define make-parameter
+
+ (case-lambda
+
+ [(init guard)
+
+ (let ([v (guard init)])
+
+ (case-lambda
+
+ [() v]
+
+ [(u) (set! v (guard u))]))]
+
+ [(init)
+
+ (make-parameter init (lambda (x) x))]))
+
In threaded versions of Chez Scheme, make-parameter creates +global parameters. +The procedure make-thread-parameter, described in +Section 15.8, may be used to make thread +parameters. + + +
+syntax: (parameterize ((param expr) ...) body1 body2 ...)
+
+returns: the values of the body body1 body2 ...
+
+libraries: (chezscheme)
+
+
Using the syntactic form parameterize, the values of parameters can +be changed in a manner analogous to fluid-let for ordinary variables. +Each param is set to the value of the corresponding +expr while the body is evaluated. +When control leaves the body by normal return or by the invocation of a +continuation created outside of the body, the parameters are restored to +their original values. +If control returns to the body via a continuation created during the +execution of the body, the parameters are again set to their temporary +values. + +
+ +
(define test
+
+ (make-parameter 0))
+
+(test) 0
+
+(test 1)
+
+(test) 1
+
+(parameterize ([test 2])
+
+ (test)) 2
+
+(test) 1
+
+(parameterize ([test 2])
+
+ (test 3)
+
+ (test)) 3
+
+(test) 1
+
+(define k (lambda (x) x))
+
+(begin (set! k (call/cc k))
+
+ 'k) k
+
+(parameterize ([test 2])
+
+ (test (call/cc k))
+
+ (test)) k
+
+(test) 1
+
+(k 3) 3
+
+(test) 1
+
The definition of parameterize is similar to the definition of +fluid-let (page 121): + +
+ +
(define-syntax parameterize
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(_ () b1 b2 ...) #'(begin b1 b2 ...)]
+
+ [(_ ((x e) ...) b1 b2 ...)
+
+ (with-syntax ([(p ...) (generate-temporaries #'(x ...))]
+
+ [(y ...) (generate-temporaries #'(x ...))])
+
+ #'(let ([p x] ... [y e] ...)
+
+ (let ([swap (lambda ()
+
+ (let ([t (p)]) (p y) (set! y t))
+
+ ...)])
+
+ (dynamic-wind swap (lambda () b1 b2 ...) swap))))])))
+
+
+A limited set of virtual registers is supported by the compiler +for use by programs that require high-speed, global, and mutable storage +locations. +Referencing or assigning a virtual register is potentially faster and +never slower than accessing an assignable local or global variable, +and the code sequences for doing so are generally smaller. +Assignment is potentially significantly faster because there is no need +to track pointers from the virtual registers to young objects, as there +is for variable locations that might reside in older generations. +On threaded versions of the system, virtual registers are "per thread" +and thus serve as thread-local storage in a manner that is less expensive +than thread parameters. + +
+The interface consists of three procedures: virtual-register-count, +which returns the number of virtual registers, set-virtual-register!, +which sets the value of a specified virtual register, and +virtual-register, which retrieves the value of a specified +virtual register. + +
+A virtual register is specified by a nonnegative fixnum index less than +the number of virtual registers. +To get optimal performance for set-virtual-register! +and virtual-register, the index should be a constant +embedded right in the call (or propagatable via optimization to the +call). +To avoid putting these constants in the source code, programmers should +consider using identifier macros to give names to virtual registers, e.g.: + +
+ +
(define-syntax current-state
+
+ (identifier-syntax
+
+ [id (virtual-register 0)]
+
+ [(set! id e) (set-virtual-register! 0 e)]))
+
+(set! current-state 'start)
+
+current-state start
+
A more elaborate macro could dole out indices at compile time and complain +when no more indices are available. + +
+Virtual-registers must be treated as an application-level resource, i.e., +libraries intended to be used by multiple applications should generally +not use virtual registers to avoid conflicts with an application's use of +the registers. + + +
+procedure: (virtual-register-count)
+
+returns: the number of virtual registers
+
+libraries: (chezscheme)
+
+
As of Version 9.0, the number of virtual registers is set at 16. +It cannot be changed except by recompiling Chez Scheme from +source. + +
+procedure: (set-virtual-register! k x)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
set-virtual-register! stores x in virtual register k. +k must be a nonnegative fixnum less than the value of +(virtual-register-count). + +
+procedure: (virtual-register k)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
virtual-register returns the value most recently +stored in virtual register k (on the current thread, in +threaded versions of the system). + + +
+ +
+procedure: (scheme-version)
+
procedure: (scheme-version show-pre-release?)
+
+returns: a version string
+
+libraries: (chezscheme)
+
+
The version string is in the form + +
+ +
"Chez Scheme Version version" +
for Chez Scheme, and + +
+ +
"Petite Chez Scheme Version version" +
for Petite Chez Scheme. + +
+version includes the major, minor, and patch version numbers +separated by .. If show-pre-release? is provided and is a +true value, and the current version is a pre-release version (i.e., +(scheme-pre-release) is a number), then version +additionally has -pre-release. and the pre-release number +appended. + +
+ +
(scheme-version) "Chez Scheme Version 9.9.9"
+
+(scheme-version #t) "Chez Scheme Version 9.9.9-pre-release.11"
+
procedure: (scheme-version-number)
+
+returns: three values: the major, minor, and patch version numbers
+
+libraries: (chezscheme)
+
+
Each of the three return values is a nonnegative fixnum. + +
+In Chez Scheme Version 9.7.3 or 9.7.3-pre-release.3: + +
+ +
(scheme-version-number) 9
+
+ 7
+
+ 3
+
procedure: (scheme-pre-release)
+
+returns: a pre-release number or #f
+
+libraries: (chezscheme)
+
+
The return value is a positive fixnum for a pre-release version, or it +is #f for a release version (which is after any +version that has a pre-release number and the same major, minor, and +patch number). + +
+In Chez Scheme Version 9.7.3: + +
+ +
(scheme-pre-release) #f +
In Chez Scheme Version 9.7.3-pre-release.3: + +
+ +
(scheme-pre-release) 3 +
procedure: (petite?)
+
+returns: #t if called in Petite Chez Scheme, #f otherwise
+
+libraries: (chezscheme)
+
+
The only difference between Petite Chez Scheme and Chez Scheme is that +the compiler is not available in the former, so this predicate can serve as +a way to determine if the compiler is available. + + +
+procedure: (threaded?)
+
+returns: #t if called in a threaded version of the system, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (interactive?)
+
+returns: #t if system is run interactively, #f otherwise
+
+libraries: (chezscheme)
+
+
This predicate returns #t if the Scheme process's +stdin and stdout are connected to a tty (Unix-based systems) or console +(Windows). +Otherwise, it returns #f. + + +
+procedure: (get-process-id)
+
+returns: the operating system process id of the current process
+
+libraries: (chezscheme)
+
+
procedure: (getenv key)
+
+returns: environment value of key or #f
+
+libraries: (chezscheme)
+
+
key must be a string. +getenv returns the operating system shell's environment value +associated with key, or #f if no environment value +is associated with key. + +
+ +
(getenv "HOME") "/u/freddy" +
procedure: (putenv key value)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
key and value must be strings. + +
+putenv stores the key, value pair in the +environment of the process, +where it is available to the current process (e.g., via getenv) +and any spawned processes. + +
+ +
(putenv "SCHEME" "rocks!")
+
+(getenv "SCHEME") "rocks!"
+
procedure: (get-registry key)
+
+returns: registry value of key or #f
+
procedure: (put-registry! key val)
+
procedure: (remove-registry! key)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
key and val must be strings. + +
+get-registry returns a string containing the registry +value of key if the value exists. +If no registry value for key exists, get-registry returns +#f. + +
+put-registry! sets the registry +value of key to val. +It raises an exception with condition type &assertion if the +value cannot be set, which may happen if +the user has insufficient access. + +
+remove-registry! removes the registry +key or value named by key. +It raises an exception with condition type &assertion if the +value cannot be removed. +Reasons for failure include the key not being present, the user having +insufficient access, or key being a key with subkeys. + +
+These routines are defined for Windows only. + +
+ +
(get-registry "hkey_local_machine\\Software\\North\\South") #f
+
+(put-registry! "hkey_local_machine\\Software\\North\\South" "east")
+
+(get-registry "hkey_local_machine\\Software\\North\\South") "east"
+
+(remove-registry! "hkey_local_machine\\Software\\North")
+
+(get-registry "hkey_local_machine\\Software\\North\\South") #f
+
+
+thread parameter: subset-mode
+
+libraries: (chezscheme)
+
+
The value of this parameter +must be #f (the default) or the symbol system. +Setting subset-mode to system allows the manipulation +of various undocumented system variables, data structures, and +settings. +It is typically used only for system debugging. + + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/threads.html b/csug10.0/threads.html
new file mode 100644
index 000000000..3f8298a72
--- /dev/null
+++ b/csug10.0/threads.html
@@ -0,0 +1,1086 @@
+
+
+
+
+
+This chapter describes the Chez Scheme thread-system procedures +and syntactic forms. +With the exception of locks, locked increment, and locked decrement, +the features of the thread system are implemented on top of the Posix +thread system (pthreads) on non-Windows-based system and directly using +the Windows API on Windows-based systems. +Consult the appropriate documentation on your system for basic details +of thread creation and interaction. + +
+Most primitive Scheme procedures are thread-safe, meaning +that they can be called concurrently from multiple threads. +This includes allocation operations like cons and make-string, +accessors like car and vector-ref, +numeric operators like + and sqrt, and nondestructive +higher-level primitive operators like append and map. + +
+Simple mutation operators, like set-car!, vector-set!, +and record field mutators are thread-safe. +Likewise, assignments to local variables, including assignments to +(unexported) library and top-level program variables are thread-safe. + +
+Other destructive operators are thread safe only if they are used to +operate on different objects from those being read or modified by other +threads. +For example, assignments to global variables are thread-safe only as +long as one thread does not assign the same variable another thread +references or assigns. +Similarly, putprop can be called in one thread while another +concurrently calls putprop or getprop if the symbols +whose property lists are being modified or accessed differ. + +
+In this context, most I/O operations should be considered destructive, +since they might modify a port's internal structure; see also +Section 15.9 for information on buffered ports. + +
+Use of operators that are not thread-safe without proper synchronization +can corrupt the objects upon which they operate. +This corruption can lead to incorrect behavior, memory faults, and even +unrecoverable errors that cause the system to abort. + +
+The compiler and interpreter are thread-safe to the extent that user code +evaluated during the compilation and evaluation process is thread-safe or +properly synchronized. +Thus, two or more threads +can call any of the compiler or interpreter entry points, i.e., +compile, compile-file, compile-program, compile-script, +compile-port, or interpret at the same time. +Naturally, the object-file targets of two file compilation operations that +run at the same time should be different. +The same is true for eval and load as long as +the default evaluator is used or is set explicitly to compile, +interpret, or some other thread-safe evaluator. + +
+One restriction should be observed when one of multiple threads creates or +loads compiled code, however, which is that only that thread or +subsequently created children, or children of subsequently created +children, etc., should run the code. +This is because multiple-processor systems upon which threaded code may +run might not guarantee that the data and instruction caches are +synchronized across processors. + +
+ +
+procedure: (fork-thread thunk)
+
+returns: a thread object
+
+libraries: (chezscheme)
+
+
thunk must be a procedure that accepts zero arguments. + +
+fork-thread invokes thunk in a new thread and returns +a thread object. + +
+Threads created by foreign code using some means other than +fork-thread must call Sactivate_thread +(Section 4.9) before touching any Scheme data +or calling any Scheme procedures. + +
+procedure: (thread-join thread)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Waits until thread has completed. + +
+procedure: (get-initial-thread)
+
+returns: a thread object for the initial thread
+
+libraries: (chezscheme)
+
+
procedure: (thread? obj)
+
+returns: #t if obj is a thread object, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (get-thread-id)
+
+returns: the thread id of the current thread
+
+libraries: (chezscheme)
+
+
The thread id is a thread number assigned by thread id, and has no +relationship to the process id returned by +get-process-id, which is the same +in all threads. + +
+procedure: (thread-preserve-ownership!)
+
procedure: (thread-preserve-ownership! thread)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Provides a hint to the storage manager that thread (which +defaults to the current thread if not supplied) can particularly +benefit from tracking the objects that it allocates for parallel +collection. + +
+ +
+procedure: (make-mutex)
+
procedure: (make-mutex name)
+
+returns: a new mutex object
+
+libraries: (chezscheme)
+
+
name, if supplied, must be a symbol which identifies the mutex, or +#f for no name. The name is printed every time the mutex is +printed, which is useful for debugging. + +
+procedure: (mutex? obj)
+
+returns: #t if obj is a mutex, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (mutex-acquire mutex)
+
procedure: (mutex-acquire mutex block?)
+
+returns: see below
+
+libraries: (chezscheme)
+
+
mutex must be a mutex. + +
+mutex-acquire acquires the mutex identified by mutex. +The optional boolean argument block? defaults to +#t and specifies whether the thread should block +waiting for the mutex. +If block? is omitted or is true, the thread +blocks until the mutex has been acquired, and an unspecified +value is returned. + +
+If block? is false and the mutex currently belongs +to a different thread, the current thread does not block. +Instead, mutex-acquire returns +immediately with the value #f to +indicate that the mutex is not available. +If block? is false and the mutex is successfully +acquired, mutex-acquire returns #t. + +
+Mutexes are recursive in Posix threads terminology, which +means that the calling thread can use mutex-acquire to +(re)acquire a mutex it already has. +In this case, an equal number of mutex-release calls +is necessary to release the mutex. + +
+procedure: (mutex-release mutex)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
mutex must be a mutex. + +
+mutex-release releases the mutex identified by mutex. +Unpredictable behavior results if the mutex is not owned by the +calling thread. + +
+syntax: (with-mutex mutex body1 body2 ...)
+
+returns: the values of the body body1 body2 ...
+
+libraries: (chezscheme)
+
+
with-mutex evaluates the expression mutex, which must +evaluate to a mutex, acquires the mutex, evaluates the body +body1 body2 ..., and releases the mutex. +The mutex is released whether the body returns normally or +via a control operation (that is, throw to a continuation, perhaps because +of an error) that results in +a nonlocal exit from the with-mutex form. +If control subsequently returns to the body via a +continuation invocation, the mutex is reacquired. + +
+Using with-mutex is generally more convenient and safer than using +mutex-acquire and mutex-release directly. + +
+procedure: (mutex-name mutex)
+
+returns: the name associated with mutex, if any; otherwise #f
+
+libraries: (chezscheme)
+
+
mutex must be a mutex. + +
+ +
+procedure: (make-condition)
+
procedure: (make-condition name)
+
+returns: a new condition object
+
+libraries: (chezscheme)
+
+
name, if supplied, must be a symbol which identifies the condition +object, or #f for no name. The name is printed every time the +condition is printed, which is useful for debugging. + +
+procedure: (thread-condition? obj)
+
+returns: #t if obj is a condition object, #f otherwise
+
+libraries: (chezscheme)
+
+
procedure: (condition-wait cond mutex)
+
procedure: (condition-wait cond mutex timeout)
+
+returns: #t if the calling thread was awakened by the condition, #f if the calling thread timed out waiting
+
+libraries: (chezscheme)
+
+
cond must be a condition object, and +mutex must be a mutex. +The optional argument timeout is a time record of type +time-duration or time-utc, or #f for no +timeout. It defaults to #f. + +
+condition-wait waits up to the specified timeout for +the condition identified by the condition object cond. +The calling thread must have acquired the mutex identified by the mutex +mutex at the time condition-wait is +called. +mutex is released as a side effect of the call to +condition-wait. +When a thread is later released from the condition variable by one of +the procedures described below or the timeout expires, mutex is +reacquired and condition-wait returns. + + +
+procedure: (condition-signal cond)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
cond must be a condition object. + +
+condition-signal releases one of the threads waiting for the +condition identified by cond. + + +
+procedure: (condition-broadcast cond)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
cond must be a condition object. + +
+condition-broadcast releases all of the threads waiting for the +condition identified by cond. + +
+procedure: (condition-name condition)
+
+returns: the name associated with condition, if any; otherwise #f
+
+libraries: (chezscheme)
+
+
condition must be a condition. + +
+ +
+Locks are more primitive but more flexible and efficient than mutexes +and can be used in situations where the added mutex functionality +is not needed or desired. +They can also be used independently of the thread system +(including in nonthreaded versions of Chez Scheme) +to synchronize operations running in separate Scheme processes +as long as the lock is allocated in memory shared by the processes. + +
+A lock is simply a word-sized integer, i.e., an iptr or +uptr foreign type (Section 4.5) with the native +endianness of the target machine, possibly part of a larger structure +defined using define-ftype (page 77). +It must be explicitly allocated in memory that resides outside the Scheme +heap and, when appropriate, explicitly deallocated. +When just threads are involved (i.e., when multiple processes are not +involved), the memory can be allocated via foreign-alloc. +When multiple processes are involved, the lock should be allocated in +some area shared by the processes that will interact with the lock. + +
+Once initialized using ftype-init-lock!, a process or thread +can attempt to lock the lock via ftype-lock! or ftype-spin-lock!. +Once the lock has been locked and before it is unlocked, further +attempts to lock the lock fail, even by the process or thread that +most recently locked it. +Locks can be unlocked, via ftype-unlock!, by any process or thread, +not just by the process or thread that most recently locked the lock. + +
+The lock mechanism provides little structure, and mistakes +in allocation and use can lead to memory faults, deadlocks, +and other problems. Furthermore, no memory ordering is implied by a lock +operation, which means that memory-order-acquire and +memory-order-release may be needed to complete the intended +synchronization of a lock. +Thus, it is usually advisable to use locks only as part of a +higher-level abstraction that ensures locks are used in a +disciplined manner. + +
+ +
(define lock
+
+ (make-ftype-pointer uptr
+
+ (foreign-alloc (ftype-sizeof uptr))))
+
+
+(ftype-init-lock! uptr () lock)
+
+(ftype-lock! uptr () lock) #t, assuming no spurious failure
+
+(ftype-lock! uptr () lock) #f
+
+(ftype-unlock! uptr () lock)
+
+(ftype-spin-lock! uptr () lock)
+
+(ftype-lock! uptr () lock) #f
+
+(ftype-unlock! uptr () lock)
+
syntax: (ftype-init-lock! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-init-lock! ftype-name (a ...) fptr-expr index)
+
+returns: unspecified
+
syntax: (ftype-lock! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-lock! ftype-name (a ...) fptr-expr index)
+
+returns: #t if the lock is not already locked, #f otherwise
+
syntax: (ftype-spin-lock! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-spin-lock! ftype-name (a ...) fptr-expr index)
+
+returns: unspecified
+
syntax: (ftype-unlock! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-unlock! ftype-name (a ...) fptr-expr index)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
Each of these has a syntax like and behaves similarly to +ftype-set! (page 86), though with an implicit +val-expr. +In particular, the restrictions on and handling of fptr-expr +and the accessors a ... is similar, with one important +restriction: the field specified by the last accessor, upon which +the form operates, must be a word-size integer, i.e., an +iptr, uptr, or the equivalent, with the native +endianness. + +
+ftype-init-lock! should be used to initialize the lock prior +to the use of any of the other operators; if this is not done, the +behavior of the other operators is undefined. + +
+ftype-lock! can be used to lock the lock. +If it finds the lock unlocked at the time of the operation, it (normally) locks +the lock and returns #t; if it finds the lock already locked, +it returns #f without changing the lock. On an architecture with a weak memory model, +ftype-lock! can spuriously fail, leaving a lock unchanged and returning +#f even if the lock is currently unlocked. On success, no memory ordering is implied, +which means that memory-order-acquire may be +needed to complete an intended synchronization. + +
+ftype-spin-lock! can also be used to lock the lock. +If it finds the lock unlocked at the time of the operation, it locks the +lock and returns; if it finds the lock already locked, it waits until +the lock is unlocked, then locks the lock and returns. +If no other thread or process unlocks the lock, the operation does +not return and cannot be interrupted by normal means, including by the +storage manager for the purpose of initiating a garbage collection. +There are also no guarantees of fairness, so a process might hang +indefinitely even if other processes are actively locking and unlocking +the lock. + +
+ftype-unlock! is used to unlock a lock. +If it finds the lock locked, it unlocks the lock and returns. +Otherwise, it returns without changing the lock. +On an architecture with a weak memory model, +no memory ordering is implied, and memory-order-release may be +needed to complete an intended synchronization. + +
+ +
+The locked operations described here can be used when just an atomic +increment or decrement is required. + +
+syntax: (ftype-locked-incr! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-locked-incr! ftype-name (a ...) fptr-expr index)
+
+returns: #t if the updated value is 0, #f otherwise
+
syntax: (ftype-locked-decr! ftype-name (a ...) fptr-expr)
+
syntax: (ftype-locked-decr! ftype-name (a ...) fptr-expr index)
+
+returns: #t if the updated value is 0, #f otherwise
+
+libraries: (chezscheme)
+
+
Each of these has a syntax like and behaves similarly to +ftype-set! (page 86), though with an implicit +val-expr. +In particular, the restrictions on and handling of fptr-expr +and the accessors a ... is similar, with one important +restriction: the field specified by the last accessor, upon which +the form operates, must be a word-size integer, i.e., an +iptr, uptr, or the equivalent, with the native +endianness. + +
+ftype-locked-incr! atomically reads the value of the specified +field, adds 1 to the value, and writes the new value back into the +field. +Similarly, ftype-locked-decr! atomically reads the value of +the specified field, subtracts 1 from the value, and writes the new +value back into the field. +Both return #t if the new value is 0, otherwise #f. + +
+ +
+Applications that manage memory outside the Scheme heap can leverage +the Scheme storage management system to help perform reference +counting via ftype guardians. +In a reference-counted memory management system, each object holds +a count of pointers to it. +The count is incremented when a new pointer is created and decremented +when a pointer is dropped. +When the count reaches zero, the object is no longer needed and the +memory it formerly occupied can be made available for some other +purpose. + +
+Ftype guardians are similar to guardians created by +make-guardian +(Section 13.2). +The guardian? procedure returns +true for both, and the +unregister-guardian +procedure can be used to unregister objects registered with either. + +
+syntax: (ftype-guardian ftype-name)
+
+returns: a new ftype guardian
+
+libraries: (chezscheme)
+
+
ftype-name must name an ftype. +The first base field of the ftype (or one of the first base fields +in the case of unions) must be a word-sized integer (iptr or uptr) +with native endianness. +This field is assumed to hold a reference count. + +
+The return value is a new ftype guardian g, with which +ftype-pointers of type ftype-name (or some subtype of +ftype-name) can be registered. +An ftype pointer is registered with g by invoking g +with the ftype pointer as an argument. + +
+An ftype guardian does not automatically protect from collection +the ftype pointers registered with it, as a normal guardian would +do. +Instead, for each registered ftype pointer that becomes inaccessible +via normal (non-weak, non-guardian pointers), the guardian decrements +the reference count of the object to which the ftype pointer points. +If the resulting reference-count value is zero, the ftype pointer +is preserved and can be retrieved from the guardian. +If the resulting reference-count value is non-zero, however, the +ftype pointer is not preserved. +Objects retrieved from an ftype guardian (by calling it without +arguments) are guaranteed to have zero reference counts, assuming +reference counts are maintained properly by code outside the +collector. + +
+The collector decrements the reference count using the equivalent +of ftype-locked-decr! +to support systems in which non-Scheme objects are stored in memory +shared by multiple processes. +In such systems, programs should themselves use +ftype-locked-incr! and +ftype-locked-decr! or non-Scheme equivalents (e.g., the C +LOCKED_INCR and +LOCKED_DECR macros in scheme.h, +which are described in Section 4.9) to maintain +reference counts. + +
+The following example defines a simple ftype and an allocator for +objects of that ftype that frees any objects of that ftype that were +previously allocated and no longer accessible. + +
+ +
(module (A make-A free-dropped-As)
+
+ (define-ftype A
+
+ (struct
+
+ [refcount uptr]
+
+ [data int]))
+
+ (define g (ftype-guardian A))
+
+ (define free-dropped-As
+
+ (lambda ()
+
+ (let ([a (g)])
+
+ (when a
+
+ (printf "freeing ~s\n" (ftype-ref A (data) a))
+
+ (foreign-free (ftype-pointer-address a))
+
+ (free-dropped-As)))))
+
+ (define make-A
+
+ (lambda (n)
+
+ (free-dropped-As)
+
+ (let ([a (make-ftype-pointer A (foreign-alloc (ftype-sizeof A)))])
+
+ (ftype-set! A (refcount) a 1)
+
+ (ftype-set! A (data) a n)
+
+ (g a)
+
+ a))))
+
We can test this by allocating, dropping, and immediately collecting +ftype pointers to A. + +
+ +
> (do ([i 10 (fx- i 1)])
+
+ ((fx= i 0))
+
+ (make-A i)
+
+ (collect))
+
+freeing 10
+
+freeing 9
+
+freeing 8
+
+freeing 7
+
+freeing 6
+
+freeing 5
+
+freeing 4
+
+freeing 3
+
+freeing 2
+
+> (free-dropped-As)
+
+freeing 1
+
Objects guarded by an ftype guardian might contain pointers to other +objects whose reference counts should also be incremented upon +allocation of the containing object and decremented upon freeing +of the containing object. + + + +
+ +
+Scheme threads can expose the memory-consistency model of the +underlying processor, except to the degree that it would interfere +with the memory safety of Scheme programs. For example, if two threads +share a vector, then a vector-set! in one thread will not +allow the other thread to read the vector and see a partially +constructed primitive object installed into the vector; the Scheme +system includes a memory fence around operations and on platforms as +needed to preserve safety. There's no guarantee, for example, that +assigning to multiple slots in an fxvector will become visible in the +same order to other threads that share the vector, because no such +ordering is required to preserve memory safety. + +
+procedure: (memory-order-acquire)
+
procedure: (memory-order-release)
+
+returns: unspecified
+
+libraries: (chezscheme)
+
+
These procedures fence memory operations in a way that is consistent +with acquire-release patterns. Specifically, +memory-order-acquire ensures at least a load-load and +load-store fence, and memory-order-release ensures at least +a store-store and store-load fence. + + +
+ +
+procedure: (make-thread-parameter object)
+
procedure: (make-thread-parameter object procedure)
+
+returns: a new thread parameter
+
+libraries: (chezscheme)
+
+
See Section 12.13 for a general +discussion of parameters and the use of the optional second argument. + +
+When a thread parameter is created, a separate location is set aside +in each current and future thread to hold the value of the parameter's +internal state variable. +(This location may be eliminated by the storage manager when the +parameter becomes inaccessible.) +Changes to the thread parameter in one thread are not seen by any +other thread. + +
+When a new thread is created (see fork-thread), +the current value (not location) of each +thread parameter is inherited from the forking thread by the new thread. +Similarly, when a thread created by some other means is activated for the +first time (see Sactivate_thread in +Section 4.9), the current value (not location) of each +thread parameter is inherited from the main (original) thread by the new +thread. + +
+Most built-in parameters are thread parameters, but some are global. +All are marked as global or thread where they are defined. +There is no distinction between built-in global and thread parameters +in the nonthreaded versions of the system. + + +
+ +
+Chez Scheme buffers file I/O operations for efficiency, but buffered +I/O is not thread safe. +Two threads that write to or read from the same buffered port concurrently +can corrupt the port, resulting in buffer overruns and, ultimately, +invalid memory references. + +
+Buffering on binary output ports can be disabled when opened with +buffer-mode none. +Buffering on input ports cannot be completely disabled, however, due to +the need to support lookahead, and buffering on textual ports, even +textual output ports, cannot be disabled completely because the +transcoders that convert between characters and bytes sometimes +require some lookahead. + +
+Two threads should thus never read from or write to the same port +concurrently, except in the special case of a binary output port +opened buffer-mode none. +Alternatives include appointing one thread to perform all I/O for a +given port and providing a per-thread generic-port wrapper that +forwards requests to the port only after acquiring a mutex. + +
+The initial console and current input and output ports are thread-safe, +as are transcript ports, so it is safe for multiple threads to print error +and/or debugging messages to the console. +The output may be interleaved, even within the same line, but the port +will not become corrupted. +Thread safety for these ports is accomplished at the high cost of +acquiring a mutex for each I/O operation. + + +
+ +
+The following code, taken from the article +"A Scheme for native threads [10]," +implements a bounded queue using many of the +thread-system features. +A bounded queue has a fixed number of available slots. +Attempting to enqueue when the queue is full causes the calling thread +to block. +Attempting to dequeue from an empty queue causes the calling thread +to block. + + +
+ +
(define-record-type bq
+
+ (fields
+
+ (immutable data)
+
+ (mutable head)
+
+ (mutable tail)
+
+ (immutable mutex)
+
+ (immutable ready)
+
+ (immutable room))
+
+ (protocol
+
+ (lambda (new)
+
+ (lambda (bound)
+
+ (new (make-vector bound) 0 0 (make-mutex)
+
+ (make-condition) (make-condition))))))
+
+
+(define dequeue!
+
+ (lambda (q)
+
+ (with-mutex (bq-mutex q)
+
+ (let loop ()
+
+ (let ([head (bq-head q)])
+
+ (cond
+
+ [(= head (bq-tail q))
+
+ (condition-wait (bq-ready q) (bq-mutex q))
+
+ (loop)]
+
+ [else
+
+ (bq-head-set! q (incr q head))
+
+ (condition-signal (bq-room q))
+
+ (vector-ref (bq-data q) head)]))))))
+
+
+(define enqueue!
+
+ (lambda (item q)
+
+ (with-mutex (bq-mutex q)
+
+ (let loop ()
+
+ (let* ([tail (bq-tail q)] [tail^ (incr q tail)])
+
+ (cond
+
+ [(= tail^ (bq-head q))
+
+ (condition-wait (bq-room q) (bq-mutex q))
+
+ (loop)]
+
+ [else
+
+ (vector-set! (bq-data q) tail item)
+
+ (bq-tail-set! q tail^)
+
+ (condition-signal (bq-ready q))]))))))
+
+
+(define incr
+
+ (lambda (q i)
+
+ (modulo (+ i 1) (vector-length (bq-data q)))))
+
The code below demonstrates the use of the bounded queue abstraction +with a set of threads that act as consumers and producers of the +data in the queue. + +
+ +
(define job-queue)
+
+(define die? #f)
+
+
+(define make-job
+
+ (let ([count 0])
+
+ (define fib
+
+ (lambda (n)
+
+ (if (< n 2)
+
+ n
+
+ (+ (fib (- n 2)) (fib (- n 1))))))
+
+ (lambda (n)
+
+ (set! count (+ count 1))
+
+ (printf "Adding job #~s = (lambda () (fib ~s))\n" count n)
+
+ (cons count (lambda () (fib n))))))
+
+
+(define make-producer
+
+ (lambda (n)
+
+ (rec producer
+
+ (lambda ()
+
+ (printf "producer ~s posting a job\n" n)
+
+ (enqueue! (make-job (+ 20 (random 10))) job-queue)
+
+ (if die?
+
+ (printf "producer ~s dying\n" n)
+
+ (producer))))))
+
+
+(define make-consumer
+
+ (lambda (n)
+
+ (rec consumer
+
+ (lambda ()
+
+ (printf "consumer ~s looking for a job~%" n)
+
+ (let ([job (dequeue! job-queue)])
+
+ (if die?
+
+ (printf "consumer ~s dying\n" n)
+
+ (begin
+
+ (printf "consumer ~s executing job #~s~%" n (car job))
+
+ (printf "consumer ~s computed: ~s~%" n ((cdr job)))
+
+ (consumer))))))))
+
+
+(define (bq-test np nc)
+
+ (set! job-queue (make-bq (max nc np)))
+
+ (do ([np np (- np 1)])
+
+ ((<= np 0))
+
+ (fork-thread (make-producer np)))
+
+ (do ([nc nc (- nc 1)])
+
+ ((<= nc 0))
+
+ (fork-thread (make-consumer nc))))
+
Here are a possible first several lines of output from a sample run of the example program. + +
+ +
> (begin
+
+ (bq-test 3 4)
+
+ (system "sleep 3")
+
+ (set! die? #t))
+
+producer 3 posting a job
+
+Adding job #1 = (lambda () (fib 29))
+
+producer 3 posting a job
+
+Adding job #2 = (lambda () (fib 26))
+
+producer 3 posting a job
+
+Adding job #3 = (lambda () (fib 22))
+
+producer 3 posting a job
+
+Adding job #4 = (lambda () (fib 21))
+
+producer 2 posting a job
+
+Adding job #5 = (lambda () (fib 29))
+
+producer 1 posting a job
+
+Adding job #6 = (lambda () (fib 29))
+
+consumer 4 looking for a job
+
+producer 3 posting a job
+
+Adding job #7 = (lambda () (fib 24))
+
+consumer 4 executing job #1
+
+consumer 3 looking for a job
+
+producer 2 posting a job
+
+Adding job #8 = (lambda () (fib 26))
+
+consumer 3 executing job #2
+
+consumer 3 computed: 121393
+
+consumer 3 looking for a job
+
+producer 1 posting a job
+
+Adding job #9 = (lambda () (fib 26))
+
+...
+
Additional examples, including definitions of suspendable threads and +threads that automatically terminate when they become inaccessible, are +given in "A Scheme for native threads [10]." + + +
+ + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/csug10.0/use.html b/csug10.0/use.html
new file mode 100644
index 000000000..7e79d7ef2
--- /dev/null
+++ b/csug10.0/use.html
@@ -0,0 +1,2061 @@
+
+
+
+
+
+Chez Scheme is often used interactively to support program development +and debugging, yet it may also be used to create stand-alone applications +with no interactive component. +This chapter describes the various ways in which Chez Scheme is +typically used and, more generally, how to get the most out of the +system. +Sections 2.1, 2.2, +and 2.3 describe how +one uses Chez Scheme interactively. +Section 2.4 discusses how libraries and RNRS +top-level programs are used in Chez Scheme. +Section 2.5 covers support for writing and running +Scheme scripts, including compiled scripts and compiled +RNRS top-level programs. +Section 2.6 describes how to structure +and compile an application to get the most efficient code possible out +of the compiler. +Section 2.7 describes how one can customize the +startup process, e.g., to alter or eliminate the command-line options, +to preload Scheme or foreign code, or to run Chez Scheme as a subordinate +program of another program. +Section 2.8 describes how to build applications +using Chez Scheme with Petite Chez Scheme for run-time support. +Finally, Section 2.9 covers command-line options used when +invoking Chez Scheme. + +
+ +
+One of the simplest and most effective ways to write and test Scheme +programs is to compose them using a text editor, like vi or +emacs, and test them interactively with Chez Scheme running in +a shell window. +When Chez Scheme is installed with default options, entering the command +scheme at the shell's prompt starts an interactive Scheme +session. +The command petite does the same for Petite Chez Scheme. +After entering this command, you should see a short greeting followed +by an angle-bracket on a line by itself, like this: + +
+ +
Chez Scheme Version 9.5.1
+
+Copyright 1984-2017 Cisco Systems, Inc.
+
+
+>
+
You also should see that the cursor is sitting one space to the +right of the angle-bracket. +The angle-bracket is a prompt issued by the system's "REPL," +which stands for "Read Eval Print Loop," so called because it +reads, evaluates, and prints an expression, then loops back to +read, evaluate, and print the next, and so on. +(In Chez Scheme, the REPL is also called a waiter.) + +
+In response to the prompt, you can type any Scheme expression. +If the expression is well-formed, the REPL will run the expression +and print the value. +Here are a few examples: + +
+ +
> 3
+
+3
+
+> (+ 3 4)
+
+7
+
+> (cons 'a '(b c d))
+
+(a b c d)
+
The reader used by the REPL is more sophisticated than an ordinary +reader. +In fact, it's a full-blown "expression editor" ("expeditor" for short) +like a regular text editor but for just one expression at a time. +One thing you might soon notice is that the system automatically indents +the second and subsequent lines of an expression. +For example, let's say we want to define fact, a procedure that +implements the factorial function. +If we type (define fact followed by the enter key, the cursor +should be sitting under the first e in define, so that +if we then type (lambda (x), we should see: + +
+ +
> (define fact
+
+ (lambda (x)
+
The expeditor also allows us to move around within the expression +(even across lines) and edit the expression to correct mistakes. +After typing: + +
+ +
> (define fact
+
+ (lambda (x)
+
+ (if (= n 0)
+
+ 0
+
+ (* n (fact
+
we might notice that the procedure's argument is named x +but we have been referencing it as n. +We can move back to the second line using the arrow keys, +remove the offending x with the backspace key, and +replace it with n. + +
+ +
> (define fact
+
+ (lambda (n)
+
+ (if (= n 0)
+
+ 0
+
+ (* n (fact
+
We can then return to the end of the expression with the arrow +keys and complete the definition. + +
+ +
> (define fact
+
+ (lambda (n)
+
+ (if (= n 0)
+
+ 0
+
+ (* n (fact (- n 1))))))
+
Now that we have a complete form with balanced parentheses, +if we hit enter with the cursor just after the final parenthesis, +the expeditor will send it on to the evaluator. +We'll know that it has accepted the definition when we get another +right-angle prompt. + +
+Now we can test our definition by entering, say, (fact 6) +in response to the prompt: + +
+ +
> (fact 6)
+
+0
+
The printed value isn't what we'd hoped for, since 6! is actually 720. +The problem, of course, is that the base-case return-value 0 +should have been 1. +Fortunately, we don't have to retype the definition to correct the +mistake. +Instead, we can use the expeditor's history mechanism to retrieve the +earlier definition. +The up-arrow key moves backward through the history. +In this case, the first up-arrow retrieves (fact 6), and +the second retrieves the fact definition. + +
+As we move back through the history, the expression editor shows us +only the first line, so after two up arrows, this is all we see of +the definition: + +
+ +
> (define fact +
We can force the expeditor to show the entire expression by typing +^L (control L, i.e., the control and L keys +pressed together): + +
+ +
> (define fact
+
+ (lambda (n)
+
+ (if (= n 0)
+
+ 0
+
+ (* n (fact (- n 1))))))
+
Now we can move to the fourth line and change the 0 to a +1. + +
+ +
> (define fact
+
+ (lambda (n)
+
+ (if (= n 0)
+
+ 1
+
+ (* n (fact (- n 1))))))
+
We're now ready to enter the corrected definition. +If the cursor is on the fourth line and we hit enter, however, it will +just open up a new line between the old fourth and fifth lines. +This is useful in other circumstances, but not now. +Of course, we can work around this by using the arrow keys to move +to the end of the expression, but an easier way is to type +^J, which forces the expression to be entered immediately +no matter where the cursor is. + +
+Finally, we can bring back (fact 6) with another two +hits of the up-arrow key and try it again: + +
+ +
> (fact 6)
+
+720
+
To exit from the REPL and return back to the shell, we can type +^D or call the exit procedure. + +
+The interaction described above uses just a few of the expeditor's +features. +The expeditor's remaining features are described in the following +section. + +
+Running programs may be interrupted by typing the interrupt +character (typically ^C). +In response, the +system enters a debug handler, which prompts for input with a +break> prompt. +One of several commands may be issued to the break handler (followed by a +newline), including +
+When an exception other than a warning occurs, the default exception +handler prints a message that describes the exception to the console +error port. +If a REPL is running, the exception handler then returns to the REPL, +where the programmer can call the debug procedure to start up the +debug handler, if desired. +The debug handler is similar to the break handler and allows the +programmer to inspect the continuation (control +stack) of the exception to help determine the cause of the problem. +If no REPL is running, as is the case for a script or top-level program +run via the --script +or --program +command-line options, the default exception handler exits from the script +or program after printing the message. +To allow scripts and top-level programs to be debugged, +the default exception handler can be forced via the +debug-on-exception +parameter or the +--debug-on-exception command-line option +to invoke debug directly. + +
+Developing a large program entirely in the REPL is unmanageable, and we +usually even want to store smaller programs in a file for future use. +(The expeditor's history is saved across Scheme sessions, but there is a +limit on the number of items, so it is not a good idea to count on a +program remaining in the history indefinitely.) +Thus, a Scheme programmer typically creates a file containing Scheme +source code using a text editor, such as vi, and loads the file +into Chez Scheme to test them. +The conventional filename extension for Chez Scheme source files is +".ss," but the file can have any extension or even no extension +at all. +A source file can be loaded during an interactive session by typing +(load "path"). +Files to be loaded can also be named on the command line when the +system is started. +Any form that can be typed interactively can be placed in a file to be loaded. + +
+Chez Scheme compiles source forms as it sees them to machine +code before evaluating them, i.e., "just in time." +In order to speed loading of a large file or group of files, each file +can be compiled ahead of time via +compile-file, which puts the +compiled code into a separate object file. +For example, (compile-file "path") compiles +the forms in the file path.ss and places the +resulting object code in the file path.so. +Loading a pre-compiled file is essentially no different from +loading the source file, except that loading is faster since +compilation has already been done. + +
+When compiling a file or set of files, it is often more convenient to +use a shell command than to enter Chez Scheme interactively to perform +the compilation. +This is easily accomplished by "piping" in the command to compile +the file as shown below. + +
+ +
echo '(compile-file "filename")' | scheme -q +
The -q option suppresses the system's greeting messages for more +compact output, which is especially useful when compiling numerous +files. +The single-quote marks surrounding the compile-file call +should be left off for Windows shells. + +
+When running in this "batch" mode, especially from within "make" +files, it is often desirable to force the default exception handler to exit +immediately to the shell with a nonzero exit status. +This may be accomplished by setting the +reset-handler to +abort. + +
+ +
echo '(reset-handler abort) (compile-file "filename")' | scheme -q +
One can also redefine the +base-exception-handler +(Section 12.1) to achieve a similar effect +while exercising more control over the format of the messages that +are produced. + + +
+ +
+When Chez Scheme is used interactively in a shell window, as described +above, or when new-cafe is invoked explicitly from a top-level +program or script run via --program or --script, the +waiter's "prompt and read" procedure employs an expression editor that +permits entry and editing of single- and multiple-line expressions, +automatically indents expressions as they are entered, supports +identifier completion outside string constants based on the identifiers defined +in the interactive environment, and supports filename completion within +string constants. +The expression editor also maintains a history of expressions typed during +and across sessions and supports tcsh-like history movement and search +commands. +Other editing commands include simple cursor movement via +arrow keys, deletion of characters via backspace and delete, and +movement, deletion, and other commands using mostly +emacs key bindings. + +
+The expression editor does not run if the TERM environment variable is not +set (on Unix-based systems), if the standard input or output files have +been redirected, or if the --eedisable command-line option +(Section 2.9) has been used. +The history is saved across sessions, by default, in the file +".chezscheme_history" in the user's home directory. +The --eehistory command-line option +(Section 2.9) can be used to specify a different +location for the history file or to disable the saving and restoring of +the history file. + +
+Keys for nearly all printing characters (letters, digits, and special +characters) are "self inserting" by default. +The open parenthesis, close parenthesis, open bracket, and close bracket +keys are self inserting as well, but also cause the editor to "flash" +to the matching delimiter, if any. +Furthermore, when a close parenthesis or close bracket is typed, it is +automatically corrected to match the corresponding open delimiter, if any. + +
+Key bindings for other keys and key sequences initially recognized by +the expression editor are given below, organized into groups by function. +Some keys or key sequences serve more than one purpose depending upon +context. +For example, tab is used for identifier completion, filename completion, +and indentation. +Such bindings are shown in each applicable functional group. + +
+Multiple-key sequences are displayed with hyphens between the keys of +the sequences, but these hyphens should not be entered. +When two or more key sequences perform the same operation, the sequences +are shown separated by commas. + +
+Detailed descriptions of the editing commands are given in +Chapter 14, which also describes parameters that allow +control over the expression editor, mechanisms for adding or changing key +bindings, and mechanisms for creating new commands. + + + +
+ + +
+
Newlines, acceptance, exiting, and redisplay: +
+enter, ^M | accept balanced entry if used at end of entry; |
+ | else add a newline before the cursor and indent |
+^J | accept entry unconditionally |
+^O | insert newline after the cursor and indent |
+^D | exit from the waiter if entry is empty; |
+ | else delete character under cursor |
+^Z | suspend to shell if shell supports job control |
+^L | redisplay entry |
+^L-^L | clear screen and redisplay entry + |
+ +
+ Basic movement and deletion: +
+leftarrow, ^B | move cursor left |
+rightarrow, ^F | move cursor right |
+uparrow, ^P | move cursor up; from top of unmodified entry, |
+ | move to preceding history entry. |
+downarrow, ^N | move cursor down; from bottom of unmodified entry, |
+ | move to next history entry |
+^D | delete character under cursor if entry not empty, |
+ | else exit from the waiter |
+backspace, ^H | delete character before cursor |
+delete | delete character under cursor + |
+ +
+ Line movement and deletion: +
+home, ^A | move cursor to beginning of line |
+end, ^E | move cursor to end of line |
+^K, +esc-k | delete to end of line or, if cursor is at the end |
+ | of a line, join with next line |
+^U | delete contents of current line + |
+ +
+When used on the first line of a multiline entry of which only the first line +is displayed, i.e., immediately after history movement, ^U deletes the +contents of the entire entry, like ^G (described below). + +
+ Expression movement and deletion: +
+esc-^F | move cursor to next expression |
+esc-^B | move cursor to preceding expression |
+esc-] | move cursor to matching delimiter |
+^] | flash cursor to matching delimiter |
+esc-^K, +esc-delete | delete next expression |
+esc-backspace, +esc-^H | delete preceding expression + |
+ +
+ Entry movement and deletion: +
+esc-< | move cursor to beginning of entry |
+esc-> | move cursor to end of entry |
+^G | delete current entry contents |
+^C | delete current entry contents; reset to end of history + |
+ +
+ Indentation: +
+tab | re-indent current line if identifier/filename prefix |
+ | not just entered; else insert completion |
+esc-tab | re-indent current line unconditionally |
+esc-q, + esc-Q, + esc-^Q | re-indent each line of entry + |
+ +
+ Identifier/filename completion: +
+tab | insert completion if identifier/filename prefix just |
+ | entered; else re-indent current line |
+tab-tab | show possible identifier/filename completions at end |
+ | of identifier/filename just typed, else re-indent |
+^R | insert next identifier/filename completion + |
+ +
+Identifier completion is performed outside of a string constant, and filename +completion is performed within a string constant. +(In determining whether the cursor is within a string constant, the +expression editor looks only at the current line and so can be fooled +by string constants that span multiple lines.) +If at end of existing identifier or filename, i.e., not one just typed, the first tab +re-indents, the second tab inserts identifier completion, and the third +shows possible completions. + +
+ History movement: +
+uparrow, ^P | move to preceding entry if at top of unmodified |
+ | entry; else move up within entry |
+downarrow, ^N | move to next entry if at bottom of unmodified |
+ | entry; else move down within entry |
+esc-uparrow, + esc-^P | move to preceding entry from unmodified entry |
+esc-downarrow, + esc-^N | move to next entry from unmodified entry |
+esc-p | search backward through history for given prefix |
+esc-n | search forward through history for given prefix |
+esc-P | search backward through history for given string |
+esc-N | search forward through history for given string + |
+ +
+To search, enter a prefix or string followed by one of the search key +sequences. +Follow with additional search key sequences to search further backward or +forward in the history. +For example, enter "(define" followed by one or more esc-p key sequences +to search backward for entries that are definitions, or "(define" +followed by one or more esc-P key sequences for entries that contain +definitions. + +
+ Word and page movement: +
+esc-f, + esc-F | move cursor to end of next word |
+esc-b, + esc-B | move cursor to start of preceding word |
+^X-[ | move cursor up one screen page |
+^X-] | move cursor down one screen page + |
+ +
+ Inserting saved text: +
+^Y | insert most recently deleted text |
+^V | insert contents of window selection/paste buffer + |
+ +
+ Mark operations: +
+^@, + ^space, + ^^ | set mark to current cursor position |
+^X-^X | move cursor to mark, leave mark at old cursor position |
+^W | delete between current cursor position and mark + |
+ +
+ Command repetition: +
+esc-^U | repeat next command four times |
+esc-^U-n | repeat next command n times + |
+ + +
+ +
+In the language of the Revised6 Report, code is structured into +libraries and "top-level programs." +The Revised6 Report does not require an implementation to support +interactive use, and it does not specify how an interactive top level +should operate, leaving such details up to the implementation. + +
+In Chez Scheme, when one enters definitions or expressions at the +prompt or loads them from a file, they operate on an +interaction environment, which is a mutable environment that initially +holds bindings only for built-in keywords and primitives. +It may be augmented by user-defined identifier bindings via top-level +definitions. +The interaction environment is also referred to as the top-level +environment, because it is at the top level for purposes of scoping. +Programs entered at the prompt or loaded from a file via load +should not be confused with RNRS top-level programs, which are +actually more similar to libraries in their behavior. +In particular, while the same identifier can be defined multiple times +in the interaction environment, to support incremental program +development, an identifier can be defined at most once in an RNRS +top-level program. + +
+The default interaction environment used for any code that occurs outside +of an RNRS top-level program or library (including such code typed at +a prompt or loaded from a file) contains all of the bindings of the +(chezscheme) library (or scheme module, which exports the +same set of bindings). +This set contains a number of bindings that are not in the RNRS libraries. +It also contains a number of bindings that extend the RNRS counterparts in +some way and are thus not strictly compatible with the RNRS bindings for +the same identifiers. +To replace these with bindings strictly compatible with RNRS, simply +import the rnrs libraries into the interaction environment by +typing the following into the REPL or loading it from a file: + +
+ +
(import
+
+ (rnrs)
+
+ (rnrs eval)
+
+ (rnrs mutable-pairs)
+
+ (rnrs mutable-strings)
+
+ (rnrs r5rs))
+
To obtain an interaction environment that contains all and only +RNRS bindings, use the following. + +
+ +
(interaction-environment
+
+ (copy-environment
+
+ (environment
+
+ '(rnrs)
+
+ '(rnrs eval)
+
+ '(rnrs mutable-pairs)
+
+ '(rnrs mutable-strings)
+
+ '(rnrs r5rs))
+
+ #t))
+
To be useful for most purposes, library and import +should probably also be included, from the (chezscheme) library. + +
+ +
(interaction-environment
+
+ (copy-environment
+
+ (environment
+
+ '(rnrs)
+
+ '(rnrs eval)
+
+ '(rnrs mutable-pairs)
+
+ '(rnrs mutable-strings)
+
+ '(rnrs r5rs)
+
+ '(only (chezscheme) library import))
+
+ #t))
+
It might also be useful to include debug in the set of +identifiers imported from (chezscheme) to allow the debugger to be +entered after an exception is raised. + +
+Most of the identifiers bound in the default interaction environment that +are not strictly compatible with the Revised6 Report are variables bound to +procedures with extended interfaces, i.e., optional arguments or extended +argument domains. +The others are keywords bound to transformers that extend the Revised6 +Report syntax in some way. +This should not be a problem except for programs that count on +exceptions being raised in cases that coincide with the extensions. +For example, if a program passes the = procedure a single numeric +argument and expects an exception to be raised, it will fail in the +initial interaction environment because = returns #t +when passed a single numeric argument. + +
+Within the default interaction environment and those created as described +above, variables that name built-in procedures are read-only, i.e., +cannot be assigned, since they resolve to the read-only bindings exported +from the (chezscheme) library or some other library: + +
+ +
(set! cons +) exception: cons is immutable +
Before assigning a variable bound to the name of a built-in +procedure, the programmer must first define the variable. +For example, + +
+ +
(define cons-count 0)
+
+(define original-cons cons)
+
+(define cons
+
+ (lambda (x y)
+
+ (set! cons-count (+ cons-count 1))
+
+ (original-cons x y)))
+
redefines cons to count the number of times it is called, and + +
+ +
(set! cons original-cons) +
assigns cons to its original value. +Once a variable has been defined in the interaction environment using +define, a subsequent definition of the same variable is equivalent +to a set!, so + +
+ +
(define cons original-cons) +
has the same effect as the set! above. +The expression + +
+ +
(import (only (chezscheme) cons)) +
also binds cons to its original value. +It also returns it to its original read-only state. + +
+The simpler redefinition + +
+ +
(define cons (let () (import scheme) cons)) +
turns cons into a mutable variable with the same value as it +originally had. +Doing so, however, prevents the compiler from generating efficient code +for calls to cons or producing warning messages when +cons is passed the wrong number of arguments. + +
+All identifiers not bound in the initial interaction environment and +not defined by the programmer are treated as "potentially bound" as +variables to facilitate the definition of mutually recursive +procedures. +For example, assuming that yin and yang have not +been defined, + +
+ +
(define yin (lambda () (- (yang) 1))) +
defines yin at top level as a variable bound to a procedure that calls +the value of the top-level variable yang, even though yang +has not yet been defined. +If this is followed by + +
+ +
(define yang (lambda () (+ (yin) 1))) +
the result is a mutually recursive pair of procedures that, when called, +will loop indefinitely or until the system runs out of space to hold the +recursion stack. +If yang must be defined as anything other than a variable, its +definition should precede the definition of yin, since the compiler +assumes yang is a variable in the absence of any indication to +the contrary when yang has not yet been defined. + +
+A subtle consequence of this useful quirk of the interaction environment is that +the procedure +free-identifier=? (Section 8.3 of The Scheme Programming Language, 4th Edition) +does not consider unbound library identifiers to be equivalent to (as yet) +undefined top-level identifiers, even if they have the +same name, because the latter are actually assumed to be valid variable bindings. + +
+ +
(library (A) (export a)
+
+ (import (rnrs))
+
+ (define-syntax a
+
+ (lambda (x)
+
+ (syntax-case x ()
+
+ [(_ id) (free-identifier=? #'id #'undefined)]))))
+
+(let () (import (A)) (a undefined)) #f
+
If it is necessary that they have the same binding, as in the case where +an identifier is used as an auxiliary keyword in a syntactic abstraction +exported from a library and used at top level, the library should define +and export a binding for the identifier. + +
+ +
(library (A) (export a aux-a)
+
+ (import (rnrs) (only (chezscheme) syntax-error))
+
+ (define-syntax aux-a
+
+ (lambda (x)
+
+ (syntax-error x "invalid context")))
+
+ (define-syntax a
+
+ (lambda (x)
+
+ (syntax-case x (aux-a)
+
+ [(_ aux-a) #''okay]
+
+ [(_ _) #''oops]))))
+
+(let () (import (A)) (a aux-a)) okay
+
+(let () (import (only (A) a)) (a aux-a)) oops
+
This issue does not arise when libraries are used entirely within other +libraries or within RNRS top-level programs, since the interaction +environment does not come into play. + + +
+ +
+An R6RS library can be defined directly in the REPL, loaded explicitly +from a file (using load or load-library), or loaded +implicitly from a file via import. +When defined directly in the REPL or loaded explicitly from a file, a +library form can be used to redefine an existing library, but +import never reloads a library once it has been defined. + +
+A library to be loaded implicitly via import +must reside in a file whose name reflects the name of the library. +For example, if the library's name is (tools sorting), the +base name of the file must be sorting with a valid extension, and +the file must be in a directory named tools which itself resides +in one of the directories searched by import. +The set of directories searched by import is determined by +the +library-directories +parameter, and the set of +extensions is determined by the +library-extensions +parameter. + +
+The values of both parameters are lists of pairs of strings. +The first string in each library-directories pair identifies a +source-file base directory, and the second identifies the corresponding +object-file base directory. +Similarly, the first string in each library-extensions pair +identifies a source-file extension, and the second identifies the +corresponding object-file extension. +The full path of a library source or object file consists of the source or +object base followed by the components of the library name, separated by +slashes, with the library extension added on the end. +For example, for base /usr/lib/scheme, library name +(app lib1), and extension .sls, the full path is +/usr/lib/scheme/app/lib1.sls. +So, if (library-directories) contains the pathnames +"/usr/lib/scheme/libraries" and ".", and +(library-extensions) contains the extensions .ss +and .sls, the path of the (tools sorting) +library must be one of the following. + +
+ +
/usr/lib/scheme/libraries/tools/sorting.ss
+
+/usr/lib/scheme/libraries/tools/sorting.sls
+
+./tools/sorting.ss
+
+./tools/sorting.sls
+
When searching for a library, import first constructs a partial +name from the list of components in the library name, e.g., a/b +for library (a b). +It then searches for the partial name in each pair +of base directories, in order, trying each of the source extensions then +each of the object extensions in turn before moving onto the next pair of +base directories. +If the partial name is an absolute pathname, e.g., ~/.myappinit +for a library named (~/.myappinit), only the specified absolute +path is searched, first with each source extension, then with each object +extension. +If the expander finds both a source file and its corresponding object +file, and the object file is not older than the source file, the +expander loads the object file. +If the object file does not exist, if the object file is older, or +if after loading the object file, the expander determines it was +built using a library or include file that has changed, the source +file is loaded or compiled, depending on the value of the parameter +compile-imported-libraries. +If compile-imported-libraries +is set to #t, the expander +compiles the library via the value of the compile-library-handler +parameter, which by default calls compile-library (which is described below). +Otherwise, the expander loads the source file. +(Loading the source file actually causes the code to be compiled, +assuming the default value of current-eval, but the compiled +code is not saved to an object file.) +The library-timestamp-mode parameter controls the meaning of "older" +for comparing library sources and object files. +An exception is raised during this process if a +source or object file exists but is not readable or if an object +file cannot be created. + +
+The search process used by the expander when processing an import +for a library that has not yet been loaded can be monitored by +setting the parameter import-notify to #t. +This parameter can be set from the command line via the +--import-notify command-line option. + +
+Whenever the expander determines it must compile a library to a file or +load one from source, it adds the directory in which the file resides to +the front of the +source-directories +list while compiling or loading the library. +This allows a library to include files stored in or relative to its +own directory. + +
+When import compiles a library as described above, it does not +also load the compiled library, because this would cause portions of +library to be reevaluated. +Because of this, run-time expressions in the file outside of a +library form will not be evaluated. +If such expressions are present and should be evaluated, the library +should be compiled ahead of time or loaded explicitly. + +
+A file containing a library may be compiled with compile-file +or compile-library. +The only difference between the two is that the latter treats the source +file as if it were prefixed by an implicit #!r6rs, which +disables Chez Scheme lexical extensions unless an explicit +#!chezscheme marker appears in the file. +Any libraries upon which the library depends must be compiled first. +If one of the libraries imported by the library is subsequently +recompiled (say because it was modified), the importing library must also +be recompiled. +Compilation and recompilation of imported libraries must be done +explicitly by default but is done automatically when the parameter +compile-imported-libraries is set to #t before +compiling the importing library. + +
+As with compile-file, compile-library can be used +in "batch" mode via a shell command: + +
+ +
echo '(compile-library "filename")' | scheme -q +
with single-quote marks surrounding the compile-library call +omitted for Windows shells. + +
+An RNRS top-level-program usually resides in a file, but one can also +enter one directly into the REPL using the top-level-program +forms, e.g.: + +
+ +
(top-level-program
+
+ (import (rnrs))
+
+ (display "What's up?\n"))
+
A top-level program stored in a file does not have the top-level-program +wrapper, so the same top-level program in a file is just: + +
+ +
(import (rnrs))
+
+(display "What's up?\n")
+
A top-level program stored in a file can be loaded from the file via the +load-program procedure. +A top-level program can also be loaded via load, but not without +affecting the semantics. +A program loaded via load is scoped at top level, where it can +see all top-level bindings, whereas a top-level program loaded via +load-program is self-contained, i.e., it can see only the +bindings made visible by the leading import form. +Also, the variable bindings in a program loaded via load also +become top-level bindings, whereas they are local to the program when +the program is loaded via load-program. +Moreover, load-program, like load-library, treats the +source file as if it were prefixed by an implicit #!r6rs, which +disables Chez Scheme lexical extensions unless an explicit +#!chezscheme marker appears in the file. +A program loaded via load is also likely to be less efficient. +Since the program's variables are not local to the program, the compiler +must assume they could change at any time, which inhibits many of its +optimizations. + +
+Top-level programs may be compiled using +compile-program, which is like +compile-file but, as with load-program, properly +implements the semantics and lexical restrictions of top-level programs. +compile-program also copies the leading #! line, +if any, from the source file to the object file, resulting in an +executable object file. +Any libraries upon which the top-level program depends, other than +built-in libraries, must be compiled first. +The program must be recompiled if any of the libraries upon which +it depends are recompiled. +Compilation and recompilation of imported libraries must be done +explicitly by default but is done automatically when the parameter +compile-imported-libraries is set to #t before +compiling the importing library. + +
+As with compile-file and compile-library, +compile-program can be used in "batch" mode via a shell +command: + +
+ +
echo '(compile-program "filename")' | scheme -q +
with single-quote marks surrounding the compile-program call +omitted for Windows shells. + +
+compile-program returns a list of libraries directly invoked by +the compiled top-level program. +When combined with the +library-requirements and +library-object-filename +procedures, the list of libraries returned by compile-program can +be used to determine the set of files that must be distributed with the +compiled program file. + +
+When run, a compiled program automatically loads the run-time code for +each library upon which it depends, as if via revisit. +If the program also imports one of the same libraries at run time, e.g., +via the environment procedure, the system will attempt to load +the compile-time information from the same file. +The compile-time information can also be loaded explicitly from the +same or a different file via load or visit. + +
+ +
+When the --script command-line option is present, the named file is +treated as a Scheme shell script, and the command-line is made +available via the parameter +command-line. +This is primarily useful on Unix-based systems, where the script file +itself may be made executable. +To support executable shell scripts, the system ignores the first +line of a loaded script if it begins with #! followed by +a space or forward slash. +For example, assuming that the Chez Scheme executable has been +installed as /usr/bin/scheme, the following script prints its command-line +arguments. + +
+ +
#! /usr/bin/scheme --script
+
+(for-each
+
+ (lambda (x) (display x) (newline))
+
+ (cdr (command-line)))
+
The following script implements the traditional Unix echo +command. + +
+ +
#! /usr/bin/scheme --script
+
+(let ([args (cdr (command-line))])
+
+ (unless (null? args)
+
+ (let-values ([(newline? args)
+
+ (if (equal? (car args) "-n")
+
+ (values #f (cdr args))
+
+ (values #t args))])
+
+ (do ([args args (cdr args)] [sep "" " "])
+
+ ((null? args))
+
+ (printf "~a~a" sep (car args)))
+
+ (when newline? (newline)))))
+
Scripts may be compiled using compile-script, which is like +compile-file but differs in that it +copies the leading #! line from the source-file script +into the object file. + +
+If Petite Chez Scheme is installed, but not Chez Scheme, +/usr/bin/scheme may be +replaced with /usr/bin/petite. + +
+The --program command-line option is like --script +except that the script file is treated as an RNRS top-level program +(Chapter 10). +The following RNRS top-level program implements the traditional Unix +echo command, as with the script above. + +
+ +
#! /usr/bin/scheme --program
+
+(import (rnrs))
+
+(let ([args (cdr (command-line))])
+
+ (unless (null? args)
+
+ (let-values ([(newline? args)
+
+ (if (equal? (car args) "-n")
+
+ (values #f (cdr args))
+
+ (values #t args))])
+
+ (do ([args args (cdr args)] [sep "" " "])
+
+ ((null? args))
+
+ (display sep)
+
+ (display (car args)))
+
+ (when newline? (newline)))))
+
Again, if only Petite Chez Scheme is installed, /usr/bin/scheme +may be replaced with /usr/bin/petite. + +
+scheme-script may be used in place of scheme --program +or petite --program, i.e., + +
+ +
#! /usr/bin/scheme-script +
scheme-script runs Chez Scheme, if available, +otherwise Petite Chez Scheme. + +
+It is also possible to use /usr/bin/env, as recommended in the +Revised6 Report nonnormative appendices, which allows +scheme-script to appear anywhere in the user's path. + +
+ +
#! /usr/bin/env scheme-script +
If a top-level program depends on libraries other than those built into +Chez Scheme, the --libdirs option can be used to specify +which source and object directories to search. +Similarly, if a library upon which a top-level program depends has an +extension other than one of the standard extensions, the +--libexts option can be used to specify additional extensions +to search. + +
+These options set the corresponding Chez Scheme parameters +library-directories and library-extensions, +which are described in Section 2.4. +The format of the arguments to --libdirs and +--libexts is the same: +a sequence of substrings separated by a single separator +character. +The separator character is a colon (:), except under Windows where it is a +semi-colon (;). +Between single separators, the source and object strings, if both are +specified, are separated by two separator characters. +If a single separator character appears at the end of the string, +the specified pairs are added to the front of the existing list; +otherwise, the specified pairs replace the existing list. + +
+For example, where the separator is a colon, + +
+ +
scheme --libdirs "/home/moi/lib:" +
adds the source/object directory pair + +
+ +
("/home/moi/lib" . "/home/moi/lib") +
to the front of the default set of library directories, and + +
+ +
scheme --libdirs "/home/moi/libsrc::/home/moi/libobj:" +
adds the source/object directory pair + +
+ +
("/home/moi/libsrc" . "/home/moi/libobj") +
to the front of the default set of library directories. +The parameters are set after all boot files have been loaded. + +
+If no --libdirs option appears and the CHEZSCHEMELIBDIRS +environment variable is set, the string value of CHEZSCHEMELIBDIRS is +treated as if it were specified by a --libdirs option. +Similarly, if no --libexts option appears and the CHEZSCHEMELIBEXTS +environment variable is set, the string value of CHEZSCHEMELIBEXTS is +treated as if it were specified by a --libexts option. + + +
+ +
+To get the most out of the Chez Scheme compiler, it is necessary to +give it a little bit of help. +The most important assistance is to avoid the use of top-level +(interaction-environment) bindings. +Top-level bindings are convenient and appropriate during program +development, since they simplify testing, redefinition, and tracing +(Section 3.1) of individual procedures and +syntactic forms. +This convenience comes at a sizable price, however. + +
+The compiler can propagate copies (of one variable to another or of +a constant to a variable) and inline procedures bound to local, +unassigned variables within a single top-level expression. +For the procedures it does not inline, it can avoid constructing and +passing unneeded closures, bypass argument-count checks, branch to the +proper entry point in a case-lambda, and build rest arguments (more +efficiently) on the caller side, where the length of the rest list is +known at compile time. +It can also discard the definitions of unreferenced variables, so there's +no penalty for including a large library of routines, only a few of +which are actually used. + +
+It cannot do any of this with top-level variable bindings, since the +top-level bindings can change at any time and new references to those +bindings can be introduced at any time. + +
+Fortunately, it is easy to restructure a program to avoid top-level +bindings. +This is naturally accomplished for portable code by placing the +code into a single RNRS top-level program or by placing a portion +of the code in a top-level program and the remainder in one or +more separate libraries. +Although not portable, one can also put all of the code into a +single top-level module form or let expression, +perhaps using include to bring in portions of the +code from separate files. +The compiler performs some optimization even across library +boundaries, so the penalty for breaking a program up in this +manner is generally acceptable. +The compiler also supports whole-program optimization (via +compile-whole-program), which can be used to eliminate all +overhead for placing portions of a program into separate libraries. + +
+Once an application's code has been placed into a single top-level program or into +a top-level program and one or more libraries, the code can be loaded +from source via load-program or compiled via +compile-program +and +compile-library, +as described in Section 2.4. +Be sure not to use compile-file for the top-level program +since this does not preserve the semantics nor result in code that +is as efficient. + +
+With an application structured as a single top-level program or as a +top-level program and one or more libraries that do not interact +frequently, we have done most of what can be done to help the compiler, +but there are still a few more things we can do. + +
+First, we can allow the compiler to generate "unsafe" code, i.e., +allow the compiler to generate code in which the usual run-time type +checks have been disabled. +We do this by using the compiler's "optimize level 3" when compiling +the program and library files. +This can be accomplished by setting the parameter optimize-level +to 3 while compiling the library or +program, e.g.: + +
+ +
(parameterize ([optimize-level 3]) (compile-program "filename")) +
or in batch mode via the --optimize-level command-line option: + +
+ +
echo '(compile-program "filename")' | scheme -q --optimize-level 3 +
It may also be useful to experiment with some of the other compiler +control parameters and also with the storage manager's run-time +operation. +The compiler-control parameters, including optimize-level, are +described in Section 12.6, and the storage manager +control parameters are described in Section 13.1. + +
+Finally, it is often useful to "profile" your code to determine that +parts of the code that are executed most frequently. +While this may help the system optimize your code, the primary +benefit is to help +you identify "hot spots" where you need to concentrate your own +hand-optimization efforts. +In these hot spots, consider using more efficient operators, like +fixnum or flonum operators in place of generic arithmetic operators, +and using explicit loops rather than nested combinations of +linear list-processing operators like append, reverse, +and map. +These operators can make code more readable when used judiciously, +but they can slow down time-critical code. + +
+Section 12.7 describes how to use the compiler's support +for automatic profiling and profile-directed optimization. +Be sure that profiling is not enabled when you compile your production +code, since the code introduced into the generated code to perform the +profiling adds significant run-time overhead. + +
+ +
+Chez Scheme and Petite Chez Scheme are built from several +subsystems: a "kernel" encapsulated in a static or shared +library (dynamic link library) that contains operating-system +interface and low-level storage management code, +an executable that parses command-line arguments and calls +into the kernel to initialize and run the system, a base +boot file (petite.boot) that contains the bulk of the run-time library code, +and an additional boot file (scheme.boot), for Chez Scheme only, +that contains the compiler. + +
+While the kernel and base boot file are essential to the +operation of all programs, the executable may be replaced or +even eliminated, and the compiler boot file need be loaded only +if the compiler is actually used. +In fact, the compiler is typically not loaded for distributed +applications unless the application creates and executes code at run time. + +
+The kernel exports a set of entry points that are used to initialize +the Scheme system, load boot or heap files, run an interactive Scheme +session, run script files, and deinitialize the system. +In the threaded versions of the system, the kernel also exports +entry points for activating, deactivating, and destroying threads. +These entry points may be used to create your own executable image +that has different (or no) command-line options or to run Scheme +as a subordinate program within another program, i.e., for use as +an extension language. + +
+These entry points are described in Section 4.9, +along with other entry points for accessing and modifying Scheme +data structures and calling Scheme procedures. + +
+The file main.c in the 'c' subdirectory contains the +"main" routine for the distributed executable image; look at +this file to gain an understanding of how the system startup +entry points are used. + +
+ +
+Although useful as a stand-alone Scheme system, +Petite Chez Scheme was conceived as a run-time system for compiled +Chez Scheme applications. +The remainder of +this section describes how to create and distribute such applications +using Petite Chez Scheme. +It begins with a discussion of the characteristics of +Petite Chez Scheme and how it compares with Chez Scheme, +then describes how to prepare application source code, +how to build and run applications, and how to distribute them. + +
+
Petite Chez Scheme Characteristics. Although interpreter-based, Petite Chez Scheme evaluates Scheme source +code faster than might be expected. +Some of the reasons for this are listed below. + +
+
+
+
+ +
+Nevertheless, compiled code is still more efficient for most +applications. +The difference between the speed of interpreted and compiled code +varies significantly from one application to another, but often amounts +to a factor of five and sometimes to a factor of ten or more. + +
+Several additional limitations result from the fact that +Petite Chez Scheme does not include the compiler: + +
+
+
+
+
+
+ +
+Except as noted above, Petite Chez Scheme does not restrict what +programs can do, and like Chez Scheme, it places essentially no +limits on the size of programs or the memory images they create, +beyond the inherent limitations of the underlying hardware or +operating system. + +
+
Compiled scripts and programs. One simple mechanism for distributing an application is to structure it as +a script or RNRS top-level program, use +compile-script or +compile-program, as appropriate +to compile it as described in Section 2.5, and +distribute the resulting object file along with a complete distribution of +Petite Chez Scheme. +When this mechanism is used on Unix-based systems, if the source file +begins with #! and the path that follows is the path to the +Chez Scheme executable, e.g., /usr/bin/scheme, the one at the +front of the object file should be replaced with the path to the +Petite Chez Scheme executable, e.g., /usr/bin/petite. +The path may have to be adjusted by the application's installation +program based on where Petite Chez Scheme is installed on the target +system. +When used under Windows, the application's installation program should +set up an appropriate shortcut that starts Petite Chez Scheme with the +--script or --program option, as appropriate, followed +by the path to the object file. + +
+The remainder of this section describes how to distribute applications +that do not require Petite Chez Scheme to be installed as a stand-alone +system on the target machine. + +
+
Preparing Application Code. While it is possible to distribute applications in source-code form, +i.e., as a set of Scheme source files to be loaded into Petite Chez Scheme +by the end user, distributing compiled code has two major +advantages over distributing source code. +First, compiled code is usually much more efficient, as discussed in +the preceding section, and second, compiled code is in binary form and +thus provides more protection for proprietary application code. + +
+Application source code generally consists of a set of Scheme source +files possibly augmented by foreign code developed specifically for the +application and packaged in shared libraries (also known as shared +objects or, on Windows, dynamic link libraries). +The following assumes that any shared-library source code has been +converted into object form; how to do this varies by platform. +(Some hints are given in Section 4.7.) +The result is a set of one or more shared libraries that are loaded +explicitly by the Scheme source code during program initialization. + +
+Once the shared libraries have been created, the next step is to +compile the Scheme source files into a set of Scheme object files. +Doing so typically involves simply invoking compile-file, +compile-library, +or +compile-program, +as appropriate, +on each source file to produce the corresponding object file. +This may be done within a build script or "make" file via a +command line such as the following: + +
+ +
echo '(compile-file "filename")' | scheme +
which produces the object file filename.so from the source +file filename.ss. + +
+If the application code has been developed interactively or is usually +loaded directly from source, +it may be necessary to make some adjustments to a file to be +compiled if the file contains expressions or definitions that +affect the compilation of subsequent forms in the file. +This can be accomplished via eval-when +(Section 12.4). +This is not typically necessary or desirable if the application consists +of a set of RNRS libraries and programs. + +
+You may also wish to disable generation of inspector information +both to reduce the size of the compiled application code and to +prevent others from having access to the expanded source code that +is retained as part of the inspector information. +To do so, set the parameter +generate-inspector-information +to #f while compiling each file +The downside of disabling inspector information is that the information +will not be present if you need to debug your application, so it is +usually desirable to disable inspector information only for production +builds of your application. +An alternative is to compile the code with inspector information enabled +and strip out the debugging information later with +strip-fasl-file. + +
+The Scheme startup procedure determines what the system does when +it is started. +The default startup procedure loads the files listed on the command +line (via load) and starts up a new café, like this. + +
+ +
(lambda fns (for-each load fns) (new-cafe)) +
The startup procedure may be changed via the parameter +scheme-start. +The following example demonstrates the installation of a variant of the +default startup procedure that prints the name of each file before +loading it. + +
+ +
(scheme-start
+
+ (lambda fns
+
+ (for-each
+
+ (lambda (fn)
+
+ (printf "loading ~a ..." fn)
+
+ (load fn)
+
+ (printf "~%"))
+
+ fns)
+
+ (new-cafe)))
+
A typical application startup procedure would first invoke the +application's initialization procedure(s) and then start the +application itself: + +
+ +
(scheme-start
+
+ (lambda fns
+
+ (initialize-application)
+
+ (start-application fns)))
+
Any shared libraries that must be present during the running of an +application must be loaded during initialization. +In addition, all foreign procedure expressions must be executed +after the shared libraries are loaded so that the addresses +of foreign routines are available to be recorded with the resulting foreign +procedures. +The following demonstrates one way in which initialization might be +accomplished for an application that links to a foreign procedure +show_state in the Windows shared library state.dll: + +
+ +
(define show-state)
+
+
+(define app-init
+
+ (lambda ()
+
+ (load-shared-object "state.dll")
+
+ (set! show-state
+
+ (foreign-procedure "show_state" (integer-32)
+
+ integer-32))))
+
+
+
+(scheme-start
+
+ (lambda fns
+
+ (app-init)
+
+ (app-run fns)))
+
Building and Running the Application. Building and running an application is straightforward once all shared +libraries have been built and Scheme source files have been compiled +to object code. + +
+Although not strictly necessary, we suggest that you concatenate your +object files, if you have more than one, into a single object file +via the concatenate-object-files procedure. +Placing all of the object code into a single file +simplifies both building and distribution of applications. + +
+For top-level programs with separate libraries, +compile-whole-program +can be used to produce a single, fully optimized object file. +Otherwise, when concatenating object files, put each library after the +libraries it depends upon, with the program last. + +
+With the Scheme object code contained within a single composite object file, +it is possible to run the application simply by loading the composite +object file into Petite Chez Scheme, e.g.: + +
+ +
petite app.so +
where app.so is the name of the composite object file, +and invoking the startup procedure to restart the system: + +
+ +
> ((scheme-start)) +
The point of setting scheme-start, however, is to allow the +set of object files to be converted into a +boot file. +Boot files are loaded during the process of building the initial heap. +Because of this, boot files have the following advantages over ordinary +object files. + +
+
+
+ +
+When an application is packaged into a boot file, the source code +that is compiled and converted into a boot file should set +scheme-start to a procedure that starts the application, +as shown in the example above. +The application should not be started directly from the boot file, +because boot files are loaded before final initialization of the +Scheme system. +The value of scheme-start is invoked automatically after +final initialization. + +
+A boot file is simply an object file containing the code for +one or more source files, prefixed by a boot header. +The boot header identifies a base boot file upon which the application +directly depends, or possibly two or more alternatives upon which the +application can be run. +In most cases, petite.boot will be identified as the base boot +file, but in a layered application it may be another boot file of your +creation that in turn depends upon petite.boot. +The base boot file, and its base boot file, if any, are loaded +automatically when your application boot file is loaded. + +
+Boot files are created with make-boot-file. +This procedure accepts two or more arguments. +The first is a string naming the file into which the boot header and +object code should be placed, the second is a list of strings naming base +boot files, and the remainder are strings naming input files. +For example, the call: + +
+ +
(make-boot-file "app.boot" '("petite") "app1.so" "app2.ss" "app3.so") +
creates the boot file app.boot that identifies a dependency upon petite.boot +and contains the object code for app1.so, the object code resulting from +compiling app2.ss, and the object code for app3.so. +The call: + +
+ +
(make-boot-file "app.boot" '("scheme" "petite") "app.so") +
creates a header file that identifies a dependency upon either +scheme.boot or petite.boot, with the object code from app.so. +In the former case, the system will automatically load petite.boot +when the application boot file is loaded, and in the latter it will +load scheme.boot if it can find it, otherwise petite.boot. +This would allow your application to run on top of the full +Chez Scheme if present, otherwise Petite Chez Scheme. + +
+In most cases, you can construct your application +so it does not depend upon features of scheme.boot (specifically, +the compiler) by specifying only "petite" in the call to +make-boot-file. +If your application calls eval, however, and you wish to +allow users to be able to take +advantage of the faster execution speed of compiled code, then specifying +both "scheme" and "petite" +is appropriate. + +
+Here is how we might create and run a simple "echo" application +from a Linux shell: + +
+ +
echo '(suppress-greeting #t)' > myecho.ss
+
+echo '(scheme-start (lambda fns (printf "~{~a~^ ~}\n" fns)))' >> myecho.ss
+
+echo '(compile-file "myecho.ss") \
+
+ (make-boot-file "myecho.boot" (quote ("petite")) "myecho.so")' \
+
+ | scheme -q
+
+scheme -b myecho.boot hello world
+
If we take the extra step of installing a copy of the Petite Chez Scheme +executable as myecho and copying myecho.boot into +the same directory as petite.boot (or set SCHEMEHEAPDIRS to +include the directory containing myecho.boot), we can simply invoke +myecho to run our echo application: + +
+ +
myecho hello world +
Distributing the Application. Distributing an application can be as simple as creating a +distribution package that includes the following items: + +
+
+ +
+The application installation script should install Petite Chez Scheme +if not already installed on the target system. +It should install the application boot file in the same directory as +the Petite Chez Scheme boot file petite.boot is installed, +and it should install the application shared libraries, if any, +either in the same location or in a standard location for shared libraries +on the target system. +It should also create a link to or copy of the Petite Chez Scheme +executable under the name of your application, i.e., the name given +to your application boot file. +Where appropriate, it should also install desktop and start-menu +shortcuts to run the executable. + +
+ +
+Chez Scheme recognizes the following command-line options. + +
+
+-q, --quiet + | suppress greeting and prompt |
+--script path + | run as shell script |
+--program path + | run rnrs top-level program as shell script |
+--libdirs dir:... + | set library directories |
+--libexts ext:... + | set library extensions |
+--compile-imported-libraries + | compile libraries before loading |
+--disable-library-timestamps + | do not check modification dates on library sources |
+--import-notify + | enable import search messages |
+--optimize-level 0 | 1 | 2 | 3 + | set initial optimize level |
+--debug-on-exception + | on uncaught exception, call debug |
+--eedisable + | disable expression editor |
+--eehistory off | path + | expression-editor history file |
+--enable-object-counts + | have collector maintain object counts |
+--retain-static-relocation + | keep reloc info for compute-size, etc. |
+-b path, --boot path + | load boot file |
+-B path, --Boot path + | load boot file relative to the current directory |
+--verbose + | trace boot-file search process |
+--version + | print version and exit |
+--help + | print help and exit |
+-- + | pass through remaining args |
+ |
+The following options are recognized but cause the system to print an +error message and exit because saved heaps are no longer supported. + +
+
+-h path, --heap path + | load heap file |
+-s[n] path, --saveheap[n] path + | save heap file |
+-c, --compact + | toggle compaction flag |
+ |
+With the default scheme-start procedure (Section 2.8), +any remaining command-line arguments are treated as the names of files +to be loaded before Chez Scheme begins interacting with the user, unless +the --script or --program is present, in which case the +remaining arguments are made available to the script via the command-line +parameter (Section 2.1). + +
+Most of the options are described elsewhere in this chapter, and a few +are self-explanatory. +The remainder pertain to the loading of boot files at system start-up +time and are described below. + +
+When Chez Scheme is run, it looks for one or more boot files +to load. +Boot files contain the compiled Scheme code that implements most of +the Scheme system, including the interpreter, compiler, and most +libraries. +Boot +files may be specified explicitly on the command +line via -b (relative to installation directory unless absolute or +starting with a . or .. path element) or -B +(relative to current directory unless absolute) options or implicitly. +In the simplest case, no -b +options +are given and the necessary boot +files are loaded +automatically based on the name of the executable. + +
+For example, if the executable name is "frob", the +system looks for +"frob.boot" in a set of standard directories. +It also looks for and loads any subordinate +boot files required +by +"frob.boot". + +
+Subordinate +boot files are also loaded automatically for the +first boot file +explicitly specified via the command line. +Each boot file must be listed before those that depend upon it. + +
+The --verbose option may be used to trace the +file searching process and must appear before any boot +arguments for which search tracing is desired. + +
+Ordinarily, the search for +boot files is limited to a set of +installation directories, but this may be overridden by setting +the environment variable SCHEMEHEAPDIRS. +SCHEMEHEAPDIRS should be a colon-separated list of directories, listed in +the order in which they should be searched. +Within each directory, the two-character escape sequence "%v" +is replaced by the current version, and the two-character escape sequence +"%m" is replaced by the machine type. +A percent followed by any other character is replaced by the second +character; in particular, "%%" is replaced by "%", and +"%:" is replaced by ":". +If SCHEMEHEAPDIRS ends in a non-escaped colon, the default directories are +searched after those in SCHEMEHEAPDIRS; otherwise, only those listed in +SCHEMEHEAPDIRS are searched. + +
+Under Windows, semi-colons are used in place of colons, and one additional +escape is recognized: "%x," which is replaced by the directory in +which the executable file resides. +The default search path under Windows consists of "%x" +and "%x\..\..\boot\%m." +The registry key HeapSearchPath in +HKLM\SOFTWARE\Chez Scheme\csvversion, where +version is the Chez Scheme version number, e.g., +7.9.4, can be set to override the default search path, +and the SCHEMEHEAPDIRS environment variable +overrides both the default and the registry setting, if any. + +
+Boot files consist of ordinary compiled code and consist of +a boot header and the compiled code for one or more +source files. +See Section 2.8 for instructions on how to create +boot files. + +
+ + + + +
+Chez Scheme Version 10 User's Guide
+Copyright © 2023 Cisco Systems, Inc.
+Licensed under the Apache License Version 2.0
+(full copyright notice.).
+Revised November 2023 for Chez Scheme Version 9.9.9-pre-release.20
+about this book
+
+
+
diff --git a/index.html b/index.html
index 22e7c43fb..cffe7a81a 100644
--- a/index.html
+++ b/index.html
@@ -109,6 +109,15 @@
+ + + + +
+This document outlines the changes made to Chez Scheme for +Version 9.9.9 since Version 8.4. + +
+Version 9.9.9 is supported for the following platforms. +The Chez Scheme machine type (returned by the machine-type +procedure) is given in parentheses. + +
+
+
+
+
+
+
+
+
+
+
+ +
+This document contains three sections describing significant +(1) functionality changes, +(2) bugs fixed, and +(3) performance enhancements. +A version number listed in parentheses in the header for a change +indicates the first minor release or internal prerelease to support +the change. + +
+More information on Chez Scheme and Petite Chez Scheme can +be found at http://www.scheme.com, +and extensive documentation is available in +The Scheme Programming Language, 4th edition (available directly from MIT Press or from online and local retailers) +and the Chez Scheme Version 9 User's Guide. +Online versions of both books can be found at +http://www.scheme.com. + +
+AArch64 (64-bit Arm) and RV64G (64-bit RISC-V) architectures are +supported. Threads are supported on architectures with weak memory +models while preserving the safety guarantee described in the +documentation for variables and primitive datatypes. + +
+The pb ("portable bytecode") machine type corresponds to a virtual +machine that the Chez Scheme kernel can interpret on practically any +desktop platform. This machine type is used to enable bootstrapping on +all native-code platforms using a single set of boot files. The pb +machine type is also used to support platforms for which Chez Scheme +does not have a supported native-code generator. For the latter use, +the pb32l, pb32b, pb64l, and pb64b machine types specialize the +interpreter to a word size and endianness, which improves performance. +For example, pb32l is a suitable machine type for compiling to +WebAssembly via Emscripten. Each pb variant has a corresponding +threaded variant: tpb, tpb32l, tpb32b, tpb64l, and tpb64b. + +
+The pbchunk-convert-file procedure can convert sequences of +static pb bytecode into C code. The generated C code can be compiled +and linked with the Chez Scheme kernel to reduce the overhead of +bytecode interpretation. In particular, since Chez Scheme is mostly +written in Chez Scheme, a pbchunk conversion of its boot files +improves performance of primitives and compilation. + + +
+Running configure assumes a threaded target machine type, +unless --nothreads or a non-threaded machine type is +specified. + +
+The build system mostly uses Zuo instead of Make, but the +configure script continues to generate wrapper makefiles, so +that there's no difference for most users who build from source and do +not modify Chez Scheme. The build process on Windows has changed so +that Unix-style tools are not required, but using Unix-style tools to +compile with MinGW is supported. + +
+The Chez Scheme sources no longer include boot files for multiple +platforms. Instead, a single set of pb boot files is normally used to +build on any platform. This change makes an initial build of Chez +Scheme slower, but it makes the build process consistent across all +supported platforms and enables a much smaller source size. +Alternatively, Chez Scheme can be bootstrapped from an older version +of Chez Scheme (9.5.4 or later) using the re.boot makefile +target. + +
+The new scheme-build-number function complements +scheme-version-number, adding an extra level of versioning +during development. The scheme-build-number procedure always +returns zero for a released version of Chez Scheme. + + +
+The compiler generates code that locally unboxes floating-point +operations, so that compositions of floating-point operations can be +much faster. + +
+The compiler infers information about the type of value produced +by an expression, and it uses that information to eliminate run-time +checks or conditionals. For example, within +(if (flonum? x) E1 E2), +assuming that the variable x is never +mutated, then it holds a flonum value within E1, so +arithmetic can be specialized to flonum operations. Type inference +requires an additional pass for compilation, but when compiling in +safe mode, the pass tends to more than pay for itself; reduced checks +and error handling create less work for later compilation passes. +Even when many checks are removed, run-time performance may improve +only modestly on modern hardware, since the removed branches are +perfectly predictable. Inference can be disabled by setting +enable-type-recovery to #f. + +
+The compiler can infer more than previously about procedures that +always return a value or that never return (because they raise a +noncontinuable exception). The compiler will no longer move an +expression from a non-tail position to a tail position if that +movement could be detected with continuation marks (see +Section 2.5), and it will not change a program in a +way that discards an error due to returning multiple values to a +single-value context. The assert-unreachable procedure always +reports an error in safe mode, but it in unsafe mode, it must never be +called; the claim that some code is unreachable propagates backward to +remove other code that must also be unreachable, and even drop +conditionals that must always go the other way to avoid unreachable +code. A macro expansion might use assert-unreachable to +indicate that unsafe mode can assume that a check succeeded and +eliminate the check, for example. + +
+The compiler consistently "lifts" procedures: When a procedure has +only known call sites, refers to only immutable variables bound +outside the procedure, and has only call site within the scope of +those variables, then variables used by the procedure are converted to +arguments, and call sites are converted to supply the variables as +arguments. As a result, nested procedure definitions can be used more +freely without a potential cost from closure allocation. There are +programs where forming a closure would be faster, but consistent +lifting is almost always faster in practice. + +
+Cross-library inlining can apply to a procedure that is exported +from a library (explicitly or implicitly) and whose body refers to +another procedure or other variable that is also exported (explicitly +or implicitly). + +
+The compiler reduces code size by using a more compact representation +for most call-return sites and by using a more compact dispatch to +interrupt checking in most cases. + +
+The internal representation of record types has changed so that a +record-type predicate is a constant-time operation, instead of +proportional to the subtype depth. + + +
+Garbage collection takes advantage of machine parallelism. Parallel +collection is automatically enabled when a program has multiple Scheme +threads active at the point that a garbage collection starts, but +parallel collection can benefit from a hint about which threads are +most relevant as allocators (see Section 2.18). + +
+The garbage collector uses a hybrid mark-copy algorithm, which +can improve performance for large objects and long-lived objects +compared to a pure copying collector. The +in-place-minimum-generation parameter tunes the hybrid by +selecting the youngest generation at which marking is used. + +
+The collect-maximum-generation-threshold-factor parameter is +used by collect when called with no arguments. In the case +that the maximum generation would be collected based on the gc-trip +counter, it is collected only when the total memory use is at least k +times the memory use just after the most recent collection of the maximum +generation, where the parameter's value is k. The default value of 2 +helps the collector adapt to the scenario that a program has much more +long-lived data than short-lived data, and where the program does not +explicitly promote its long-lived data to the static generation. +Setting the parameter to 0 makes collect behave as in +previous versions of Chez Scheme. + +
+See also Sections 2.19 and 2.20 for +related new functionality. + + +
+Continuation marks add key-value information to continuations. +The with-continuation-mark form associates a key-value pair +to the current continuation, replacing any same-keyed mark already +associated to the immediate continuation, and adding to marks +associated with continuations that the current continuation extends. +Inspect marks with these functions: + +
+ +
current-continuation-marks
+
+continuation-next-marks
+
+continuation-marks-first
+
+continuation-marks->list
+
+continuation-marks->iterator
+
+call-with-immediate-continuation-mark
+
+continuation-marks?
+
The call-in-continuation function can invoke a continuation +similar to calling a procedure as a function, but instead of a value +to deliver to the continuation, it takes a procedure of no arguments +to call within the continuation. + + +
+New operations support common bit-related operations on fixnums: + +
+ +
fx+/wraparound
+
+fx-/wraparound
+
+fx*/wraparound
+
+fxsll/wraparound
+
+fxpopcount
+
+fxpopcount32
+
+fxpopcount16
+
Immutable fixnum vectors are no longer supported, so the following +functions are removed: + +
+ +
fxvector->immutable-fxvector ; removed
+
+mutable-fxvector? ; removed
+
+immutable-fxvector? ; removed
+
+The eq? operator works on flonums in the sense that two +flonums values that are eq? at some point (such as creation +time) will continue to be eq? in the future. + +
+Mutable flonum vectors cooperate with local unboxing (see +Section 2.3) and are supported through the +following functions: + +
+ +
flvector?
+
+make-flvector
+
+flvector-length
+
+flvector-ref
+
+flvector-set!
+
+flvector-fill!
+
+flvector->list
+
+list->flvector
+
+flvector-copy
+
The flsingle operation drops precision from a flonum so that +the result is representable as a single-precision (32-bit) flonum. +Wrapping each operation of flonum arithmetic with flsingle +produces the same result as single-precision arithmetic, and local +unboxing plus type inference makes the combination reasonably +efficient. + +
+Flonum printing can be controlled by new parameters: + +
+ +
print-subnormal-precision
+
+print-positive-exponent-sign
+
+print-select-flonum-exponential-format
+
The fl=, fl<, , fl>, fl<=, and +fl>= no longer produce #f for a single argument +that's +nan.0, which makes them consistent with =, +<, >, <=, and >=. + + +
+Multiplication of very large numbers uses Karatsuba, Toom-3, or +Toom-4, while division (including GCD) uses Burnikel-Ziegler. These +changes make arithmetic and number-to-string conversions faster for +large values, and they avoid unbounded delays between interrupt +polling. + + +
+Division of an inexact number by an exact 0 now raises +exception instead of producing +inf.0 or -inf.0. +This makes division more consistent with with the existing behavior of +multiplication, where multiplication of an inexact number by an exact +0 produces an exact 0. + +
+Small changes to transcendental functions help improve consistency for +derived compositions. The expt function with two ++inf.0 or -inf.0 arguments now produces ++nan.0+nan.0i instead of a complex number with infinite +components. The sqrt and log functions change so +that (sqrt -0.0) and (log -0.0) produce real +numbers, instead of complex numbers, on the grounds that +(negative? -0.0) produces #f. + +
+The expt function recognizes an exact 1/2 as its +second argument, and in that case it behaves like sqrt, which +may produce an exact result. + + +
+New functions support decoding grapheme clusters within strings or +character streams and expose the underlying new character classifiers: + +
+ +
string-grapheme-span
+
+string-grapheme-count
+
+char-grapheme-step
+
+char-grapheme-break-property
+
+char-extended-pictographic?
+
The string-append-immutable function enables the creation of +an immutable string as the result of appending strings without +creating an intermediate mutable string. + +
+The path-build procedure combines two path strings to form a +path, adding a directory separator between them if necessary. + + +
+Operations returning hashtable cells (hashtable-cell, +eq-hashtable-cell, symbol-hashtable-cell, and +hashtable-cells) now raise an exception when given an immutable +hashtable. This is an incompatible change, as they previously +accepted immutable hashtables (and allowed changing them). + +
+The make-weak-hashtable and make-ephemeron-hashtable +functions support weak and ephemeron hash tables with arbitrary +equality and hashing functions. + + +
+New operations for hashtable cells resemble procedures like +hashtable-keys or hashtable-ref: + +
+ +
hashtable-cells
+
+hashtable-ref-cell
+
+eq-hashtable-ref-cell
+
+symbol-hashtable-ref-cell
+
The eq-hashtable-try-atomic-cell procedure supports lock-free +use of an eq?-based hash table, but with constraints on +concurrent operations and resizing. Clean-up resizing can be performed +within a collect-request handler, since only one thread can run at that +time. + +
+A weak or ephemeron eqv? hash table now retains non-fixnum +numbers only weakly, instead of strongly. This change is related to +changes to eq? for flonum values and the availability of weak +and ephemeron hash tables with arbitrary equality and hashing +functions. + + +
+Stencil vectors provide support in the compiler and runtime for +implementing data structures such as persistent maps: + +
+ +
stencil-vector
+
+stencil-vector?
+
+stencil-vector-mask
+
+stencil-vector-length
+
+stencil-vector-ref
+
+stencil-vector-set!
+
+stencil-vector-update
+
+stencil-vector-truncate!
+
+stencil-vector-mask-width
+
+While gensyms support most symbol-generation needs, uninterned symbols +are useful for purposes where properties must not prevent a symbol +from being reclaimed by the storage manager: + +
+ +
string->uninterned-symbol
+
+uninterned-symbol?
+
The string returned by symbol->string is always immutable. + + +
+Records can have anonymous fields, which can save memory in the +representation when many record types need to be created (as opposed +to many record instances of a few types), each with many fields. For a +given record type and its ancestors, either all fields are named or +all fields are anonymous. + +
+ +
make-record-type-descriptor*
+
+record-type-named-fields?
+
+record-type-field-indices
+
The new record-instance? predicate is a specialization of +record?, where the first argument is required to be a record. +An unsafe record-instance? test can be faster than an unsafe +record? test. + + +
+In a context where pairs are not mutated, the new +list-assuming-immutable? predicate is useful as a variant of +the list? predicate. The new predicate implements an +efficient, amortized constant-time decision on whether a value +represents a list, but its behavior is unspecified if the +cdr or any pair relevant to the result is mutated. + + +
+A new random-number API implements the MRG32K3A algorithm: + +
+ +
make-pseudo-random-generator
+
+pseudo-random-generator?
+
+pseudo-random-generator-next!
+
+pseudo-random-generator-seed!
+
+pseudo-random-generator->vector
+
+vector->pseudo-random-generator
+
+A wrapper procedure provides an inexpensive way to an adjust a +procedure's name, constrain its arity, or associate extra data to the +procedure. A wrapper procedure is implemented as closure with an +optimized jump to the wrapped procedure after arity checking, +propagating the original arguments faster than apply. + +
+ +
make-wrapper-procedure
+
+make-arity-wrapper-procedure
+
+wrapper-procedure?
+
+wrapper-procedure-procedure
+
+wrapper-procedure-data
+
+set-wrapper-procedure-data!
+
+set-wrapper-procedure!
+
+The new thread-join operator can be used to wait for a thread +to terminate. Waiting for termination in this sense can be useful to +ensure that a single thread is running and calling collect is +legal, for example. + +
+The new get-initial-thread procedure returns a descriptor for +the initial thread (like a descriptor produced by fork-thread +for a subsequently created thread). + +
+The new thread-preserve-ownership! procedure provides a hint +to the storage manager that parallel garbage collection is likely to +benefit by keeping track of which objects were allocated by a given +thread. + +
+Useful on architectures with a weak consistency model, +memory-order-acquire and memory-order-release +implement fencing operators suitable for abstractions that acquire +(load-load and load-store fence) or release (store-store and +store-load fence) shared resources. + + +
+Similar to enable-object-counts, the +enable-object-backreferences parameter enables recording of +information about reachability. After a collection with backreferences +enabled, object-backreferences reports an association for +each object to the a referencing object---one that caused the storage +manager to consider the former object reachable. + +
+A new bytes-finalized procedure reports the number of bytes +that have been finalized via guardians, which is useful for deciding +when to perform an extra major collection as a follow-up to an +old-generation garbage collection. + +
+A phantom bytevector is a small object that stands for a large +externally allocated object, especially one that can be finalized. +Registering external allocations with the storage manager helps it +trigger collection requests at times that take into account the rate +and scale of external allocation. + +
+ +
make-phantom-bytevector
+
+phantom-bytevector?
+
+phantom-bytevector-length
+
+set-phantom-bytevector-length!
+
The new compute-size-increments procedure is similar to +compute-size. Instead of a single object, it takes a list of +objects, and it reports a list of sizes where any memory use +attributed to objects earlier in the list is not counted for objects +later in the list, while objects later the list are not considered +reachable by objects earlier in the list. For example, given a list of +threads, compute-size-increments effectively treats each +thread as an accounting domain, where memory is charged to an earlier +thread rather than a later thread when objects are reachable from +both. Since this computation involves the same sort of traversal as a +garbage collection, the collect function takes a list as +an optional last argument to fuse a garbage collection with size +accounting. + + +
+The make-guardian function accepts an option to create an +ordered guardian. An ordered guardian treats each of its +objects as accessible in the case that object is reachable from a +guardian-registered object, whether or not the latter object is +considered accessible. Ordered finalization is error-prone and cannot +handle reference cycles, but it can be necessary to implement certain +storage-management interfaces and abstractions. + +
+An immobile object is one that the storage manager will not +relocate as a long as it is referenced, in the same way that a locked +object is never relocated. Unlike a locked object, an immobile +object can be reclaimed by the storage manager. + +
+ +
box-immobile
+
+make-immobile-vector
+
+make-immobile-bytevector
+
For foreign interfaces that involve arrays of references to allocated +objects, the storage manager supports reference +bytevectors. A reference bytevector is a bytevector, but each +word-aligned group of bytes is treated as a potential reference to an +object managed by the collector; only a word whose value corresponds a +region of managed memory is treated as an object reference, and it can +be updated by the garbage collector if the referenced object is +relocated. Using the reference-bytevector interface requires care, but +it can greatly simplify certain foreign-library interactions. An +object reference in a bytevector takes the form of a reference +address for a Scheme object. The reference address of a bytevector +(including a reference bytevector) or flvector is the address of the +first byte of its content. + +
+ +
make-reference-bytevector
+
+make-immobile-reference-bytevector
+
+reference-bytevector?
+
+bytevector-reference-set!
+
+bytevector-reference-ref
+
+bytevector-reference*-ref
+
+object->reference-address
+
+reference-address->object
+
+reference*-address->object
+
The keep-live procedure accepts any value and returns +(void), but the argument to keep-live is defined to +be reachable until the call to keep-live returns. + +
+The maximum non-static generation for collection has been reduced from +254 to 6. This change is related to parallel garbage collection and +internal changes that make allocation thread-local, which in turn +makes the size of a thread's representation proportional to the +maximum number of generations. + + +
+Some ABIs treat functions with varargs (i.e., specified with +... in the C prototype) differently than functions without +varargs, and some ABIs treat specific arguments differently depending +on whether the argument is a vararg (i.e., before the ... or +not). A procedure type described with foreign-procedure or a +function type can include a __varargs or +(__varargs_after n) convention to indicate which +arguments of a function are varargs. + +
+The new foreign-alignof procedure reflects alignment +information for a primitive type. + +
+To better support the pb machine type, where endianness is not known +statically, endianness in a foreign type can not be native or +swapped in addition to big or little. + +
+Chez Scheme's kernel also expose record-type and field access to +C, mainly useful for for records that contain only pointer-sized +values: + +
+ +
Srecord_type
+
+Srecord_type_parent
+
+Srecord_type_size
+
+Srecord_type_uniformp
+
+Srecord_uniform_ref
+
The kernel also provides a new function +Sregister_boot_file_fd_segment for loading a boot file from a +file descriptor and offset. This form of boot-file registration is +useful for loading boot files that are embedded with an executable +segment. + + +
+Reading fasl data has been made safe no matter how deeply nested the +structure of the data. + +
+For reading and writing fasl data, the fasl-write procedure +accepts a predicate to detect "external" values for which only a +placeholder is saved, and fasl-read accepts a table of +external values to substitute for placeholders. These "external" +values can then have their own serialization and deserialization. The +fasl-write function also accepts an option to save a record +type as only its unique ID, which can save space and time in contexts +where the relevant record types will always be available already (and +where savings are worth skipping a consistency check). The +compile-to-port procedure accepts new arguments like +fasl-write. + +
+A fasl stream can be converted a vfasl (very fasl) format, +which is close in structure to an image of data in memory. Using vfasl +for boot files to load directly into a static generation can make +startup much faster; otherwise, the time-space tradeoff rarely pays +off. Convert from fasl to vfasl using vfasl-convert-file. + + +
+Two new parameters skip safety checks in specific situations: +enable-unsafe-application assumes that the target of a +procedure application is a procedure, and +enable-unsafe-variable-reference assumes that a variable has +a value when it is referenced. These checks would be skipped at +optimize-level 3, but the parameters cause them to be skipped +independent of the value of optimize-level. + +
+A true value for the enable-arithmetic-left-associative +parameter ensures that arithmetic operations are performed as +left-associative, which amounts to a constraint on optimizations. + +
+A new set of parameters control the way that libraries are compiled +and invoked so that consistency checks, invocations checks, and +recompilations can be skipped (to save time and space) in a context +that ensures that they are unnecessary: + +
+ +
library-timestamp-mode
+
+expand-omit-library-invocations
+
+compile-omit-concatenate-support
+
Along those lines, the current-generate-id parameter provides +control over names that are generated during macro expansion. While +the default parameter uses gensym, name generation can +potentially be made deterministic, which in turn may reduce the need +to recompile clients. + +
+The new procedure-known-single-valued? predicate is always +allowed to return #f, but it may return #t for a +procedure that the compiler was able to prove always returns a single +value. This information may, in turn, be useful for run-time +specialization in a library. + +
+Procedure objects recognize the realm inspector message +alongside name. The result for realm is normally +#f, but if compile-procedure-realm is set to a +symbol when the procedure is compiled, then the procedure answers +realm with that symbol. The intent of a realm is that it +describes where a procedure name came from, so the name can be +converted as appropriate for a run-time context that uses different +naming conventions. + +
+The enable-error-source-expression parameter determines +whether error messages that become embedded in code can refer to the +original source file's path. + + +
+The following new functions +allow foreign code to try converting Scheme +values to signed or unsigned integer values +without triggering a longjmp in the Scheme runtime +as can happen when calling the corresponding functions +Sinteger_value, etc: + +
Stry_integer_value
+
+Stry_integer32_value
+
+Stry_integer64_value
+
+Stry_unsigned_value
+
+Stry_unsigned32_value
+
+Stry_unsigned64_value
+
+The header file scheme.h distributed with Chez Scheme now defines +Sint32_t, Suint32_t, Sint64_t, and Suint64_t +types for 32-bit and 64-bit signed and unsigned integers that are compatible +with the types for exports such as Sinteger64. + +
+The new parameter transcoded-port-buffer-size specifies the size +of the string buffer that is allocated when creating a new transcoded port. +If the underlying binary port implements port-position, +a transcoded input port allocates an internal fxvector the same size +as its string buffer for use by port-position. +The new parameter make-codec-buffer can be used to supply an appropriately +sized internal bytevector buffer for the codec used by a new transcoded port. +The size of these string and bytevector buffers was previously hardcoded at 1024. + +
+The character sets, character classes, and word-breaking algorithms for character, string, +and Unicode-related bytevector operations have now been updated to Unicode 15.0. + +
+Previously, it was possible to interfere with the definition of ftypes by +creating a syntactic binding for one of the built-in types, such as +integer-32, float, etc. +As of 9.5.8, syntactic bindings that do not bind an ftype descriptor are no +longer considered when defining ftypes. + +
+This change also allows a base ftype to be bound using define-ftype, though +this fixes the endianness of the type. For instance: + +
+ +
(define-ftype integer-32 integer-32) +
This binds the ftype integer-32 to the native-endian integer-32. It is possible to bind both endiannesses by using explicit names: + +
+ +
(define-ftype integer-32-be (endian big integer-32))
+
+(define-ftype integer-32-le (endian little integer-32))
+
+(define-ftype integer-32 integer-32) ;; fixed to native endianness
+
+When the reader reports an invalid bytevector element, the error +message now includes the token value only if the token type is atomic. + +
+When the expander reports that an ellipsis is missing in a syntax form, +it now includes the name of an identifier that is missing an ellipsis +within that form. + +
+The reader now case-insensitively accepts #true and +#false as alternative spellings of the booleans #t +and #f, respectively. + +
+The new parameter self-evaluating-vectors can be used to treat unquoted vector +literals as self-evaluating instead of syntax errors. This parameter is turned off by +default. + +
+In previous versions of Chez Scheme, the collector always promoted +surviving objects from every collected generation into a single +target generation. +For example, when the target generation was 3, it promoted not only +surviving objects from generation 2 to generation 3 but also surviving +objects from generations 0 and 1 directly to generation 3. +This caused some prematurely promoted objects to be subjected to +collection less frequently than their ages justified, potentially +resulting in substantial inappropriate storage retention. +This is particularly problematic when side effects result in pointers +from the inappropriately retained objects to younger objects, as +can happen with nonfunctional queues and lazy streams. + +
+Unless directed to do otherwise, the collector now promotes objects +up only one generation at a time. +That is, generation 0 objects that survive collection are promoted +to generation 1, generation 1 objects are promoted to generation +2, and so on. +(Objects that survive a maximum nonstatic collection are promoted +back into the maximum nonstatic collection.) +Most applications should exhibit lower peak memory usage and possibly +lower run times with this change. +Applications that are adversely affected, if any, might benefit +from a custom collect-request handler or custom values for the +collection parameters that affect the behavior of the default +handler. + +
+Console I/O now supports characters from the Unicode Basic +Multilingual Plane in Windows. Windows consoles do not yet support the +supplementary planes. + +
+The fasl (fast-load) format now supports per-object compression. +Whether the fasl writer actually performs compression is determined +by the new fasl-compressed parameter, whose value defaults +to #t. +The compression format and level are determined by the +compress-format and compress-level +parameters. + +
+The compile-compressed parameter has been eliminated. +Since compiled files are written in fasl format, the +fasl-compressed parameter also now controls whether compiled +files are compressed. + +
+Because individual portions of a fasl file are already compressed +by default, attempting to compress a fasl file as a whole is often +ineffective as well as inefficient both when writing and reading +fasl objects. +Thus, in particular, the output-port and wpo-port +supplied to compile-port and compile-to-port +should not be opened for compression. +Similarly, external tools should not expect compiled files to be +compressed as a whole, nor should they compress compiled files. + +
+Because compression of fasl files was previously encouraged and is +now discouraged, the first attempt to write fasl data to or read +fasl data from a compressed port will cause a warning to be issued, +i.e., an exception with condition type &warning to be +raised. + +
+The rationale for this change is to allow the fasl reader to seek +past, without reading, portions of an object file that contain +compile-time code at run time and run-time code at compile time. + +
+The procedure bytevector-compress now selects the level of +compression based on the compress-level parameter. +Prior to this it always used a default setting for compression. + +
+The compress-level parameter can now take on the new value +minimum in addition to low, medium, +high, and maximum. + +
+In previous versions of Chez Scheme, multiple object files could +be combined by concatenating them into a single file. To support faster +object file loading and loadability verification (described later in this +document), recompile information and information about libraries and +top-level programs within an object file is now placed at the top of the +file. The new concatenate-object-files procedure can be used to +combine multiple object files while moving this information to the +top of the combined file. + +
+The new procedure invoke-library can be used to force +the evaluation of a library's body expressions (variable definition +right-hand sides and initialization expressions) before they might +otherwise be needed. +It is generally useful only for libraries whose body expressions +have side effects. + +
+The new procedure verify-loadability can be used to +determine, without actually loading any object code or defining any +libraries, whether a set of object files and the object files +satisfying their library dependencies, direct or indirect, are +present, readable, and mutually compatible. + +
+To support loadability verification, information about libraries +and top-level programs within an object file is now placed at the +top of the file, just after recompile information. This change can +be detected by unusual setups, e.g., a source file that interleaves +library definitions and top-level forms that call library-list, but +is backward compatible for standard use cases in which each file +contains one or more libraries possibly followed by a top-level +program. + +
+The set of as-yet unresurrected objects registered with a guardian +can be unregistered and retrieved by means of the new primitive +unregister-guardian. +Consult the user's guide for usage and caveats. +Guardians can now be distinguished from other procedures (and other +objects) via the new primitive guardian?. + +
+When the new parameter generate-covin-files is set to #t +rather than the default #f, file compilation routines such as +compile-file and compile-library produce coverage +information (.covin) files that can be used in conjunction with +profile information to measure coverage of a source-code base. +Coverage information is also written out when the optional covop +argument is supplied to compile-port and compile-to-port. + +
+A covin file contains a printed representation of a source +table mapping each profiled source object in the code base to a +count of zero. +Source tables generally associate source objects with arbitrary values +and are allocated and manipulated with hashtable-like operations specific +to source tables. + +
+Profile information can be tracked even through releasing and clearing +of profile counters via the new procedure with-profile-tracker, +which produces a source table. + +
+Coverage of a source-code base can thus be achieved by comparing +the set of source objects in the covin-file source tables for one +or more source files with the set of source objects in the source +tables produced by one or more runs of tests run with profile +information tracked by with-profile-tracker. + +
+As described in Section 4.4, +importing a library from an object file now causes the object file +to be visited rather than fully loaded. +If the run-time information is needed, i.e., if the library is +invoked, the file will be revisited. +This is typically transparent to the program, but problems can arise +if the program changes its current directory (via +current-directory) prior to invoking a library, and the +object file cannot be found. + +
+As described in Section 4.4, all +recompile information is now placed at the front of each object +file where it can be read without the need to scan through the +remainder of the file. +Because the library manager expects to find recompile information +at the front of an object file, it will not find all recompile +information if object files are concatenated together via some +mechanism other than then new concatenate-object-files +procedure. + +
+Also, the compiler has to hold in memory the object code for all +expressions in a file so that it can emit the unified recompile +information, rather than writing to the object file incrementally, +which can significantly increase the memory required to compile a +large file full of individual top-level forms. +This does not affect top-level programs, which were already handled +as a whole, or a typical library file that contains just a single +library form. + +
+It is now possible to direct fasl-read to read only visit +(compile-time) or revisit (run-time) objects via the optional new +situation argument. +Situation visit causes the fasl reader to skip over +revisit (run-time-only) objects, while +revisit causes the fasl reader to skip over +visit (compile-time-only) objects. +Situation load doesn't skip over any objects. + +
+In addition to the optional input-port argument, read-token now takes +optional sfd (source-file-descriptor) and bfp (beginning-file-position) +arguments. +If either is provided, both must be provided. +Specifying sfd and bfp improves the quality of error messages, +guarantees the read-token start and end return values can be determined, +and eliminates the overhead of asking for a file position on each call +to read-token. +bfp is normally 0 for the first call +to read-token at the start of a file, +and the end return value of the preceding +call for each subsequent call. + +
+Support for LZ4 compression has been added. +LZ4 is now the default format when compressing files (including +object files produced by the compiler) and bytevectors, while gzip is still supported and can be enabled by setting +the new compress-format parameter to the symbol gzip instead of the +default lz4. Reading in compressed mode +infers the format, so reading gzip-compressed files will still +work without changing compress-format. Reading LZ4-format +files tends to be much faster than reading gzip-format files, +while gzip-compressed files tend to be smaller. +In particular, object files created by the compiler now tend to be +larger but load more quickly. + +
+The new compress-level parameter can be used to control +the amount of time spent on file and bytevector compression. +It can be set to one of the symbols minimum, low, +medium, high, and maximum, which are +listed in order from shortest to longest compression time and least +to greatest effectiveness. +The default value is medium. + +
+The procedures make-mutex and make-condition now +accept an optional argument name, which must be a symbol +that identifies the object or #f for no name. The name is +printed every time the mutex or condition object is printed, which +is useful for debugging. + +
+The Chez Scheme Makefile has been enhanced with new targets for +creating binary packages for Unix-like operating systems. +The create-tarball target generates a binary tarball package for +distribution, the create-rpm target generates a Linux RPM package, and +the create-pkg target generates a macOS package file. + +
+The new library-search-handler parameter controls how library source +or object code is located when import, compile-whole-program, +or compile-whole-library are used to load a library. +The value of the library-search-handler parameter must be a procedure +expecting four arguments: the who argument is a symbol that provides +context in import-notify messages, the library argument is the +name of the desired library, the directories is a list of source and +object directory pairs in the form returned by library-directories, +and the extensions parameter is a list of source and object extension +pairs in the form returned by library-extensions. +The default value of the library-search-handler is the newly exposed +default-library-search-handler procedure. + +
+Applications that manage memory outside the Scheme heap can leverage +new support for ftype guardians to help perform reference counting. +An ftype guardian is like an ordinary guardian except that it does +not necessarily save from collection each ftype pointer registered +with it but instead decrements (atomically) a reference count at +the head of the object to which the ftype pointer points. +If the reference count becomes zero as a result of the decrement, +it preserves the object so that it can be retrieved from the guardian +and freed; otherwise it allows it to be collected. + +
+compile-whole-program and compile-whole-library +now propagate recompile information from the named wpo +file to the object file to support maybe-compile-program +and maybe-compile-library in the case where the new object +file overwrites the original object file. + +
+The value of a compile-time value created by make-compile-time-value +can be retrieved via the new procedure compile-time-value-value. +The new predicate compile-time-value? can be used to determine if +an object is a compile-time value. + +
+The new hashtable-cells function is similar to +hashtable-entries, but it returns a vector of cells instead +of two vectors. An optional argument to hashtable-keys, +hashtable-values, hashtable-entries, or hashtable-cells +limits the size of the result vector. + +
+Profile data is now retained indefinitely even for code objects +that have been reclaimed by the garbage collector. +Previously, the counters holding the data were reclaimed by the +collector along with the code objects. +This makes profile output more complete and accurate, but it does +represent a potential space leak in programs that create or load +and release code dynamically. +Such programs can avoid the potential space leak by releasing the +counters explicitly via the new procedure +profile-release-counters. + +
+When generate-inspector-information is set to #f and +generate-procedure-source-information is set to #t, +source location information is preserved for a procedure, even though +other inspector information is not preserved. + +
+The new procedures box-cas! and vector-cas! +atomically update a box or vector with a given new value when the +current content is eq? to a given old value. Atomicity is +guaranteed even if multiple threads attempt to update the same box or +vector. + +
+A new __collect_safe foreign-procedure convention, which can +be combined with other conventions, causes a foreign-procedure call to +deactivate the current thread during the call so that other threads can +perform a garbage collection. Similarly, the __collect_safe +convention modifier for callables causes the current thread to be +activated on entry to the callable, and the activation state is +reverted on exit from the callable; this activation makes callables +work from threads that are otherwise unknown to the Scheme system. + +
+A new collect-rendezvous function performs a garbage +collection in the same way as when the system determines that a +collection should occur. For many purposes, +collect-rendezvous is a variant of collect that +works when multiple threads are active. More precisely, the +collect-rendezvous function invokes the collect-request +handler (in an unspecified thread) after synchronizing all active +threads and temporarily deactivating all but the one used to call the +collect-request handler. + +
+A new (& ftype) form allows a struct or union to be +passed between Scheme and a foreign procedure. The Scheme-side +representation of a (& ftype) argument is the +same as a (* ftype) argument, but where +(& ftype) passes an address between the Scheme and C +worlds, (& ftype) passes a copy of the data at the +address. When (& ftype) is used as a result type, +an extra (* ftype) argument must be provided to receive +the copied result, and the directly returned result is unspecified. + +
+Several new procedures and parameters allow a program to control what +equal? and equal-hash do when applied +to structures containing record instances. +The procedures record-type-equal-procedure and +record-type-hash-procedure can be used to customize the +handling of records of specific types by equal? and hash, and +the procedures record-equal-procedure and +record-hash-procedure can be used to look up the +applicable (possibly inherited) equality and hashing procedures +for specific record instances. +The parameters default-record-equal-procedure and +default-record-hash-procedure can be used to control +the default behavior when comparing or hashing records without +type-specific equality and hashing procedures. + +
+Support for immutable vectors, fxvectors, bytevectors, strings, and boxes +has been added. +Immutable vectors are created via vector->immutable-vector, +and immutable fxvectors, bytevectors, and strings are created by similarly named +procedures. +Immutable boxes are created via box-immutable. +Any attempt to modify an immutable object causes an exception to be raised. + +
+Support for ephemeron pairs has been added, along with eq and eqv +hashtables that use ephemeron pairs to combine keys and values. An +ephemeron pair avoids the "key in value" problem of weak pairs, +where a weakly held key is paired to a value that refers back to the +key, in which case the key remains reachable as long as the pair is +reachable. In an ephemeron pair, the cdr of the pair is not considered +reachable by the garbage collector until both the pair and the car of +the pair have been found reachable. An ephemeron hashtable implements +a weak mapping where referencing a key in a value does not prevent the +mapping from being removed from the table. + +
+The condition-wait procedure now takes an optional +timeout argument and returns a boolean indicating whether the +thread was awakened by the condition before the timeout. The +timeout can be a time record of type time-duration or +time-utc, or it can be #f for no timeout (the +default). + +
+The new primitive procedures date-dst? and +date-zone-name access time-zone information for a +date record that is created without an explicit +zone offset. The zone-offset argument to make-date +is now optional. + +
+The new primitive procedure procedure-arity-mask takes a +procedure p and returns a two's complement bitmask representing +the argument counts accepted by p. +For example, the arity mask for a two-argument procedure such as +cons is 4 (only bit two set), +while the arity mask for a procedure that accepts one or more arguments, +such as list*, is -2 (all but bit 0 set). + +
+The new primitive procedures bytevector-compress and +bytevector-decompress exposes for bytevectors the kind of +compression functionality that is used for files with the +compressed option. + +
+The locate-source function accepts an optional argument that +enables the use of a cache for line information, so that a source file +does not have to be consulted each time to compute line information. +To further avoid file and caching issues, a source object has optional +beginning-line and beginning-column components. Source objects with line +and column components take more space, but they allow reporting of line and column +information even if a source file is later modified or becomes unavailable. +The value of the current-make-source-object parameter is used by the +reader to construct source objects for programs, and the parameter can be +modified to collect line and column information eagerly. The value of the +current-locate-source-object-source parameter is used for +error reporting, instead of calling locate-source or +locate-source-object-source directly, so that just-in-time +source-location lookup can be adjusted, too. + +
+When running on Windows 8 and up, Chez Scheme uses the high-precision +clock time function for the current date and time. + +
+Chez Scheme extends the syntax of identifiers as described in the +introduction to the Chez Scheme User's Guide, except within forms prefixed +by #!r6rs, which is implied in a library or top-level program. +Prior to Version 9.5, the printer always printed such identifiers using +hex scalar value escapes as necessary to render them with valid R6RS identifier syntax. +When the new parameter print-extended-identifiers is set +to #t, these identifiers are printed without escapes, e.g., +1+ prints as 1+ rather than as \x31;+. +The default value of this parameter is #f. + +
+The expression editor now supports Unicode characters under Linux and MacOS X +except that combining characters are not treated correctly for +line-wrapping. + +
+compile-whole-program now supports incomplete +whole-program optimization, i.e., whole program optimization that +incorporates only libraries for which wpo files are available while +leaving separate libraries for which only object files are available. +In addition, imported libraries can be left visible for run-time +use by the environment procedure or for dynamically loaded +object files that might require them. +The new procedure compile-whole-library supports the combination +of groups of libraries separate from programs and unconditionally +leaves all imported libraries visible. + +
+The total size of the fields within an ftype bits can now be +24, 40, 48, or 56 (as well as 8, 16, 32, and 64). + +
+Object counting (see object-counts below) is now enabled for +all collections targeting the static generation. + +
+Previously, the output of profile-dump was not specified. +It is now specified to be a list of source-object, profile-count pairs. +In addition, profile-dump-html, profile-dump-list, +and profile-dump-data all now take an optional dump +argument, which is a list of source-object, profile-count pairs in +the form returned by profile-dump and defaults to the current +value of (profile-dump). + +
+With these changes, it is now possible to obtain a dump from +profile-dump in one process, and write it to a fasl file +(using fasl-write) for subsequent off-line processing in +another process, where it can be read from the fasl file (using +fasl-read) and processed using profile-dump-html, +profile-dump-list, profile-dump-data or some +custom mechanism. + +
+A new parameter, release-minimum-generation, determines when +the collector attempts to return unneeded virtual memory to the O/S. +It defaults to the value of collect-maximum-generation, so the +collector attempts to return memory to the O/S only when performing a +maximum-generation collection. +It can be set to a lower generation number to cause the collector to +do so for younger generations we well. + +
+The vector-based sstats structure has been replaced with a record type. +The time fields are all time objects, and the bytes and count fields +are now exact integers. +time-difference no longer coerces negative results to zero. + +
+With the extensions to compile-whole-program and the +addition of compile-whole-library, as described above, +support for whole-program and whole-library optimization now subsumes +the functionality of the experimental library-group form, +and the form has been eliminated. +This is an incompatible change. + +
+Prior to Version 8, the semantics of the interaction environment +used by the read-eval-print loop (REPL), aka waiter, and by +load, compile, and interpret without +explicit environment arguments treated all variables in the environment +as mutable, including those bound to primitives. +This meant that top-level references to primitive names could not +be optimized by the compiler because their values might change at +run time, except that, at optimize-level 2 and above, the compiler +did treat primitive names as always having their original values. + +
+In Version 8 and subsequent versions, primitive bindings in the +interaction environment are immutable, as if imported directly from +the immutable Scheme environment. +That is, they cannot be assigned, although they can be replaced +with new bindings with a top-level definition. + +
+To provide temporary backward compatibility, the +--revert-interaction-semantics command-line option and +revert-interaction-semantics parameter allowed programmers +to revert the interaction environment to Version 7 semantics. +This functionality has now been eliminated and along with it the +special treatment of primitive bindings at optimize level 2 and +above. + +
+This is an incompatible change. + +
+Version 9.3.1 augments existing support for explicit source-code +annotations with additional features targeted at source profiling +for externally generated programs, including programs generated by +language front ends that target Scheme and use Chez Scheme as the +back end. +Included is a profile expression that explicitly associates +a specified source object with a profile count (of times the +expression is evaluated), generate-profile-forms parameter +that controls whether the compiler (also) associates profile counts +with source locations implicitly identified by annotated expressions +in the input, and a finer-grained method for marking whether an +individual annotation should be used for debugging, profiling, or +both. + +
+When compile-imported-libraries is set to #t, +libraries required indirectly by one of the +file-compilation procedures, e.g., compile-library, +compile-program, and compile-file, are automatically +compiled if and only if the object file is not present, older than +the source (main and include) files, or some library upon which +they depend has been or needs to be recompiled. + +
+Version 9.3.1 adds three new procedures: maybe-recompile-library, +maybe-recompile-program, and maybe-recompile-file, +that perform a similar analysis and compile the library, program, +or file only under similar circumstances. + +
+Three new primitives have been added to allow a Scheme process to +track usage of virtual memory for its heap. + +
+current-memory-bytes returns the total number of bytes of +virtual memory used or reserved to represent the Scheme heap. +This differs from bytes-allocated, which returns the number +of bytes currently occupied by Scheme objects. +current-memory-bytes additionally includes memory used for +heap management as well as memory held in reserve to satisfy future +allocation requests. + +
+maximum-memory-bytes returns the maximum number of bytes +of virtual memory occupied or reserved for the Scheme heap by the +calling process since the last call to reset-maximum-memory-bytes! +or, if reset-maximum-memory-bytes! has never been called, +since system start-up. + +
+reset-maximum-memory-bytes! resets the maximum memory bytes +to the current memory bytes. + +
+The character sets, character classes, and word-breaking algorithms +for character, string, and Unicode-related bytevector operations +have now been updated to Unicode 7.0. + +
+Support for running Chez Scheme on 32-bit PowerPC processors +running Linux has been added, with machines type ppc32le (nonthreaded) +and tppc32le (threaded). +C code intended to be linked with these versions of the system +should be compiled using the GNU C compiler's -m32 option. + +
+The printed representation of a procedure now includes the source +file and beginning file position when available. + +
+The default exception handler now catches I/O exceptions that occur +when it attempts to display a condition and, if an I/O exception +does occur, resets as if by calling the reset procedure. +The intent is to avoid an infinite regression (ultimately ending +in exhaustion of memory) in which the process repeatedly recurs +back to the default exception handler trying to write to a console-error +port (typically stderr) that is no longer writable, e.g., due to +the other end of a pipe or socket having been closed. + +
+The header file scheme.h distributed with Chez Scheme now includes +several new lock-related macros: +INITLOCK (corresponding to ftype-init-lock!), +SPINLOCK (ftype-spin-lock!), +UNLOCK (ftype-unlock!), +LOCKED_INCR (ftype-locked-incr!), and +LOCKED_DECR (ftype-locked-decr!). +All take a pointer to an iptr or uptr. +LOCKED_INCR and LOCKED_DECR also take an +lvalue argument that is set to true (nonzero) if the result +of the increment or decrement is zero, otherwise false (zero). + +
+The new procedure compile-to-file is similar to +compile-to-port with the output port replaced with an +output pathname. + +
+Version 9.2 includes support for whole-program optimization of a top-level +program and the libraries upon which it depends at run time based on "wpo" +(whole-program-optimization) files produced as a byproduct of compiling +the program and libraries when the parameter generate-wpo-files +is set to #t. +The new procedure compile-whole-program takes as input +a wpo file for a top-level program, combines it with the wpo files for +any libraries the program requires at run time, and produces a single +object file containing a self-contained program. +In so doing, it discards unused code and optimizes across program and +library boundaries, potentially reducing program load time, run time, +and memory requirements. + +
+compile-file, compile-program, compile-library, +and compile-script produce wpo files as well as ordinary +object files when the new generate-wpo-files parameter is set +to #t (the default is #f). +compile-port and compile-to-port do so when passed +an optional wpo output port. + +
+A new set of primitives that operate on symbol +hashtables has been added: + +
+ +
symbol-hashtable?
+
+symbol-hashtable-ref
+
+symbol-hashtable-set!
+
+symbol-hashtable-contains?
+
+symbol-hashtable-cell
+
+symbol-hashtable-update!
+
+symbol-hashtable-delete!
+
These are like their generic counterparts but operate only on symbol +hashtables, i.e., hashtables created with symbol-hash as +the hash function and eq?, eqv?, equal?, +or symbol=? as the equivalence function. + +
+These primitives are more efficient at optimize-level 3 than their +generic counterparts when both are applied to symbol hashtables. +The performance of symbol hashtables has been improved even when the new +operators are not used (Section 4.19). + +
+strip-fasl-file can now strip fasl files created for a machine +type other than the machine type of the calling process as long as the +Chez Scheme version is the same. + +
+The new procedure source-file-descriptor can be used to construct +a custom source-file descriptor or reconstruct a source-file descriptor +from values previously extracted from another source-file descriptor. +It takes two arguments: a string path and exact nonnegative integer +checksum and returns a new source-file descriptor. + +
+The new procedure locate-source can be used to determine a full +path, line number, and character position from a source-file descriptor +and file position. +It accepts two arguments: a source-file descriptor sfd and an +exact nonnegative integer file position fp. +It returns zero values if the unmodified file is not found in the source +directories and three values (string path, exact nonnegative +integer line, and exact nonnegative integer char) if the +file is found. + +
+Support for creating and handling files that begin with uncompressed +data and end with compressed data has been added in the form of the +new procedure port-file-compressed! that takes a port and +if not already set up to read or write compressed data, sets it up +to do so. +The port must be a file port pointing to a regular file, i.e., a +file on disk rather than a socket or pipe, and the port must not be +an input/output port. +The port can be a binary or textual port. +If the port is an output port, subsequent output sent to the port +will be compressed. +If the port is an input port, subsequent input will be decompressed +if and only if the port is currently pointing at compressed data. + +
+When the parameter compile-compressed is set ot #t, +the compile-script and compile-program procedures +take advantage of this functionality to copy the #! prefix, +if present in the source file, uncompressed in the object file while +compressing the object code emitted for the program, thus reducing +the size of the resulting file without preventing the #! +line from being read and interpreted properly by the operating +system. + +
+In previous releases, when an object file was found before the +corresponding source file in the library directories, the object file was +older, and the parameter compile-imported-libraries was not set, +the object file was loaded rather than the source file. +The (newer) source file is now loaded instead, just as it would be if +the source file is found before the corresponding, older object file. +This is an incompatible change. + +
+strip-fasl-file now supports stripping of all compile-time +information and no longer supports stripping of just library visit code. +Stripping all compile-time information nearly always results in smaller +object files than stripping just library visit code, with a corresponding +reduction in the memory required when the resulting +file is loaded. + +
+To reflect this, the old fasl-strip option library-visit-code +has been eliminated, and the new fasl-strip option +compile-time-information has been added. +This is an incompatible change in that code that previously +used the fasl-strip option library-visit-code will +have to be modified to omit the option or to replace it with +compile-time-information. + +
+Visiting (via visit) a library no longer loads the library's +run-time information (invoke dependencies and invoke code), and revisiting +(via revisit) a library no longer loads the library's +compile-time information (import and visit dependencies and import and +visit code). + +
+When a library is invoked due to a run-time dependency of another +library or a top-level program on the library, the library is now +"revisited" (as if via revisit) rather than "loaded" +(as if via load). +As a result, the compile-time information is not loaded, which can result +in substantial reductions in both library invocation time and memory +footprint. + +
+If a library is revisited, either explicitly or as the result of run-time +dependency, a subsequent import of the library causes it to be +"visited" (as if via visit) if the same object file can be +found at the same path and the visit code has not been stripped. +The compile-time code can alternatively be loaded explicitly from the same or a +different file via a direct call to visit. + +
+While this change is mostly transparent (ignoring the reduced invocation +time and memory footprint), it is an incompatible change in the +sense that the system potentially reads the file twice and can run +code that is marked using eval-when as both visit +and revisit code. + +
+Version 9.1 includes support for a new heap inspection tool that +allows a programmer to look for objects in the heap according to +arbitrary predicates. +The new procedure make-object-finder takes a predicate pred and two optional +arguments: a starting point x and a maximum generation g. +The starting point defaults to the value of the procedure oblist, +and the maximum generation defaults to the value of the parameter +collect-maximum-generation. +make-object-finder returns an object finder p that can be used to +search for objects satisfying pred within the starting-point object x. +Immediate objects and objects in generations older than g are treated +as leaves. +p is a procedure accepting no arguments. +If an object y satisfying pred can be found starting with x, +p returns a list whose first element is y and whose remaining +elements represent the path of objects from x to y, listed +in reverse order. +p can be invoked multiple times to find additional objects satisfying +the predicate, if any. +p returns #f if no more objects matching the predicate +can be found. + +
+p maintains internal state recording where it has been so that it +can restart at the point of the last found object and not return +the same object twice. +The state can be several times the size of the starting-point object +x and all that is reachable from x. + +
+The interactive inspector provides a convenient interface to the object +finder in the form of find and find-next commands. +The find command evaluates its first argument, which should +evaluate to the desired predicate, and treats its second argument, if +present, as the maximum generation, overriding the default. +The starting point x is the object upon which the +inspector is currently focused. +If an object is found, the inspector's new focus is the found object, +the parent focus (obtainable via the up command) is the first +element in the (reversed) path, the parent's parent is the next element, +and so on up to x. +The find-next command repeats the last find, as if by an explicit +invocation of the same object finder. + +
+Relocation tables for static code objects are discarded by default, which +prevents object finders from providing accurate results when static code +objects are involved. +That is, they will not find any objects pointed to directly from a code +object that has been promoted to the static generation. +If this is a problem, the command-line argument +--retain-static-relocation can be used to prevent the relocation +tables from being discarded. + +
+The new procedure object-counts can be used to determine, +for each type of object, the number and size in bytes of objects of +that type in each generation. +Its return value has the following structure: + +
+ +
((type (generation count . bytes) ...) ...) +
type is either the name of a primitive type, represented as a +symbol, e.g., pair, or a record-type descriptor (rtd). +generation is a nonnegative fixnum between 0 and the value +of (collect-maximum-generation), inclusive, or the symbol +static representing the static generation. +count and bytes are nonnegative fixnums. + +
+Object counts are accurate for a generation n immediately after +a collection of generation n or higher if enabled during that +collection. +Object counts are enabled by setting the parameter +enable-object-counts to #t. +The command-line option --enable-object-counts can be used to +set this parameter to #t on startup. +Object counts are not enabled by default since it adds overhead to +garbage collection. + +
+To make the information more useful in the presence of ftype pointers, +the ftype descriptors produced by define-ftype for each +defined ftype now carry the name of the ftype rather than a generic +name like ftd-struct. +(Ftype descriptors are subtypes of record-type descriptors and can appear +as types in the object-counts return value.) + +
+To simplify interaction with tools that naively expose multiple-character +end-of-line sequences such as CRLF as separate characters to the user, the +native end-of-line style (native-eol-style) is now none +on all machine types. +This is an incompatible change. + +
+In previous releases, the library-requirements procedure +returns a list of all libraries required by the specified library, +whether they are needed when the specified library is imported, +visited, or invoked. +While this remains the default behavior, library-requirements +now takes an optional "options" argument. +This must be a library-requirements-options enumerations set, i.e., the +value of a library-requirements-options form with some subset of +the options import, visit@visit, invoke@visit, +and invoke. import includes the libraries +that must be imported when the specified library is imported; +visit@visit includes the libraries that must be visited when +the specified library is visited; invoke@visit includes the libraries +that must be invoked when the specified library is visited; and +invoke includes the libraries that must be invoked when +the specified library is invoked. +The default behavior is obtained by supplying a enumeration set containing all +of these options. + +
+Two new procedures, compute-size and +compute-composition, can be used to determine the +size and make-up of nested objects with the heap. + +
+Both take an object and an optional generation. +The generation must be a fixnum between 0 and the value of +(collect-maximum-generation), inclusive, or the symbol static. +It defaults to the value of (collect-maximum-generation). + +
+compute-size returns the number of bytes occupied by the object +and everything to which it points, ignoring objects in generations older +than the specified generation. + +
+compute-composition returns an association list giving the +number and number of bytes of each type of object that the specified +object is constructed from, ignoring objects in generations older than +the specified generation. The association list maps type names (e.g., +pair and flonum) or record-type descriptors to a pair of fixnums +giving the count and bytes. +Types with zero counts are not included in the list. + +
+A surprising number of objects effectively point indirectly to a large +percentage of all objects in the heap due to the attachment of top-level +environment bindings to symbols, but the generation argument can be used +in combination with explicit calls to collect (with automatic collections +disabled) to measure precisely how much space is allocated to freshly +allocated structures. + +
+When used directly from the REPL with no other threads running, +(compute-size (oblist) 'static) effectively gives the size of +the entire heap, and (compute-composition (oblist) 'static) +effectively gives the composition of the entire heap. + +
+The inspector makes the aggregate size of an object similarly available +through the size inspector-object message and the corresponding +size interactive-inspector command, with the twist that it +does not include objects whose sizes were previously requested in the +same session, making it possible to see the effectively smaller sizes +of what the programmer perceives to be substructures in shared and +cyclic structures. + +
+These procedures potentially allocate a large amount of memory and +so should be used only when the information returned by the +procedure object-counts (see preceding entry) does not suffice. + +
+Relocation tables for static code objects are discarded by default, +which prevents these procedures from providing accurate results when +static code objects are involved. +That is, they will not find any objects pointed to directly from a code +object that has been promoted to the static generation. +If accurate sizes and compositions for static code objects are +required, the command-line argument --retain-static-relocation +can be used to prevent the relocation tables from being discarded. + +
+When the parameter expand-output is set to a textual output +port, the output of the expander is printed to the port as a side effect +of running compile, interpret, or any of the file +compiling primitives, e.g., compile-file or +compile-library. +Similarly, when the parameter expand/optimize-output is set to a +textual output port, the output of the source optimizer is printed. + +
+When undefined-variable-warnings is set to #t, the +compiler issues a warning message whenever it cannot determine that +a variable bound by letrec, letrec*, or an internal +definition will not be referenced before it is defined. +The default value is #f. + +
+Regardless of the setting of this parameter, the compiler inserts code +to check for the error, except at optimize level 3. +The check is fairly inexpensive and does not typically inhibit inlining +or other optimizations. +In code that must be carefully tuned, however, it is sometimes useful +to reorder bindings or make other changes to eliminate the checks. +Enabling this warning can facilitate this process. + +
+The checks are also visible in the output of expand/optimize. + +
+When the new boolean parameter require-nongenerative-clause +is set to #t, a define-record-type without a +nongenerative clause is treated as a syntax error. +This allows the programmer to detect accidental use of generative +record types. +Generative record types are rarely useful and are less efficient +than nongenerative types, since generative record types require the +construction of a record-type-descriptor each time a +define-record-type form is evaluated rather than once, +at compile time. +To support the rare need for a generative record type while still +allowing accidental generativity to be detected, +define-record-type has been extended to allow a generative +record type to be explicitly declared with a nongenerative +clause with #f for the uid, i.e., (nongenerative #f). + +
+Cross-compilation support has been improved in two ways: (1) it is +now possible to cross-compile a library and import it later in a +separate process for cross-compilation of dependent libraries, and +(2) the code produced for the target machine when cross compiling is no +longer less efficient than code produced natively on the target +machine. + +
+Support for running Chez Scheme on ARMv6 processors running Linux +has been added, with machine type arm32le (32-bit nonthreaded). +C code intended to be linked with these versions of the system +should be compiled using the GNU C compiler's -m32 option. + +
+When available at compile time, source information is now included +in run-time error messages produced when ftype-&ref, +ftype-ref, ftype-set!, and the locked ftype +operations are handed invalid inputs, e.g., ftype pointers of some +unexpected type, RHS values of some unexpected type, or improper +indices. + +
+When passed a single top-level-program form, +compile-to-port now returns a list of the libraries the +top-level program requires at run time, as with compile-program. +Otherwise, the return value is unspecified. + +
+When make-record-type or make-record-type-descriptor +detect an incompatibility between two record types with the same +UID, the resulting error messages provide more information to +describe the mismatch, i.e., whether the parent, fields, flags, or +mutability differ. + +
+When a library is compiled, information is stored with the object +code to enable propagation of constants and inlining of procedures +defined in the library into dependent libraries. +The new parameter enable-cross-library-optimization, whose +value defaults to #t, can be set to #f to prevent +this information from being stored and disable the corresponding +optimizations. +This might be done to reduce the size of the object files or to +reduce the potential for exposure of near-source information via +the object file. + +
+The new procedure strip-fasl-file allows the removal of +source information of various sorts from a compiled object (fasl) file +produced by compile-file or one of the other file compiling +procedures. +It also allows removal of library visit code, i.e., the code +required to compile (but not run) dependent libraries. + +
+strip-fasl-file accepts three arguments: an input pathname, +and output pathname, and a fasl-strip-options enumeration set, +created by fasl-strip-options with zero or more of the +following options. + +
+
+
+
+
+The bound of an ftype array can now be zero and, when zero, is +treated as unbounded in the sense that no run-time upper-bound +checks are performed for accesses to the array. +This simplifies the creation of ftype arrays whose actual bounds +are determined dynamically. + +
+In previous releases, profile and inspector source information was +gathered and stored together so that compiling with profiling enabled +required that inspector information also be stored with each code object. +This is no longer the case. + +
+case now uses member rather than memv for key +comparisons, a generalization that allows case to be used for +strings, lists, vectors, etc., rather than just atomic values. +This adds no overhead when keys are comparable with memv, +since the compiler converts calls to member into calls to +memv (or memq, or even individual inline pointer +comparisons) when it can determine the more expensive test is not +required. + +
+The case syntax exported by the (rnrs) and +(rnrs base) libraries still uses memv for +compatibility with the R6RS standard. + +
+The write and display procedures now recognize +foreign addresses that happen to look like Scheme objects and print +them as #<foreign>; previously, write and +display would attempt to treat the addresses as Scheme +objects, typically leading to invalid memory references. +Some foreign addresses are indistinguishable from fixnums and +still print as fixnums. + +
+Compiled code can be instrumented to gather two kinds of +execution counts, source-level and block-level, via different settings +of the compile-profile parameter. +When compile-profile is set to the symbol source +at compile time, source execution counts are gathered by the generated +code, and when compile-profile is set to block, +block execution counts are gathered. +Setting it to #f (the default) disables instrumentation. + +
+Source counts are identical to the source counts gathered by generated +code in previous releases when compiled with +compile-profile set to #t, and #t +can be still be used in place of source for backward +compatibility. +Source counts can be viewed by the programmer at the end of the run +of the generated code via profile-dump-list and +profile-dump-html. + +
+Block counts are per basic block. +Basic blocks are individual sequences of straight-line code and are +the building blocks of the machine code generated by the compiler. +Counting the number of times a block is executed is thus equivalent +to counting the number of times the instructions within it are +executed. + +
+There is no mechanism for the programmer to view block counts, but +both block counts and source counts can now be saved after a sample +run of the generated code for use in guiding various optimizations +during a subsequent compilation of the same code. + +
+The source counts can be used by "profile-aware macros," i.e., +macros whose expansion is guided by profiling information. +A profile-aware macro can use profile information to optimize +the code it produces. +For example, a macro defining an abstract datatype might choose +representations and algorithms based on the frequencies +of its operations. +Similarly, a macro, like case, that performs a set of +disjoint tests might choose to order those tests based on which are +most likely to succeed. +Indeed, the built-in case now does just that. +A new syntactic form, exclusive-cond, abstracts a common +use case for profile-aware macros. + +
+The block counts are used to guide certain low-level optimizations, +such as block ordering and register allocation. + +
+The procedure profile-dump-data writes to a specified file +the profile data collected during the run of a program compiled +with compile-profile set to either source or +block. +It is similar to profile-dump-list or profile-dump-html +but stores the profile data in a machine readable form. + +
+The procedure profile-load-data loads one or more files +previously created by profile-dump-data into an internal +database. + +
+The database associates weights with source locations or +blocks, where a weight is a flonum representing the ratio of the +location's count versus the maximum count. +When multiple profile data sets are loaded, the weights for each +location are averaged across the data sets. + +
+The procedure profile-query-weight accepts a source object +and returns the weight associated with the location identified by +the source object, or #f if no weight is associated with +the location. +This procedure is intended to be used by a profile-aware macro on +pieces of its input to optimize code based on profile data previously +stored by profile-dump-data and loaded by +profile-load-data. + +
+The procedure profile-clear-data clears the database. + +
+The new exclusive-cond syntax is similar to cond +except it assumes the tests performed by the clauses are disjoint +and reorders them based on available profiling data. +Because the tests might be reordered, the order in which side effects +of the test expressions occur is undefined. +The built-in case form is implemented in terms of +exclusive-cond. + +
+A new foreign type, ssize_t, is now supported. +It is the signed analogue of size_t. + +
+When make-guardian is passed a second, representative, +argument, the representative is returned from the guardian in place +of the guarded object when the guarded object is no longer accessible. + +
+A library initially imported from an object file is now reimported from +source when a dependency (another library or include file) has changed +since the library was compiled. + +
+The expression editor now performs filename- rather than +command-completion within string constants. +It looks only at the current line to determine whether the cursor is +within a string constant; this can lead to the wrong kind of command +completion for strings that cross line boundaries. + +
+The built in ftype ftype-lock has been eliminated along +with the corresponding procedures, acquire-lock, +release-lock, and initialize-lock. +This is an incompatible change, although defining +ftype-lock and the associated procedures is straightforward +using the forms described below. + +
+The functionality has been replaced and generalized by four new syntactic +forms that operate on lock fields wherever they appear within a foreign +type: + +
+ +
(ftype-init-lock! T (a ...) e)
+
+(ftype-lock! T (a ...) e)
+
+(ftype-spin-lock! T (a ...) e)
+
+(ftype-unlock! T (a ...) e)
+
The access chain a ... must specify a word-size +integer represented using the native endianness, i.e., a uptr +or iptr. +It is a syntax violation when this is not the case. + +
+For each of the forms, the expression e is evaluated first +and must evaluate to a ftype pointer p of type T. + +
+ftype-init-lock! initializes the specified field of the foreign +object to which p points, puts the field into the unlocked state, +and returns an unspecified value. + +
+If the field is in the unlocked state, ftype-lock! puts it +into the locked state and returns #t. +If the field is already in the locked state, ftype-lock! +returns #f. + +
+ftype-spin-lock! loops until the lock is in the unlocked +state, then puts it into the locked state and returns an unspecified +value. +This operation will never return if no other thread or process +unlocks the field, causing interrupts and requests for collection to +be ignored. + +
+Finally, ftype-unlock puts the field into the unlocked state +(regardless of the current state) and returns an unspecified value. + +
+An additional pair of syntactic forms can be used when just an +atomic increment or decrement is required: + +
+ +
(ftype-locked-incr! T (a ...) e)
+
+(ftype-locked-decr! T (a ...) e)
+
As for the first set of forms, the access chain a ... +must specify a word-size integer represented using the native endianness. + +
+The new procedure ftype-pointer-null? can be used to compare the +address of its single argument, which must be an ftype pointer, against 0. +It returns #t if the address is 0 and #f otherwise. +Similarly, ftype-pointer=? can be used to compare the +addresses of two ftype-pointer arguments. +It returns #t if the address are the same and #f +otherwise. + +
+These are potentially more efficient than extracting ftype-pointer +addresses first, which might result in bignum allocation for addresses +outside the fixnum range, +although the compiler also now +tries to avoid allocation when the result of a call to +ftype-pointer-address is directly compared with 0 or with the +result of another call to ftype-pointer-address, as described +in Section 4.26. + +
+gensym now accepts a second optional argument, the unique +name to use. +It must be a string and should not be used by any other gensym intended +to be distinct from the new gensym. + +
+In previous releases, collection times as reported by statistics +or printed by display-statistics were gathered internally +with millisecond granularity at each collection, possibly leading to +significant inaccuracies over the course of many collections. +They are now maintained using high-resolution timers with generally +much better accuracy. + +
+New time types time-collector-cpu and time-collector-real +have been added. +When current-time is passed one of these types, a time +object of the specified type is returned and represents the time +(cpu or real) spent during collection. + +
+Previously, this information was available only via the +statistics or display-statistics procedures, and then +with lower precision. + +
+Three new storage-management introspection procedures have been +added: + +
+ +
(collections)
+
+(initial-bytes-allocated)
+
+(bytes-deallocated)
+
collections returns the number of collections performed so +far by the current Scheme process. + +
+initial-bytes-allocated returns the number of bytes +allocated after loading the boot files and before running any +non-boot user code. + +
+bytes-deallocated returns the total number of bytes +deallocated by the collector. + +
+Previously, this information was available only via the +statistics or display-statistics +procedures. + +
+Three new procedures for performing arithmetic on time objects have +been added, per SRFI 19: + +
+ +
(time-difference t1 t2) t3
+
+(add-duration t1 t2) t3
+
+(subtract-duration t1 t2) t3
+
time-difference takes two time objects t1 and t2, +which must have the same time type, and returns the result of subtracting +t2 from t1, represented as a new time object with type +time-duration. +add-duration adds time object t2, which must be of type +time-duration, to time object t1, producing a new time object +t3 with the same type as t1. +subtract-duration subtracts time object t2 which must be +of type time-duration, from time object t1, producing a new +time object t3 with the same type as t1. + +
+SRFI 19 also names destructive versions of these operators: + +
+ +
(time-difference! t1 t2) t3
+
+(add-duration! t1 t2) t3
+
+(subtract-duration! t1 t2) t3
+
These are available as well in Chez Scheme but are actually +nondestructive, i.e., entirely equivalent to the nondestructive +versions. + +
+The compiler now collects and reports profile counts for every +source expression that is not determined to be dead either at +compile time or by the time the profile information is obtained via +profile-dump-list or profile-dump-html. +Previously, the compiler suppressed profile counts for constants and +variable references in contexts where the information was likely (though +not guaranteed) to be redundant, and it dropped profile counts for some +forms that were optimized away, such as inlined calls, folded calls, +or useless code. +Furthermore, profile counts now uniformly represent the number of times +a source expression's evaluation was started, which was not always the +case before. + +
+A small related enhancement has been made in the HTML output produced +by profile-dump-html. +Hovering over a source expression now shows, in addition to the count, +the starting position (line number and character) of the source expression +to which the count belongs. +This is useful for identifying when a source expression does not have its +own count but instead inherits the count (and color) from an enclosing +expression. + +
+A limited set of virtual registers is now supported by the compiler +for use by programs that require high-speed, global, and mutable storage +locations. +Referencing or assigning a virtual register is potentially faster and +never slower than accessing an assignable local or global variable, +and the code sequences for doing so are generally smaller. +Assignment is potentially significantly faster because there is no need +to track pointers from the virtual registers to young objects, as there +is for variable locations that might reside in older generations. +On threaded versions of the system, virtual registers are "per thread" +and thus serve as thread-local storage in a manner that is less expensive +than thread parameters. + +
+The interface consists of three procedures: + +
+(virtual-register-count) returns the number of virtual registers. +As of this writing, the count is set at 16. This number is fixed, i.e., +cannot be changed except by recompiling Chez Scheme from source. + +
+(set-virtual-register! k x) stores x in virtual +register k. +k must be a fixnum between 0 (inclusive) and the value of +(virtual-register-count) (exclusive). + +
+(virtual-register k) returns the value most recently +stored in virtual register k (on the current thread, in threaded +versions of the system). + +
+To get the fastest possible speed out of the latter two procedures, +k should be a constant embedded right in the call +(or propagatable via optimization to the call). +To avoid putting these constants in the source code, programmers should +consider using identifier macros to give names to virtual registers, e.g.: + +
+ +
(define-syntax foo
+
+ (identifier-syntax
+
+ [id (virtual-register 0)]
+
+ [(set! id e) (set-virtual-register! 0 e)]))
+
+(set! foo 'hello)
+
+foo hello
+
Virtual-registers must be treated as an application-level resource, i.e., +libraries intended to be used by multiple applications should generally +not use virtual registers to avoid conflicts with the applications use of +the registers. + +
+Support for storing and extracting 24-, 40-, 48-, and 56-bit integers +to and from records, bytevectors, and foreign types (ftypes) has been +added. +For records and ftypes, this is accomplished by declaring a field +to be of type +integer-24, unsigned-24, +integer-40, unsigned-40, +integer-48, unsigned-48, +integer-56, or unsigned-56. +For bytevectors, this is accomplished via the following new +primitives: + +
+ +
bytevector-24-ref
+
+bytevector-24-set!
+
+bytevector-40-ref
+
+bytevector-40-set!
+
+bytevector-48-ref
+
+bytevector-48-set!
+
+bytevector-56-ref
+
+bytevector-56-set!
+
Similarly, support has been added for sending and receiving +24-, 40-, 48-, and 56-bit integers to and from foreign code via +foreign-procedure and foreign-callable. +Arguments and return values of type integer-24 and +unsigned-24 are passed as 32-bit quantities, while +those of type integer-40, unsigned-40, +integer-48, unsigned-48, integer-56, +and unsigned-56 are passed as 64-bit quantities. + +
+For unpacked ftypes, a 48-bit (6-byte) quantity is aligned +on an even two-byte boundary, while a +24-bit (3-byte), 40-bit (5-byte), or 56-bit (7-byte) quantity +is aligned on an arbitrary byte boundary. + +
+A pariah expression: + +
+ +
(pariah expr expr ...) +
is syntactically similar and semantically equivalent to a begin +expression but tells the compiler that the expressions within are +relatively unlikely to be executed. +This information is currently used by the compiler for prioritizing +allocation of registers to variables and for putting pariah code +out-of-line in an attempt to reduce instruction cache misses for the +remaining code. + +
+A pariah form is generally most usefully wrapped around the +consequent or alternative of an if expression to identify which +is the less likely path. + +
+The compiler implicitly treats as pariah code any code that leads +up to an unconditional call to raise, error, +errorf, assertion-violation, etc., so it is not +necessary to wrap a pariah around such a call. + +
+At some point, there will likely be an option for gathering similar +information automatically via profiling. +In the meantime, we are interested in feedback about whether the +mechanism is beneficial and whether the benefit of using the +pariah form outweighs the programming overhead. + +
+Local imports within a library now trigger automatic recompilation +of the library when the imported library has been recompiled or needs +to be recompiled, in the same manner as imports listed directly in the +importing library's library form. +Changes in include files also trigger automatic recompilation. + +
+(Automatic recompilation of a library is enabled when an import of +the library, e.g., in another library or in a top-level program, is +compiled and the parameter compile-imported-libraries is set +to a true value.) + +
+Profiling information is no longer produced for constants and variable +references where the information is likely to be redundant. +It is still produced in contexts where the counts are likely to differ +from those of the enclosing form, e.g., where a constant or variable +reference occurs in the consequent or alternative of an if +expression. +This change brings the profiling information largely in sync with +Version 8.4.1 and earlier, though Version 8.9.2 retains source information +in a few cases where it is inappropriately discarded by Version 8.4.1's +compiler, and Version 8.9.2 discards source information in a few cases +where the code has been optimized away. + +
+The procedure compile-to-port is like compile-port +but, instead of taking an input port from which it reads expressions +to be compiled, takes a list of expressions to be compiled. +As with compile-port, the second argument must be a binary +output port. + +
+Newly introduced debug levels control the amount of debugging support +embedded in the code generated by the compiler. +The current debug level is controlled by the parameter +debug-level and must be set when the compiler is run to have +any effect on the generated code. +Valid debug levels are 0, 1, 2, and 3, and the default is 1. +At present, the only difference between debug levels is whether calls to +certain error-producing routines, like error, whether explicit +or as the result of an implicit run-time check (such as the pair check +in car), are treated as tail calls even when not in tail position. +At debug levels 0 and 1, they are treated as tail calls, and at debug +levels 2 and 3, they are treated as nontail calls. +Treating them as tail calls is more efficient, but treating them as +nontail calls leaves more information on the stack, which affects what +can be shown by the inspector. + +
+For example, assume f is defined as follows: + +
+ +
(define f
+
+ (lambda (x)
+
+ (unless (pair? x) (error #f "oops"))
+
+ (car x)))
+
and is called with a non-pair argument, e.g.: + +
+ +
(f 3) +
If the debug level is 2 or more at the time the definition is compiled, +the call to f will still be on the stack when the exception +is raised by error and will thus be visible to the inspector: + +
+ +
> (f 3)
+
+Exception: oops
+
+Type (debug) to enter the debugger.
+
+> (debug)
+
+debug> i
+
+#<continuation in f> : sf
+
+ 0: #<continuation in f>
+
+ 1: #<system continuation in new-cafe>
+
+#<continuation in f> : s
+
+ continuation: #<system continuation in new-cafe>
+
+ procedure code: (lambda (x) (if (...) ...) (car x))
+
+ call code: (error #f "oops")
+
+ frame and free variables:
+
+ 0. x: 3
+
On the other hand, if the debug level is 1 (the default) or 0 at the +time the definition of f is compiled, the call to f +will no longer be on the stack: + +
+ +
> (f 3)
+
+Exception: oops
+
+Type (debug) to enter the debugger.
+
+> (debug)
+
+debug> i
+
+#<system continuation in new-cafe> : sf
+
+ 1: #<system continuation in new-cafe>
+
+Cost centers are used to track the bytes allocated, instructions executed, +and/or cpu time elapsed while evaluating selected sections of code. +Cost centers are created via the procedure make-cost-center, and +costs are tracked via the procedure with-cost-center. + +
+Allocation and instruction counts are tracked only for code instrumented +for that purpose. +This instrumentation is controlled by the generate-allocation-counts +and generate-instruction-counts parameters. +Instrumentation is disabled by default. +Built in procedures are not instrumented, nor is interpreted code or +non-Scheme code. +Elapsed time is tracked only when the optional timed? argument to +with-cost-center is provided and is not false. + +
+The with-cost-center procedure accurately tracks costs, subject +to the caveats above, even when reentered with the same cost center, used +simultaneously in multiple threads, and exited or reentered one or more +times via continuation invocation. + +
+thread parameter: generate-allocation-counts + +
+When this parameter has a true value, the compiler inserts a short sequence of +instructions at each allocation point in generated code to track the amount of +allocation that occurs. +This parameter is initially false. + +
+thread parameter: generate-instruction-counts + +
+When this parameter has a true value, the compiler inserts a short +sequence of instructions in each block of generated code to track the +number of instructions executed by that block. +This parameter is initially false. + +
+procedure: (make-cost-center) + +
+Creates a new cost-center object with all of its recorded costs +set to zero. + +
+procedure: (cost-center? obj) + +
+Returns #t if obj is a cost-center object, otherwise +returns #f. + +
+procedure: (with-cost-center cost-center thunk)
+
+procedure: (with-cost-center timed? cost-center thunk)
+
+
+This procedure invokes thunk without arguments and returns its +values. +It also tracks, dynamically, the bytes allocated, instructions executed, +and cpu time elapsed while evaluating the invocation of thunk and +adds the tracked costs to the cost center's running record of these costs. + +
+Allocation counts are tracked only for code compiled with the parameter +generate-allocation-counts set to true, and +instruction counts are tracked only for code compiled with +generate-instruction-counts set to true. +Cpu time is tracked only if timed? is provided and not false and +includes cpu time spent in instrumented, uninstrumented, and non-Scheme +code. + +
+procedure: (cost-center-instruction-count cost-center) + +
+This procedure returns instructions executed recorded by +cost-center. + +
+procedure: (cost-center-allocation-count cost-center) + +
+This procedure returns the bytes allocated recorded by cost-center. + +
+procedure: (cost-center-time cost-center) + +
+This procedure returns the cpu time recorded by cost-center. + +
+procedure: (reset-cost-center! cost-center) + +
+This procedure resets the costs recorded by cost-center to zero. + +
+Two system primitives, #%$read-time-stamp-counter and +#%$read-performance-monitoring-counter, provide access to the +x86 and x86_64 hardware time-stamp counter register and to the +model-specific performance monitoring registers. + +
+These primitives rely on instructions that might be restricted to run only in +kernel mode, depending on kernel configuration. +The performance monitoring counters must also be configured to enable +monitoring and to specify which event to monitor. +This can be configured only by instructions executed in kernel mode. + +
+procedure: (#%$read-time-stamp-counter) + +
+This procedure returns the current value of the time-stamp counter for +the processor core executing this code. +A general protection fault, which manifests as an invalid memory +reference exception, results if this operation is not permitted by +the operating system. + +
+Since multiple processes might run on the same core between reads of +the time-stamp counter, the counter does not necessarily reflect time +spent only in the current process. +Also, on machines with multiple cores, the executing process might be +swapped to a different core with a different time-stamp counter. + +
+procedure: (#%$read-performance-monitoring-counter counter) + +
+This procedure returns the current value of the model-specific +performance monitoring register specified by counter. +counter must be a fixnum and should specify a valid performance +monitoring register. +Allowable values depend on the processor model. +A general protection fault, which manifests as an invalid memory +reference exception, results if this operation is not permitted by +the operating system or if the specified counter does not exist. + +
+In order to get meaningful results, the performance monitoring registers +must be enabled, and the event to be monitored must by configured by +the performance monitoring control register. +This configuration can be done only by code run in kernel mode. + +
+Since multiple processes might run on the same core between reads of +a performance monitoring register, the register does not necessarily reflect +only the activities of the current process. +Also, on machines with multiple cores, the executing process might be +swapped to a different core with its own set of performance monitoring +registers and possibly a different configuration for those registers. + +
+Within the interactive inspector, closure and frame variables can now +be set by name, and the forward (f) and back (b) commands can now be +used to to move among the frames that comprise a continuation. + +
+A new show-local (sl) command can be be used to look at just the local +variables of a stack frame. +This contrasts with the show (s) command, which shows the free variables +of the frame's closure as well. + +
+Errors occurring during inspection, such as attempts to assign immutable +variables, are handled more smoothly than in previous versions. + +
+The fasl writer and reader now support records with non-ptr fields, +e.g., integer-32, wchar, etc., allowing constant record instances with +such fields to appear in source code (or be introduced as constants +by macros) into code to be compiled via compile-file, +compile-library, compile-program, +compile-script, or compile-port. +Ftype-pointer fields are not supported, since storing addresses +in fasl files does not generally make sense. + +
+At optimize-level 3, the record? predicate could short circuit without +evaluating the rtd expression. + +
+On 32-bit platforms, calling Sinteger64 or Sunsigned64 +with 0x8000000000000000 could return the wrong value. + +
+When called on a C value equal to most-negative-fixnum, Sinteger32 +and Sinteger64 could return a bignum where a fixnum is expected. +The values have the same printed representation, yet comparing the resulting bignum with +most-negative-fixnum via Scheme's = returned false. + +
+A bug where import did not recognize a library-spec +of the form (library library-reference) has been fixed. + +
+A bug where the garbage collector sometimes incorrectly handles epehemeron pairs has +been fixed. + +
+A bug where the garbage collector sometimes incorrectly handles mutated weak pairs has +been fixed. + +
+A bug that caused /, cfl/, atan, and atanh to return +an incorrect real or imaginary +nan.0 component has been fixed. The inexact complex number +division routine now uses Robert L. Smith's 1962 algorithm. + +
+Fixed a crash at optimize-level 2 and higher caused by the compiler generating +an invalid live-pointer mask when inline-expanding certain primitive calls that +store raw data on the stack and whose operands contain calls. + +
+When remove, member or assoc were used in +optimize-level 3 in a position where the result was discarded, +a bug in the source code optimizer could drop the call even though the first +argument may be a record with a custom equality predicate that has side effects. + +
+When a foreign callable receives a double or float argument, the +allocation of space to box the number would try to save the +floating-point return register in the (rare) case that allocation +requires a new page of memory. Saving the return register is harmless on +most platforms, but on x86, a save and restore involves popping then +pushing the x87 register stack, which is invalid if nothing was there +at the start. + +
+Branch generation would go wrong if the displacement was exactly 32,764 bytes. + +
+The character difference operator returned a large positive integer in +situations where the first argument is represented by a lower number than the +second argument. For example: (char- #\a #\b) on 64-bit macOS returns +720575940379279351. The fix corrects this, so that it instead +returns -1. + +
+The arithmetic comparison functions (<, <=, =, +>=, and >) are required to be transitive by the R6RS +specification, but this property was not maintained for <=, +=, and >= comparisons between exact and inexact numbers +in the range where fixnum precision is greater than flonum precision. For +example, the flonum representation of 9007199254740992.0 and +9007199254740993.0 is identical, but obviously +9007199254740992 and 9007199254740993 (which are fixnums +on 64 bit systems) are not. The arithmetic comparators now no longer +convert comparisons of a fixnum and flonum to comparisons of two flonums +when the fixnum cannot be converted without loss of precision. + +
+The rational-value? function returned incorrect results when called on +a value with an inexact zero imaginary part and real part that is an exceptional +floating point value (i.e., an infinity or NaN). For example, +(rational-valued? +inf.0+0.0i) incorrectly returned #t, but now +returns #f. + +
+A interaction bug between Microsoft's longjmp on 64-bit Windows and foreign-callable stack +frames has been fixed. + +
+A bug in the compiler that causes an invalid memory reference with particular +printf control strings and argument counts has been fixed. One example is +(printf "~a~:*"). + +
+The x86_64 code generator now properly sign-extends foreign-call +arguments passed in registers via (& integer-8) and (& integer-16). + +
+When a negative bignum is shifted right by a multiple of the big-digit +bit size (32), a shifted-off bit is non-zero, and the result would be +a sequence of big digits with all one bits before rounding to deal +with the dropped bits, then a carry that should have been delivered to +a new high digit was dropped, producing 0 instead of a negative +number. + +
+For example, (ash (- 1 (ash 1 64)) -32) no longer returns 0. + +
+Prior to this release, sleep of a negative duration would +result in an infinite pause in Windows. Now sleep returns +immediately on all platforms when given a negative duration. + +
+The remainder and modulo functions could produce +imprecise or wrong answers for large integer flonums. Most of the +repair was to use the C library's fmod. + +
+Prior to this release, only one unhandled signal was buffered for +any signal for which a handler has been registered via +register-signal-handler, so two signals delivered in +quick succession could be seen as only one. +The system now buffers a much larger number (63 in this release) of +signals, and the fact that signals can be dropped has now been +documented. + +
+A bug has been fixed in which a call to clear-output-port +on a port could lead to unexpected behavior involving the port, +including loss of buffering or suppression of future output to the +port. + +
+A variety of primitive argument type-checking issues have been +fixed, including missing checks, misleading error messages, +and checks made later than appropriate, i.e., after the primitive +has already had side effects. + +
+The __collect_safe mode for a foreign call or callable now +correctly preserves floating-point registers used for arguments or +results while activating or deactivating a thread on x86_64. + +
+putenv now calls the host system's setenv instead of +putenv on non-Windows hosts and avoids allocating memory that +is never freed, although setenv might do so. + +
+A bug that miscalculated the buffer size for +open-string-input-port given an immutable string has been +fixed. + +
+A bug that produced the wrong sign when multiplying -230 with +itself on 64-bit platforms has been fixed. + +
+A bug that could cause the source optimizer to drop effects within +the argument of a record-accessor call has been fixed. + +
+The welcome text and copyright year in the macOS package file was +corrected. + +
+A bug in the reading of mutually recursive ftype definitions from +compiled files has been fixed. +The bug was triggered by recursive ftype definitions in which one +of the mutually recursive ftypes is a subtype of another, as in: + +
+ +
(define-ftype
+
+ [A (* B)]
+
+ [B (struct [h A])]))
+
It manifested in the fasl reader raising bogus "incompatible record +type" exceptions when two or more references to one of the ftypes +occur in in separate compiled files or in separate top-level forms +of a file compiled via compile-file. +The bug could also have affected other record-type descriptors with +cycles involving parent rtds and "extra" fields as well as fasl +output created via fasl-write. + +
+A bug in compile-whole-library that allowed the invoke code for a +library included in the combined library body to be executed without first +invoking its binary library dependencies has been fixed. +This bug could arise when a member of a combined library was invoked without +invoking the requirements of the other libraries it was combined with. For +instance, consider the case where libraries (A) and (B) are +combined and (B) has dependencies on library (A) and binary +library (C). +One possible sort order of this graph is (C), (A), +(B), where the invoke code for (A) and (B) are +combined into a single block of invoke code. If library (A) is +invoked first, it will implicitly cause the invoke code for (B) to be +invoked without invoking the code for (C). +We address this by adding explicit dependencies between (A) and all +the binary libraries that precede it and all of the other libraries clustered +with (A) and (A), such that no matter which library clustered +with (A) is invoked first, (A) will be invoked, causing all +binary libraries that precede (A) to be invoked. +It is also possible for a similar problem to exist between clusters, where +invoking a later cluster may invoke an earlier cluster without invoking the +binary dependencies for the earlier cluster. +We address this issue by adding an invoke requirement between each cluster and +the first library in the cluster that precedes it. +These extended invoke requirements are also added to the import requirements +for each library, and the dependency graph is enhanced with import requirement +links to ensure these are taken into account during the topological sort. + + +
+A bug in automatic recompilation involving missing include files +has been fixed. +The bug caused automatic recompilation to fail, often with an +exception in file-modification-time, when a file specified +by an absolute pathname or pathname starting with "./" or "../" was +included via include during a previous compilation run and +is no longer present. + +
+A bug that caused evaluation of a foreign-callable expression in +code that has been collected into the static generation (e.g., when the +foreign-callable form appears in code compiled to a boot file) +to result in an invalid memory reference has been fixed. + +
+A bug in the source optimizer (cp0) allowed constant-folding of some calls to +apply where the last argument is not known to be a list. For example, +cp0 incorrectly reduced +(apply zero? 0) to #t +and reduced +(lambda (x) (apply box? x) x) to (lambda (x) x), +but now preserves these calls to apply so that they may raise an +exception. + +
+In Windows, filenames that start with a disk designator but no +directory separator are now treated as relative paths. For example, +(path-absolute? "C:") now returns #f, and +(directory-list "C:") now lists the files in the current +directory on disk C instead of the files in the root directory of disk +C. + +
+In addition, file-access-time, file-change-time, +file-directory?, file-exists?, +file-modification-time, and get-mode no longer +remove trailing directory separators on Windows. + +
+The globally unique names of gensyms no longer contain the IP address +on non-Windows systems. Windows systems already used a universally +unique identifier. + +
+A compiler bug that could result in an invalid memory reference or +some other unpleasant behavior for calls to fxvector in +which the nested subexpression to compute the new value to be stored +is nontrivial has been fixed. +This bug could also affect calls to vector-set-fixnum! and possibly +other primitive operations. + +
+A bug in the implementation of the default exit handler with multiple +values has been fixed. + +
+Compiled library code may now appear within fasl objects loaded during +the boot process, provided that they are appended to the end of the base boot +file or appear within a later boot file. + +
+The library system no longer reports a cyclic dependency error +during the second and subsequent attempts to visit or invoke a +library after the first attempt fails for some reason other than +an actual cyclic dependency. +The fix also allows a library to be visited or invoked successfully +on the second or subsequent attempt if the visit or invoke failed +for a transient reason, such as a missing or incorrect version in +an imported library. + +
+A bug that limited the (import import-spec ...) form within a +standalone export form to (import import-spec) has been +fixed. + +
+In Windows, deleting a file or directory briefly leaves the file or +directory in a state where a subsequent create operation fails with +permission denied. This race condition is now mitigated. +[This bug applies to all versions up to 9.5 on Windows 7 and later.] + +
+A bug when date->time-utc is called on Windows with a +date-zone-offset smaller than the system's time-zone offset has been +fixed. +[This bug dated back to Version 9.5.] + +
+A bug in the source optimizer that caused an internal compiler error when +folding certain calls to fx+/carry, fx-/carry, and +fx*/carry has been fixed. +[This bug dated back to Version 9.1.] + +
+A bug in that caused an internal compiler error when optimizing certain +nested calls to call-with-values has been fixed. +[This bug dated back to Version 8.9.1.] + +
+A bug in the expansion of define-values that caused it to produce +a non-definition form when used to define no values has been fixed. +[This bug dated back to at least Version 8.4.] + +
+A bug in the source optimizer that caused pariah forms to be ignored +has been fixed. +[This bug dated back to at least Version 9.3.1.] + +
+A bug on 64-bit platforms that occasionally caused invalid memory +references when operating on inexact complex numbers or the imaginary parts +of inexact complex numbers has been fixed. +[This bug dated back to Version 8.9.1.] + +
+A bug that caused fxsll, fxarithmetic-shift-left, +and fxarithmetic-shift to fail to detect overflow in certain +cases has been fixed. +[This bug dated back to Version 4.0.] + +
+A missing argument check that resulted in the procedure returned by enum-set-indexer +causing an invalid memory reference when passed a non-symbol argument has been fixed. +[This bug dated back to Version 7.5.] + +
+The C heap storage for inaccessible mutexes and conditions is now reclaimed. +[This bug dated back to Version 6.5.] + +
+A bug that caused guardian entries for a thread to be lost when a +thread exits has been fixed. +[This bug dated back to Version 6.5.] + +
+A bug in the source optimizer that produced incorrect code for certain +nested if patterns has been fixed. +For example, the code generated for the following expression: + +
+ +
(if (if (if (if (zero? (a)) #f #t) (begin (b) #t) #f)
+
+ (c)
+
+ #f)
+
+ (x)
+
+ (y))
+
inappropriately evaluated the subexpression (b) when the +subexpression (a) evaluates to 0 and not when (a) +evaluates to 1. +[This bug dated back to Version 9.0.] + +
+A bug in the pass of the compiler that inserts valid checks for +letrec and letrec* bindings has been fixed. +The bug resulted in an internal compiler exception with a condition +message regarding a leaked or unexpected cpvalid-defer form. +[This bug dated back to Version 6.9c.] + +
+string->number and the reader previously treated all complex +numbers written in polar notation that Chez Scheme cannot represent +exactly as inexact, even with an explicit #e prefix. +For such numbers with the #e prefix, string->number +now returns #f and the reader now raises an exception with +condition type &implementation-restriction. +Both still return an inexact representation for such numbers written without +the #e prefix, even if R6RS requires an exact result, i.e., +even if they have no decimal point, exponent, or mantissa width. + +
+Ratios with an exponent, like 1/2e10, are non-standard and +now cause the procedure string->number imported from +(rnrs) to return #f. +When the reader encounters a ratio followed by an exponent while in R6RS +mode (i.e., when reading a library or top-level program and not following +an #!chezscheme, or when following an explicit #!r6rs), +it raises an exception. + +
+Positive or negative zero followed by a large exponent now properly +produces zero rather than an infinity, e.g., 0e3000 now produces +0 rather than +inf.0. + +
+A rounding bug converting some small ratios into floating point numbers, +when those numbers fall into the range of denormalized floats, has +been fixed. +This bug also affected the reading of and conversion of strings into +denormalized floating-point numbers. +[Some of these bugs dated back to Version 3.0.] + +
+date->time-utc has been fixed to properly take into account the +zone-offset field. +[This bug dated back to Version 8.0.] + +
+On Windows, the source optimizer has been fixed to handle wchar and +wchar_t record field types. + +
+On Windows, the path-related procedures now raise an appropriate exception when the path argument is not a string. + +
+A bug in the handling of mutexes has been fixed. +The bug typically presented as a spurious "recursively locked" exception. + +
+A bug causing dynamic-wind to unconditionally enable +interrupts upon a nonlocal exit from the body thunk has been fixed. +Interrupts are now properly enabled only when the optional +critical? argument is supplied and is not false. +[This bug dated back to Version 6.9c.] + +
+Mistakes in our primitive database that caused the source optimizer +to treat append, append!, list*, +cons*, and record-type-parent as always returning +true values have been fixed, along with mistakes that caused the +source optimizer to treat null-environment, +source-object-bfp, source-object-efp, and +source-object-sfd as not requiring argument checks. +[This bug dated back to Version 6.0.] + +
+We have worked around a limitation in the number of distinct allocation +areas the Windows VirtualAlloc function permits to be allocated by +allocating fewer, larger chunks of memory, effectively increasing the +maximum size of the heap to the full amount permitted by the operating +system. + +
+The expander now handles let and let* in such a +way that certain syntax errors previously reported as syntax errors +in lambda are now reported properly as syntax errors in +let or let*. This includes duplicate identifier +errors for let and errors involving internal definitions +for both let and let*. + +
+A bug that caused effect-context calls to profile-dump-html +to be dropped at optimize-level 3 has been fixed. +[This bug dated back to Version 7.5.] + +
+A deficiency in the handling of library dependencies that prevented meta +definitions exported in one library from being used reliably by a macro +defined in another library has been fixed. +Handling imported meta bindings involves tracking +visit-visit-requirements, which for a library (A) is the set of +libraries that must be visited (rather than invoked) when (A) +is visited. +An attempt to assign a meta variable imported from a library now results +in a syntax error. +[This bug dated back to Version 7.9.1.] + +
+A bug that prevented an identifier given a property via +define-property from being exported from a library (A), +imported into and reexported from a second library (B), and +imported from both (A) and (B) into and reexported +from a third library (C) has been fixed. +[This bug dated back to Version 8.1.] + +
+The fasl (fast load) format used for compiled files now supports cyclic +record-type descriptors (RTDs), which are produced for recursive ftype +definitions. +Previously, compiling a file containing a recursive ftype definition +and subsequently loading the file resulted in corruption of the ftype +descriptor used to typecheck ftype pointers, potentially leading to +incorrect behavior or invalid memory references. +[This bug dated back to Version 8.2.] + +
+A bug that caused the optimizer to fold calls to record accessors applied +to a constant value of the wrong type, sometimes resulting in compile-time +invalid memory references or other compile-time errors, has been fixed. +[This bug dated back to Version 8.4.] + +
+A bug that prevented objects larger than 4GB to be created under Windows +x86_64 has been fixed. +[This bug dated back to Version 8.4.] + +
+When given a bytevector whose length is less than file-buffer-size, +bytevector->string now allocates the minimum size string buffer, +internal ioffsets fxvector, and internal codec buffer. +The size of each was formerly hardcoded at 1024. +The +bytevector->string, +get-bytevector-all, +get-bytevector-n, +get-string-all, and +get-string-n procedures +may avoid extra allocation and copying when the result is not more than +file-buffer-size and no intermediate reads need to be stitched +together to form the result. + +
+The basic arithmetic operations (addition, subtraction, multiplication, +division) are now much faster when presented with certain special +cases, e.g., multiplication of a large integer by 1 or -1 or addition +of large integer and 0. + +
+Right shifting a large integer is now much faster in most cases +where the shift count is a significant fraction of the number of +bits in the large integer. + +
+Visiting an object file (to obtain only compile-time information and +code) and revisiting an object file (to obtain only run-time information +and code) is now faster, because revisions to the fasl format, fasl +writer, and fasl reader allow run-time code to be seeked past when +visiting and compile-time code to be seeked past when revisiting. +For compressed object files (the default), seeking still requires +reading all of the data, but the cost of parsing the fasl format and +building objects in the skipped portions is avoided, as are certain +side effects, such as associating record type descriptors with their +uids. + +
+Similarly, recompile information is now placed at the front of each +object file where it can be loaded separately from +the remainder of an object file without even seeking past the other +portions of the file. +Recompile information is used by import (when +compile-imported-libraries is #t) and by maybe-compile +routines such as maybe-compile-program to help determine +whether recompilation is necessary. + +
+Importing a library from an object file now causes the object file +to be visited rather than fully loaded. (Libraries were already +just revisited when required for their run-time code, e.g., when +used from a top-level program.) + +
+Together these changes can significantly reduce compile-time and +run-time overhead, particularly in applications that make use of +a large number of libraries. + +
+profile-release-counters is now generation-friendly, meaning +it does not incur any overhead for code objects in generations that +have not been collected since the last call toprofile-release-counters. +Also, it no longer allocates memory when counters are released. + +
+The cost of obtaining profile counts via profile-dump and +other mechanisms has been reduced significantly. + +
+The compiler now generates better inline code for the bytevector +procedure. +Instead of one byte memory write for each argument, it writes up +to four (32-bit machines) or eight (64-bit machines) bytes at a +time, which almost always results in fewer instructions and fewer +writes. + +
+The last call to the procedure passed to vector-for-each +or string-for-each is now reliably implemented as tail +call, as was already the case for for-each. + +
+After running the main source optimization pass (cp0), the +compiler optionally runs a commonization pass, which +commonizes code for similar lambda expressions. +The parameter commonization-level controls whether the +commonization pass is run and, if so, how aggressive it is. +The parameter's value must be a nonnegative exact integer ranging +from 0 through 9. When the parameter is set to 0, the default, +commonization is not run. Otherwise, higher values result in more +commonization. + +
+Compile times are now lower, sometimes by an order of magnitude or +more, for procedures with thousands of parameters, local variables, +and compiler-introduced temporaries. +For such procedures, the register/frame allocator proactively spills +variables with large live ranges, cutting down on the size and cost +of building the conflict graph used to represent pairs of variables +that are live at the same time and therefore cannot share a location. + +
+As a result of improvements in the handing of the oblist (symbol table), +the storage for a symbol is often reclaimed more quickly after it +becomes inaccessible, less space is set aside for the oblist at +start-up, oblist lookups are faster when the oblist contains a large +number of symbols, and the minimum cost of a maximum-generation +collection has been cut significantly, down from tens of microseconds +to just a handful on contemporary hardware. + +
+Various changes in the storage manager have reduced the amount of +extra memory required for managing heap storage and increased the +likelihood that memory can be returned to the O/S as the heap +shrinks. +Returning memory to the O/S is now faster, so the minimum time for +a maximum-generation collection, or any other collection where +release of memory to the O/S is enabled, has been cut. + +
+Libraries now load faster at both compile and run time, with more +pronounced improvements when dozens of libraries or more are being +loaded. + +
+The source optimizer now maintains information about partially static +record instances to eliminate field accesses and type checks when a +binding site for a record instance is visible to the access or checking +code. +For example, + +
+ +
(let ()
+
+ (import scheme)
+
+ (define-record foo ([immutable ptr a] [immutable ptr b]))
+
+ (define (inc r) (make-foo (foo-a r) (+ (foo-b r) 1)))
+
+ (lambda (x)
+
+ (let* ([r (make-foo 37 x)]
+
+ [r (inc r)]
+
+ [r (inc r)])
+
+ r)))
+
is reduced by the source optimizer down to: + +
+ +
(lambda (x) ($record '#<record type foo> 37 (+ (+ x 1) 1))) +
where $record is a low-level primitive for creating record +instances. +That is, the source optimizer eliminates the intermediate record +structures, record references, and type checks, in addition to +creating the record-type descriptor at compile time, eliminating +the record-constructor descriptor, record constructor, and record +accessors produced by expansion of the record definition. + +
+The source optimizer now handles apply with a known-list +final argument, e.g., a constant list or list constructed directly +within the apply operation via cons, list, or +list* (cons*) as if it were an ordinary call, +i.e., without the apply and without the constant list +wrapper or list constructor. +For example: + +
+ +
(apply apply apply + (list 1 (cons 2 (list x (cons* 4 '(5 6)))))) +
folds down to (+ 18 x). +While not common at the source level, patterns like this can +materialize as the result of other source optimizations, +particularly inlining. + +
+The source optimizer now also reduces applications of car and +cdr to the list-building operators cons and +list, e.g.: + +
+ +
(car (cons e1 e2)) (begin e2 e1)
+
+(car (list e1 e2 e3)) (begin e2 e3 e1)
+
+(cdr (list e1 e2 e3)) (begin e1 (list e2 e3))
+
discarding side-effect-free expressions in the begin forms +where appropriate. +It treats similarly calls of vector-ref on vector; +list-ref on list, list*, and cons*; +string-ref on string; and fxvector-ref +on fxvector, taking care with string-ref and +fxvector-ref not to optimize when doing so might mask an +invalid type of argument to a safe constructor. + +
+Finally, the source optimizer now removes certain unnecessary +let bindings within the constraints of evaluation-order +preservation. +For example, + +
+ +
(let ([x e1] [y e2]) (list (cons x y) 7)) +
reduces to: + +
+ +
(list (cons e1 e2) 7) +
Such bindings commonly arise from inlining. Eliminating them tends +to make the output of expand/optimize more readable. + +
+The impact on performance is minimal, but it can result in smaller +expressions and thus enable more inlining within the same size limits. + +
+Various composed operation on ftypes now avoid allocating +and dereferencing intermediate ftype pointers, i.e., ftype-ref, +ftype-set!, ftype-init-lock!, ftype-lock!, +ftype-unlock!, ftype-spin-lock!, +ftype-locked-incr!, or ftype-locked-decr! applied +directly to the result of ftype-ref, ftype-&ref, or +make-ftype-pointer. + +
+The source optimizer does a few new optimizations: it folds +calls to symbol->string, string->symbol, and +gensym->unique-string if the argument is known at compile +time and has the right type; it folds zero-argument calls to +vector, string, bytevector, and +fxvector; and it discards subsumed case-lambda clauses, +e.g., the second clause in +(case-lambda [(x . y) e1] [(x y) e2]). + +
+A call to apply with a very long argument list can cause a +large chunk of memory to be allocated for the topmost portion of +the stack. +This space is now reclaimed during the next collection. + +
+The performance of operations on symbol hashtables has been improved +generally over previous releases by eliminating call overhead for the +hash and equality functions. +Further improvements are possible with the use of the new type-specific +symbol-hashtable operators (Section 2.88). + +
+The amount of time required to invoke a library and the amount of memory +occupied by the library when the library is invoked as the result of a +run-time dependency of another library or a top-level program have both +been reduced by "revisiting" rather than "invoking" the library, +effectively leaving the compile-time information on disk until if and +when it is needed. + +
+Unless the command-line parameter --retain-static-relocation +is supplied, the collector now discards relocation tables for code +objects when the code objects are promoted to the static generation, +either at boot time via heap compaction or via a call to collect +with the symbol static as the target generation. +This results in a significant reduction in the memory occupied by the +code object (around 20% in our tests). + +
+The code to register an object with a guardian is now open-coded, at +the cost of some additional work during the next collection. +The result is a modest net improvement in registration overhead (around +15% in our tests). +Of potentially greater importance when threaded, each registration no +longer requires synchronization. + +
+The compiler generates better code in several small ways, resulting +in small decreases in code size and corresponding small +performance improvements in the range of 1-5% in our tests. + +
+In previous releases, a factor in collector performance was the +overall size of the heap (measured both in number of pages and the +amount of virtual memory spanned by the heap). +Through various changes to the data structures used to support the +storage manager, this factor has been eliminated, which can +significantly reduce the cost of collecting a younger generation +with a small number of accessible objects relative to overall heap +size. +In our experiments, the minimum cost of collection on contemporary +hardware exceeded 100 microseconds for heaps of 64MB or more and 5 +milliseconds for heaps of 1GB or more. +The minimum cost grew in proportion to the heap size from there. +This is now fixed for all heap sizes at just a few microseconds. + +
+Improvements in the compiler and storage manager have been made to +reduce the cost of tracking possible pointers from older to younger +generations when objects are mutated. + +
+Ftype pointers with constant addresses are now created at compile +time, with ftype-pointer address checks optimized away as well. + +
+Bignum allocation overhead is avoided for addresses outside the +fixnum range when the results of two ftype-pointer-address +calls are directly compared or the result of one +ftype-pointer-address call is directly compared with 0. +That is, comparisons like: + +
+ +
(= (ftype-pointer-address x) 0)
+
+(= (ftype-pointer-address x) (ftype-pointer-address y))
+
are effectively optimized to: + +
+ +
(ftype-pointer-null? x)
+
+(ftype-pointer=? x y)
+
This optimization is performed when the comparison procedure is +=, eqv?, or equal? and the arguments +are given in either order. +The optimization is also performed when zero? is applied directly +to the result of ftype-pointer-address. + +
+Bignum allocation overhead is also avoided at optimize-level 3 +when ftype-pointer-address is used in combination with +make-ftype-pointer to effect a type cast, as in: + +
+ +
(make-ftype-pointer T (ftype-pointer-address x)) +
Both bignum and ftype-pointer allocation is avoided when the result +of such a cast is used directly as the base pointer in an +ftype-ref, ftype-&ref, ftype-set!, +ftype-locked-incr!, ftype-locked-decr!, +ftype-init-lock!, ftype-lock!, ftype-spin-lock!, +or ftype-unlock! form, as in: + +
+ +
(ftype-ref T (fld) (make-ftype-pointer T (ftype-pointer-address x))) +
These optimizations do not occur when the calls to +ftype-pointer-address are not nested directly within the outer +form, as when a let binding is used to name the result of the +ftype-pointer-address call, e.g.: + +
+ +
(let ([addr (ftype-pointer-address x)]) (= addr 0)) +
In other places where ftype-pointer-address is used, the compiler +now open-codes the extraction and (if necessary) bignum allocation, +reducing overhead by the cost of a procedure call. + +
+In addition to improvements in the tracking of profile counts, the +run-time overhead for gathering profile information has gone down by +5-10% in our tests and is now typically around 10% of the total +unprofiled run time. +(Unprofiled code is also slightly faster, but by less than 2% in +our tests.) + +
+Versions starting with 8.9.1 employ a new compiler back end that is +structured as a series of nanopasses and replaces the old linear-time +register allocator with a graph-coloring register allocator. +Compilation with the new back end is substantially slower (up to a factor +of two) than with the old back end, while code generated with the new +back end is faster (14-40% depending on architecture and optimization +level) in our tests. +These improvements are independent of improvements +resulting from cross-library constant folding and inlining +(Section 4.31). +The code generated for a specific program might be faster or slower. + +
+Calls to make-guardian are now open-coded by the compiler to +expose the implicit resulting case-lambda expression so that +calls to the guardian can themselves be inlined, thus reducing the overhead +for registering objects with a guardian and querying the guardian for +resurrected objects. + +
+make-parameter and make-thread-parameter +are now open-coded in all cases to expose the implicit resulting +case-lambda expression. +(They were already open-coded when the second, filter, +argument was a lambda expression or primitive name.) + +
+The compiler now propagates constants and inlines simple procedures +across library boundaries. +A simple procedure is one that, after optimization of the exporting +library, is smaller than a given threshold, contains no free references +to other bindings in the exporting library, and contains no constants +that cannot be copied without breaking pointer identity. +The size threshold is determined, as for inlining within a library or +other compilation unit, by the parameter cp0-score-limit. +In this case, the size threshold is determined based on the size +before inlining rather than the size after inlining, +which is often more conservative. +Omitting larger procedures that might generate less code when inlined in +a particular context reduces the amount of information that must be stored +in the exporting library's object code to support cross-library inlining. + +
+One particularly useful benefit of this optimization is that record +predicates, accessors, mutators, and (depending on protocols) +constructors created by a record definition in one library and exported +by another are inlined in the importing library, just as if the record +type were defined in the importing library. + +
+
+ © 2023 Cisco Systems, Inc.
+
+ Licensed under the Apache License Version 2.0
+
+
+
+
diff --git a/release_notes/v10.0/release_notes.pdf b/release_notes/v10.0/release_notes.pdf
new file mode 100644
index 000000000..f4934c619
Binary files /dev/null and b/release_notes/v10.0/release_notes.pdf differ
diff --git a/release_notes/v10.0/releasenotes.css b/release_notes/v10.0/releasenotes.css
new file mode 100644
index 000000000..ef7507d2c
--- /dev/null
+++ b/release_notes/v10.0/releasenotes.css
@@ -0,0 +1,57 @@
+BODY {background-color: #FFFFFF}
+A:link {color:#880000; text-decoration:underline}
+A:active {color:#880000; text-decoration:underline}
+A:visited {color:#000088; text-decoration:underline}
+A:hover {color:white; text-decoration:underline; background:#880000}
+
+A.plain:link {color:#880000; text-decoration:none}
+A.plain:active {color:#880000; text-decoration:none}
+A.plain:visited {color:#000088; text-decoration:none}
+A.plain:hover {color:white; text-decoration:none; background:#880000}
+
+A.static:link {color:#880000; text-decoration:underline}
+A.static:active {color:#880000; text-decoration:underline}
+A.static:visited {color:#880000; text-decoration:underline}
+A.static:hover {color:white; text-decoration:underline; background:#880000}
+
+A.plainstatic:link {color:#880000; text-decoration:none}
+A.plainstatic:active {color:#880000; text-decoration:none}
+A.plainstatic:visited {color:#880000; text-decoration:none}
+A.plainstatic:hover {color:white; text-decoration:none; background:#880000}
+
+A.ref:link {color:#880000; text-decoration:underline}
+A.ref:active {color:#880000; text-decoration:underline}
+A.ref:visited {color:#880000; text-decoration:underline}
+A.ref:hover {color:white; text-decoration:underline; background:#880000}
+
+A.plainlink:link {color:#880000; text-decoration:none}
+A.plainlink:active {color:#880000; text-decoration:none}
+A.plainlink:visited {color:#880000; text-decoration:none}
+A.plainlink:hover {color:white; text-decoration:none; background:#880000}
+
+A.toc:link {color:#000088; text-decoration:none}
+A.toc:active {color:#000088; text-decoration:none}
+A.toc:visited {color:#000088; text-decoration:none}
+A.toc:hover {color:white; text-decoration:none; background:#000088}
+
+input.default { background: #ffffff; color: #000000; vertical-align: middle}
+
+H1, H2 { margin-top: 1em; margin-bottom: 1em }
+H3, H4, H5, H6 { margin-top: 1em; margin-bottom: 0em }
+
+H1, H2 {color: #880000}
+H3, H4 {color: #000088}
+H1 {font-size: 2em}
+H2 {font-size: 1.5em}
+H3 {font-size: 1.17em}
+H1, H2, H3, H4 {font-weight: bold}
+
+table.indent {margin-left: 20px}
+
+.pruned{ color: red; }
+.inserted{ color: green; }
+.attr{ font-weight: bold; }
+.attrvalue{ color: blue; }
+.tag{ color: navy; font-weight: bold; }
+.entity{ color: purple; font-weight: bold; }
+.errflag{ color: red; font-weight: bold; }