~ chicken-core (chicken-5) 434e6446d54fdf7c9a0371d1c9111c97ad186b0a
commit 434e6446d54fdf7c9a0371d1c9111c97ad186b0a Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sun Dec 6 13:26:07 2009 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sun Dec 6 13:26:07 2009 +0100 Incorporated changes from the wiki-version of the manual (patch provided by zbigniew) diff --git a/manual/Accessing external objects b/manual/Accessing external objects index 4da3c0cb..8d1771b6 100644 --- a/manual/Accessing external objects +++ b/manual/Accessing external objects @@ -6,7 +6,7 @@ === foreign-code - [syntax] (foreign-code STRING ...) +<macro>(foreign-code STRING ...)</macro> Executes the embedded C/C++ code {{STRING ...}}, which should be a sequence of C statements, which are executed and return an unspecified result. @@ -20,7 +20,7 @@ Code wrapped inside {{foreign-code}} may not invoke callbacks into Scheme. === foreign-value - [syntax] (foreign-value CODE TYPE) +<macro>(foreign-value CODE TYPE)</macro> Evaluates the embedded C/C++ expression {{CODE}} (which may be a string or symbol), returning a value of type given in the foreign-type specifier {{TYPE}}. @@ -32,14 +32,14 @@ in the foreign-type specifier {{TYPE}}. === foreign-declare - [syntax] (foreign-declare STRING ...) +<macro>(foreign-declare STRING ...)</macro> Include given strings verbatim into header of generated file. === define-foreign-type - [syntax] (define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]]) +<macro>(define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])</macro> Defines an alias for {{TYPE}} with the name {{NAME}} (a symbol). {{TYPE}} may be a type-specifier or a string naming a C type. The @@ -72,7 +72,7 @@ in multiple files. === define-foreign-variable - [syntax] (define-foreign-variable NAME TYPE [STRING]) +<macro>(define-foreign-variable NAME TYPE [STRING])</macro> Defines a foreign variable of name {{NAME}} (a symbol). {{STRING}} should be the real name of a foreign variable or parameterless @@ -88,7 +88,7 @@ even have to specify an lvalue. === foreign-lambda - [syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...) +<macro>(foreign-lambda RETURNTYPE NAME ARGTYPE ...)</macro> Represents a binding to an external routine. This form can be used in the position @@ -98,7 +98,7 @@ name of the external procedure and should be a string or a symbol. === foreign-lambda* - [syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...) +<macro>(foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)</macro> Similar to {{foreign-lambda}}, but instead of generating code to call an external function, the body of the C procedure is directly given @@ -120,7 +120,7 @@ commences in the calling code. === foreign-safe-lambda - [syntax] (foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...) +<macro>(foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)</macro> This is similar to {{foreign-lambda}}, but also allows the called function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]]. @@ -128,7 +128,7 @@ function to call Scheme functions and allocate Scheme data-objects. See [[Callba === foreign-safe-lambda* - [syntax] (foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...) +<macro>(foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)</macro> This is similar to {{foreign-lambda*}}, but also allows the called function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]]. @@ -137,7 +137,7 @@ function to call Scheme functions and allocate Scheme data-objects. See [[Callba === foreign-primitive - [syntax] (foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...) +<macro>(foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)</macro> This is also similar to {{foreign-lambda*}} but the code will be executed in a ''primitive'' CPS context, which means it will not actually return, but diff --git a/manual/Callbacks b/manual/Callbacks index 8490b583..0f45f2f7 100644 --- a/manual/Callbacks +++ b/manual/Callbacks @@ -30,8 +30,8 @@ a different callback, your program is likely to crash. === define-external - [syntax] (define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...) - [syntax] (define-external NAME TYPE [INIT]) +<macro>(define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...)</macro><br> +<macro>(define-external NAME TYPE [INIT])</macro> The first form defines an externally callable Scheme procedure. {{NAME}} should be a symbol, which, when converted to a diff --git a/manual/Data representation b/manual/Data representation index 53049dc2..3fff3123 100644 --- a/manual/Data representation +++ b/manual/Data representation @@ -1,56 +1,55 @@ [[tags: manual]] -== Data representation -''Note: In all cases below, bits are numbered starting at 1 and beginning with the lowest-order bit.'' +== Data representation There exist two different kinds of data objects in the CHICKEN system: immediate and non-immediate objects. === Immediate objects -Immediate objects are represented by a single machine word, which is usually of 32 bits length, or 64 bits -on 64-bit architectures. The immediate objects -come in four different flavors: +Immediate objects are represented by a single machine word, 32 or 64 bits depending on the architecture. They come in four different flavors: -'''fixnums''', that is, small exact integers, where bit 1 is +'''fixnums''', that is, small exact integers, where the lowest order bit is set to 1. This gives fixnums a range of 31 bits for the actual numeric value (63 bits on 64-bit architectures). -'''characters''', where bits 1-4 are equal to {{C_CHARACTER_BITS}}. The -Unicode code point of the character is encoded in bits 9 to 32. +'''characters''', where the four lowest-order bits are equal to +{{C_CHARACTER_BITS}}, currently 1010. The Unicode code point +of the character is encoded in the next 24 bits. -'''booleans''', where bits 1-4 are equal to {{C_BOOLEAN_BITS}}. Bit 5 -is one for #t and zero for #f. +'''booleans''', where the four lowest-order bits are equal to {{C_BOOLEAN_BITS}}, +currently 0110. The next bit is one for #t and zero for #f. '''other values''': the empty list, the value of unbound identifiers, -the undefined value (void), and end-of-file. Bits 1-4 are equal to {{C_SPECIAL_BITS}}; bits 5 to 8 contain an identifying -number for this type of object. The following constants are -defined: {{C_SCHEME_END_OF_LIST C_SCHEME_UNDEFINED C_SCHEME_UNBOUND -C_SCHEME_END_OF_FILE}} - -Collectively, bits 1 and 2 are known as the ''immediate mark bits''. When bit 1 is set, the object is a fixnum, as described above, and bit 2 is part of its value. When bit 1 is clear but bit 2 is set, it is an immediate object other than a fixnum. If neither bit 1 nor bit 2 is set, the object is non-immediate, as described below. +the undefined value (void), and end-of-file. The four lowest-order bits are equal to +{{C_SPECIAL_BITS}}, currently 1110. The next four bits contain an identifying +number for this type of object, one of: +{{C_SCHEME_END_OF_LIST}}, currently 0000; +{{C_SCHEME_UNDEFINED}}, currently 0001; +{{C_SCHEME_UNBOUND}}, currently 0010; or +{{C_SCHEME_END_OF_FILE}}, currently 0011. === Non-immediate objects +Collectively, the two lowest-order bits are known as the ''immediate mark bits''. When the lowest bit is set, the object is a fixnum, as described above, and the next bit is part of its value. When the lowest bit is clear but the next bit is set, it is an immediate object other than a fixnum. If neither bit is set, the object is non-immediate, as described below. + Non-immediate objects are blocks of data represented by a pointer into -the heap. The pointer's immediate mark bits (bits 1 and 2) must be zero to indicate the object is non-immediate; +the heap. The pointer's immediate mark bits must be zero to indicate the object is non-immediate; this guarantees the data block is aligned on a 4-byte boundary, at minimum. Alignment of data words is required on modern architectures anyway, so we get the ability to distinguish between immediate and non-immediate objects for free. The first word of the data block contains a header, which gives -information about the type of the object. The header has the size of a -machine word, usually 32 bits (64 bits on 64 bit architectures). - -Bits 1 to 24 contain the length of the data object, which is either -the number of bytes in a string (or byte-vector) or the the number -of elements for a vector or for a structure type. +information about the type of the object. The header is a +single machine word. -Bits 25 to 28 contain the type code of the object. +The 24 lowest-order bits contain the length of the data object, which is either +the number of bytes in a string or byte-vector, or the the number +of elements for a vector or record type. -Bits 29 to 32 contain miscellaneous flags used for garbage +The remaining bits are placed in the high-order end of the header. +The four highest-order bits are used for garbage collection or internal data type dispatching. -These flags are: ; C_GC_FORWARDING_BIT : Flag used for forwarding garbage collected object pointers. diff --git a/manual/Declarations b/manual/Declarations index deabbeee..e3f6cee5 100644 --- a/manual/Declarations +++ b/manual/Declarations @@ -7,7 +7,7 @@ === declare - [syntax] (declare DECLSPEC ...) +<macro>(declare DECLSPEC ...)</macro> Process declaration specifiers. Declarations always override any command-line settings. Declarations are valid for the whole @@ -284,26 +284,26 @@ given here: BASIC --> * | string - | symbol - | char - | number - | boolean - | list - | pair - | procedure - | vector - | null - | eof - | port - | blob - | pointer - | locative - | fixnum - | float + | symbol + | char + | number + | boolean + | list + | pair + | procedure + | vector + | null + | eof + | port + | blob + | pointer + | locative + | fixnum + | float RESULTS --> * | (RVAL1 ...) - + RVAL --> undefined | noreturn diff --git a/manual/Deviations from the standard b/manual/Deviations from the standard index c8c01fdc..40b5ed34 100644 --- a/manual/Deviations from the standard +++ b/manual/Deviations from the standard @@ -94,6 +94,6 @@ read/write invariance to inexact numbers. not implemented. R5RS does not require them. --- -Previous: [[Supported language]] +Previous: [[The R5RS standard]] Next: [[Extensions to the standard]] diff --git a/manual/Embedding b/manual/Embedding index 45c6c5c2..f1133a3f 100644 --- a/manual/Embedding +++ b/manual/Embedding @@ -61,7 +61,7 @@ Scheme program. === return-to-host - [procedure] (return-to-host) +<procedure>(return-to-host)</procedure> Exits the Scheme code and returns to the invoking context that called {{CHICKEN_run}} or {{CHICKEN_continue}}. diff --git a/manual/Extensions b/manual/Extensions index dbd98ac1..2c3d4b0b 100644 --- a/manual/Extensions +++ b/manual/Extensions @@ -81,7 +81,7 @@ script has to be in the root path of the archive. ==== install-extension - (install-extension ID FILELIST [INFOLIST]) +<procedure>(install-extension ID FILELIST [INFOLIST])</procedure> Installs the extension library with the name {{ID}}. All files given in the list of strings {{FILELIST}} will be copied to the extension repository. It should be noted here that @@ -92,7 +92,7 @@ by the {{require-at-runtime}} property. {{FILELIST}} may be a filename, a list of filenames, or a list of pairs of the form {{(SOURCE DEST)}} (if you want to copy into a particular sub-directory - the destination directory will be created as needed). If {{DEST}} is a relative pathname, -< it will be copied into the extension repository. +it will be copied into the extension repository. The optional argument {{INFOLIST}} should be an association list that maps symbols to values, this list will be stored as {{ID.setup-info}} at the same @@ -146,14 +146,14 @@ string. ==== install-program - [procedure] (install-program ID FILELIST [INFOLIST]) +<procedure>(install-program ID FILELIST [INFOLIST])</procedure> Similar to {{install-extension}}, but installs an executable program in the executable path (usually {{/usr/local/bin}}). ==== install-script - [procedure] (install-script ID FILELIST [INFOLIST]) +<procedure>(install-script ID FILELIST [INFOLIST])</procedure> Similar to {{install-program}}, but additionally changes the file permissions of all files in {{FILELIST}} to executable (for installing shell-scripts). @@ -179,7 +179,7 @@ a simple single-file extension. This is roughly equivalent to: ==== run - [syntax] (run FORM ...) +<macro>(run FORM ...)</macro> Runs the shell command {{FORM}}, which is wrapped in an implicit {{quasiquote}}. {{(run (csc ...))}} is treated specially and passes {{-v}} (if {{-verbose}} has been given @@ -187,13 +187,13 @@ to {{chicken-install}}) and {{-feature compiling-extension}} options to the comp ==== compile - [syntax] (compile FORM ...) +<macro>(compile FORM ...)</macro> Equivalent to {{(run (csc FORM ...))}}. ==== make - [syntax] (make ((TARGET (DEPENDENT ...) COMMAND ...) ...) ARGUMENTS) +<macro>(make ((TARGET (DEPENDENT ...) COMMAND ...) ...) ARGUMENTS)</macro> A ''make'' macro that executes the expressions {{COMMAND ...}}, when any of the dependents {{DEPENDENT ...}} have changed, to build {{TARGET}}. This is the same as the {{make}} @@ -203,7 +203,7 @@ extension, which is available separately. For more information, see ==== patch - [procedure] (patch WHICH REGEX SUBST) +<procedure>(patch WHICH REGEX SUBST)</procedure> Replaces all occurrences of the regular expression {{REGEX}} with the string {{SUBST}}, in the file given in {{WHICH}}. If {{WHICH}} is a string, the file will be patched and @@ -212,28 +212,28 @@ overwritten. If {{WHICH}} is a list of the form {{OLD NEW}}, then a different fi ==== copy-file - [procedure] (copy-file FROM TO) +<procedure>(copy-file FROM TO)</procedure> Copies the file or directory (recursively) given in the string {{FROM}} to the destination file or directory {{TO}}. ==== move-file - [procedure] (move-file FROM TO) +<procedure>(move-file FROM TO)</procedure> Moves the file or directory (recursively) given in the string {{FROM}} to the destination file or directory {{TO}}. ==== remove-file* - [procedure] (remove-file* PATH) +<procedure>(remove-file* PATH)</procedure> Removes the file or directory given in the string {{PATH}}. ==== find-library - [procedure] (find-library NAME PROC) +<procedure>(find-library NAME PROC)</procedure> Returns {{#t}} if the library named {{libNAME.[a|so]}} (unix) or {{NAME.lib}} (windows) could be found by compiling and linking a test program. {{PROC}} should be the name of a @@ -242,13 +242,13 @@ be resolved, {{#f}} is returned. ==== find-header - [procedure] (find-header NAME) +<procedure>(find-header NAME)</procedure> Returns {{#t}} if a C include-file with the given name is available, or {{#f}} otherwise. ==== try-compile - [procedure] (try-compile CODE #!key cc cflags ldflags compile-only c++) +<procedure>(try-compile CODE #!key cc cflags ldflags compile-only c++)</procedure> Returns {{#t}} if the C code in {{CODE}} compiles and links successfully, or {{#f}} otherwise. The keyword parameters {{cc}} (compiler name, defaults to the C compiler used to build this system), @@ -259,20 +259,20 @@ If the keyword argument {{c++}} is given and true, then the code will be compile ==== create-directory - [procedure] (create-directory PATH) +<procedure>(create-directory PATH)</procedure> Creates the directory given in the string {{PATH}}, with all parent directories as needed. ==== chicken-prefix - [parameter] chicken-prefix +<parameter>chicken-prefix</parameter> The installation prefix specified when CHICKEN was built. ==== installation-prefix - [parameter] installation-prefix +<parameter>installation-prefix</parameter> An alternative installation prefix that will be prepended to extension installation paths if specified. It is set by the {{-install-prefix}} @@ -280,7 +280,7 @@ option or environment variable {{CHICKEN_INSTALL_PREFIX}}. ==== program-path - [parameter] (program-path [PATH]) +<parameter>(program-path [PATH])</parameter> Holds the path where executables are installed and defaults to either {{$CHICKEN_PREFIX/bin}}, if the environment variable {{CHICKEN_PREFIX}} is set or the @@ -289,21 +289,21 @@ path where the CHICKEN binaries ({{chicken}}, {{csi}}, etc.) are installed. ==== setup-root-directory - [parameter] (setup-root-directory [PATH]) +<parameter>(setup-root-directory [PATH])</parameter> Contains the path of the directory where {{chicken-install}} was invoked. ==== setup-install-mode - [parameter] (setup-install-mode [BOOL]) +<parameter>(setup-install-mode [BOOL])</parameter> Reflects the setting of the {{-no-install}} option, i.e. is {{#f}}, if {{-no-install}} was given to {{chicken-install}}. ==== required-chicken-version - [procedure] (required-chicken-version VERSION) +<procedure>(required-chicken-version VERSION)</procedure> Signals an error if the version of CHICKEN that this script runs under is lexicographically less than {{VERSION}} (the argument will be converted to a string, first). @@ -311,7 +311,7 @@ Signals an error if the version of CHICKEN that this script runs under is lexico ==== required-extension-version - [procedure] (required-extension-version EXTENSION1 VERSION1 ...) +<procedure>(required-extension-version EXTENSION1 VERSION1 ...)</procedure> Checks whether the extensions {{EXTENSION1 ...}} are installed and at least of version {{VERSION1 ...}}. The test is made by lexicographically comparing the string-representations of the given version with the version @@ -321,7 +321,7 @@ or is of a version older than the one specified. ==== host-extension - [parameter] host-extension +<parameter>host-extension</parameter> For a cross-compiling CHICKEN, when compiling an extension, then it should be built for the host environment (as opposed to the target diff --git a/manual/Locations b/manual/Locations index c2fd820f..c4fd2b4b 100644 --- a/manual/Locations +++ b/manual/Locations @@ -14,7 +14,7 @@ machine word, and double-precision floating point values. === define-location - [syntax] (define-location NAME TYPE [INIT]) +<macro>(define-location NAME TYPE [INIT])</macro> Identical to {{(define-external NAME TYPE [INIT])}}, but the variable is not accessible from outside of the current compilation unit (it is @@ -22,14 +22,14 @@ declared {{static}}). === let-location - [syntax] (let-location ((NAME TYPE [INIT]) ...) BODY ...) +<macro>(let-location ((NAME TYPE [INIT]) ...) BODY ...)</macro> Defines a lexically bound location. === location - [syntax] (location NAME) - [syntax] (location X) +<macro>(location NAME)</macro><br> +<macro>(location X)</macro> This form returns a pointer object that contains the address of the variable {{NAME}}. diff --git a/manual/Modules and macros b/manual/Modules and macros index bc4be9d2..483b5b0d 100644 --- a/manual/Modules and macros +++ b/manual/Modules and macros @@ -13,7 +13,7 @@ macro system based on ''explicit renaming''. ==== define-syntax - [syntax] (define-syntax IDENTIFIER TRANSFORMER) +<macro>(define-syntax IDENTIFIER TRANSFORMER)</macro> Defines a macro named {{IDENTIFIER}} that will transform an expression with {{IDENTIFIER}} in operator position according to {{TRANSFORMER}}. @@ -50,7 +50,7 @@ transformer procedure is undefined. ==== define-compiled-syntax - [syntax] (define-compiled-syntax IDENTIFIER TRANSFORMER) +<macro>(define-compiled-syntax IDENTIFIER TRANSFORMER)</macro> Equivalent to {{define-syntax}}, but when compiled, will also define the macro at runtime. @@ -58,7 +58,7 @@ at runtime. ==== syntax - [syntax] (syntax EXPRESSION) +<macro>(syntax EXPRESSION)</macro> Similar to {{quote}} but retains syntactical context information for embedded identifiers. @@ -66,7 +66,7 @@ embedded identifiers. ==== strip-syntax - [procedure] (strip-syntax EXPRESSION) +<procedure>(strip-syntax EXPRESSION)</procedure> Strips all syntactical information from {{EXPRESSION}}, returning a new expression where symbols have all context-information removed. @@ -241,8 +241,8 @@ CHICKEN's module system has the following features and shortcomings: ==== module - [syntax] (module NAME (EXPORT ...) BODY ...) - [syntax] (module NAME * BODY ...) +<macro>(module NAME (EXPORT ...) BODY ...)</macro><br> +<macro>(module NAME * BODY ...)</macro> Defines a module with the name {{NAME}}, a set of exported bindings and a contained sequence of toplevel expressions that are evaluated in @@ -278,7 +278,7 @@ will modify the original, imported definition. ==== export - [syntax] (export EXPORT ...) +<macro>(export EXPORT ...)</macro> Allows augmenting module-exports from inside the module-body. {{EXPORT}} is if the same form as an export-specifier in a @@ -287,7 +287,7 @@ Allows augmenting module-exports from inside the module-body. ==== import - [syntax] (import IMPORT ...) +<macro>(import IMPORT ...)</macro> Imports module bindings into the current syntactical environment. The visibility of any imported bindings is limited to the current @@ -307,7 +307,7 @@ a module): (begin (import m1) - ... ; imports not visible here + ...) ; imports not visible here ... ; imports visible here @@ -339,7 +339,7 @@ Prefixes all imported identifiers with {{SYMBOL}}. ==== import-for-syntax - [syntax] (import-for-syntax IMPORT ...) +<macro>(import-for-syntax IMPORT ...)</macro> Similar to {{import}}, but imports exported bindings of a module into the environment in which macro transformers are evaluated. diff --git a/manual/Non-standard macros and special forms b/manual/Non-standard macros and special forms index b30bad0a..6529beb8 100644 --- a/manual/Non-standard macros and special forms +++ b/manual/Non-standard macros and special forms @@ -8,7 +8,7 @@ ==== require-library - [syntax] (require-library ID ...) +<macro>(require-library ID ...)</macro> This form does all the necessary steps to make the libraries or extensions given in {{ID ...}} available. It loads syntactic extensions, if needed and generates @@ -47,7 +47,7 @@ See also: {{set-extension-specifier!}} ==== require-extension - [syntax] (require-extension ID ...) +<macro>(require-extension ID ...)</macro> This is equivalent to {{(require-library ID ...)}} but performs an implicit {{import}}. @@ -56,7 +56,7 @@ This implementation of {{require-extension}} is compliant with [[http://srfi.sch ==== use - [syntax] (use ID ...) +<macro>(use ID ...)</macro> {{use}} is just a shorter alias for {{require-extension}}. @@ -65,7 +65,7 @@ This implementation of {{require-extension}} is compliant with [[http://srfi.sch ==== optional - [syntax] (optional ARGS DEFAULT) +<macro>(optional ARGS DEFAULT)</macro> Use this form for procedures that take a single optional argument. If {{ARGS}} is the empty list {{DEFAULT}} is evaluated and @@ -79,7 +79,7 @@ an error if {{ARGS}} contains more than one value. </enscript> ==== case-lambda - [syntax] (case-lambda (LAMBDA-LIST1 EXP1 ...) ...) +<macro>(case-lambda (LAMBDA-LIST1 EXP1 ...) ...)</macro> Expands into a lambda that invokes the body following the first matching lambda-list. @@ -103,7 +103,7 @@ For more information see the documentation for ==== let-optionals - [syntax] (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...) +<macro> (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...)</macro> Binding constructs for optional procedure arguments. {{ARGS}} should be a rest-parameter taken from a lambda-list. {{let-optionals}} @@ -120,7 +120,7 @@ arguments are provided. ==== let-optionals* - [syntax] (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...) +<macro> (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)</macro> Binding constructs for optional procedure arguments. {{ARGS}} should be a rest-parameter taken from a lambda-list. {{let-optionals}} @@ -141,7 +141,7 @@ an error if any excess arguments are provided. ==== and-let* - [syntax] (and-let* (BINDING ...) EXP1 EXP2 ...) +<macro>(and-let* (BINDING ...) EXP1 EXP2 ...)</macro> SRFI-2. Bind sequentially and execute body. {{BINDING}} can be a list of a variable and an expression, a list with a single @@ -156,8 +156,8 @@ result of the {{and-let*}} form. See also the documentation for ==== rec - [syntax] (rec NAME EXPRESSION) - [syntax] (rec (NAME VARIABLE ...) BODY ...) +<macro>(rec NAME EXPRESSION)</macro><br> +<macro>(rec (NAME VARIABLE ...) BODY ...)</macro> Allows simple definition of recursive definitions. {{(rec NAME EXPRESSION)}} is equivalent to {{(letrec ((NAME EXPRESSION)) NAME)}} and {{(rec (NAME VARIABLE ...) BODY ...)}} @@ -165,35 +165,35 @@ is the same as {{(letrec ((NAME (lambda (VARIABLE ...) BODY ...))) NAME)}}. ==== cut - [syntax] (cut SLOT ...) - [syntax] (cute SLOT ...) +<macro>(cut SLOT ...)</macro><br> +<macro>(cute SLOT ...)</macro> [[http://srfi.schemers.org/srfi-26/srfi-26.html|Syntactic sugar for specializing parameters]]. ==== define-values - [syntax] (define-values (NAME ...) EXP) +<macro>(define-values (NAME ...) EXP)</macro> Defines several variables at once, with the result values of expression {{EXP}}. ==== fluid-let - [syntax] (fluid-let ((VAR1 X1) ...) BODY ...) +<macro>(fluid-let ((VAR1 X1) ...) BODY ...)</macro> Binds the variables {{VAR1 ...}} dynamically to the values {{X1 ...}} during execution of {{BODY ...}}. ==== let-values - [syntax] (let-values (((NAME ...) EXP) ...) BODY ...) +<macro>(let-values (((NAME ...) EXP) ...) BODY ...)</macro> SRFI 11. Binds multiple variables to the result values of {{EXP ...}}. All variables are bound simultaneously. ==== let*-values - [syntax] (let*-values (((NAME ...) EXP) ...) BODY ...) +<macro>(let*-values (((NAME ...) EXP) ...) BODY ...)</macro> SRFI 11. Binds multiple variables to the result values of {{EXP ...}}. The variables are bound sequentially. @@ -206,7 +206,7 @@ The variables are bound sequentially. ==== letrec-values - [syntax] (letrec-values (((NAME ...) EXP) ...) BODY ...) +<macro>(letrec-values (((NAME ...) EXP) ...) BODY ...)</macro> Binds the result values of {{EXP ...}} to multiple variables at once. All variables are mutually recursive. @@ -221,7 +221,7 @@ All variables are mutually recursive. ==== parameterize - [syntax] (parameterize ((PARAMETER1 X1) ...) BODY ...) +<macro>(parameterize ((PARAMETER1 X1) ...) BODY ...)</macro> Binds the parameters {{PARAMETER1 ...}} dynamically to the values {{X1 ...}} during execution of {{BODY ...}}. (see also: @@ -230,37 +230,27 @@ expression that evaluates to a parameter procedure. ==== receive - [syntax] (receive (NAME1 ... [. NAMEn]) VALUEEXP BODY ...) - [syntax] (receive VALUEEXP) +<macro>(receive (NAME ...) VALUEEXP BODY ...)</macro><br> +<macro>(receive (NAME1 ... NAMEn . NAMEn+1) VALUEEXP BODY ...)</macro><br> +<macro>(receive VALUEEXP)</macro> SRFI-8. Syntactic sugar for {{call-with-values}}. Binds variables to the result values of {{VALUEEXP}} and evaluates {{BODY ...}}. -The syntax - -<enscript highlight=scheme> -(receive VALUEEXP) -</enscript> - -is equivalent to - -<enscript highlight=scheme> -(receive _ VALUEEXP _) -</enscript> +{{(receive VALUEEXP)}} is equivalent to {{(receive _ VALUEEXP _)}}. ==== set!-values - [syntax] (set!-values (NAME ...) EXP) +<macro>(set!-values (NAME ...) EXP)</macro> Assigns the result values of expression {{EXP}} to multiple variables. - === Substitution forms and macros ==== define-constant - [syntax] (define-constant NAME CONST) +<macro>(define-constant NAME CONST)</macro> Define a variable with a constant value, evaluated at compile-time. Any reference to such a @@ -277,8 +267,9 @@ This for should only be used at top-level. ==== define-inline - [syntax] (define-inline (NAME VAR ... [. VAR]) BODY ...) - [syntax] (define-inline NAME EXP) +<macro>(define-inline (NAME VAR ...) BODY ...)</macro><br> +<macro>(define-inline (NAME VAR1 ... VARn . VARn+1) BODY ...)</macro><br> +<macro>(define-inline NAME EXP)</macro> Defines an inline procedure. Any occurrence of {{NAME}} will be replaced by {{EXP}} or {{(lambda (VAR ... [. VAR]) BODY ...)}}. @@ -295,8 +286,8 @@ definitions should only appear at toplevel. ==== define-for-syntax - [syntax] (define-for-syntax (NAME VAR ... [. VAR]) EXP1 ...) - [syntax] (define-for-syntax NAME [VALUE]) +<macro>(define-for-syntax (NAME VAR ...) EXP1 ...)</macro><br> +<macro>(define-for-syntax (NAME VAR1 ... VARn . VARn+1) EXP1 ...)</macro><br> Defines the toplevel variable {{NAME}} at macro-expansion time. This can be helpful when you want to define support procedures for use in macro-transformers, @@ -305,8 +296,8 @@ for example. ==== define-compiler-syntax - [syntax] (define-compiler-syntax NAME TRANSFORMER) - [syntax] (define-compiler-syntax (NAME VAR ...) BODY ...) +<macro>(define-compiler-syntax NAME TRANSFORMER)</macro><br> +<macro>(define-compiler-syntax (NAME VAR ...) BODY ...)</macro> Defines what is usually called a ''compiler macro'': {{NAME}} should be the name of a globally or locally bound procedure. Any direct call to this procedure @@ -332,7 +323,7 @@ exported. ==== let-compiler-syntax - [syntax] (let-compiler-syntax ((NAME TRANSFORMER) ...) BODY ...) +<macro>(let-compiler-syntax ((NAME TRANSFORMER) ...) BODY ...)</macro> Allows definition local compiler macros, which are only applicable inside {{BODY ...}}. @@ -341,13 +332,13 @@ Allows definition local compiler macros, which are only applicable inside {{BODY ==== select - [syntax] (select EXP ((KEY ...) EXP1 ...) ... [(else EXPn ...)]) +<macro>(select EXP ((KEY ...) EXP1 ...) ... [(else EXPn ...)])</macro> This is similar to {{case}}, but the keys are evaluated. ==== unless - [syntax] (unless TEST EXP1 EXP2 ...) +<macro>(unless TEST EXP1 EXP2 ...)</macro> Equivalent to: @@ -357,7 +348,7 @@ Equivalent to: ==== when - [syntax] (when TEST EXP1 EXP2 ...) +<macro>(when TEST EXP1 EXP2 ...)</macro> Equivalent to: @@ -370,7 +361,7 @@ Equivalent to: ==== define-record - [syntax] (define-record NAME SLOTNAME ...) +<macro>(define-record NAME SLOTNAME ...)</macro> Defines a record type. Call {{make-NAME}} to create an instance of the structure (with one initialization-argument for each slot). @@ -389,10 +380,7 @@ and updated using {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}. ==== define-record-type - [syntax] (define-record-type NAME - (CONSTRUCTOR TAG ...) - PREDICATE - (FIELD ACCESSOR [MODIFIER]) ...) +<macro>(define-record-type NAME (CONSTRUCTOR TAG ...) PREDICATE (FIELD ACCESSOR [MODIFIER]) ...)</macro> SRFI-9 record types. For more information see the documentation for [[http://srfi.schemers.org/srfi-9/srfi-9.html|SRFI-9]]. @@ -400,8 +388,8 @@ SRFI-9 record types. For more information see the documentation for ==== define-record-printer - [syntax] (define-record-printer (NAME RECORDVAR PORTVAR) BODY ...) - [syntax] (define-record-printer NAME PROCEDURE) +<macro>(define-record-printer (NAME RECORDVAR PORTVAR) BODY ...)</macro><br> +<macro>(define-record-printer NAME PROCEDURE)</macro> Defines a printing method for record of the type {{NAME}} by associating a procedure with the record type. When a record of this @@ -430,7 +418,7 @@ s ==> "#,(foo 1 2 3)" ==== assert - [syntax] (assert EXP [STRING ARG ...]) +<macro>(assert EXP [STRING ARG ...])</macro> Signals an error if {{EXP}} evaluates to false. An optional message {{STRING}} and arguments {{ARG ...}} may be supplied to give a @@ -442,7 +430,7 @@ The result is the value of {{EXP}}. ==== begin-for-syntax - [syntax] (begin-for-syntax EXP ...) +<macro>(begin-for-syntax EXP ...)</macro> Equivalent to {{(begin EXP ...)}}, but performs the evaluation of the expression during macro-expansion time. @@ -450,7 +438,7 @@ the expression during macro-expansion time. ==== cond-expand - [syntax] (cond-expand FEATURE-CLAUSE ...) +<macro>(cond-expand FEATURE-CLAUSE ...)</macro> Expands by selecting feature clauses. This form is allowed to appear in non-toplevel expressions. @@ -470,7 +458,7 @@ For further information, see the documentation for [[http://srfi.schemers.org/sr ==== ensure - [syntax] (ensure PREDICATE EXP [ARGUMENTS ...]) +<macro>(ensure PREDICATE EXP [ARGUMENTS ...])</macro> Evaluates the expression {{EXP}} and applies the one-argument procedure {{PREDICATE}} to the result. If the predicate returns @@ -485,7 +473,7 @@ with the offending value and {{PREDICATE}} expression. ==== eval-when - [syntax] (eval-when (SITUATION ...) EXP ...) +<macro>(eval-when (SITUATION ...) EXP ...)</macro> Controls evaluation/compilation of subforms. {{SITUATION}} should be one of the symbols {{eval}}, {{compile}} or {{load}}. @@ -508,7 +496,7 @@ The following table should make this clearer: ==== include - [syntax] (include STRING) +<macro>(include STRING)</macro> Include toplevel-expressions from the given source file in the currently compiled/interpreted program. If the included file has the extension @@ -518,14 +506,14 @@ current directory and, if not found, in all directories specified in the ==== nth-value - [syntax] (nth-value N EXP) +<macro>(nth-value N EXP)</macro> Returns the {{N}}th value (counting from zero) of the values returned by expression {{EXP}}. ==== time - [syntax] (time EXP1 ...) +<macro>(time EXP1 ...)</macro> Evaluates {{EXP1 ...}} and prints elapsed time and some values about GC use, like time spent in major GCs, number of minor diff --git a/manual/Other support procedures b/manual/Other support procedures index 23d915b6..2866a38f 100644 --- a/manual/Other support procedures +++ b/manual/Other support procedures @@ -5,7 +5,7 @@ === argc+argv - [procedure] (argc+argv) +<procedure>(argc+argv)</procedure> Returns two values: an integer and a foreign-pointer object representing the {{argc}} and {{argv}} arguments passed to the current process. diff --git a/manual/Parameters b/manual/Parameters index b1c7d7c5..aa8ddc51 100644 --- a/manual/Parameters +++ b/manual/Parameters @@ -25,7 +25,7 @@ CHICKEN implements [[http://srfi.schemers.org/srfi-39/srfi-39.html|SRFI-39]]. === make-parameter - [procedure] (make-parameter VALUE [GUARD]) +<procedure>(make-parameter VALUE [GUARD])</procedure> Returns a procedure that accepts zero or one argument. Invoking the procedure with zero arguments returns {{VALUE}}. Invoking the diff --git a/manual/Supported language b/manual/Supported language index 8f546a16..4ffdd9d6 100644 --- a/manual/Supported language +++ b/manual/Supported language @@ -2,6 +2,7 @@ == Supported language +* [[The R5RS standard]] * [[Deviations from the standard]] * [[Extensions to the standard]] * [[Non-standard read syntax]] diff --git a/manual/The R5RS standard b/manual/The R5RS standard new file mode 100644 index 00000000..95964cee --- /dev/null +++ b/manual/The R5RS standard @@ -0,0 +1,3065 @@ +This document describes Chicken's R5RS support, with a heavy emphasis +on syntax and procedures. It is based directly on the +''Revised^5 Report on the Algorithmic Language Scheme''. +[[toc:]] +== Overview of Scheme +== Lexical conventions +== Basic concepts +== Expressions + +Expression types are categorized as primitive or derived. Primitive +expression types include variables and procedure calls. Derived +expression types are not semantically primitive, but can instead be +defined as macros. With the exception of quasiquote, whose macro +definition is complex, the derived expressions are classified as +library features. Suitable definitions are given in section 7.3. + +=== Primitive expression types + +==== Variable references + +<macro><variable></macro><br> + +An expression consisting of a variable (section 3.1) is a variable +reference. The value of the variable reference is the value stored in +the location to which the variable is bound. It is an error to +reference an unbound variable. + + (define x 28) + x ===> 28 + +==== Literal expressions + +<macro>(quote <datum>)</macro><br> +<macro>'<datum></macro><br> +<macro><constant></macro><br> + +(quote <datum>) evaluates to <datum>. <Datum> may be any external +representation of a Scheme object (see section 3.3). This notation is +used to include literal constants in Scheme code. + + (quote a) ===> a + (quote #(a b c)) ===> #(a b c) + (quote (+ 1 2)) ===> (+ 1 2) + +(quote <datum>) may be abbreviated as '<datum>. The two notations are +equivalent in all respects. + + 'a ===> a + '#(a b c) ===> #(a b c) + '() ===> () + '(+ 1 2) ===> (+ 1 2) + '(quote a) ===> (quote a) + "a ===> (quote a) + +Numerical constants, string constants, character constants, and boolean +constants evaluate "to themselves"; they need not be quoted. + + '"abc" ===> "abc" + "abc" ===> "abc" + '145932 ===> 145932 + 145932 ===> 145932 + '#t ===> #t + #t ===> #t + +As noted in section 3.4, it is an error to alter a constant (i.e. the +value of a literal expression) using a mutation procedure like set-car! +or string-set!. + +==== Procedure calls + +<macro>(<operator> <operand[1]> ...)</macro><br> + +A procedure call is written by simply enclosing in parentheses +expressions for the procedure to be called and the arguments to be +passed to it. The operator and operand expressions are evaluated (in an +unspecified order) and the resulting procedure is passed the resulting +arguments. + + (+ 3 4) ===> 7 + ((if #f + *) 3 4) ===> 12 + +A number of procedures are available as the values of variables in the +initial environment; for example, the addition and multiplication +procedures in the above examples are the values of the variables + and *. +New procedures are created by evaluating lambda expressions (see +section 4.1.4). Procedure calls may return any number of values (see +values in section 6.4). With the exception of values the procedures +available in the initial environment return one value or, for +procedures such as apply, pass on the values returned by a call to one +of their arguments. + +Procedure calls are also called combinations. + +Note: In contrast to other dialects of Lisp, the order of +evaluation is unspecified, and the operator expression and the +operand expressions are always evaluated with the same evaluation +rules. + +Note: Although the order of evaluation is otherwise unspecified, +the effect of any concurrent evaluation of the operator and operand +expressions is constrained to be consistent with some sequential +order of evaluation. The order of evaluation may be chosen +differently for each procedure call. + +Note: In many dialects of Lisp, the empty combination, (), is a +legitimate expression. In Scheme, combinations must have at least +one subexpression, so () is not a syntactically valid expression. + +==== Procedures + +<macro>(lambda <formals> <body>)</macro><br> + +Syntax: <Formals> should be a formal arguments list as described below, +and <body> should be a sequence of one or more expressions. + +Semantics: A lambda expression evaluates to a procedure. The +environment in effect when the lambda expression was evaluated is +remembered as part of the procedure. When the procedure is later called +with some actual arguments, the environment in which the lambda +expression was evaluated will be extended by binding the variables in +the formal argument list to fresh locations, the corresponding actual +argument values will be stored in those locations, and the expressions +in the body of the lambda expression will be evaluated sequentially in +the extended environment. The result(s) of the last expression in the +body will be returned as the result(s) of the procedure call. + + (lambda (x) (+ x x)) ===> a procedure + ((lambda (x) (+ x x)) 4) ===> 8 + + (define reverse-subtract + (lambda (x y) (- y x))) + (reverse-subtract 7 10) ===> 3 + + (define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) + (add4 6) ===> 10 + +<Formals> should have one of the following forms: + +* (<variable[1]> ...): The procedure takes a fixed number of + arguments; when the procedure is called, the arguments will be + stored in the bindings of the corresponding variables. + +* <variable>: The procedure takes any number of arguments; when the + procedure is called, the sequence of actual arguments is converted + into a newly allocated list, and the list is stored in the binding + of the <variable>. + +* (<variable[1]> ... <variable[n]> . <variable[n+1]>): If a + space-delimited period precedes the last variable, then the + procedure takes n or more arguments, where n is the number of + formal arguments before the period (there must be at least one). + The value stored in the binding of the last variable will be a + newly allocated list of the actual arguments left over after all + the other actual arguments have been matched up against the other + formal arguments. + +It is an error for a <variable> to appear more than once in <formals>. + + ((lambda x x) 3 4 5 6) ===> (3 4 5 6) + ((lambda (x y . z) z) + 3 4 5 6) ===> (5 6) + +Each procedure created as the result of evaluating a lambda expression +is (conceptually) tagged with a storage location, in order to make eqv? +and eq? work on procedures (see section 6.1). + +==== Conditionals + +<macro>(if <test> <consequent> <alternate>)</macro><br> +<macro>(if <test> <consequent>)</macro><br> + +Syntax: <Test>, <consequent>, and <alternate> may be arbitrary +expressions. + +Semantics: An if expression is evaluated as follows: first, <test> is +evaluated. If it yields a true value (see section 6.3.1), then +<consequent> is evaluated and its value(s) is(are) returned. Otherwise +<alternate> is evaluated and its value(s) is(are) returned. If <test> +yields a false value and no <alternate> is specified, then the result +of the expression is unspecified. + + (if (> 3 2) 'yes 'no) ===> yes + (if (> 2 3) 'yes 'no) ===> no + (if (> 3 2) + (- 3 2) + (+ 3 2)) ===> 1 + +==== Assignments + +<macro>(set! <variable> <expression>)</macro><br> + +<Expression> is evaluated, and the resulting value is stored in the +location to which <variable> is bound. <Variable> must be bound either +in some region enclosing the set! expression or at top level. The +result of the set! expression is unspecified. + + (define x 2) + (+ x 1) ===> 3 + (set! x 4) ===> unspecified + (+ x 1) ===> 5 + +=== Derived expression types + +The constructs in this section are hygienic, as discussed in section +4.3. For reference purposes, section 7.3 gives macro definitions that +will convert most of the constructs described in this section into the +primitive constructs described in the previous section. + +==== Conditionals + +<macro>(cond <clause[1]> <clause[2]> ...)</macro><br> + +Syntax: Each <clause> should be of the form + + (<test> <expression[1]> ...) + +where <test> is any expression. Alternatively, a <clause> may be of the +form + + (<test> => <expression>) + +The last <clause> may be an "else clause," which has the form + + (else <expression[1]> <expression[2]> ...). + +Semantics: A cond expression is evaluated by evaluating the <test> +expressions of successive <clause>s in order until one of them +evaluates to a true value (see section 6.3.1). When a <test> evaluates +to a true value, then the remaining <expression>s in its <clause> are +evaluated in order, and the result(s) of the last <expression> in the +<clause> is(are) returned as the result(s) of the entire cond +expression. If the selected <clause> contains only the <test> and no +<expression>s, then the value of the <test> is returned as the result. +If the selected <clause> uses the => alternate form, then the +<expression> is evaluated. Its value must be a procedure that accepts +one argument; this procedure is then called on the value of the <test> +and the value(s) returned by this procedure is(are) returned by the +cond expression. If all <test>s evaluate to false values, and there is +no else clause, then the result of the conditional expression is +unspecified; if there is an else clause, then its <expression>s are +evaluated, and the value(s) of the last one is(are) returned. + + (cond ((> 3 2) 'greater) + ((< 3 2) 'less)) ===> greater + (cond ((> 3 3) 'greater) + ((< 3 3) 'less) + (else 'equal)) ===> equal + (cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f)) ===> 2 + +<macro>(case <key> <clause[1]> <clause[2]> ...)</macro><br> + +Syntax: <Key> may be any expression. Each <clause> should have the form + + ((<datum[1]> ...) <expression[1]> <expression[2]> ...), + +where each <datum> is an external representation of some object. All +the <datum>s must be distinct. The last <clause> may be an "else +clause," which has the form + + (else <expression[1]> <expression[2]> ...). + +Semantics: A case expression is evaluated as follows. <Key> is +evaluated and its result is compared against each <datum>. If the +result of evaluating <key> is equivalent (in the sense of eqv?; see +section 6.1) to a <datum>, then the expressions in the corresponding +<clause> are evaluated from left to right and the result(s) of the last +expression in the <clause> is(are) returned as the result(s) of the +case expression. If the result of evaluating <key> is different from +every <datum>, then if there is an else clause its expressions are +evaluated and the result(s) of the last is(are) the result(s) of the +case expression; otherwise the result of the case expression is +unspecified. + + (case (* 2 3) + ((2 3 5 7) 'prime) + ((1 4 6 8 9) 'composite)) ===> composite + (case (car '(c d)) + ((a) 'a) + ((b) 'b)) ===> unspecified + (case (car '(c d)) + ((a e i o u) 'vowel) + ((w y) 'semivowel) + (else 'consonant)) ===> consonant + +<macro>(and <test[1]> ...)</macro><br> + +The <test> expressions are evaluated from left to right, and the value +of the first expression that evaluates to a false value (see section +6.3.1) is returned. Any remaining expressions are not evaluated. If all +the expressions evaluate to true values, the value of the last +expression is returned. If there are no expressions then #t is +returned. + + (and (= 2 2) (> 2 1)) ===> #t + (and (= 2 2) (< 2 1)) ===> #f + (and 1 2 'c '(f g)) ===> (f g) + (and) ===> #t + +<macro>(or <test[1]> ...)</macro><br> + +The <test> expressions are evaluated from left to right, and the value +of the first expression that evaluates to a true value (see section +6.3.1) is returned. Any remaining expressions are not evaluated. If all +expressions evaluate to false values, the value of the last expression +is returned. If there are no expressions then #f is returned. + + (or (= 2 2) (> 2 1)) ===> #t + (or (= 2 2) (< 2 1)) ===> #t + (or #f #f #f) ===> #f + (or (memq 'b '(a b c)) + (/ 3 0)) ===> (b c) + +==== Binding constructs + +The three binding constructs let, let*, and letrec give Scheme a block +structure, like Algol 60. The syntax of the three constructs is +identical, but they differ in the regions they establish for their +variable bindings. In a let expression, the initial values are computed +before any of the variables become bound; in a let* expression, the +bindings and evaluations are performed sequentially; while in a letrec +expression, all the bindings are in effect while their initial values +are being computed, thus allowing mutually recursive definitions. + +<macro>(let <bindings> <body>)</macro><br> + +Syntax: <Bindings> should have the form + + ((<variable[1]> <init[1]>) ...), + +where each <init> is an expression, and <body> should be a sequence of +one or more expressions. It is an error for a <variable> to appear more +than once in the list of variables being bound. + +Semantics: The <init>s are evaluated in the current environment (in +some unspecified order), the <variable>s are bound to fresh locations +holding the results, the <body> is evaluated in the extended +environment, and the value(s) of the last expression of <body> is(are) +returned. Each binding of a <variable> has <body> as its region. + + (let ((x 2) (y 3)) + (* x y)) ===> 6 + + (let ((x 2) (y 3)) + (let ((x 7) + (z (+ x y))) + (* z x))) ===> 35 + +See also named let, section 4.2.4. + +<macro>(let* <bindings> <body>)</macro><br> + +Syntax: <Bindings> should have the form + + ((<variable[1]> <init[1]>) ...), + +and <body> should be a sequence of one or more expressions. + +Semantics: Let* is similar to let, but the bindings are performed +sequentially from left to right, and the region of a binding indicated +by (<variable> <init>) is that part of the let* expression to the right +of the binding. Thus the second binding is done in an environment in +which the first binding is visible, and so on. + + (let ((x 2) (y 3)) + (let* ((x 7) + (z (+ x y))) + (* z x))) ===> 70 + +<macro>(letrec <bindings> <body>)</macro><br> + +Syntax: <Bindings> should have the form + + ((<variable[1]> <init[1]>) ...), + +and <body> should be a sequence of one or more expressions. It is an +error for a <variable> to appear more than once in the list of +variables being bound. + +Semantics: The <variable>s are bound to fresh locations holding +undefined values, the <init>s are evaluated in the resulting +environment (in some unspecified order), each <variable> is assigned to +the result of the corresponding <init>, the <body> is evaluated in the +resulting environment, and the value(s) of the last expression in +<body> is(are) returned. Each binding of a <variable> has the entire +letrec expression as its region, making it possible to define mutually +recursive procedures. + + (letrec ((even? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) + ===> #t + +One restriction on letrec is very important: it must be possible to +evaluate each <init> without assigning or referring to the value of any +<variable>. If this restriction is violated, then it is an error. The +restriction is necessary because Scheme passes arguments by value +rather than by name. In the most common uses of letrec, all the <init>s +are lambda expressions and the restriction is satisfied automatically. + +==== Sequencing + +<macro>(begin <expression[1]> <expression[2]> ...)</macro><br> + +The <expression>s are evaluated sequentially from left to right, and +the value(s) of the last <expression> is(are) returned. This expression +type is used to sequence side effects such as input and output. + + (define x 0) + + (begin (set! x 5) + (+ x 1)) ===> 6 + + (begin (display "4 plus 1 equals ") + (display (+ 4 1))) ===> unspecified + and prints 4 plus 1 equals 5 + +==== Iteration + +<macro>(do ((<variable[1]> <init[1]> <step[1]>) ...) (<test> <expression> ...) <command> ...)</macro><br> + +Do is an iteration construct. It specifies a set of variables to be +bound, how they are to be initialized at the start, and how they are to +be updated on each iteration. When a termination condition is met, the +loop exits after evaluating the <expression>s. + +Do expressions are evaluated as follows: The <init> expressions are +evaluated (in some unspecified order), the <variable>s are bound to +fresh locations, the results of the <init> expressions are stored in +the bindings of the <variable>s, and then the iteration phase begins. + +Each iteration begins by evaluating <test>; if the result is false (see +section 6.3.1), then the <command> expressions are evaluated in order +for effect, the <step> expressions are evaluated in some unspecified +order, the <variable>s are bound to fresh locations, the results of the +<step>s are stored in the bindings of the <variable>s, and the next +iteration begins. + +If <test> evaluates to a true value, then the <expression>s are +evaluated from left to right and the value(s) of the last <expression> +is(are) returned. If no <expression>s are present, then the value of +the do expression is unspecified. + +The region of the binding of a <variable> consists of the entire do +expression except for the <init>s. It is an error for a <variable> to +appear more than once in the list of do variables. + +A <step> may be omitted, in which case the effect is the same as if +(<variable> <init> <variable>) had been written instead of (<variable> +<init>). + + (do ((vec (make-vector 5)) + (i 0 (+ i 1))) + ((= i 5) vec) + (vector-set! vec i i)) ===> #(0 1 2 3 4) + + (let ((x '(1 3 5 7 9))) + (do ((x x (cdr x)) + (sum 0 (+ sum (car x)))) + ((null? x) sum))) ===> 25 + +<macro>(let <variable> <bindings> <body>)</macro><br> + +"Named let" is a variant on the syntax of let which provides a more +general looping construct than do and may also be used to express +recursions. It has the same syntax and semantics as ordinary let except +that <variable> is bound within <body> to a procedure whose formal +arguments are the bound variables and whose body is <body>. Thus the +execution of <body> may be repeated by invoking the procedure named by +<variable>. + + (let loop ((numbers '(3 -2 1 6 -5)) + (nonneg '()) + (neg '())) + (cond ((null? numbers) (list nonneg neg)) + ((>= (car numbers) 0) + (loop (cdr numbers) + (cons (car numbers) nonneg) + neg)) + ((< (car numbers) 0) + (loop (cdr numbers) + nonneg + (cons (car numbers) neg))))) + ===> ((6 1 3) (-5 -2)) + +==== Delayed evaluation + +<macro>(delay <expression>)</macro><br> + +The delay construct is used together with the procedure force to +implement lazy evaluation or call by need. (delay <expression>) returns +an object called a promise which at some point in the future may be +asked (by the force procedure) to evaluate <expression>, and deliver +the resulting value. The effect of <expression> returning multiple +values is unspecified. + +See the description of force (section 6.4) for a more complete +description of delay. + +==== Quasiquotation + +<macro>(quasiquote <qq template>)</macro><br> +<macro>`<qq template></macro><br> + +"Backquote" or "quasiquote" expressions are useful for constructing +a list or vector structure when most but not all of the desired +structure is known in advance. If no commas appear within the <qq +template>, the result of evaluating `<qq template> is equivalent to the +result of evaluating '<qq template>. If a comma appears within the <qq +template>, however, the expression following the comma is evaluated +("unquoted") and its result is inserted into the structure instead of +the comma and the expression. If a comma appears followed immediately +by an at-sign (@), then the following expression must evaluate to a +list; the opening and closing parentheses of the list are then +"stripped away" and the elements of the list are inserted in place of +the comma at-sign expression sequence. A comma at-sign should only +appear within a list or vector <qq template>. + + `(list ,(+ 1 2) 4) ===> (list 3 4) + (let ((name 'a)) `(list ,name ',name)) + ===> (list a (quote a)) + `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b) + ===> (a 3 4 5 6 b) + `(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons))) + ===> ((foo 7) . cons) + `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8) + ===> #(10 5 2 4 3 8) + +Quasiquote forms may be nested. Substitutions are made only for +unquoted components appearing at the same nesting level as the +outermost backquote. The nesting level increases by one inside each +successive quasiquotation, and decreases by one inside each +unquotation. + + `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) + ===> (a `(b ,(+ 1 2) ,(foo 4 d) e) f) + (let ((name1 'x) + (name2 'y)) + `(a `(b ,,name1 ,',name2 d) e)) + ===> (a `(b ,x ,'y d) e) + +The two notations `<qq template> and (quasiquote <qq template>) are +identical in all respects. ,<expression> is identical to (unquote +<expression>), and ,@<expression> is identical to (unquote-splicing +<expression>). The external syntax generated by write for two-element +lists whose car is one of these symbols may vary between +implementations. + + (quasiquote (list (unquote (+ 1 2)) 4)) + ===> (list 3 4) + '(quasiquote (list (unquote (+ 1 2)) 4)) + ===> `(list ,(+ 1 2) 4) + i.e., (quasiquote (list (unquote (+ 1 2)) 4)) + +Unpredictable behavior can result if any of the symbols quasiquote, +unquote, or unquote-splicing appear in positions within a <qq template> +otherwise than as described above. + +=== Macros + +Scheme programs can define and use new derived expression types, called +macros. Program-defined expression types have the syntax + + (<keyword> <datum> ...) + +where <keyword> is an identifier that uniquely determines the +expression type. This identifier is called the syntactic keyword, or +simply keyword, of the macro. The number of the <datum>s, and their +syntax, depends on the expression type. + +Each instance of a macro is called a use of the macro. The set of rules +that specifies how a use of a macro is transcribed into a more +primitive expression is called the transformer of the macro. + +The macro definition facility consists of two parts: + +* A set of expressions used to establish that certain identifiers are + macro keywords, associate them with macro transformers, and control + the scope within which a macro is defined, and + +* a pattern language for specifying macro transformers. + +The syntactic keyword of a macro may shadow variable bindings, and +local variable bindings may shadow keyword bindings. All macros defined +using the pattern language are "hygienic" and "referentially +transparent" and thus preserve Scheme's lexical scoping: + +* If a macro transformer inserts a binding for an identifier + (variable or keyword), the identifier will in effect be renamed + throughout its scope to avoid conflicts with other identifiers. + Note that a define at top level may or may not introduce a binding; + see section 5.2. + +* If a macro transformer inserts a free reference to an identifier, + the reference refers to the binding that was visible where the + transformer was specified, regardless of any local bindings that + may surround the use of the macro. + +==== Binding constructs for syntactic keywords + +Let-syntax and letrec-syntax are analogous to let and letrec, but they +bind syntactic keywords to macro transformers instead of binding +variables to locations that contain values. Syntactic keywords may also +be bound at top level; see section 5.3. + +<macro>(let-syntax <bindings> <body>)</macro><br> + +Syntax: <Bindings> should have the form + + ((<keyword> <transformer spec>) ...) + +Each <keyword> is an identifier, each <transformer spec> is an instance +of syntax-rules, and <body> should be a sequence of one or more +expressions. It is an error for a <keyword> to appear more than once in +the list of keywords being bound. + +Semantics: The <body> is expanded in the syntactic environment obtained +by extending the syntactic environment of the let-syntax expression +with macros whose keywords are the <keyword>s, bound to the specified +transformers. Each binding of a <keyword> has <body> as its region. + + (let-syntax ((when (syntax-rules () + ((when test stmt1 stmt2 ...) + (if test + (begin stmt1 + stmt2 ...)))))) + (let ((if #t)) + (when if (set! if 'now)) + if)) ===> now + + (let ((x 'outer)) + (let-syntax ((m (syntax-rules () ((m) x)))) + (let ((x 'inner)) + (m)))) ===> outer + +<macro>(letrec-syntax <bindings> <body>)</macro><br> + +Syntax: Same as for let-syntax. + +Semantics: The <body> is expanded in the syntactic environment obtained +by extending the syntactic environment of the letrec-syntax expression +with macros whose keywords are the <keyword>s, bound to the specified +transformers. Each binding of a <keyword> has the <bindings> as well as +the <body> within its region, so the transformers can transcribe +expressions into uses of the macros introduced by the letrec-syntax +expression. + + (letrec-syntax + ((my-or (syntax-rules () + ((my-or) #f) + ((my-or e) e) + ((my-or e1 e2 ...) + (let ((temp e1)) + (if temp + temp + (my-or e2 ...))))))) + (let ((x #f) + (y 7) + (temp 8) + (let odd?) + (if even?)) + (my-or x + (let temp) + (if y) + y))) ===> 7 + +==== Pattern language + +A <transformer spec> has the following form: + + (syntax-rules <literals> <syntax rule> ...) + +Syntax: <Literals> is a list of identifiers and each <syntax rule> +should be of the form + + (<pattern> <template>) + +The <pattern> in a <syntax rule> is a list <pattern> that begins with +the keyword for the macro. + +A <pattern> is either an identifier, a constant, or one of the +following + + (<pattern> ...) + (<pattern> <pattern> ... . <pattern>) + (<pattern> ... <pattern> <ellipsis>) + #(<pattern> ...) + #(<pattern> ... <pattern> <ellipsis>) + +and a template is either an identifier, a constant, or one of the +following + + (<element> ...) + (<element> <element> ... . <template>) + #(<element> ...) + +where an <element> is a <template> optionally followed by an <ellipsis> +and an <ellipsis> is the identifier "..." (which cannot be used as an +identifier in either a template or a pattern). + +Semantics: An instance of syntax-rules produces a new macro transformer +by specifying a sequence of hygienic rewrite rules. A use of a macro +whose keyword is associated with a transformer specified by +syntax-rules is matched against the patterns contained in the <syntax +rule>s, beginning with the leftmost <syntax rule>. When a match is +found, the macro use is transcribed hygienically according to the +template. + +An identifier that appears in the pattern of a <syntax rule> is a +pattern variable, unless it is the keyword that begins the pattern, is +listed in <literals>, or is the identifier "...". Pattern variables +match arbitrary input elements and are used to refer to elements of the +input in the template. It is an error for the same pattern variable to +appear more than once in a <pattern>. + +The keyword at the beginning of the pattern in a <syntax rule> is not +involved in the matching and is not considered a pattern variable or +literal identifier. + +Rationale: The scope of the keyword is determined by the +expression or syntax definition that binds it to the associated +macro transformer. If the keyword were a pattern variable or +literal identifier, then the template that follows the pattern +would be within its scope regardless of whether the keyword were +bound by let-syntax or by letrec-syntax. + +Identifiers that appear in <literals> are interpreted as literal +identifiers to be matched against corresponding subforms of the input. +A subform in the input matches a literal identifier if and only if it +is an identifier and either both its occurrence in the macro expression +and its occurrence in the macro definition have the same lexical +binding, or the two identifiers are equal and both have no lexical +binding. + +A subpattern followed by ... can match zero or more elements of the +input. It is an error for ... to appear in <literals>. Within a pattern +the identifier ... must follow the last element of a nonempty sequence +of subpatterns. + +More formally, an input form F matches a pattern P if and only if: + +* P is a non-literal identifier; or + +* P is a literal identifier and F is an identifier with the same + binding; or + +* P is a list (P[1] ... P[n]) and F is a list of n forms that match P + [1] through P[n], respectively; or + +* P is an improper list (P[1] P[2] ... P[n] . P[n+1]) and F is a list + or improper list of n or more forms that match P[1] through P[n], + respectively, and whose nth "cdr" matches P[n+1]; or + +* P is of the form (P[1] ... P[n] P[n+1] <ellipsis>) where <ellipsis> + is the identifier ... and F is a proper list of at least n forms, + the first n of which match P[1] through P[n], respectively, and + each remaining element of F matches P[n+1]; or + +* P is a vector of the form #(P[1] ... P[n]) and F is a vector of n + forms that match P[1] through P[n]; or + +* P is of the form #(P[1] ... P[n] P[n+1] <ellipsis>) where + <ellipsis> is the identifier ... and F is a vector of n or more + forms the first n of which match P[1] through P[n], respectively, + and each remaining element of F matches P[n+1]; or + +* P is a datum and F is equal to P in the sense of the equal? + procedure. + +It is an error to use a macro keyword, within the scope of its binding, +in an expression that does not match any of the patterns. + +When a macro use is transcribed according to the template of the +matching <syntax rule>, pattern variables that occur in the template +are replaced by the subforms they match in the input. Pattern variables +that occur in subpatterns followed by one or more instances of the +identifier ... are allowed only in subtemplates that are followed by as +many instances of .... They are replaced in the output by all of the +subforms they match in the input, distributed as indicated. It is an +error if the output cannot be built up as specified. + +Identifiers that appear in the template but are not pattern variables +or the identifier ... are inserted into the output as literal +identifiers. If a literal identifier is inserted as a free identifier +then it refers to the binding of that identifier within whose scope the +instance of syntax-rules appears. If a literal identifier is inserted +as a bound identifier then it is in effect renamed to prevent +inadvertent captures of free identifiers. + +As an example, if let and cond are defined as in section 7.3 then they +are hygienic (as required) and the following is not an error. + + (let ((=> #f)) + (cond (#t => 'ok))) ===> ok + +The macro transformer for cond recognizes => as a local variable, and +hence an expression, and not as the top-level identifier =>, which the +macro transformer treats as a syntactic keyword. Thus the example +expands into + + (let ((=> #f)) + (if #t (begin => 'ok))) + +instead of + + (let ((=> #f)) + (let ((temp #t)) + (if temp ('ok temp)))) + +which would result in an invalid procedure call. + +== Program structure + +== Standard procedures + +This chapter describes Scheme's built-in procedures. The initial (or +"top level") Scheme environment starts out with a number of variables +bound to locations containing useful values, most of which are +primitive procedures that manipulate data. For example, the variable +abs is bound to (a location initially containing) a procedure of one +argument that computes the absolute value of a number, and the variable ++ is bound to a procedure that computes sums. Built-in procedures that +can easily be written in terms of other built-in procedures are +identified as "library procedures". + +A program may use a top-level definition to bind any variable. It may +subsequently alter any such binding by an assignment (see 4.1.6). These +operations do not modify the behavior of Scheme's built-in procedures. +Altering any top-level binding that has not been introduced by a +definition has an unspecified effect on the behavior of the built-in +procedures. + +=== Equivalence predicates + +A predicate is a procedure that always returns a boolean value (#t or #f). +An equivalence predicate is the computational analogue of a +mathematical equivalence relation (it is symmetric, reflexive, and +transitive). Of the equivalence predicates described in this section, +eq? is the finest or most discriminating, and equal? is the coarsest. +eqv? is slightly less discriminating than eq?. + +<procedure>(eqv? obj[1] obj[2])</procedure><br> + +The eqv? procedure defines a useful equivalence relation on objects. +Briefly, it returns #t if obj[1] and obj[2] should normally be regarded +as the same object. This relation is left slightly open to +interpretation, but the following partial specification of eqv? holds +for all implementations of Scheme. + +The eqv? procedure returns #t if: + +* obj[1] and obj[2] are both #t or both #f. + +* obj[1] and obj[2] are both symbols and + + (string=? (symbol->string obj1) + (symbol->string obj2)) + ===> #t + +Note: This assumes that neither obj[1] nor obj[2] is an +"uninterned symbol" as alluded to in section 6.3.3. This +report does not presume to specify the behavior of eqv? on +implementation-dependent extensions. + +* obj[1] and obj[2] are both numbers, are numerically equal (see =, + section 6.2), and are either both exact or both inexact. + +* obj[1] and obj[2] are both characters and are the same character + according to the char=? procedure (section 6.3.4). + +* both obj[1] and obj[2] are the empty list. + +* obj[1] and obj[2] are pairs, vectors, or strings that denote the + same locations in the store (section 3.4). + +* obj[1] and obj[2] are procedures whose location tags are equal + (section 4.1.4). + +The eqv? procedure returns #f if: + +* obj[1] and obj[2] are of different types (section 3.2). + +* one of obj[1] and obj[2] is #t but the other is #f. + +* obj[1] and obj[2] are symbols but + + (string=? (symbol->string obj[1]) + (symbol->string obj[2])) + ===> #f + +* one of obj[1] and obj[2] is an exact number but the other is an + inexact number. + +* obj[1] and obj[2] are numbers for which the = procedure returns #f. + +* obj[1] and obj[2] are characters for which the char=? procedure + returns #f. + +* one of obj[1] and obj[2] is the empty list but the other is not. + +* obj[1] and obj[2] are pairs, vectors, or strings that denote + distinct locations. + +* obj[1] and obj[2] are procedures that would behave differently + (return different value(s) or have different side effects) for some + arguments. + + (eqv? 'a 'a) ===> #t + (eqv? 'a 'b) ===> #f + (eqv? 2 2) ===> #t + (eqv? '() '()) ===> #t + (eqv? 100000000 100000000) ===> #t + (eqv? (cons 1 2) (cons 1 2)) ===> #f + (eqv? (lambda () 1) + (lambda () 2)) ===> #f + (eqv? #f 'nil) ===> #f + (let ((p (lambda (x) x))) + (eqv? p p)) ===> #t + +The following examples illustrate cases in which the above rules do not +fully specify the behavior of eqv?. All that can be said about such +cases is that the value returned by eqv? must be a boolean. + + (eqv? "" "") ===> unspecified + (eqv? '#() '#()) ===> unspecified + (eqv? (lambda (x) x) + (lambda (x) x)) ===> unspecified + (eqv? (lambda (x) x) + (lambda (y) y)) ===> unspecified + +The next set of examples shows the use of eqv? with procedures that +have local state. Gen-counter must return a distinct procedure every +time, since each procedure has its own internal counter. Gen-loser, +however, returns equivalent procedures each time, since the local state +does not affect the value or side effects of the procedures. + + (define gen-counter + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) n)))) + (let ((g (gen-counter))) + (eqv? g g)) ===> #t + (eqv? (gen-counter) (gen-counter)) + ===> #f + (define gen-loser + (lambda () + (let ((n 0)) + (lambda () (set! n (+ n 1)) 27)))) + (let ((g (gen-loser))) + (eqv? g g)) ===> #t + (eqv? (gen-loser) (gen-loser)) + ===> unspecified + + (letrec ((f (lambda () (if (eqv? f g) 'both 'f))) + (g (lambda () (if (eqv? f g) 'both 'g)))) + (eqv? f g)) + ===> unspecified + + (letrec ((f (lambda () (if (eqv? f g) 'f 'both))) + (g (lambda () (if (eqv? f g) 'g 'both)))) + (eqv? f g)) + ===> #f + +Since it is an error to modify constant objects (those returned by +literal expressions), implementations are permitted, though not +required, to share structure between constants where appropriate. Thus +the value of eqv? on constants is sometimes implementation-dependent. + + (eqv? '(a) '(a)) ===> unspecified + (eqv? "a" "a") ===> unspecified + (eqv? '(b) (cdr '(a b))) ===> unspecified + (let ((x '(a))) + (eqv? x x)) ===> #t + +Rationale: The above definition of eqv? allows implementations +latitude in their treatment of procedures and literals: +implementations are free either to detect or to fail to detect that +two procedures or two literals are equivalent to each other, and +can decide whether or not to merge representations of equivalent +objects by using the same pointer or bit pattern to represent both. + +<procedure>(eq? obj[1] obj[2])</procedure><br> + +Eq? is similar to eqv? except that in some cases it is capable of +discerning distinctions finer than those detectable by eqv?. + +Eq? and eqv? are guaranteed to have the same behavior on symbols, +booleans, the empty list, pairs, procedures, and non-empty strings and +vectors. Eq?'s behavior on numbers and characters is +implementation-dependent, but it will always return either true or +false, and will return true only when eqv? would also return true. Eq? +may also behave differently from eqv? on empty vectors and empty +strings. + + (eq? 'a 'a) ===> #t + (eq? '(a) '(a)) ===> unspecified + (eq? (list 'a) (list 'a)) ===> #f + (eq? "a" "a") ===> unspecified + (eq? "" "") ===> unspecified + (eq? '() '()) ===> #t + (eq? 2 2) ===> unspecified + (eq? #\A #\A) ===> unspecified + (eq? car car) ===> #t + (let ((n (+ 2 3))) + (eq? n n)) ===> unspecified + (let ((x '(a))) + (eq? x x)) ===> #t + (let ((x '#())) + (eq? x x)) ===> #t + (let ((p (lambda (x) x))) + (eq? p p)) ===> #t + +Rationale: It will usually be possible to implement eq? much more +efficiently than eqv?, for example, as a simple pointer comparison +instead of as some more complicated operation. One reason is that +it may not be possible to compute eqv? of two numbers in constant +time, whereas eq? implemented as pointer comparison will always +finish in constant time. Eq? may be used like eqv? in applications +using procedures to implement objects with state since it obeys the +same constraints as eqv?. + +<procedure>(equal? obj[1] obj[2])</procedure><br> + +Equal? recursively compares the contents of pairs, vectors, and +strings, applying eqv? on other objects such as numbers and symbols. A +rule of thumb is that objects are generally equal? if they print the +same. Equal? may fail to terminate if its arguments are circular data +structures. + + (equal? 'a 'a) ===> #t + (equal? '(a) '(a)) ===> #t + (equal? '(a (b) c) + '(a (b) c)) ===> #t + (equal? "abc" "abc") ===> #t + (equal? 2 2) ===> #t + (equal? (make-vector 5 'a) + (make-vector 5 'a)) ===> #t + (equal? (lambda (x) x) + (lambda (y) y)) ===> unspecified + +=== Numbers + +Numerical computation has traditionally been neglected by the Lisp +community. Until Common Lisp there was no carefully thought out +strategy for organizing numerical computation, and with the exception +of the MacLisp system [20] little effort was made to execute numerical +code efficiently. This report recognizes the excellent work of the +Common Lisp committee and accepts many of their recommendations. In +some ways this report simplifies and generalizes their proposals in a +manner consistent with the purposes of Scheme. + +It is important to distinguish between the mathematical numbers, the +Scheme numbers that attempt to model them, the machine representations +used to implement the Scheme numbers, and notations used to write +numbers. This report uses the types number, complex, real, rational, +and integer to refer to both mathematical numbers and Scheme numbers. +Machine representations such as fixed point and floating point are +referred to by names such as fixnum and flonum. + +==== Numerical types + +Mathematically, numbers may be arranged into a tower of subtypes in +which each level is a subset of the level above it: + + number + complex + real + rational + integer + +For example, 3 is an integer. Therefore 3 is also a rational, a real, +and a complex. The same is true of the Scheme numbers that model 3. For +Scheme numbers, these types are defined by the predicates number?, +complex?, real?, rational?, and integer?. + +There is no simple relationship between a number's type and its +representation inside a computer. Although most implementations of +Scheme will offer at least two different representations of 3, these +different representations denote the same integer. + +Scheme's numerical operations treat numbers as abstract data, as +independent of their representation as possible. Although an +implementation of Scheme may use fixnum, flonum, and perhaps other +representations for numbers, this should not be apparent to a casual +programmer writing simple programs. + +It is necessary, however, to distinguish between numbers that are +represented exactly and those that may not be. For example, indexes +into data structures must be known exactly, as must some polynomial +coefficients in a symbolic algebra system. On the other hand, the +results of measurements are inherently inexact, and irrational numbers +may be approximated by rational and therefore inexact approximations. +In order to catch uses of inexact numbers where exact numbers are +required, Scheme explicitly distinguishes exact from inexact numbers. +This distinction is orthogonal to the dimension of type. + +==== Exactness + +Scheme numbers are either exact or inexact. A number is exact if it was +written as an exact constant or was derived from exact numbers using +only exact operations. A number is inexact if it was written as an +inexact constant, if it was derived using inexact ingredients, or if it +was derived using inexact operations. Thus inexactness is a contagious +property of a number. If two implementations produce exact results for +a computation that did not involve inexact intermediate results, the +two ultimate results will be mathematically equivalent. This is +generally not true of computations involving inexact numbers since +approximate methods such as floating point arithmetic may be used, but +it is the duty of each implementation to make the result as close as +practical to the mathematically ideal result. + +Rational operations such as + should always produce exact results when +given exact arguments. If the operation is unable to produce an exact +result, then it may either report the violation of an implementation +restriction or it may silently coerce its result to an inexact value. +See section 6.2.3. + +With the exception of inexact->exact, the operations described in this +section must generally return inexact results when given any inexact +arguments. An operation may, however, return an exact result if it can +prove that the value of the result is unaffected by the inexactness of +its arguments. For example, multiplication of any number by an exact +zero may produce an exact zero result, even if the other argument is +inexact. + +==== Implementation restrictions + +Implementations of Scheme are not required to implement the whole tower +of subtypes given in section 6.2.1, but they must implement a coherent +subset consistent with both the purposes of the implementation and the +spirit of the Scheme language. For example, an implementation in which +all numbers are real may still be quite useful. + +Implementations may also support only a limited range of numbers of any +type, subject to the requirements of this section. The supported range +for exact numbers of any type may be different from the supported range +for inexact numbers of that type. For example, an implementation that +uses flonums to represent all its inexact real numbers may support a +practically unbounded range of exact integers and rationals while +limiting the range of inexact reals (and therefore the range of inexact +integers and rationals) to the dynamic range of the flonum format. +Furthermore the gaps between the representable inexact integers and +rationals are likely to be very large in such an implementation as the +limits of this range are approached. + +An implementation of Scheme must support exact integers throughout the +range of numbers that may be used for indexes of lists, vectors, and +strings or that may result from computing the length of a list, vector, +or string. The length, vector-length, and string-length procedures must +return an exact integer, and it is an error to use anything but an +exact integer as an index. Furthermore any integer constant within the +index range, if expressed by an exact integer syntax, will indeed be +read as an exact integer, regardless of any implementation restrictions +that may apply outside this range. Finally, the procedures listed below +will always return an exact integer result provided all their arguments +are exact integers and the mathematically expected result is +representable as an exact integer within the implementation: + + + - * + quotient remainder modulo + max min abs + numerator denominator gcd + lcm floor ceiling + truncate round rationalize + expt + +Implementations are encouraged, but not required, to support exact +integers and exact rationals of practically unlimited size and +precision, and to implement the above procedures and the / procedure in +such a way that they always return exact results when given exact +arguments. If one of these procedures is unable to deliver an exact +result when given exact arguments, then it may either report a +violation of an implementation restriction or it may silently coerce +its result to an inexact number. Such a coercion may cause an error +later. + +An implementation may use floating point and other approximate +representation strategies for inexact numbers. This report recommends, +but does not require, that the IEEE 32-bit and 64-bit floating point +standards be followed by implementations that use flonum +representations, and that implementations using other representations +should match or exceed the precision achievable using these floating +point standards [12]. + +In particular, implementations that use flonum representations must +follow these rules: A flonum result must be represented with at least +as much precision as is used to express any of the inexact arguments to +that operation. It is desirable (but not required) for potentially +inexact operations such as sqrt, when applied to exact arguments, to +produce exact answers whenever possible (for example the square root of +an exact 4 ought to be an exact 2). If, however, an exact number is +operated upon so as to produce an inexact result (as by sqrt), and if +the result is represented as a flonum, then the most precise flonum +format available must be used; but if the result is represented in some +other way then the representation must have at least as much precision +as the most precise flonum format available. + +Although Scheme allows a variety of written notations for numbers, any +particular implementation may support only some of them. For example, +an implementation in which all numbers are real need not support the +rectangular and polar notations for complex numbers. If an +implementation encounters an exact numerical constant that it cannot +represent as an exact number, then it may either report a violation of +an implementation restriction or it may silently represent the constant +by an inexact number. + +==== Syntax of numerical constants + +The syntax of the written representations for numbers is described +formally in section 7.1.1. Note that case is not significant in +numerical constants. + +A number may be written in binary, octal, decimal, or hexadecimal by +the use of a radix prefix. The radix prefixes are #b (binary), #o +(octal), #d (decimal), and #x (hexadecimal). With no radix prefix, a +number is assumed to be expressed in decimal. + +A numerical constant may be specified to be either exact or inexact by +a prefix. The prefixes are #e for exact, and #i for inexact. An +exactness prefix may appear before or after any radix prefix that is +used. If the written representation of a number has no exactness +prefix, the constant may be either inexact or exact. It is inexact if +it contains a decimal point, an exponent, or a "#" character in the +place of a digit, otherwise it is exact. In systems with inexact +numbers of varying precisions it may be useful to specify the precision +of a constant. For this purpose, numerical constants may be written +with an exponent marker that indicates the desired precision of the +inexact representation. The letters s, f, d, and l specify the use of +short, single, double, and long precision, respectively. (When fewer +than four internal inexact representations exist, the four size +specifications are mapped onto those available. For example, an +implementation with two internal representations may map short and +single together and long and double together.) In addition, the +exponent marker e specifies the default precision for the +implementation. The default precision has at least as much precision as +double, but implementations may wish to allow this default to be set by +the user. + + 3.14159265358979F0 + Round to single --- 3.141593 + 0.6L0 + Extend to long --- .600000000000000 + +==== Numerical operations + +The reader is referred to section 1.3.3 for a summary of the naming +conventions used to specify restrictions on the types of arguments to +numerical routines. The examples used in this section assume that any +numerical constant written using an exact notation is indeed +represented as an exact number. Some examples also assume that certain +numerical constants written using an inexact notation can be +represented without loss of accuracy; the inexact constants were chosen +so that this is likely to be true in implementations that use flonums +to represent inexact numbers. + +<procedure>(number? obj)</procedure><br> +<procedure>(complex? obj)</procedure><br> +<procedure>(real? obj)</procedure><br> +<procedure>(rational? obj)</procedure><br> +<procedure>(integer? obj)</procedure><br> + +These numerical type predicates can be applied to any kind of argument, +including non-numbers. They return #t if the object is of the named +type, and otherwise they return #f. In general, if a type predicate is +true of a number then all higher type predicates are also true of that +number. Consequently, if a type predicate is false of a number, then +all lower type predicates are also false of that number. If z is an +inexact complex number, then (real? z) is true if and only if (zero? +(imag-part z)) is true. If x is an inexact real number, then (integer? +x) is true if and only if (= x (round x)). + + (complex? 3+4i) ===> #t + (complex? 3) ===> #t + (real? 3) ===> #t + (real? -2.5+0.0i) ===> #t + (real? #e1e10) ===> #t + (rational? 6/10) ===> #t + (rational? 6/3) ===> #t + (integer? 3+0i) ===> #t + (integer? 3.0) ===> #t + (integer? 8/4) ===> #t + +Note: The behavior of these type predicates on inexact numbers is +unreliable, since any inaccuracy may affect the result. + +Note: In many implementations the rational? procedure will be the +same as real?, and the complex? procedure will be the same as +number?, but unusual implementations may be able to represent some +irrational numbers exactly or may extend the number system to +support some kind of non-complex numbers. + +<procedure>(exact? z)</procedure><br> +<procedure>(inexact? z)</procedure><br> + +These numerical predicates provide tests for the exactness of a +quantity. For any Scheme number, precisely one of these predicates is +true. + +<procedure>(= z[1] z[2] z[3] ...)</procedure><br> +<procedure>(< x[1] x[2] x[3] ...)</procedure><br> +<procedure>(> x[1] x[2] x[3] ...)</procedure><br> +<procedure>(<= x[1] x[2] x[3] ...)</procedure><br> +<procedure>(>= x[1] x[2] x[3] ...)</procedure><br> + +These procedures return #t if their arguments are (respectively): +equal, monotonically increasing, monotonically decreasing, +monotonically nondecreasing, or monotonically nonincreasing. + +These predicates are required to be transitive. + +Note: The traditional implementations of these predicates in +Lisp-like languages are not transitive. + +Note: While it is not an error to compare inexact numbers using +these predicates, the results may be unreliable because a small +inaccuracy may affect the result; this is especially true of = and +zero?. When in doubt, consult a numerical analyst. + +<procedure>(zero? z)</procedure><br> +<procedure>(positive? x)</procedure><br> +<procedure>(negative? x)</procedure><br> +<procedure>(odd? n)</procedure><br> +<procedure>(even? n)</procedure><br> + +These numerical predicates test a number for a particular property, +returning #t or #f. See note above. + +<procedure>(max x[1] x[2] ...)</procedure><br> +<procedure>(min x[1] x[2] ...)</procedure><br> + +These procedures return the maximum or minimum of their arguments. + + (max 3 4) ===> 4 ; exact + (max 3.9 4) ===> 4.0 ; inexact + +Note: If any argument is inexact, then the result will also be +inexact (unless the procedure can prove that the inaccuracy is not +large enough to affect the result, which is possible only in +unusual implementations). If min or max is used to compare numbers +of mixed exactness, and the numerical value of the result cannot be +represented as an inexact number without loss of accuracy, then the +procedure may report a violation of an implementation restriction. + +<procedure>(+ z[1] ...)</procedure><br> +<procedure>(* z[1] ...)</procedure><br> + +These procedures return the sum or product of their arguments. + + (+ 3 4) ===> 7 + (+ 3) ===> 3 + (+) ===> 0 + (* 4) ===> 4 + (*) ===> 1 + +<procedure>(- z[1] z[2])</procedure><br> +<procedure>(- z)</procedure><br> +<procedure>(- z[1] z[2] ...)</procedure><br> +<procedure>(/ z[1] z[2])</procedure><br> +<procedure>(/ z)</procedure><br> +<procedure>(/ z[1] z[2] ...)</procedure><br> + +With two or more arguments, these procedures return the difference or +quotient of their arguments, associating to the left. With one +argument, however, they return the additive or multiplicative inverse +of their argument. + + (- 3 4) ===> -1 + (- 3 4 5) ===> -6 + (- 3) ===> -3 + (/ 3 4 5) ===> 3/20 + (/ 3) ===> 1/3 + +<procedure>(abs x)</procedure><br> + +Abs returns the absolute value of its argument. + + (abs -7) ===> 7 + +<procedure>(quotient n[1] n[2])</procedure><br> +<procedure>(remainder n[1] n[2])</procedure><br> +<procedure>(modulo n[1] n[2])</procedure><br> + +These procedures implement number-theoretic (integer) division. n[2] +should be non-zero. All three procedures return integers. If n[1]/n[2] +is an integer: + + (quotient n[1] n[2]) ===> n[1]/n[2] + (remainder n[1] n[2]) ===> 0 + (modulo n[1] n[2]) ===> 0 + +If n[1]/n[2] is not an integer: + + (quotient n[1] n[2]) ===> n[q] + (remainder n[1] n[2]) ===> n[r] + (modulo n[1] n[2]) ===> n[m] + +where n[q] is n[1]/n[2] rounded towards zero, 0 < |n[r]| < |n[2]|, 0 < +|n[m]| < |n[2]|, n[r] and n[m] differ from n[1] by a multiple of n[2], +n[r] has the same sign as n[1], and n[m] has the same sign as n[2]. + +From this we can conclude that for integers n[1] and n[2] with n[2] not +equal to 0, + + (= n[1] (+ (* n[2] (quotient n[1] n[2])) + (remainder n[1] n[2]))) + ===> #t + +provided all numbers involved in that computation are exact. + + (modulo 13 4) ===> 1 + (remainder 13 4) ===> 1 + + (modulo -13 4) ===> 3 + (remainder -13 4) ===> -1 + + (modulo 13 -4) ===> -3 + (remainder 13 -4) ===> 1 + + (modulo -13 -4) ===> -1 + (remainder -13 -4) ===> -1 + + (remainder -13 -4.0) ===> -1.0 ; inexact + +<procedure>(gcd n[1] ...)</procedure><br> +<procedure>(lcm n[1] ...)</procedure><br> + +These procedures return the greatest common divisor or least common +multiple of their arguments. The result is always non-negative. + + (gcd 32 -36) ===> 4 + (gcd) ===> 0 + (lcm 32 -36) ===> 288 + (lcm 32.0 -36) ===> 288.0 ; inexact + (lcm) ===> 1 + +<procedure>(numerator q)</procedure><br> +<procedure>(denominator q)</procedure><br> + +These procedures return the numerator or denominator of their argument; +the result is computed as if the argument was represented as a fraction +in lowest terms. The denominator is always positive. The denominator of +0 is defined to be 1. + + (numerator (/ 6 4)) ===> 3 + (denominator (/ 6 4)) ===> 2 + (denominator + (exact->inexact (/ 6 4))) ===> 2.0 + +<procedure>(floor x)</procedure><br> +<procedure>(ceiling x)</procedure><br> +<procedure>(truncate x)</procedure><br> +<procedure>(round x)</procedure><br> + +These procedures return integers. Floor returns the largest integer not +larger than x. Ceiling returns the smallest integer not smaller than x. +Truncate returns the integer closest to x whose absolute value is not +larger than the absolute value of x. Round returns the closest integer +to x, rounding to even when x is halfway between two integers. + +Rationale: Round rounds to even for consistency with the default +rounding mode specified by the IEEE floating point standard. + +Note: If the argument to one of these procedures is inexact, then +the result will also be inexact. If an exact value is needed, the +result should be passed to the inexact->exact procedure. + + (floor -4.3) ===> -5.0 + (ceiling -4.3) ===> -4.0 + (truncate -4.3) ===> -4.0 + (round -4.3) ===> -4.0 + + (floor 3.5) ===> 3.0 + (ceiling 3.5) ===> 4.0 + (truncate 3.5) ===> 3.0 + (round 3.5) ===> 4.0 ; inexact + + (round 7/2) ===> 4 ; exact + (round 7) ===> 7 + +<procedure>(rationalize x y)</procedure><br> + +Rationalize returns the simplest rational number differing from x by no +more than y. A rational number r[1] is simpler than another rational +number r[2] if r[1] = p[1]/q[1] and r[2] = p[2]/q[2] (in lowest terms) +and |p[1]| < |p[2]| and |q[1]| < |q[2]|. Thus 3/5 is simpler than 4/7. +Although not all rationals are comparable in this ordering (consider 2/ +7 and 3/5) any interval contains a rational number that is simpler than +every other rational number in that interval (the simpler 2/5 lies +between 2/7 and 3/5). Note that 0 = 0/1 is the simplest rational of +all. + + (rationalize + (inexact->exact .3) 1/10) ===> 1/3 ; exact + (rationalize .3 1/10) ===> #i1/3 ; inexact + +<procedure>(exp z)</procedure><br> +<procedure>(log z)</procedure><br> +<procedure>(sin z)</procedure><br> +<procedure>(cos z)</procedure><br> +<procedure>(tan z)</procedure><br> +<procedure>(asin z)</procedure><br> +<procedure>(acos z)</procedure><br> +<procedure>(atan z)</procedure><br> +<procedure>(atan y x)</procedure><br> + +These procedures are part of every implementation that supports general +real numbers; they compute the usual transcendental functions. Log +computes the natural logarithm of z (not the base ten logarithm). Asin, +acos, and atan compute arcsine (sin^-1), arccosine (cos^-1), and +arctangent (tan^-1), respectively. The two-argument variant of atan +computes (angle (make-rectangular x y)) (see below), even in +implementations that don't support general complex numbers. + +In general, the mathematical functions log, arcsine, arccosine, and +arctangent are multiply defined. The value of log z is defined to be +the one whose imaginary part lies in the range from -pi +(exclusive) to pi (inclusive). log 0 is undefined. With log +defined this way, the values of sin^-1 z, cos^-1 z, and tan^-1 z are +according to the following formulae: + + sin^-1 z = - i log (i z + (1 - z^2)^1/2) + + cos^-1 z = pi / 2 - sin^-1 z + + tan^-1 z = (log (1 + i z) - log (1 - i z)) / (2 i) + +The above specification follows [27], which in turn cites [19]; refer +to these sources for more detailed discussion of branch cuts, boundary +conditions, and implementation of these functions. When it is possible +these procedures produce a real result from a real argument. + +<procedure>(sqrt z)</procedure><br> + +Returns the principal square root of z. The result will have either +positive real part, or zero real part and non-negative imaginary part. + +<procedure>(expt z[1] z[2])</procedure><br> + +Returns z[1] raised to the power z[2]. For z[1] != 0 + + z[1]^z[2] = e^z[2] log z[1] + +0^z is 1 if z = 0 and 0 otherwise. + +<procedure>(make-rectangular x[1] x[2])</procedure><br> +<procedure>(make-polar x[3] x[4])</procedure><br> +<procedure>(real-part z)</procedure><br> +<procedure>(imag-part z)</procedure><br> +<procedure>(magnitude z)</procedure><br> +<procedure>(angle z)</procedure><br> + +These procedures are part of every implementation that supports general +complex numbers. Suppose x[1], x[2], x[3], and x[4] are real numbers +and z is a complex number such that + + z = x[1] + x[2]i = x[3] . e^i x[4] + +Then + + (make-rectangular x[1] x[2]) ===> z + (make-polar x[3] x[4]) ===> z + (real-part z) ===> x[1] + (imag-part z) ===> x[2] + (magnitude z) ===> |x[3]| + (angle z) ===> x[angle] + +where - pi < x[angle] < pi with x[angle] = x[4] + 2 pi n +for some integer n. + +Rationale: Magnitude is the same as abs for a real argument, but +abs must be present in all implementations, whereas magnitude need +only be present in implementations that support general complex +numbers. + +<procedure>(exact->inexact z)</procedure><br> +<procedure>(inexact->exact z)</procedure><br> + +Exact->inexact returns an inexact representation of z. The value +returned is the inexact number that is numerically closest to the +argument. If an exact argument has no reasonably close inexact +equivalent, then a violation of an implementation restriction may be +reported. + +Inexact->exact returns an exact representation of z. The value returned +is the exact number that is numerically closest to the argument. If an +inexact argument has no reasonably close exact equivalent, then a +violation of an implementation restriction may be reported. + +These procedures implement the natural one-to-one correspondence +between exact and inexact integers throughout an +implementation-dependent range. See section 6.2.3. + +==== Numerical input and output + +<procedure>(number->string z)</procedure><br> +<procedure>(number->string z radix)</procedure><br> + +Radix must be an exact integer, either 2, 8, 10, or 16. If omitted, radix +defaults to 10. The procedure number->string takes a number and a +radix and returns as a string an external representation of the given +number in the given radix such that + + (let ((number number) + (radix radix)) + (eqv? number + (string->number (number->string number + radix) + radix))) + +is true. It is an error if no possible result makes this expression +true. + +If z is inexact, the radix is 10, and the above expression can be +satisfied by a result that contains a decimal point, then the result +contains a decimal point and is expressed using the minimum number of +digits (exclusive of exponent and trailing zeroes) needed to make the +above expression true [3, 5]; otherwise the format of the result is +unspecified. + +The result returned by number->string never contains an explicit radix +prefix. + +Note: The error case can occur only when z is not a complex +number or is a complex number with a non-rational real or imaginary +part. + +Rationale: If z is an inexact number represented using flonums, +and the radix is 10, then the above expression is normally +satisfied by a result containing a decimal point. The unspecified +case allows for infinities, NaNs, and non-flonum representations. + +<procedure>(string->number string)</procedure><br> +<procedure>(string->number string radix)</procedure><br> + +Returns a number of the maximally precise representation expressed by +the given string. Radix must be an exact integer, either 2, 8, 10, or +16. If supplied, radix is a default radix that may be overridden by an +explicit radix prefix in string (e.g. "#o177"). If radix is not +supplied, then the default radix is 10. If string is not a +syntactically valid notation for a number, then string->number +returns #f. + + (string->number "100") ===> 100 + (string->number "100" 16) ===> 256 + (string->number "1e2") ===> 100.0 + (string->number "15##") ===> 1500.0 + +Note: The domain of string->number may be restricted by +implementations in the following ways. String->number is permitted +to return #f whenever string contains an explicit radix prefix. If +all numbers supported by an implementation are real, then string-> +number is permitted to return #f whenever string uses the polar or +rectangular notations for complex numbers. If all numbers are +integers, then string->number may return #f whenever the fractional +notation is used. If all numbers are exact, then string->number may +return #f whenever an exponent marker or explicit exactness prefix +is used, or if a # appears in place of a digit. If all inexact +numbers are integers, then string->number may return #f whenever a +decimal point is used. + +=== Other data types + +This section describes operations on some of Scheme's non-numeric data +types: booleans, pairs, lists, symbols, characters, strings and +vectors. + +==== Booleans + +The standard boolean objects for true and false are written as #t and #f. +What really matters, though, are the objects that the Scheme +conditional expressions (if, cond, and, or, do) treat as true or false. +The phrase "a true value" (or sometimes just "true") means any +object treated as true by the conditional expressions, and the phrase +"a false value" (or "false") means any object treated as false by +the conditional expressions. + +Of all the standard Scheme values, only #f counts as false in +conditional expressions. Except for #f, all standard Scheme values, +including #t, pairs, the empty list, symbols, numbers, strings, +vectors, and procedures, count as true. + +Note: Programmers accustomed to other dialects of Lisp should be +aware that Scheme distinguishes both #f and the empty list from the +symbol nil. + +Boolean constants evaluate to themselves, so they do not need to be +quoted in programs. + + #t ===> #t + #f ===> #f + '#f ===> #f + +<procedure>(not obj)</procedure><br> + +Not returns #t if obj is false, and returns #f otherwise. + + (not #t) ===> #f + (not 3) ===> #f + (not (list 3)) ===> #f + (not #f) ===> #t + (not '()) ===> #f + (not (list)) ===> #f + (not 'nil) ===> #f + +<procedure>(boolean? obj)</procedure><br> + +Boolean? returns #t if obj is either #t or #f and returns #f otherwise. + + (boolean? #f) ===> #t + (boolean? 0) ===> #f + (boolean? '()) ===> #f + +==== Pairs and lists + +A pair (sometimes called a dotted pair) is a record structure with two +fields called the car and cdr fields (for historical reasons). Pairs +are created by the procedure cons. The car and cdr fields are accessed +by the procedures car and cdr. The car and cdr fields are assigned by +the procedures set-car! and set-cdr!. + +Pairs are used primarily to represent lists. A list can be defined +recursively as either the empty list or a pair whose cdr is a list. +More precisely, the set of lists is defined as the smallest set X such +that + +* The empty list is in X. +* If list is in X, then any pair whose cdr field contains list is + also in X. + +The objects in the car fields of successive pairs of a list are the +elements of the list. For example, a two-element list is a pair whose +car is the first element and whose cdr is a pair whose car is the +second element and whose cdr is the empty list. The length of a list is +the number of elements, which is the same as the number of pairs. + +The empty list is a special object of its own type (it is not a pair); +it has no elements and its length is zero. + +Note: The above definitions imply that all lists have finite +length and are terminated by the empty list. + +The most general notation (external representation) for Scheme pairs is +the "dotted" notation (c[1] . c[2]) where c[1] is the value of the +car field and c[2] is the value of the cdr field. For example (4 . 5) +is a pair whose car is 4 and whose cdr is 5. Note that (4 . 5) is the +external representation of a pair, not an expression that evaluates to +a pair. + +A more streamlined notation can be used for lists: the elements of the +list are simply enclosed in parentheses and separated by spaces. The +empty list is written () . For example, + + (a b c d e) + +and + + (a . (b . (c . (d . (e . ()))))) + +are equivalent notations for a list of symbols. + +A chain of pairs not ending in the empty list is called an improper +list. Note that an improper list is not a list. The list and dotted +notations can be combined to represent improper lists: + + (a b c . d) + +is equivalent to + + (a . (b . (c . d))) + +Whether a given pair is a list depends upon what is stored in the cdr +field. When the set-cdr! procedure is used, an object can be a list one +moment and not the next: + + (define x (list 'a 'b 'c)) + (define y x) + y ===> (a b c) + (list? y) ===> #t + (set-cdr! x 4) ===> unspecified + x ===> (a . 4) + (eqv? x y) ===> #t + y ===> (a . 4) + (list? y) ===> #f + (set-cdr! x x) ===> unspecified + (list? x) ===> #f + +Within literal expressions and representations of objects read by the +read procedure, the forms '<datum>, `<datum>, ,<datum>, and ,@<datum> +denote two-element lists whose first elements are the symbols quote, +quasiquote, unquote, and unquote-splicing, respectively. The second +element in each case is <datum>. This convention is supported so that +arbitrary Scheme programs may be represented as lists. That is, +according to Scheme's grammar, every <expression> is also a <datum> +(see section 7.1.2). Among other things, this permits the use of the +read procedure to parse Scheme programs. See section 3.3. + +<procedure>(pair? obj)</procedure><br> + +Pair? returns #t if obj is a pair, and otherwise returns #f. + + (pair? '(a . b)) ===> #t + (pair? '(a b c)) ===> #t + (pair? '()) ===> #f + (pair? '#(a b)) ===> #f + +<procedure>(cons obj[1] obj[2])</procedure><br> + +Returns a newly allocated pair whose car is obj[1] and whose cdr is +obj[2]. The pair is guaranteed to be different (in the sense of eqv?) +from every existing object. + + (cons 'a '()) ===> (a) + (cons '(a) '(b c d)) ===> ((a) b c d) + (cons "a" '(b c)) ===> ("a" b c) + (cons 'a 3) ===> (a . 3) + (cons '(a b) 'c) ===> ((a b) . c) + +<procedure>(car pair)</procedure><br> + +Returns the contents of the car field of pair. Note that it is an error +to take the car of the empty list. + + (car '(a b c)) ===> a + (car '((a) b c d)) ===> (a) + (car '(1 . 2)) ===> 1 + (car '()) ===> error + +<procedure>(cdr pair)</procedure><br> + +Returns the contents of the cdr field of pair. Note that it is an error +to take the cdr of the empty list. + + (cdr '((a) b c d)) ===> (b c d) + (cdr '(1 . 2)) ===> 2 + (cdr '()) ===> error + +<procedure>(set-car! pair obj)</procedure><br> + +Stores obj in the car field of pair. The value returned by set-car! is +unspecified. + + (define (f) (list 'not-a-constant-list)) + (define (g) '(constant-list)) + (set-car! (f) 3) ===> unspecified + (set-car! (g) 3) ===> error + +<procedure>(set-cdr! pair obj)</procedure><br> + +Stores obj in the cdr field of pair. The value returned by set-cdr! is +unspecified. + +<procedure>(caar pair)</procedure><br> +<procedure>(cadr pair)</procedure><br> +<procedure>(cdddar pair)</procedure><br> +<procedure>(cddddr pair)</procedure><br> + +These procedures are compositions of car and cdr, where for example +caddr could be defined by + + (define caddr (lambda (x) (car (cdr (cdr x))))). + +Arbitrary compositions, up to four deep, are provided. There are +twenty-eight of these procedures in all. + +<procedure>(null? obj)</procedure><br> + +Returns #t if obj is the empty list, otherwise returns #f. + +<procedure>(list? obj)</procedure><br> + +Returns #t if obj is a list, otherwise returns #f. By definition, all +lists have finite length and are terminated by the empty list. + + (list? '(a b c)) ===> #t + (list? '()) ===> #t + (list? '(a . b)) ===> #f + (let ((x (list 'a))) + (set-cdr! x x) + (list? x)) ===> #f + +<procedure>(list obj ...)</procedure><br> + +Returns a newly allocated list of its arguments. + + (list 'a (+ 3 4) 'c) ===> (a 7 c) + (list) ===> () + +<procedure>(length list)</procedure><br> + +Returns the length of list. + + (length '(a b c)) ===> 3 + (length '(a (b) (c d e))) ===> 3 + (length '()) ===> 0 + +<procedure>(append list ...)</procedure><br> + +Returns a list consisting of the elements of the first list followed by +the elements of the other lists. + + (append '(x) '(y)) ===> (x y) + (append '(a) '(b c d)) ===> (a b c d) + (append '(a (b)) '((c))) ===> (a (b) (c)) + +The resulting list is always newly allocated, except that it shares +structure with the last list argument. The last argument may actually +be any object; an improper list results if the last argument is not a +proper list. + + (append '(a b) '(c . d)) ===> (a b c . d) + (append '() 'a) ===> a + +<procedure>(reverse list)</procedure><br> + +Returns a newly allocated list consisting of the elements of list in +reverse order. + + (reverse '(a b c)) ===> (c b a) + (reverse '(a (b c) d (e (f)))) + ===> ((e (f)) d (b c) a) + +<procedure>(list-tail list k)</procedure><br> + +Returns the sublist of list obtained by omitting the first k elements. +It is an error if list has fewer than k elements. List-tail could be +defined by + + (define list-tail + (lambda (x k) + (if (zero? k) + x + (list-tail (cdr x) (- k 1))))) + +<procedure>(list-ref list k)</procedure><br> + +Returns the kth element of list. (This is the same as the car of +(list-tail list k).) It is an error if list has fewer than k elements. + + (list-ref '(a b c d) 2) ===> c + (list-ref '(a b c d) + (inexact->exact (round 1.8))) + ===> c + +<procedure>(memq obj list)</procedure><br> +<procedure>(memv obj list)</procedure><br> +<procedure>(member obj list)</procedure><br> + +These procedures return the first sublist of list whose car is obj, +where the sublists of list are the non-empty lists returned by +(list-tail list k) for k less than the length of list. If obj does not +occur in list, then #f (not the empty list) is returned. Memq uses eq? +to compare obj with the elements of list, while memv uses eqv? and +member uses equal?. + + (memq 'a '(a b c)) ===> (a b c) + (memq 'b '(a b c)) ===> (b c) + (memq 'a '(b c d)) ===> #f + (memq (list 'a) '(b (a) c)) ===> #f + (member (list 'a) + '(b (a) c)) ===> ((a) c) + (memq 101 '(100 101 102)) ===> unspecified + (memv 101 '(100 101 102)) ===> (101 102) + +<procedure>(assq obj alist)</procedure><br> +<procedure>(assv obj alist)</procedure><br> +<procedure>(assoc obj alist)</procedure><br> + +Alist (for "association list") must be a list of pairs. These +procedures find the first pair in alist whose car field is obj, and +returns that pair. If no pair in alist has obj as its car, then #f (not +the empty list) is returned. Assq uses eq? to compare obj with the car +fields of the pairs in alist, while assv uses eqv? and assoc uses +equal?. + + (define e '((a 1) (b 2) (c 3))) + (assq 'a e) ===> (a 1) + (assq 'b e) ===> (b 2) + (assq 'd e) ===> #f + (assq (list 'a) '(((a)) ((b)) ((c)))) + ===> #f + (assoc (list 'a) '(((a)) ((b)) ((c)))) + ===> ((a)) + (assq 5 '((2 3) (5 7) (11 13))) + ===> unspecified + (assv 5 '((2 3) (5 7) (11 13))) + ===> (5 7) + +Rationale: Although they are ordinarily used as predicates, memq, +memv, member, assq, assv, and assoc do not have question marks in +their names because they return useful values rather than just #t +or #f. + +==== Symbols + +Symbols are objects whose usefulness rests on the fact that two symbols +are identical (in the sense of eqv?) if and only if their names are +spelled the same way. This is exactly the property needed to represent +identifiers in programs, and so most implementations of Scheme use them +internally for that purpose. Symbols are useful for many other +applications; for instance, they may be used the way enumerated values +are used in Pascal. + +The rules for writing a symbol are exactly the same as the rules for +writing an identifier; see sections 2.1 and 7.1.1. + +It is guaranteed that any symbol that has been returned as part of a +literal expression, or read using the read procedure, and subsequently +written out using the write procedure, will read back in as the +identical symbol (in the sense of eqv?). The string->symbol procedure, +however, can create symbols for which this write/read invariance may +not hold because their names contain special characters or letters in +the non-standard case. + +Note: Some implementations of Scheme have a feature known as +"slashification" in order to guarantee write/read invariance for +all symbols, but historically the most important use of this +feature has been to compensate for the lack of a string data type. + +Some implementations also have "uninterned symbols", which defeat +write/read invariance even in implementations with slashification, +and also generate exceptions to the rule that two symbols are the +same if and only if their names are spelled the same. + +<procedure>(symbol? obj)</procedure><br> + +Returns #t if obj is a symbol, otherwise returns #f. + + (symbol? 'foo) ===> #t + (symbol? (car '(a b))) ===> #t + (symbol? "bar") ===> #f + (symbol? 'nil) ===> #t + (symbol? '()) ===> #f + (symbol? #f) ===> #f + +<procedure>(symbol->string symbol)</procedure><br> + +Returns the name of symbol as a string. If the symbol was part of an +object returned as the value of a literal expression (section 4.1.2) or +by a call to the read procedure, and its name contains alphabetic +characters, then the string returned will contain characters in the +implementation's preferred standard case -- some implementations will +prefer upper case, others lower case. If the symbol was returned by +string->symbol, the case of characters in the string returned will be +the same as the case in the string that was passed to string->symbol. +It is an error to apply mutation procedures like string-set! to strings +returned by this procedure. + +The following examples assume that the implementation's standard case +is lower case: + + (symbol->string 'flying-fish) + ===> "flying-fish" + (symbol->string 'Martin) ===> "martin" + (symbol->string + (string->symbol "Malvina")) + ===> "Malvina" + +<procedure>(string->symbol string)</procedure><br> + +Returns the symbol whose name is string. This procedure can create +symbols with names containing special characters or letters in the +non-standard case, but it is usually a bad idea to create such symbols +because in some implementations of Scheme they cannot be read as +themselves. See symbol->string. + +The following examples assume that the implementation's standard case +is lower case: + + (eq? 'mISSISSIppi 'mississippi) + ===> #t + (string->symbol "mISSISSIppi") + ===> the symbol with name "mISSISSIppi" + (eq? 'bitBlt (string->symbol "bitBlt")) + ===> #f + (eq? 'JollyWog + (string->symbol + (symbol->string 'JollyWog))) + ===> #t + (string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) + ===> #t + +==== Characters + +Characters are objects that represent printed characters such as +letters and digits. Characters are written using the notation #\ +<character> or #\<character name>. For example: + + #\a ; lower case letter + #\A ; upper case letter + #\( ; left parenthesis + #\ ; the space character + #\space ; the preferred way to write a space + #\newline ; the newline character + +Case is significant in #\<character>, but not in #\<character name>. If +<character> in #\<character> is alphabetic, then the character +following <character> must be a delimiter character such as a space or +parenthesis. This rule resolves the ambiguous case where, for example, +the sequence of characters "#\space" could be taken to be either a +representation of the space character or a representation of the +character "#\s" followed by a representation of the symbol "pace." + +Characters written in the #\ notation are self-evaluating. That is, +they do not have to be quoted in programs. Some of the procedures that +operate on characters ignore the difference between upper case and +lower case. The procedures that ignore case have "-ci" (for "case +insensitive") embedded in their names. + +<procedure>(char? obj)</procedure><br> + +Returns #t if obj is a character, otherwise returns #f. + +<procedure>(char=? char[1] char[2])</procedure><br> +<procedure>(char<? char[1] char[2])</procedure><br> +<procedure>(char>? char[1] char[2])</procedure><br> +<procedure>(char<=? char[1] char[2])</procedure><br> +<procedure>(char>=? char[1] char[2])</procedure><br> + +These procedures impose a total ordering on the set of characters. It +is guaranteed that under this ordering: + +* The upper case characters are in order. For example, (char<? #\A #\ + B) returns #t. +* The lower case characters are in order. For example, (char<? #\a #\ + b) returns #t. +* The digits are in order. For example, (char<? #\0 #\9) returns #t. +* Either all the digits precede all the upper case letters, or vice + versa. +* Either all the digits precede all the lower case letters, or vice + versa. + +Some implementations may generalize these procedures to take more than +two arguments, as with the corresponding numerical predicates. + +<procedure>(char-ci=? char[1] char[2])</procedure><br> +<procedure>(char-ci<? char[1] char[2])</procedure><br> +<procedure>(char-ci>? char[1] char[2])</procedure><br> +<procedure>(char-ci<=? char[1] char[2])</procedure><br> +<procedure>(char-ci>=? char[1] char[2])</procedure><br> + +These procedures are similar to char=? et cetera, but they treat upper +case and lower case letters as the same. For example, (char-ci=? #\A #\ +a) returns #t. Some implementations may generalize these procedures to +take more than two arguments, as with the corresponding numerical +predicates. + +<procedure>(char-alphabetic? char)</procedure><br> +<procedure>(char-numeric? char)</procedure><br> +<procedure>(char-whitespace? char)</procedure><br> +<procedure>(char-upper-case? letter)</procedure><br> +<procedure>(char-lower-case? letter)</procedure><br> + +These procedures return #t if their arguments are alphabetic, numeric, +whitespace, upper case, or lower case characters, respectively, +otherwise they return #f. The following remarks, which are specific to +the ASCII character set, are intended only as a guide: The alphabetic +characters are the 52 upper and lower case letters. The numeric +characters are the ten decimal digits. The whitespace characters are +space, tab, line feed, form feed, and carriage return. + +<procedure>(char->integer char)</procedure><br> +<procedure>(integer->char n)</procedure><br> + +Given a character, char->integer returns an exact integer +representation of the character. Given an exact integer that is the +image of a character under char->integer, integer->char returns that +character. These procedures implement order-preserving isomorphisms +between the set of characters under the char<=? ordering and some +subset of the integers under the <= ordering. That is, if + + (char<=? a b) ===> #t and (<= x y) ===> #t + +and x and y are in the domain of integer->char, then + + (<= (char->integer a) + (char->integer b)) ===> #t + + (char<=? (integer->char x) + (integer->char y)) ===> #t + +<procedure>(char-upcase char)</procedure><br> +<procedure>(char-downcase char)</procedure><br> + +These procedures return a character char[2] such that (char-ci=? char +char[2]). In addition, if char is alphabetic, then the result of +char-upcase is upper case and the result of char-downcase is lower +case. + +==== Strings + +Strings are sequences of characters. Strings are written as sequences +of characters enclosed within doublequotes ("). A doublequote can be +written inside a string only by escaping it with a backslash (\), as in + +"The word \"recursion\" has many meanings." + +A backslash can be written inside a string only by escaping it with +another backslash. Scheme does not specify the effect of a backslash +within a string that is not followed by a doublequote or backslash. + +A string constant may continue from one line to the next, but the exact +contents of such a string are unspecified. The length of a string is +the number of characters that it contains. This number is an exact, +non-negative integer that is fixed when the string is created. The +valid indexes of a string are the exact non-negative integers less than +the length of the string. The first character of a string has index 0, +the second has index 1, and so on. + +In phrases such as "the characters of string beginning with index +start and ending with index end," it is understood that the index +start is inclusive and the index end is exclusive. Thus if start and +end are the same index, a null substring is referred to, and if start +is zero and end is the length of string, then the entire string is +referred to. + +Some of the procedures that operate on strings ignore the difference +between upper and lower case. The versions that ignore case have +"-ci" (for "case insensitive") embedded in their names. + +<procedure>(string? obj)</procedure><br> + +Returns #t if obj is a string, otherwise returns #f. + +<procedure>(make-string k)</procedure><br> +<procedure>(make-string k char)</procedure><br> + +Make-string returns a newly allocated string of length k. If char is +given, then all elements of the string are initialized to char, +otherwise the contents of the string are unspecified. + +<procedure>(string char ...)</procedure><br> + +Returns a newly allocated string composed of the arguments. + +<procedure>(string-length string)</procedure><br> + +Returns the number of characters in the given string. + +<procedure>(string-ref string k)</procedure><br> + +k must be a valid index of string. String-ref returns character k of +string using zero-origin indexing. + +<procedure>(string-set! string k char)</procedure><br> + +k must be a valid index of string. String-set! stores char in element k +of string and returns an unspecified value. + + (define (f) (make-string 3 #\*)) + (define (g) "***") + (string-set! (f) 0 #\?) ===> unspecified + (string-set! (g) 0 #\?) ===> error + (string-set! (symbol->string 'immutable) + 0 + #\?) ===> error + +<procedure>(string=? string[1] string[2])</procedure><br> +<procedure>(string-ci=? string[1] string[2])</procedure><br> + +Returns #t if the two strings are the same length and contain the same +characters in the same positions, otherwise returns #f. String-ci=? +treats upper and lower case letters as though they were the same +character, but string=? treats upper and lower case as distinct +characters. + +<procedure>(string<? string[1] string[2])</procedure><br> +<procedure>(string>? string[1] string[2])</procedure><br> +<procedure>(string<=? string[1] string[2])</procedure><br> +<procedure>(string>=? string[1] string[2])</procedure><br> +<procedure>(string-ci<? string[1] string[2])</procedure><br> +<procedure>(string-ci>? string[1] string[2])</procedure><br> +<procedure>(string-ci<=? string[1] string[2])</procedure><br> +<procedure>(string-ci>=? string[1] string[2])</procedure><br> + +These procedures are the lexicographic extensions to strings of the +corresponding orderings on characters. For example, string<? is the +lexicographic ordering on strings induced by the ordering char<? on +characters. If two strings differ in length but are the same up to the +length of the shorter string, the shorter string is considered to be +lexicographically less than the longer string. + +Implementations may generalize these and the string=? and string-ci=? +procedures to take more than two arguments, as with the corresponding +numerical predicates. + +<procedure>(substring string start end)</procedure><br> + +String must be a string, and start and end must be exact integers +satisfying + + 0 < start < end < (string-length string) + +Substring returns a newly allocated string formed from the characters +of string beginning with index start (inclusive) and ending with index +end (exclusive). + +<procedure>(string-append string ...)</procedure><br> + +Returns a newly allocated string whose characters form the +concatenation of the given strings. + +<procedure>(string->list string)</procedure><br> +<procedure>(list->string list)</procedure><br> + +String->list returns a newly allocated list of the characters that make +up the given string. List->string returns a newly allocated string +formed from the characters in the list list, which must be a list of +characters. String->list and list->string are inverses so far as equal? +is concerned. + +<procedure>(string-copy string)</procedure><br> + +Returns a newly allocated copy of the given string. + +<procedure>(string-fill! string char)</procedure><br> + +Stores char in every element of the given string and returns an +unspecified value. + +==== Vectors + +Vectors are heterogenous structures whose elements are indexed by +integers. A vector typically occupies less space than a list of the +same length, and the average time required to access a randomly chosen +element is typically less for the vector than for the list. + +The length of a vector is the number of elements that it contains. This +number is a non-negative integer that is fixed when the vector is +created. The valid indexes of a vector are the exact non-negative +integers less than the length of the vector. The first element in a +vector is indexed by zero, and the last element is indexed by one less +than the length of the vector. + +Vectors are written using the notation #(obj ...). For example, a +vector of length 3 containing the number zero in element 0, the list (2 +2 2 2) in element 1, and the string "Anna" in element 2 can be written +as following: + + #(0 (2 2 2 2) "Anna") + +Note that this is the external representation of a vector, not an +expression evaluating to a vector. Like list constants, vector +constants must be quoted: + + '#(0 (2 2 2 2) "Anna") + ===> #(0 (2 2 2 2) "Anna") + +<procedure>(vector? obj)</procedure><br> + +Returns #t if obj is a vector, otherwise returns #f. + +<procedure>(make-vector k)</procedure><br> +<procedure>(make-vector k fill)</procedure><br> + +Returns a newly allocated vector of k elements. If a second argument is +given, then each element is initialized to fill. Otherwise the initial +contents of each element is unspecified. + +<procedure>(vector obj ...)</procedure><br> + +Returns a newly allocated vector whose elements contain the given +arguments. Analogous to list. + + (vector 'a 'b 'c) ===> #(a b c) + +<procedure>(vector-length vector)</procedure><br> + +Returns the number of elements in vector as an exact integer. + +<procedure>(vector-ref vector k)</procedure><br> + +k must be a valid index of vector. Vector-ref returns the contents of +element k of vector. + + (vector-ref '#(1 1 2 3 5 8 13 21) + 5) + ===> 8 + (vector-ref '#(1 1 2 3 5 8 13 21) + (let ((i (round (* 2 (acos -1))))) + (if (inexact? i) + (inexact->exact i) + i))) + ===> 13 + +<procedure>(vector-set! vector k obj)</procedure><br> + +k must be a valid index of vector. Vector-set! stores obj in element k +of vector. The value returned by vector-set! is unspecified. + + (let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec) + ===> #(0 ("Sue" "Sue") "Anna") + + (vector-set! '#(0 1 2) 1 "doe") + ===> error ; constant vector + +<procedure>(vector->list vector)</procedure><br> +<procedure>(list->vector list)</procedure><br> + +Vector->list returns a newly allocated list of the objects contained in +the elements of vector. List->vector returns a newly created vector +initialized to the elements of the list list. + + (vector->list '#(dah dah didah)) + ===> (dah dah didah) + (list->vector '(dididit dah)) + ===> #(dididit dah) + +<procedure>(vector-fill! vector fill)</procedure><br> + +Stores fill in every element of vector. The value returned by +vector-fill! is unspecified. + +=== Control features + +This chapter describes various primitive procedures which control the +flow of program execution in special ways. The procedure? predicate is +also described here. + +<procedure>(procedure? obj)</procedure><br> + +Returns #t if obj is a procedure, otherwise returns #f. + + (procedure? car) ===> #t + (procedure? 'car) ===> #f + (procedure? (lambda (x) (* x x))) + ===> #t + (procedure? '(lambda (x) (* x x))) + ===> #f + (call-with-current-continuation procedure?) + ===> #t + +<procedure>(apply proc arg[1] ... args)</procedure><br> + +Proc must be a procedure and args must be a list. Calls proc with the +elements of the list (append (list arg[1] ...) args) as the actual +arguments. + + (apply + (list 3 4)) ===> 7 + + (define compose + (lambda (f g) + (lambda args + (f (apply g args))))) + + ((compose sqrt *) 12 75) ===> 30 + +<procedure>(map proc list[1] list[2] ...)</procedure><br> + +The lists must be lists, and proc must be a procedure taking as many +arguments as there are lists and returning a single value. If more than +one list is given, then they must all be the same length. Map applies +proc element-wise to the elements of the lists and returns a list of +the results, in order. The dynamic order in which proc is applied to +the elements of the lists is unspecified. + + (map cadr '((a b) (d e) (g h))) + ===> (b e h) + + (map (lambda (n) (expt n n)) + '(1 2 3 4 5)) + ===> (1 4 27 256 3125) + + (map + '(1 2 3) '(4 5 6)) ===> (5 7 9) + + (let ((count 0)) + (map (lambda (ignored) + (set! count (+ count 1)) + count) + '(a b))) ===> (1 2) or (2 1) + +<procedure>(for-each proc list[1] list[2] ...)</procedure><br> + +The arguments to for-each are like the arguments to map, but for-each +calls proc for its side effects rather than for its values. Unlike map, +for-each is guaranteed to call proc on the elements of the lists in +order from the first element(s) to the last, and the value returned by +for-each is unspecified. + + (let ((v (make-vector 5))) + (for-each (lambda (i) + (vector-set! v i (* i i))) + '(0 1 2 3 4)) + v) ===> #(0 1 4 9 16) + +<procedure>(force promise)</procedure><br> + +Forces the value of promise (see delay, section 4.2.5). If no value has +been computed for the promise, then a value is computed and returned. +The value of the promise is cached (or "memoized") so that if it is +forced a second time, the previously computed value is returned. + + (force (delay (+ 1 2))) ===> 3 + (let ((p (delay (+ 1 2)))) + (list (force p) (force p))) + ===> (3 3) + + (define a-stream + (letrec ((next + (lambda (n) + (cons n (delay (next (+ n 1))))))) + (next 0))) + (define head car) + (define tail + (lambda (stream) (force (cdr stream)))) + + (head (tail (tail a-stream))) + ===> 2 + +Force and delay are mainly intended for programs written in functional +style. The following examples should not be considered to illustrate +good programming style, but they illustrate the property that only one +value is computed for a promise, no matter how many times it is forced. + + (define count 0) + (define p + (delay (begin (set! count (+ count 1)) + (if (> count x) + count + (force p))))) + (define x 5) + p ===> a promise + (force p) ===> 6 + p ===> a promise, still + (begin (set! x 10) + (force p)) ===> 6 + +Here is a possible implementation of delay and force. Promises are +implemented here as procedures of no arguments, and force simply calls +its argument: + + (define force + (lambda (object) + (object))) + +We define the expression + + (delay <expression>) + +to have the same meaning as the procedure call + + (make-promise (lambda () <expression>)) + +as follows + + (define-syntax delay + (syntax-rules () + ((delay expression) + (make-promise (lambda () expression))))), + +where make-promise is defined as follows: + + (define make-promise + (lambda (proc) + (let ((result-ready? #f) + (result #f)) + (lambda () + (if result-ready? + result + (let ((x (proc))) + (if result-ready? + result + (begin (set! result-ready? #t) + (set! result x) + result)))))))) + +Rationale: A promise may refer to its own value, as in the last +example above. Forcing such a promise may cause the promise to be +forced a second time before the value of the first force has been +computed. This complicates the definition of make-promise. + +Various extensions to this semantics of delay and force are supported +in some implementations: + +* Calling force on an object that is not a promise may simply return + the object. + +* It may be the case that there is no means by which a promise can be + operationally distinguished from its forced value. That is, + expressions like the following may evaluate to either #t or to #f, + depending on the implementation: + + (eqv? (delay 1) 1) ===> unspecified + (pair? (delay (cons 1 2))) ===> unspecified + +* Some implementations may implement "implicit forcing," where the + value of a promise is forced by primitive procedures like cdr and + +: + + (+ (delay (* 3 7)) 13) ===> 34 + +<procedure>(call-with-current-continuation proc)</procedure><br> + +Proc must be a procedure of one argument. The procedure +call-with-current-continuation packages up the current continuation +(see the rationale below) as an "escape procedure" and passes it as +an argument to proc. The escape procedure is a Scheme procedure that, +if it is later called, will abandon whatever continuation is in effect +at that later time and will instead use the continuation that was in +effect when the escape procedure was created. Calling the escape +procedure may cause the invocation of before and after thunks installed +using dynamic-wind. + +The escape procedure accepts the same number of arguments as the +continuation to the original call to call-with-current-continuation. +Except for continuations created by the call-with-values procedure, all +continuations take exactly one value. The effect of passing no value or +more than one value to continuations that were not created by +call-with-values is unspecified. + +The escape procedure that is passed to proc has unlimited extent just +like any other procedure in Scheme. It may be stored in variables or +data structures and may be called as many times as desired. + +The following examples show only the most common ways in which +call-with-current-continuation is used. If all real uses were as simple +as these examples, there would be no need for a procedure with the +power of call-with-current-continuation. + + (call-with-current-continuation + (lambda (exit) + (for-each (lambda (x) + (if (negative? x) + (exit x))) + '(54 0 37 -3 245 19)) + #t)) ===> -3 + + (define list-length + (lambda (obj) + (call-with-current-continuation + (lambda (return) + (letrec ((r + (lambda (obj) + (cond ((null? obj) 0) + ((pair? obj) + (+ (r (cdr obj)) 1)) + (else (return #f)))))) + (r obj)))))) + + (list-length '(1 2 3 4)) ===> 4 + + (list-length '(a b . c)) ===> #f + +Rationale: + +A common use of call-with-current-continuation is for structured, +non-local exits from loops or procedure bodies, but in fact +call-with-current-continuation is extremely useful for implementing +a wide variety of advanced control structures. + +Whenever a Scheme expression is evaluated there is a continuation +wanting the result of the expression. The continuation represents +an entire (default) future for the computation. If the expression +is evaluated at top level, for example, then the continuation might +take the result, print it on the screen, prompt for the next input, +evaluate it, and so on forever. Most of the time the continuation +includes actions specified by user code, as in a continuation that +will take the result, multiply it by the value stored in a local +variable, add seven, and give the answer to the top level +continuation to be printed. Normally these ubiquitous continuations +are hidden behind the scenes and programmers do not think much +about them. On rare occasions, however, a programmer may need to +deal with continuations explicitly. Call-with-current-continuation +allows Scheme programmers to do that by creating a procedure that +acts just like the current continuation. + +Most programming languages incorporate one or more special-purpose +escape constructs with names like exit, return, or even goto. In +1965, however, Peter Landin [16] invented a general purpose escape +operator called the J-operator. John Reynolds [24] described a +simpler but equally powerful construct in 1972. The catch special +form described by Sussman and Steele in the 1975 report on Scheme +is exactly the same as Reynolds's construct, though its name came +from a less general construct in MacLisp. Several Scheme +implementors noticed that the full power of the catch construct +could be provided by a procedure instead of by a special syntactic +construct, and the name call-with-current-continuation was coined +in 1982. This name is descriptive, but opinions differ on the +merits of such a long name, and some people use the name call/cc +instead. + +<procedure>(values obj ...)</procedure><br> + +Delivers all of its arguments to its continuation. Except for +continuations created by the call-with-values procedure, all +continuations take exactly one value. Values might be defined as +follows: + + (define (values . things) + (call-with-current-continuation + (lambda (cont) (apply cont things)))) + +<procedure>(call-with-values producer consumer)</procedure><br> + +Calls its producer argument with no values and a continuation that, +when passed some values, calls the consumer procedure with those values +as arguments. The continuation for the call to consumer is the +continuation of the call to call-with-values. + + (call-with-values (lambda () (values 4 5)) + (lambda (a b) b)) + ===> 5 + + (call-with-values * -) ===> -1 + +<procedure>(dynamic-wind before thunk after)</procedure><br> + +Calls thunk without arguments, returning the result(s) of this call. +Before and after are called, also without arguments, as required by the +following rules (note that in the absence of calls to continuations +captured using call-with-current-continuation the three arguments are +called once each, in order). Before is called whenever execution enters +the dynamic extent of the call to thunk and after is called whenever it +exits that dynamic extent. The dynamic extent of a procedure call is +the period between when the call is initiated and when it returns. In +Scheme, because of call-with-current-continuation, the dynamic extent +of a call may not be a single, connected time period. It is defined as +follows: + +* The dynamic extent is entered when execution of the body of the + called procedure begins. + +* The dynamic extent is also entered when execution is not within the + dynamic extent and a continuation is invoked that was captured + (using call-with-current-continuation) during the dynamic extent. + +* It is exited when the called procedure returns. + +* It is also exited when execution is within the dynamic extent and a + continuation is invoked that was captured while not within the + dynamic extent. + +If a second call to dynamic-wind occurs within the dynamic extent of +the call to thunk and then a continuation is invoked in such a way that +the afters from these two invocations of dynamic-wind are both to be +called, then the after associated with the second (inner) call to +dynamic-wind is called first. + +If a second call to dynamic-wind occurs within the dynamic extent of +the call to thunk and then a continuation is invoked in such a way that +the befores from these two invocations of dynamic-wind are both to be +called, then the before associated with the first (outer) call to +dynamic-wind is called first. + +If invoking a continuation requires calling the before from one call to +dynamic-wind and the after from another, then the after is called +first. + +The effect of using a captured continuation to enter or exit the +dynamic extent of a call to before or after is undefined. + + (let ((path '()) + (c #f)) + (let ((add (lambda (s) + (set! path (cons s path))))) + (dynamic-wind + (lambda () (add 'connect)) + (lambda () + (add (call-with-current-continuation + (lambda (c0) + (set! c c0) + 'talk1)))) + (lambda () (add 'disconnect))) + (if (< (length path) 4) + (c 'talk2) + (reverse path)))) + + ===> (connect talk1 disconnect + connect talk2 disconnect) + +=== Eval + +<procedure>(eval expression environment-specifier)</procedure><br> + +Evaluates expression in the specified environment and returns its +value. Expression must be a valid Scheme expression represented as +data, and environment-specifier must be a value returned by one of the +three procedures described below. Implementations may extend eval to +allow non-expression programs (definitions) as the first argument and +to allow other values as environments, with the restriction that eval +is not allowed to create new bindings in the environments associated +with null-environment or scheme-report-environment. + + (eval '(* 7 3) (scheme-report-environment 5)) + ===> 21 + + (let ((f (eval '(lambda (f x) (f x x)) + (null-environment 5)))) + (f + 10)) + ===> 20 + +<procedure>(scheme-report-environment version)</procedure><br> +<procedure>(null-environment version)</procedure><br> + +Version must be the exact integer 5, corresponding to this revision of +the Scheme report (the Revised^5 Report on Scheme). +Scheme-report-environment returns a specifier for an environment that +is empty except for all bindings defined in this report that are either +required or both optional and supported by the implementation. +Null-environment returns a specifier for an environment that is empty +except for the (syntactic) bindings for all syntactic keywords defined +in this report that are either required or both optional and supported +by the implementation. + +Other values of version can be used to specify environments matching +past revisions of this report, but their support is not required. An +implementation will signal an error if version is neither 5 nor another +value supported by the implementation. + +The effect of assigning (through the use of eval) a variable bound in a +scheme-report-environment (for example car) is unspecified. Thus the +environments specified by scheme-report-environment may be immutable. + +<procedure>(interaction-environment)</procedure><br> + +This procedure returns a specifier for the environment that contains +implementation-defined bindings, typically a superset of those listed +in the report. The intent is that this procedure will return the +environment in which the implementation would evaluate expressions +dynamically typed by the user. + +=== Input and output + +==== Ports + +Ports represent input and output devices. To Scheme, an input port is a +Scheme object that can deliver characters upon command, while an output +port is a Scheme object that can accept characters. + +<procedure>(call-with-input-file string proc)</procedure><br> +<procedure>(call-with-output-file string proc)</procedure><br> + +String should be a string naming a file, and proc should be a procedure +that accepts one argument. For call-with-input-file, the file should +already exist; for call-with-output-file, the effect is unspecified if +the file already exists. These procedures call proc with one argument: +the port obtained by opening the named file for input or output. If the +file cannot be opened, an error is signalled. If proc returns, then the +port is closed automatically and the value(s) yielded by the proc is +(are) returned. If proc does not return, then the port will not be +closed automatically unless it is possible to prove that the port will +never again be used for a read or write operation. + +Rationale: Because Scheme's escape procedures have unlimited +extent, it is possible to escape from the current continuation but +later to escape back in. If implementations were permitted to close +the port on any escape from the current continuation, then it would +be impossible to write portable code using both +call-with-current-continuation and call-with-input-file or +call-with-output-file. + +<procedure>(input-port? obj)</procedure><br> +<procedure>(output-port? obj)</procedure><br> + +Returns #t if obj is an input port or output port respectively, +otherwise returns #f. + +<procedure>(current-input-port)</procedure><br> +<procedure>(current-output-port)</procedure><br> + +Returns the current default input or output port. + +<procedure>(with-input-from-file string thunk)</procedure><br> +<procedure>(with-output-to-file string thunk)</procedure><br> + +String should be a string naming a file, and proc should be a procedure +of no arguments. For with-input-from-file, the file should already +exist; for with-output-to-file, the effect is unspecified if the file +already exists. The file is opened for input or output, an input or +output port connected to it is made the default value returned by +current-input-port or current-output-port (and is used by (read), +(write obj), and so forth), and the thunk is called with no arguments. +When the thunk returns, the port is closed and the previous default is +restored. With-input-from-file and with-output-to-file return(s) the +value(s) yielded by thunk. If an escape procedure is used to escape +from the continuation of these procedures, their behavior is +implementation dependent. + +<procedure>(open-input-file filename)</procedure><br> + +Takes a string naming an existing file and returns an input port +capable of delivering characters from the file. If the file cannot be +opened, an error is signalled. + +<procedure>(open-output-file filename)</procedure><br> + +Takes a string naming an output file to be created and returns an +output port capable of writing characters to a new file by that name. +If the file cannot be opened, an error is signalled. If a file with the +given name already exists, the effect is unspecified. + +<procedure>(close-input-port port)</procedure><br> +<procedure>(close-output-port port)</procedure><br> + +Closes the file associated with port, rendering the port incapable of +delivering or accepting characters. These routines have no effect if +the file has already been closed. The value returned is unspecified. + +==== Input + +<procedure>(read)</procedure><br> +<procedure>(read port)</procedure><br> + +Read converts external representations of Scheme objects into the +objects themselves. That is, it is a parser for the nonterminal <datum> +(see sections 7.1.2 and 6.3.2). Read returns the next object parsable +from the given input port, updating port to point to the first +character past the end of the external representation of the object. + +If an end of file is encountered in the input before any characters are +found that can begin an object, then an end of file object is returned. +The port remains open, and further attempts to read will also return an +end of file object. If an end of file is encountered after the +beginning of an object's external representation, but the external +representation is incomplete and therefore not parsable, an error is +signalled. + +The port argument may be omitted, in which case it defaults to the +value returned by current-input-port. It is an error to read from a +closed port. + +<procedure>(read-char)</procedure><br> +<procedure>(read-char port)</procedure><br> + +Returns the next character available from the input port, updating the +port to point to the following character. If no more characters are +available, an end of file object is returned. Port may be omitted, in +which case it defaults to the value returned by current-input-port. + +<procedure>(peek-char)</procedure><br> +<procedure>(peek-char port)</procedure><br> + +Returns the next character available from the input port, without +updating the port to point to the following character. If no more +characters are available, an end of file object is returned. Port may +be omitted, in which case it defaults to the value returned by +current-input-port. + +Note: The value returned by a call to peek-char is the same as +the value that would have been returned by a call to read-char with +the same port. The only difference is that the very next call to +read-char or peek-char on that port will return the value returned +by the preceding call to peek-char. In particular, a call to +peek-char on an interactive port will hang waiting for input +whenever a call to read-char would have hung. + +<procedure>(eof-object? obj)</procedure><br> + +Returns #t if obj is an end of file object, otherwise returns #f. The +precise set of end of file objects will vary among implementations, but +in any case no end of file object will ever be an object that can be +read in using read. + +<procedure>(char-ready?)</procedure><br> +<procedure>(char-ready? port)</procedure><br> + +Returns #t if a character is ready on the input port and returns #f +otherwise. If char-ready returns #t then the next read-char operation +on the given port is guaranteed not to hang. If the port is at end of +file then char-ready? returns #t. Port may be omitted, in which case it +defaults to the value returned by current-input-port. + +Rationale: Char-ready? exists to make it possible for a program +to accept characters from interactive ports without getting stuck +waiting for input. Any input editors associated with such ports +must ensure that characters whose existence has been asserted by +char-ready? cannot be rubbed out. If char-ready? were to return #f +at end of file, a port at end of file would be indistinguishable +from an interactive port that has no ready characters. + +==== Output + +<procedure>(write obj)</procedure><br> +<procedure>(write obj port)</procedure><br> + +Writes a written representation of obj to the given port. Strings that +appear in the written representation are enclosed in doublequotes, and +within those strings backslash and doublequote characters are escaped +by backslashes. Character objects are written using the #\ notation. +Write returns an unspecified value. The port argument may be omitted, +in which case it defaults to the value returned by current-output-port. + +<procedure>(display obj)</procedure><br> +<procedure>(display obj port)</procedure><br> + +Writes a representation of obj to the given port. Strings that appear +in the written representation are not enclosed in doublequotes, and no +characters are escaped within those strings. Character objects appear +in the representation as if written by write-char instead of by write. +Display returns an unspecified value. The port argument may be omitted, +in which case it defaults to the value returned by current-output-port. + +Rationale: Write is intended for producing machine-readable +output and display is for producing human-readable output. +Implementations that allow "slashification" within symbols will +probably want write but not display to slashify funny characters in +symbols. + +<procedure>(newline)</procedure><br> +<procedure>(newline port)</procedure><br> + +Writes an end of line to port. Exactly how this is done differs from +one operating system to another. Returns an unspecified value. The port +argument may be omitted, in which case it defaults to the value +returned by current-output-port. + +<procedure>(write-char char)</procedure><br> +<procedure>(write-char char port)</procedure><br> + +Writes the character char (not an external representation of the +character) to the given port and returns an unspecified value. The port +argument may be omitted, in which case it defaults to the value +returned by current-output-port. + +==== System interface + +Questions of system interface generally fall outside of the domain of +this report. However, the following operations are important enough to +deserve description here. + +<procedure>(load filename)</procedure><br> + +Filename should be a string naming an existing file containing Scheme +source code. The load procedure reads expressions and definitions from +the file and evaluates them sequentially. It is unspecified whether the +results of the expressions are printed. The load procedure does not +affect the values returned by current-input-port and +current-output-port. Load returns an unspecified value. + +Rationale: For portability, load must operate on source files. +Its operation on other kinds of files necessarily varies among +implementations. + +<procedure>(transcript-on filename)</procedure><br> +<procedure>(transcript-off)</procedure><br> + +(These procedures are not implemented in Chicken.) + +Filename must be a string naming an output file to be created. The +effect of transcript-on is to open the named file for output, and to +cause a transcript of subsequent interaction between the user and the +Scheme system to be written to the file. The transcript is ended by a +call to transcript-off, which closes the transcript file. Only one +transcript may be in progress at any time, though some implementations +may relax this restriction. The values returned by these procedures are +unspecified. + + +--- +Previous: [[Supported language]] + +Next: [[Deviations from the standard]] diff --git a/manual/Unit data-structures b/manual/Unit data-structures index dd50f236..34df6e4b 100644 --- a/manual/Unit data-structures +++ b/manual/Unit data-structures @@ -12,7 +12,7 @@ structures. ==== alist-ref - [procedure] (alist-ref KEY ALIST [TEST [DEFAULT]]) +<procedure>(alist-ref KEY ALIST [TEST [DEFAULT]])</procedure> Looks up {{KEY}} in {{ALIST}} using {{TEST}} as the comparison function (or {{eqv?}} if no test was given) and returns the cdr of the found pair, or {{DEFAULT}} (which defaults to {{#f}}). @@ -20,7 +20,7 @@ no test was given) and returns the cdr of the found pair, or {{DEFAULT}} (which ==== alist-update! - [procedure] (alist-update! KEY VALUE ALIST [TEST]) +<procedure>(alist-update! KEY VALUE ALIST [TEST])</procedure> If the list {{ALIST}} contains a pair of the form {{(KEY . X)}}, then this procedure replaces {{X}} with {{VALUE}} and returns {{ALIST}}. If {{ALIST}} contains no such item, then @@ -31,7 +31,7 @@ and defaults to {{eqv?}}. ==== atom? - [procedure] (atom? X) +<procedure>(atom? X)</procedure> Returns {{#t}} if {{X}} is not a pair. This is identical to {{not-pair?}} from [[Unit srfi-1]] but kept for historical reasons. @@ -39,7 +39,7 @@ kept for historical reasons. ==== rassoc - [procedure] (rassoc KEY LIST [TEST]) +<procedure>(rassoc KEY LIST [TEST])</procedure> Similar to {{assoc}}, but compares {{KEY}} with the {{cdr}} of each pair in {{LIST}} using {{TEST}} as the comparison procedures (which defaults to {{eqv?}}. @@ -47,14 +47,14 @@ Similar to {{assoc}}, but compares {{KEY}} with the {{cdr}} of each pair in {{LI ==== butlast - [procedure] (butlast LIST) +<procedure>(butlast LIST)</procedure> Returns a fresh list with all elements but the last of {{LIST}}. ==== chop - [procedure] (chop LIST N) +<procedure>(chop LIST N)</procedure> Returns a new list of sublists, where each sublist contains {{N}} elements of {{LIST}}. If {{LIST}} has a length that is not @@ -69,7 +69,7 @@ elements. ==== compress - [procedure] (compress BLIST LIST) +<procedure>(compress BLIST LIST)</procedure> Returns a new list with elements taken from {{LIST}} with corresponding true values in the list {{BLIST}}. @@ -82,7 +82,7 @@ corresponding true values in the list {{BLIST}}. ==== flatten - [procedure] (flatten LIST1 ...) +<procedure>(flatten LIST1 ...)</procedure> Returns {{LIST1 ...}} concatenated together, with nested lists removed (flattened). @@ -90,14 +90,14 @@ removed (flattened). ==== intersperse - [procedure] (intersperse LIST X) +<procedure>(intersperse LIST X)</procedure> Returns a new list with {{X}} placed between each element. ==== join - [procedure] (join LISTOFLISTS [LIST]) +<procedure>(join LISTOFLISTS [LIST])</procedure> Concatenates the lists in {{LISTOFLISTS}} with {{LIST}} placed between each sublist. {{LIST}} defaults to the empty list. @@ -117,7 +117,7 @@ between each sublist. {{LIST}} defaults to the empty list. ==== shuffle - [procedure] (shuffle LIST RANDOM) +<procedure>(shuffle LIST RANDOM)</procedure> Returns {{LIST}} with its elements sorted in a random order given by procedure {{RANDOM}}. @@ -125,7 +125,7 @@ procedure {{RANDOM}}. ==== tail? - [procedure] (tail? X LIST) +<procedure>(tail? X LIST)</procedure> Returns true if {{X}} is one of the tails (cdr's) of {{LIST}}. @@ -134,7 +134,7 @@ Returns true if {{X}} is one of the tails (cdr's) of {{LIST}}. ==== list->queue - [procedure] (list->queue LIST) +<procedure>(list->queue LIST)</procedure> Returns {{LIST}} converted into a queue, where the first element of the list is the same as the first element of the queue. The resulting @@ -144,21 +144,21 @@ after this operation. ==== make-queue - [procedure] (make-queue) +<procedure>(make-queue)</procedure> Returns a newly created queue. ==== queue? - [procedure] (queue? X) +<procedure>(queue? X)</procedure> Returns {{#t}} if {{X}} is a queue, or {{#f}} otherwise. ==== queue->list - [procedure] (queue->list QUEUE) +<procedure>(queue->list QUEUE)</procedure> Returns {{QUEUE}} converted into a list, where the first element of the list is the same as the first element of the queue. The resulting @@ -167,21 +167,21 @@ list may share memory with the queue object and should not be modified. ==== queue-add! - [procedure] (queue-add! QUEUE X) +<procedure>(queue-add! QUEUE X)</procedure> Adds {{X}} to the rear of {{QUEUE}}. ==== queue-empty? - [procedure] (queue-empty? QUEUE) +<procedure>(queue-empty? QUEUE)</procedure> Returns {{#t}} if {{QUEUE}} is empty, or {{#f}} otherwise. ==== queue-first - [procedure] (queue-first QUEUE) +<procedure>(queue-first QUEUE)</procedure> Returns the first element of {{QUEUE}}. If {{QUEUE}} is empty an error is signaled @@ -189,7 +189,7 @@ an error is signaled ==== queue-last - [procedure] (queue-last QUEUE) +<procedure>(queue-last QUEUE)</procedure> Returns the last element of {{QUEUE}}. If {{QUEUE}} is empty an error is signaled @@ -197,7 +197,7 @@ an error is signaled ==== queue-remove! - [procedure] (queue-remove! QUEUE) +<procedure>(queue-remove! QUEUE)</procedure> Removes and returns the first element of {{QUEUE}}. If {{QUEUE}} is empty an error is signaled @@ -205,7 +205,7 @@ is empty an error is signaled ==== queue-push-back! - [procedure] (queue-push-back! QUEUE ITEM) +<procedure>(queue-push-back! QUEUE ITEM)</procedure> Pushes an item into the first position of a queue, i.e. the next {{queue-remove!}} will return {{ITEM}}. @@ -213,7 +213,7 @@ Pushes an item into the first position of a queue, i.e. the next ==== queue-push-back-list! - [procedure] (queue-push-back-list! QUEUE LIST) +<procedure>(queue-push-back-list! QUEUE LIST)</procedure> Pushes the items in item-list back onto the queue, so that {{(car LIST)}} becomes the next removable item. @@ -225,8 +225,8 @@ so that {{(car LIST)}} becomes the next removable item. ==== merge - [procedure] (merge LIST1 LIST2 LESS?) - [procedure] (merge! LIST1 LIST2 LESS?) +<procedure>(merge LIST1 LIST2 LESS?)</procedure><br> +<procedure>(merge! LIST1 LIST2 LESS?)</procedure> Joins two lists in sorted order. {{merge!}} is the destructive version of merge. {{LESS? }} should be a procedure of two arguments, @@ -236,8 +236,8 @@ second argument. ==== sort - [procedure] (sort SEQUENCE LESS?) - [procedure] (sort! SEQUENCE LESS?) +<procedure>(sort SEQUENCE LESS?)</procedure><br> +<procedure>(sort! SEQUENCE LESS?)</procedure> Sort {{SEQUENCE}}, which should be a list or a vector. {{sort!}} is the destructive version of sort. @@ -249,7 +249,6 @@ is the destructive version of sort. Returns true if the list or vector {{SEQUENCE}} is already sorted. - ==== topological-sort [procedure] (topological-sort DAG PRED) @@ -288,7 +287,7 @@ Time complexity: O (|V| + |E|) ==== conc - [procedure] (conc X ...) +<procedure>(conc X ...)</procedure> Returns a string with the string-represenation of all arguments concatenated together. {{conc}} could be implemented as @@ -302,14 +301,14 @@ together. {{conc}} could be implemented as ==== ->string - [procedure] (->string X) +<procedure>(->string X)</procedure> Returns a string-representation of {{X}}. ==== string-chop - [procedure] (string-chop STRING LENGTH) +<procedure>(string-chop STRING LENGTH)</procedure> Returns a list of substrings taken by ''chopping'' {{STRING}} every {{LENGTH}} characters: @@ -322,7 +321,7 @@ characters: ==== string-chomp - [procedure] (string-chomp STRING [SUFFIX]) +<procedure>(string-chomp STRING [SUFFIX])</procedure> If {{STRING}} ends with {{SUFFIX}}, then this procedure returns a copy of its first argument with the suffix removed, otherwise returns {{STRING}} unchanged. {{SUFFIX}} defaults to {{"\n"}}. @@ -330,8 +329,8 @@ removed, otherwise returns {{STRING}} unchanged. {{SUFFIX}} defaults to {{"\n"}} ==== string-compare3 - [procedure] (string-compare3 STRING1 STRING2) - [procedure] (string-compare3-ci STRING1 STRING2) +<procedure>(string-compare3 STRING1 STRING2)</procedure><br> +<procedure>(string-compare3-ci STRING1 STRING2)</procedure> Perform a three-way comparison between the {{STRING1}} and {{STRING2}}, returning either {{-1}} if {{STRING1}} is lexicographically less @@ -341,7 +340,7 @@ than {{STRING2}}, {{0}} if it is equal, or {{1}} if it s greater. ==== string-intersperse - [procedure] (string-intersperse LIST [STRING]) +<procedure>(string-intersperse LIST [STRING])</procedure> Returns a string that contains all strings in {{LIST}} concatenated together. {{STRING}} is placed between each concatenated string and @@ -360,7 +359,7 @@ is equivalent to ==== string-split - [procedure] (string-split STRING [DELIMITER-STRING [KEEPEMPTY]]) +<procedure>(string-split STRING [DELIMITER-STRING [KEEPEMPTY]])</procedure> Split string into substrings separated by the given delimiters. If no delimiters are specified, a string comprising the tab, newline and space characters @@ -376,7 +375,7 @@ substrings are retained: ==== string-translate - [procedure] (string-translate STRING FROM [TO]) +<procedure>(string-translate STRING FROM [TO])</procedure> Returns a fresh copy of {{STRING}} with characters matching {{FROM}} translated to {{TO}}. If {{TO}} is omitted, then @@ -388,7 +387,7 @@ as the matching character in {{FROM}} is substituted. ==== string-translate* - [procedure] (string-translate* STRING SMAP) +<procedure>(string-translate* STRING SMAP)</procedure> Substitutes elements of {{STRING}} according to {{SMAP}}. {{SMAP}} should be an association-list where each element of the list @@ -406,8 +405,8 @@ the string {{MATCH}} in {{STRING}} will be replaced by the string ==== substring=? - [procedure] (substring=? STRING1 STRING2 [START1 [START2 [LENGTH]]]) - [procedure] (substring-ci=? STRING1 STRING2 [START1 [START2 [LENGTH]]]) +<procedure>(substring=? STRING1 STRING2 [START1 [START2 [LENGTH]]])</procedure><br> +<procedure>(substring-ci=? STRING1 STRING2 [START1 [START2 [LENGTH]]])</procedure> Returns {{#t}} if the strings {{STRING1}} and {{STRING2}} are equal, or {{#f}} otherwise. @@ -418,8 +417,8 @@ length of both strings). ==== substring-index - [procedure] (substring-index WHICH WHERE [START]) - [procedure] (substring-index-ci WHICH WHERE [START]) +<procedure>(substring-index WHICH WHERE [START])</procedure><br> +<procedure>(substring-index-ci WHICH WHERE [START])</procedure> Searches for first index in string {{WHERE}} where string {{WHICH}} occurs. If the optional argument {{START}} is given, @@ -429,7 +428,7 @@ is a case-insensitive version of {{substring-index}}. ==== reverse-string-append - [procedure] (reverse-string-append LIST) +<procedure>(reverse-string-append LIST)</procedure> {{(apply string-append (reverse LIST))}} @@ -439,35 +438,35 @@ is a case-insensitive version of {{substring-index}}. ==== any? - [procedure] (any? X) +<procedure>(any? X)</procedure> Ignores its argument and always returns {{#t}}. This is actually useful sometimes. ==== none? - [procedure] (none? X) +<procedure>(none? X)</procedure> Ignores its argument and always returns {{#f}}. This is actually useful sometimes. ==== always? - [procedure] (always? X) +<procedure>(always? X)</procedure> Ignores its arguments and always returns {{#t}}. This is actually useful sometimes. ==== never? - [procedure] (never? X) +<procedure>(never? X)</procedure> Ignores its arguments and always returns {{#f}}. This is actually useful sometimes. ==== constantly - [procedure] (constantly X ...) +<procedure>(constantly X ...)</procedure> Returns a procedure that always returns the values {{X ...}} regardless of the number and value of its arguments. @@ -478,7 +477,7 @@ Returns a procedure that always returns the values {{X ...}} regardless of the n ==== complement - [procedure] (complement PROC) +<procedure>(complement PROC)</procedure> Returns a procedure that returns the boolean inverse of {{PROC}}. @@ -489,7 +488,7 @@ Returns a procedure that returns the boolean inverse of {{PROC}}. ==== compose - [procedure] (compose PROC1 PROC2 ...) +<procedure>(compose PROC1 PROC2 ...)</procedure> Returns a procedure that represents the composition of the argument-procedures {{PROC1 PROC2 ...}}. @@ -506,7 +505,7 @@ argument-procedures {{PROC1 PROC2 ...}}. ==== conjoin - [procedure] (conjoin PRED ...) +<procedure>(conjoin PRED ...)</procedure> Returns a procedure that returns {{#t}} if its argument satisfies the predicates {{PRED ...}}. @@ -518,7 +517,7 @@ predicates {{PRED ...}}. ==== disjoin - [procedure] (disjoin PRED ...) +<procedure>(disjoin PRED ...)</procedure> Returns a procedure that returns {{#t}} if its argument satisfies any predicate {{PRED ...}}. @@ -530,7 +529,7 @@ predicate {{PRED ...}}. ==== each - [procedure] (each PROC ...) +<procedure>(each PROC ...)</procedure> Returns a procedure that applies {{PROC ...}} to its arguments, and returns the result(s) of the last procedure application. For example @@ -553,7 +552,7 @@ is equivalent to ==== flip - [procedure] (flip PROC) +<procedure>(flip PROC)</procedure> Returns a two-argument procedure that calls {{PROC}} with its arguments swapped: @@ -564,21 +563,21 @@ arguments swapped: ==== identity - [procedure] (identity X) +<procedure>(identity X)</procedure> Returns its sole argument {{X}}. ==== project - [procedure] (project N) +<procedure>(project N)</procedure> Returns a procedure that returns its {{N}}th argument (starting from 0). ==== list-of? - [procedure] (list-of? PRED) +<procedure>(list-of? PRED)</procedure> Returns a procedure of one argument that returns {{#t}} when applied to a list of elements that all satisfy the predicate procedure @@ -592,14 +591,14 @@ applied to a list of elements that all satisfy the predicate procedure ==== noop - [procedure] (noop X ...) +<procedure>(noop X ...)</procedure> Ignores its arguments, does nothing and returns an unspecified value. ==== o - [procedure] (o PROC ...) +<procedure>(o PROC ...)</procedure> A single value version of {{compose}} (slightly faster). {{(o)}} is equivalent to {{identity}}. @@ -607,7 +606,7 @@ to {{identity}}. ==== left-section - [procedure] (left-section PROC ARG0 ...) +<procedure>(left-section PROC ARG0 ...)</procedure> Returns a procedure that partially applies some of its arguments starting from the left. @@ -618,7 +617,7 @@ Returns a procedure that partially applies some of its arguments starting from t ==== right-section - [procedure] (right-section PROC ARG0 ...) +<procedure>(right-section PROC ARG0 ...)</procedure> Returns a procedure that partially applies some of its arguments starting from the right. @@ -633,7 +632,7 @@ Returns a procedure that partially applies some of its arguments starting from t ==== binary-search - [procedure] (binary-search SEQUENCE PROC) +<procedure>(binary-search SEQUENCE PROC)</procedure> Performs a binary search in {{SEQUENCE}}, which should be a sorted list or vector. {{PROC}} is called to compare items in the sequence, diff --git a/manual/Unit eval b/manual/Unit eval index aa109554..f92997ca 100644 --- a/manual/Unit eval +++ b/manual/Unit eval @@ -11,7 +11,7 @@ option. ==== load - [procedure] (load FILE [EVALPROC]) +<procedure>(load FILE [EVALPROC])</procedure> Loads and evaluates expressions from the given source file, which may be either a string or an input port. Each expression read is passed to @@ -42,14 +42,14 @@ Support for reloading compiled code dynamically is still experimental. ==== load-relative - [procedure] (load-relative FILE [EVALPROC]) +<procedure>(load-relative FILE [EVALPROC])</procedure> Similar to {{load}}, but loads {{FILE}} relative to the path of the currently loaded file. ==== load-noisily - [procedure] (load-noisily FILE #!key EVALUATOR TIME PRINTER) +<procedure>(load-noisily FILE #!key EVALUATOR TIME PRINTER)</procedure> As {{load}} but the result(s) of each evaluated toplevel-expression is written to standard output. If {{EVALUATOR}} is given and not {{#f}}, @@ -63,7 +63,7 @@ argument, which should be a one-argument procedure. See also the [[http://chicken.wiki.br/Parameters#load-verbose|load-verbose]] parameter. ==== load-library - [procedure] (load-library UNIT [LIBRARYFILE]) +<procedure>(load-library UNIT [LIBRARYFILE])</procedure> On platforms that support dynamic loading, {{load-library}} loads the compiled library unit {{UNIT}} (which should be a symbol). If the @@ -82,7 +82,7 @@ the {{load-library}} does nothing. ==== set-dynamic-load-mode! - [procedure] (set-dynamic-load-mode! MODELIST) +<procedure>(set-dynamic-load-mode! MODELIST)</procedure> On systems that support dynamic loading of compiled code via the {{dlopen(3)}} interface (for example Linux and Solaris), some options can be specified to @@ -102,7 +102,7 @@ this facility is mainly of interest when accessing foreign code. ==== repl - [procedure] (repl) +<procedure>(repl)</procedure> Start a new read-eval-print loop. Sets the {{reset-handler}} so that any invocation of {{reset}} restarts the read-eval-print loop. Also @@ -125,7 +125,7 @@ or the default library path ==== extension-information - [procedure] (extension-information ID) +<procedure>(extension-information ID)</procedure> If an extension with the name {{ID}} is installed and if it has a setup-information list registered in the extension repository, then the info-list is returned. Otherwise @@ -133,21 +133,21 @@ list registered in the extension repository, then the info-list is returned. Oth ==== provide - [procedure] (provide ID ...) +<procedure>(provide ID ...)</procedure> Registers the extension IDs {{ID ...}} as loaded. This is mainly intended to provide aliases for certain extension identifiers. ==== provided? - [procedure] (provided? ID ...) +<procedure>(provided? ID ...)</procedure> Returns {{#t}} if the extension with the IDs {{ID ...}} are currently loaded, or {{#f}} otherwise. ==== require - [procedure] (require ID ...) +<procedure>(require ID ...)</procedure> If the extension library {{ID}} is not already loaded into the system, then {{require}} will lookup the location of the shared @@ -164,7 +164,7 @@ from one of the following locations: ==== set-extension-specifier! - [procedure] (set-extension-specifier! SYMBOL PROC) +<procedure>(set-extension-specifier! SYMBOL PROC)</procedure> Registers the handler-procedure {{PROC}} as a extension-specifier with the name {{SYMBOL}}. This facility allows extending the set of valid extension @@ -195,7 +195,7 @@ visible in compiled code. ==== chicken-home - [procedure] (chicken-home) +<procedure>(chicken-home)</procedure> Returns a string given the installation directory (usually {{/usr/local/share/chicken}} on UNIX-like systems). As a last option, @@ -207,7 +207,7 @@ if the environment variable {{CHICKEN_PREFIX}} is set, then {{chicken-home}} wil ==== eval - [procedure] (eval EXP [ENVIRONMENT]) +<procedure>(eval EXP [ENVIRONMENT])</procedure> Evaluates {{EXP}} and returns the result of the evaluation. The second argument is optional and defaults to the value of {{(interaction-environment)}}. diff --git a/manual/Unit expand b/manual/Unit expand index 47f0ad82..f024fc9a 100644 --- a/manual/Unit expand +++ b/manual/Unit expand @@ -11,7 +11,7 @@ option. ==== get-line-number - [procedure] (get-line-number EXPR) +<procedure>(get-line-number EXPR)</procedure> If {{EXPR}} is a pair with the car being a symbol, and line-number information is available for this expression, then this procedure returns @@ -21,14 +21,14 @@ expressions is only available in the compiler. ==== expand - [procedure] (expand X) +<procedure>(expand X)</procedure> If {{X}} is a macro-form, expand the macro (and repeat expansion until expression is a non-macro form). Returns the resulting expression. ==== syntax-error - [procedure] (syntax-error [LOCATION] MESSAGE ARGUMENT ...) +<procedure>(syntax-error [LOCATION] MESSAGE ARGUMENT ...)</procedure> Signals an exception of the kind {{(exn syntax)}}. Otherwise identical to {{error}}. diff --git a/manual/Unit extras b/manual/Unit extras index 7ca63497..4eb46d4b 100644 --- a/manual/Unit extras +++ b/manual/Unit extras @@ -14,7 +14,7 @@ option. ==== random-seed - [procedure] (random-seed [SEED]) +<procedure>(random-seed [SEED])</procedure> Seeds the random number generator with {{SEED}} (an {{integer}}) or {{(current-seconds)}} if {{SEED}} is not given. @@ -22,7 +22,7 @@ Seeds the random number generator with {{SEED}} (an {{integer}}) or ==== randomize - [procedure] (randomize [SEED]) +<procedure>(randomize [SEED])</procedure> Set random-number seed. If {{SEED}} (an {{exact integer}}) is not supplied, the current time is used. On startup (when Unit {{extras}} is initialized), the @@ -31,7 +31,7 @@ random number generator is initialized with the current time. ==== random - [procedure] (random N) +<procedure>(random N)</procedure> Returns a random {{integer}} in {{[0 N-1]}}. {{N}} is an {{integer}}. @@ -46,9 +46,9 @@ On '''Windows''' {{N}} and the random value are {{exact integer}}. ==== fprintf ==== sprintf - [procedure] (fprintf PORT FORMATSTRING [ARG...]) - [procedure] (printf FORMATSTRING [ARG...]) - [procedure] (sprintf FORMATSTRING [ARG...]) +<procedure>(fprintf PORT FORMATSTRING [ARG...])</procedure><br> +<procedure>(printf FORMATSTRING [ARG...])</procedure><br> +<procedure>(sprintf FORMATSTRING [ARG...])</procedure> Simple formatted output to a given port ({{fprintf}}), the value of {{(current-output-port)}} ({{printf}}), or a string @@ -85,7 +85,7 @@ invoke formatted output routine recursively with the next two arguments as forma ==== format - [procedure] (format [DESTINATION] FORMATSTRING [ARG...]) +<procedure>(format [DESTINATION] FORMATSTRING [ARG...])</procedure> The parameters {{FORMATSTRING}} and {{ARG...}} are as for {{printf}}. @@ -102,8 +102,8 @@ The optional {{DESTINATION}}, when supplied, performs: ==== pretty-print - [procedure] (pretty-print EXP [PORT]) - [procedure] (pp EXP [PORT]) +<procedure>(pretty-print EXP [PORT])</procedure><br> +<procedure>(pp EXP [PORT])</procedure> Print expression nicely formatted. {{PORT}} defaults to the value of {{(current-output-port)}}. @@ -119,15 +119,15 @@ wrap will occur. ==== read-byte ==== write-byte - [procedure] (read-byte [PORT]) - [procedure] (write-byte BYTE [PORT]) +<procedure>(read-byte [PORT])</procedure><br> +<procedure>(write-byte BYTE [PORT])</procedure> Read/write a byte to the port given in {{PORT}}, which default to the values of {{(current-input-port)}} and {{(current-output-port)}}, respectively. ==== read-file - [procedure] (read-file [FILE-OR-PORT [READER [MAXCOUNT]]]) +<procedure>(read-file [FILE-OR-PORT [READER [MAXCOUNT]]])</procedure> Returns a list containing all toplevel expressions read from the file or port {{FILE-OR-PORT}}. If no argument is given, @@ -142,8 +142,8 @@ If {{MAXCOUNT}} is given then only up to {{MAXCOUNT}} expressions will be read i ==== read-line ==== write-line - [procedure] (read-line [PORT [LIMIT]]) - [procedure] (write-line STRING [PORT]) +<procedure>(read-line [PORT [LIMIT]])</procedure><br> +<procedure>(write-line STRING [PORT])</procedure> Line-input and -output. {{PORT}} defaults to the value of {{(current-input-port)}} and {{(current-output-port)}}, @@ -154,7 +154,7 @@ characters per line. {{read-line}} returns a string without the terminating newl ==== read-lines - [procedure] (read-lines [PORT [MAX]]) +<procedure>(read-lines [PORT [MAX]])</procedure> Read {{MAX}} or fewer lines from {{PORT}}. {{PORT}} defaults to the value of {{(current-input-port)}}. {{PORT}} may optionally be @@ -165,9 +165,9 @@ a string naming a file. Returns a list of strings, each string representing a li ==== read-string! ==== write-string - [procedure] (read-string [NUM [PORT]]) - [procedure] (read-string! NUM STRING [PORT [START]]) - [procedure] (write-string STRING [NUM [PORT]] +<procedure>(read-string [NUM [PORT]])</procedure><br> +<procedure>(read-string! NUM STRING [PORT [START]])</procedure><br> +<procedure>(write-string STRING [NUM [PORT]])</procedure> Read or write {{NUM}} characters from/to {{PORT}}, which defaults to the value of {{(current-input-port)}} or {{(current-output-port)}}, respectively. @@ -182,7 +182,7 @@ the read characters are stored starting at that position. ==== read-token - [procedure] (read-token PREDICATE [PORT]) +<procedure>(read-token PREDICATE [PORT])</procedure> Reads characters from {{PORT}} (which defaults to the value of {{(current-input-port)}}) and calls the procedure {{PREDICATE}} with each character until {{PREDICATE}} returns diff --git a/manual/Unit files b/manual/Unit files index 8657159a..fdf399ae 100644 --- a/manual/Unit files +++ b/manual/Unit files @@ -27,7 +27,7 @@ For any component that is not contained in {{PATHNAME}}, {{#f}} is returned. ==== make-pathname ==== make-absolute-pathname -<procedure>(make-pathname DIRECTORY FILENAME [EXTENSION])</procedure> +<procedure>(make-pathname DIRECTORY FILENAME [EXTENSION])</procedure><br> <procedure>(make-absolute-pathname DIRECTORY FILENAME [EXTENSION])</procedure> Returns a string that names the file with the @@ -43,41 +43,31 @@ and {{EXTENSION}} should be strings or {{#f}}. The {{[SEPARATOR]}} argument is deprecated. ==== pathname-directory - -<procedure>(pathname-directory PATHNAME)</procedure> - ==== pathname-file - -<procedure>(pathname-file PATHNAME)</procedure> - ==== pathname-extension +<procedure>(pathname-directory PATHNAME)</procedure><br> +<procedure>(pathname-file PATHNAME)</procedure><br> <procedure>(pathname-extension PATHNAME)</procedure> Accessors for the components of {{PATHNAME}}. If the pathname does not contain the accessed component, then {{#f}} is returned. ==== pathname-replace-directory - -<procedure>(pathname-replace-directory PATHNAME DIRECTORY)</procedure> - ==== pathname-replace-file - -<procedure>(pathname-replace-file PATHNAME FILENAME)</procedure> - ==== pathname-replace-extension +<procedure>(pathname-replace-directory PATHNAME DIRECTORY)</procedure><br> +<procedure>(pathname-replace-file PATHNAME FILENAME)</procedure><br> <procedure>(pathname-replace-extension PATHNAME EXTENSION)</procedure> Return a new pathname with the specified component of {{PATHNAME}} replaced by a new value. ==== pathname-strip-directory - -<procedure>(pathname-strip-directory PATHNAME)</procedure> - ==== pathname-strip-extension +<procedure>(pathname-strip-directory PATHNAME)</procedure><br> <procedure>(pathname-strip-extension PATHNAME)</procedure> Return a new pathname with the specified component of {{PATHNAME}} diff --git a/manual/Unit library b/manual/Unit library index d652b406..27ca46de 100644 --- a/manual/Unit library +++ b/manual/Unit library @@ -19,18 +19,18 @@ Adds/subtracts 1 from {{N}}. ==== Binary integer operations -Binary integer operations. {{arithmetic-shift}} shifts the argument {{N1}} by -{{N2}} bits to the left. If {{N2}} is negative, than {{N1}} is shifted to the -right. These operations only accept exact integers or inexact integers in word -range (32 bit signed on 32-bit platforms, or 64 bit signed on 64-bit -platforms). - <procedure>(bitwise-and N1 ...)</procedure> <procedure>(bitwise-ior N1 ...)</procedure> <procedure>(bitwise-xor N1 ...)</procedure> <procedure>(bitwise-not N)</procedure> <procedure>(arithmetic-shift N1 N2)</procedure> +Binary integer operations. {{arithmetic-shift}} shifts the argument {{N1}} by +{{N2}} bits to the left. If {{N2}} is negative, then {{N1}} is shifted to the +right. These operations only accept exact integers or inexact integers in word +range (32 bit signed on 32-bit platforms, or 64 bit signed on 64-bit +platforms). + ==== bit-set? <procedure>(bit-set? N INDEX)</procedure> @@ -38,18 +38,8 @@ platforms). Returns {{#t}} if the bit at the position {{INDEX}} in the integer {{N}} is set, or {{#f}} otherwise. The rightmost/least-significant bit is bit 0. - ==== Arithmetic fixnum operations -These procedures do not check their arguments, so non-fixnum parameters will -result in incorrect results. {{fxneg}} negates its argument. - -On division by zero, {{fx/}} and {{fxmod}} signal a condition of kind -{{(exn arithmetic)}}. - -{{fxshl}} and {{fxshr}} perform arithmetic shift left and right, -respectively. - <procedure>(fx+ N1 N2)</procedure> <procedure>(fx- N1 N2)</procedure> <procedure>(fx* N1 N2)</procedure> @@ -70,9 +60,19 @@ respectively. <procedure>(fxshl N1 N2)</procedure> <procedure>(fxshr N1 N2)</procedure> +{{fx+}} and friends are arithmetic fixnum operations. These procedures do not +check their arguments, so non-fixnum parameters will result in incorrect +results. {{fxneg}} negates its argument. + +On division by zero, {{fx/}} and {{fxmod}} signal a condition of kind +{{(exn arithmetic)}}. + +{{fxshl}} and {{fxshr}} perform arithmetic shift left and right, +respectively. + ==== fixnum? - [procedure] (fixnum? X) +<procedure>(fixnum? X)</procedure> Returns {{#t}} if {{X}} is a fixnum, or {{#f}} otherwise. @@ -126,7 +126,7 @@ Note: {{fpround}} implements POSIX, which is different from R5RS. ==== flonum? - [procedure] (flonum? X) +<procedure>(flonum? X)</procedure> Returns {{#t}} if {{X}} is a flonum, or {{#f}} otherwise. @@ -160,7 +160,7 @@ Returns {{#f}} if {{N}} is negative or positive infinity, and {{#t}} otherwise. ==== signum - [procedure] (signum N) +<procedure>(signum N)</procedure> Returns {{1}} if {{N}} is positive, {{-1}} if {{N}} is negative or {{0}} if {{N}} is zero. {{signum}} is exactness preserving. @@ -405,7 +405,7 @@ more information, see the ==== condition-case - [syntax] (condition-case EXPRESSION CLAUSE ...) +<macro>(condition-case EXPRESSION CLAUSE ...)</macro> Evaluates {{EXPRESSION}} and handles any exceptions that are covered by {{CLAUSE ...}}, where {{CLAUSE}} should be of the following form: @@ -519,10 +519,6 @@ argument. If the condition does not have a value for the desired property and if the optional argument is given, no error is signaled and the accessor returns the third argument. -* In composite conditions all properties are currently collected in a single -property-list, so in the case that to conditions have the same named property, -only one will be visible. - === Environment information and system interface @@ -581,8 +577,8 @@ Returns the error code of the last system call. ==== get-environment-variable - [procedure] (get-environment-variable STRING) - [procedure] (getenv STRING) +<procedure>(get-environment-variable STRING)</procedure><br> +<procedure>(getenv STRING)</procedure> Returns the value of the environment variable {{STRING}} or {{#f}} if that variable is not defined. See also [[http://srfi.schemers.org/srfi-98/|SRFI-98]]. diff --git a/manual/Unit lolevel b/manual/Unit lolevel index d145c033..324e832f 100644 --- a/manual/Unit lolevel +++ b/manual/Unit lolevel @@ -29,7 +29,7 @@ object'', but a ''pointer-like object''. The distinction is artificial. ==== address->pointer - [procedure] (address->pointer ADDRESS) +<procedure>(address->pointer ADDRESS)</procedure> Creates a new foreign pointer object initialized to point to the address given in the integer {{ADDRESS}}. @@ -37,7 +37,7 @@ given in the integer {{ADDRESS}}. ==== allocate - [procedure] (allocate BYTES) +<procedure>(allocate BYTES)</procedure> Returns a foreign pointer object to a freshly allocated region of static memory. @@ -51,7 +51,7 @@ This procedure could be defined as follows: ==== free - [procedure] (free POINTER) +<procedure>(free POINTER)</procedure> Frees the memory pointed to by {{POINTER}}. @@ -64,14 +64,14 @@ This procedure could be defined as follows: ==== null-pointer - [procedure] (null-pointer) +<procedure>(null-pointer)</procedure> Another way to say {{(address->pointer 0)}}. ==== null-pointer? - [procedure] (null-pointer? POINTER*) +<procedure>(null-pointer? POINTER*)</procedure> Returns {{#t}} if the pointer-like object {{POINTER*}} contains a {{NULL}} pointer, or {{#f}} otherwise. @@ -79,7 +79,7 @@ or {{#f}} otherwise. ==== object->pointer - [procedure] (object->pointer X) +<procedure>(object->pointer X)</procedure> Returns a foreign pointer object pointing to the Scheme object X, which should be a non-immediate object. ("foreign" here is a bit of a misnomer.) @@ -89,7 +89,7 @@ Note that data in the garbage collected heap moves during garbage collection. ==== pointer->object - [procedure] (pointer->object POINTER) +<procedure>(pointer->object POINTER)</procedure> Returns the Scheme object pointed to by the pointer object {{POINTER}}. @@ -98,21 +98,21 @@ at your own risk. ==== pointer? - [procedure] (pointer? X) +<procedure>(pointer? X)</procedure> Returns {{#t}} if {{X}} is a pointer object, or {{#f}} otherwise. ==== pointer-like? - [procedure] (pointer-like? X) +<procedure>(pointer-like? X)</procedure> Returns {{#t}} if {{X}} is a pointer-like object, or {{#f}} otherwise. ==== pointer=? - [procedure] (pointer=? POINTER*1 POINTER*2) +<procedure>(pointer=? POINTER*1 POINTER*2)</procedure> Returns {{#t}} if the pointer-like objects {{POINTER*1}} and {{POINTER*2}} point to the same address, or {{#f}} otherwise. @@ -120,14 +120,14 @@ to the same address, or {{#f}} otherwise. ==== pointer->address - [procedure] (pointer->address POINTER*) +<procedure>(pointer->address POINTER*)</procedure> Returns the address, to which the pointer-like object {{POINTER*}} points. ==== pointer-offset - [procedure] (pointer-offset POINTER* N) +<procedure>(pointer-offset POINTER* N)</procedure> Returns a new foreign pointer object representing the pointer-like object {{POINTER*}} address value increased by the byte-offset {{N}}. @@ -137,7 +137,7 @@ Use of anything other than a pointer object as an argument is questionable. ==== align-to-word - [procedure] (align-to-word POINTER*-OR-INT) +<procedure>(align-to-word POINTER*-OR-INT)</procedure> Accepts either a pointer-like object or an integer as the argument and returns a new foreign pointer or integer aligned to the native word size of the host @@ -155,120 +155,120 @@ However, as usual, use of anything other than a pointer object is questionable. ==== pointer-u8-ref - [procedure] (pointer-u8-ref POINTER) +<procedure>(pointer-u8-ref POINTER)</procedure> Returns the unsigned byte at the address designated by {{POINTER}}. ==== pointer-s8-ref - [procedure] (pointer-s8-ref POINTER) +<procedure>(pointer-s8-ref POINTER)</procedure> Returns the signed byte at the address designated by {{POINTER}}. ==== pointer-u16-ref - [procedure] (pointer-u16-ref POINTER) +<procedure>(pointer-u16-ref POINTER)</procedure> Returns the unsigned 16-bit integer at the address designated by {{POINTER}}. ==== pointer-s16-ref - [procedure] (pointer-s16-ref POINTER) +<procedure>(pointer-s16-ref POINTER)</procedure> Returns the signed 16-bit integer at the address designated by {{POINTER}}. ==== pointer-u32-ref - [procedure] (pointer-u32-ref POINTER) +<procedure>(pointer-u32-ref POINTER)</procedure> Returns the unsigned 32-bit integer at the address designated by {{POINTER}}. ==== pointer-s32-ref - [procedure] (pointer-s32-ref POINTER) +<procedure>(pointer-s32-ref POINTER)</procedure> Returns the signed 32-bit integer at the address designated by {{POINTER}}. ==== pointer-f32-ref - [procedure] (pointer-f32-ref POINTER) +<procedure>(pointer-f32-ref POINTER)</procedure> Returns the 32-bit float at the address designated by {{POINTER}}. ==== pointer-f64-ref - [procedure] (pointer-f64-ref POINTER) +<procedure>(pointer-f64-ref POINTER)</procedure> Returns the 64-bit double at the address designated by {{POINTER}}. ==== pointer-u8-set! - [procedure] (pointer-u8-set! POINTER N) - [procedure] (set! (pointer-u8-ref POINTER) N) +<procedure>(pointer-u8-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-u8-ref POINTER) N)</procedure> Stores the unsigned byte {{N}} at the address designated by {{POINTER}}. ==== pointer-s8-set! - [procedure] (pointer-s8-set! POINTER N) - [procedure] (set! (pointer-s8-ref POINTER) N) +<procedure>(pointer-s8-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-s8-ref POINTER) N)</procedure> Stores the signed byte {{N}} at the address designated by {{POINTER}}. ==== pointer-u16-set! - [procedure] (pointer-u16-set! POINTER N) - [procedure] (set! (pointer-u16-ref POINTER) N) +<procedure>(pointer-u16-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-u16-ref POINTER) N)</procedure> Stores the unsigned 16-bit integer {{N}} at the address designated by {{POINTER}}. ==== pointer-s16-set! - [procedure] (pointer-s16-set! POINTER N) - [procedure] (set! (pointer-s16-ref POINTER) N) +<procedure>(pointer-s16-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-s16-ref POINTER) N)</procedure> Stores the signed 16-bit integer {{N}} at the address designated by {{POINTER}}. ==== pointer-u32-set! - [procedure] (pointer-u32-set! POINTER N) - [procedure] (set! (pointer-u32-ref POINTER) N) +<procedure>(pointer-u32-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-u32-ref POINTER) N)</procedure> Stores the unsigned 32-bit integer {{N}} at the address designated by {{POINTER}}. ==== pointer-s32-set! - [procedure] (pointer-s32-set! POINTER N) - [procedure] (set! (pointer-s32-ref POINTER) N) +<procedure>(pointer-s32-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-s32-ref POINTER) N)</procedure> Stores the 32-bit integer {{N}} at the address designated by {{POINTER}}. ==== pointer-f32-set! - [procedure] (pointer-f32-set! POINTER N) - [procedure] (set! (pointer-f32-ref POINTER) N) +<procedure>(pointer-f32-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-f32-ref POINTER) N)</procedure> Stores the 32-bit floating-point number {{N}} at the address designated by {{POINTER}}. ==== pointer-f64-set! - [procedure] (pointer-f64-set! POINTER N) - [procedure] (set! (pointer-f64-ref POINTER) N) +<procedure>(pointer-f64-set! POINTER N)</procedure><br> +<procedure>(set! (pointer-f64-ref POINTER) N)</procedure> Stores the 64-bit floating-point number {{N}} at the address designated by {{POINTER}}. @@ -281,7 +281,7 @@ Stores the 64-bit floating-point number {{N}} at the address designated by {{POI ==== tag-pointer - [procedure] (tag-pointer POINTER* TAG) +<procedure>(tag-pointer POINTER* TAG)</procedure> Creates a new tagged foreign pointer object from the pointer-like object {{POINTER*}} with the tag {{TAG}}, which may an arbitrary Scheme object. @@ -290,7 +290,7 @@ Use of anything other than a pointer object is questionable. ==== tagged-pointer? - [procedure] (tagged-pointer? X [TAG]) +<procedure>(tagged-pointer? X [TAG])</procedure> Returns {{#t}} if {{X}} is a tagged foreign pointer object, or {{#f}} otherwise. @@ -300,7 +300,7 @@ Further, returns {{#t}} when {{X}} has the optional tag {{TAG}} (using an ==== pointer-tag - [procedure] (pointer-tag POINTER*) +<procedure>(pointer-tag POINTER*)</procedure> If {{POINTER}} is a tagged foreign pointer object, its tag is returned. If {{POINTER*}} is any other kind of pointer-like object {{#f}} is returned. Otherwise an @@ -323,7 +323,7 @@ The effect of creating locatives for evicted data (see {{object-evict}}) is unde ==== make-locative - [procedure] (make-locative OBJ [INDEX]) +<procedure>(make-locative OBJ [INDEX])</procedure> Creates a locative that refers to the element of the non-immediate object {{OBJ}} at position {{INDEX}}. {{OBJ}} may be a vector, pair, string, blob, @@ -333,7 +333,7 @@ SRFI-4 number-vector, or record structure. {{INDEX}} should be a fixnum. ==== make-weak-locative - [procedure] (make-weak-locative OBJ [INDEX]) +<procedure>(make-weak-locative OBJ [INDEX])</procedure> Creates a ''weak'' locative. Even though the locative refers to an element of a container object, the container object will still be reclaimed by garbage collection if no other references @@ -342,14 +342,14 @@ to it exist. ==== locative? - [procedure] (locative? X) +<procedure>(locative? X)</procedure> Returns {{#t}} if {{X}} is a locative, or {{#f}} otherwise. ==== locative-ref - [procedure] (locative-ref LOC) +<procedure>(locative-ref LOC)</procedure> Returns the element to which the locative {{LOC}} refers. If the containing object has been reclaimed by garbage collection, an error is signalled. @@ -358,8 +358,8 @@ object has been reclaimed by garbage collection, an error is signalled. ==== locative-set! - [procedure] (locative-set! LOC X) - [procedure] (set! (locative-ref LOC) X) +<procedure>(locative-set! LOC X)</procedure><br> +<procedure>(set! (locative-ref LOC) X)</procedure> Changes the element to which the locative {{LOC}} refers to {{X}}. If the containing @@ -368,7 +368,7 @@ object has been reclaimed by garbage collection, an error is signalled. ==== locative->object - [procedure] (locative->object LOC) +<procedure>(locative->object LOC)</procedure> Returns the object that contains the element referred to by {{LOC}} or {{#f}} if the container has been reclaimed by garbage collection. @@ -382,7 +382,7 @@ Returns the object that contains the element referred to by {{LOC}} or ==== extend-procedure - [procedure] (extend-procedure PROCEDURE X) +<procedure>(extend-procedure PROCEDURE X)</procedure> Returns a copy of the procedure {{PROCEDURE}} which contains an additional data slot initialized to {{X}}. If {{PROCEDURE}} is already an extended procedure, @@ -392,7 +392,7 @@ returned. Signals an error when {{PROCEDURE}} is not a procedure. ==== extended-procedure? - [procedure] (extended-procedure? PROCEDURE) +<procedure>(extended-procedure? PROCEDURE)</procedure> Returns {{#t}} if {{PROCEDURE}} is an extended procedure, or {{#f}} otherwise. @@ -400,7 +400,7 @@ or {{#f}} otherwise. ==== procedure-data - [procedure] (procedure-data PROCEDURE) +<procedure>(procedure-data PROCEDURE)</procedure> Returns the data object contained in the extended procedure {{PROCEDURE}}, or {{#f}} if it is not an extended procedure. @@ -408,7 +408,7 @@ Returns the data object contained in the extended procedure {{PROCEDURE}}, or ==== set-procedure-data! - [procedure] (set-procedure-data! PROCEDURE X) +<procedure>(set-procedure-data! PROCEDURE X)</procedure> Changes the data object contained in the extended procedure {{PROCEDURE}} to {{X}}. Signals an error when {{PROCEDURE}} is not an extended procedure. @@ -436,7 +436,7 @@ Note that strings and blobs are not considered vector-like. ==== block-ref - [procedure] (block-ref VECTOR* INDEX) +<procedure>(block-ref VECTOR* INDEX)</procedure> Returns the contents of the {{INDEX}}th slot of the vector-like object {{VECTOR*}}. @@ -444,22 +444,22 @@ Returns the contents of the {{INDEX}}th slot of the vector-like object ==== block-set! - [procedure] (block-set! VECTOR* INDEX X) - [procedure] (set! (block-ref VECTOR* INDEX) X) +<procedure>(block-set! VECTOR* INDEX X)</procedure><br> +<procedure>(set! (block-ref VECTOR* INDEX) X)</procedure> Sets the contents of the {{INDEX}}th slot of the vector-like object {{VECTOR*}} to the value of {{X}}. ==== number-of-slots - [procedure] (number-of-slots VECTOR*) +<procedure>(number-of-slots VECTOR*)</procedure> Returns the number of slots that the vector-like object {{VECTOR*}} contains. ==== number-of-bytes - [procedure] (number-of-bytes BLOCK) +<procedure>(number-of-bytes BLOCK)</procedure> Returns the number of bytes that the object {{BLOCK}} contains. {{BLOCK}} may be any non-immediate value. @@ -467,7 +467,7 @@ be any non-immediate value. ==== object-copy - [procedure] (object-copy X) +<procedure>(object-copy X)</procedure> Copies {{X}} recursively and returns the fresh copy. Objects allocated in static memory are copied back into garbage collected storage. @@ -475,7 +475,7 @@ static memory are copied back into garbage collected storage. ==== move-memory! - [procedure] (move-memory! FROM TO [BYTES [FROM-OFFSET [TO-OFFSET]]) +<procedure>(move-memory! FROM TO [BYTES [FROM-OFFSET [TO-OFFSET]]])</procedure> Copies {{BYTES}} bytes of memory from {{FROM}} to {{TO}}. {{FROM}} and {{TO}} may be strings, blobs, SRFI-4 number-vectors (see: @ref{Unit srfi-4}), memory @@ -498,7 +498,7 @@ Signals an error if any of the above constraints is violated. ==== object-evict - [procedure] (object-evict X [ALLOCATOR]) +<procedure>(object-evict X [ALLOCATOR])</procedure> Copies the object {{X}} recursively into the memory pointed to by the foreign pointer object returned by {{ALLOCATOR}}, which should be a procedure of a @@ -528,7 +528,7 @@ The {{ALLOCATOR}} defaults to {{allocate}}. ==== object-evict-to-location - [procedure] (object-evict-to-location X POINTER* [LIMIT]) +<procedure>(object-evict-to-location X POINTER* [LIMIT])</procedure> As {{object-evict}} but moves the object at the address pointed to by the pointer-like object {{POINTER*}}. If the number of copied bytes exceeds @@ -543,7 +543,7 @@ questionable. ==== object-evicted? - [procedure] (object-evicted? X) +<procedure>(object-evicted? X)</procedure> Returns {{#t}} if {{X}} is a non-immediate evicted data object, or {{#f}} otherwise. @@ -551,7 +551,7 @@ otherwise. ==== object-release - [procedure] (object-release X [RELEASER]) +<procedure>(object-release X [RELEASER])</procedure> Frees memory occupied by the evicted object {{X}} recursively. {{RELEASER}} should be a procedure of a single argument (a foreign @@ -561,7 +561,7 @@ pointer object to the static memory to be freed) and defaults to ==== object-unevict - [procedure] (object-unevict X [FULL]) +<procedure>(object-unevict X [FULL])</procedure> Copies the object {{X}} and nested objects back into the normal Scheme heap. Symbols are re-interned into the symbol table. Strings and byte-vectors are @@ -570,7 +570,7 @@ Symbols are re-interned into the symbol table. Strings and byte-vectors are ==== object-size - [procedure] (object-size X) +<procedure>(object-size X)</procedure> Returns the number of bytes that would be needed to evict the data object {{X}}. @@ -582,7 +582,7 @@ Returns the number of bytes that would be needed to evict the data object ==== global-bound? - [procedure] (global-bound? SYMBOL) +<procedure>(global-bound? SYMBOL)</procedure> Returns {{#t}}, if the global (''toplevel'') variable with the name {{SYMBOL}} is bound to a value, or {{#f}} otherwise. @@ -590,7 +590,7 @@ is bound to a value, or {{#f}} otherwise. ==== global-ref - [procedure] (global-ref SYMBOL) +<procedure>(global-ref SYMBOL)</procedure> Returns the value of the global variable {{SYMBOL}}. If no variable under that name is bound, an error is signalled. @@ -602,8 +602,8 @@ or if the code has been compiled in {{block}} mode. ==== global-set! - [procedure] (global-set! SYMBOL X) - [procedure] (set! (global-ref SYMBOL) X) +<procedure>(global-set! SYMBOL X)</procedure><br> +<procedure>(set! (global-ref SYMBOL) X)</procedure> Sets the global variable named {{SYMBOL}} to the value {{X}}. @@ -614,7 +614,7 @@ Sets the global variable named {{SYMBOL}} to the value {{X}}. ==== make-record-instance - [procedure] (make-record-instance SYMBOL ARG1 ...) +<procedure>(make-record-instance SYMBOL ARG1 ...)</procedure> Returns a new instance of the record type {{SYMBOL}}, with its slots initialized to {{ARG1 ...}}. To illustrate: @@ -643,7 +643,7 @@ expands into something quite similar to: ==== record-instance? - [procedure] (record-instance? X [SYMBOL]) +<procedure>(record-instance? X [SYMBOL])</procedure> Returns {{#t}} if {{X}} is a record structure, or {{#f}} otherwise. @@ -652,7 +652,7 @@ Further, returns {{#t}} if {{X}} is of type {{SYMBOL}}, or {{#f}} otherwise. ==== record-instance-type - [procedure] (record-instance-type RECORD) +<procedure>(record-instance-type RECORD)</procedure> Returns type symbol of the record structure {{RECORD}}. Signals an error if {{RECORD}} is not a record structure. @@ -660,7 +660,7 @@ Returns type symbol of the record structure {{RECORD}}. Signals an error if ==== record-instance-length - [procedure] (record-instance-length RECORD) +<procedure>(record-instance-length RECORD)</procedure> Returns number of slots for the record structure {{RECORD}}. The record-instance type is not counted. Signals an error if @@ -669,7 +669,7 @@ record-instance type is not counted. Signals an error if ==== record-instance-slot - [procedure] (record-instance-slot RECORD INDEX) +<procedure>(record-instance-slot RECORD INDEX)</procedure> Returns the contents of the {{INDEX}}th slot of the record structure {{RECORD}}. The slot index range is the open interval (([0 @@ -679,8 +679,8 @@ structure. ==== record-instance-slot-set! - [procedure] (record-instance-slot-set! RECORD INDEX X) - [procedure] (set! (record-instance-slot RECORD INDEX) X) +<procedure>(record-instance-slot-set! RECORD INDEX X)</procedure><br> +<procedure>(set! (record-instance-slot RECORD INDEX) X)</procedure> Sets the {{INDEX}}th slot of the record structure {{RECORD}} to {{X}}. The slot index range is the open interval (([0 record-instance-length)}}. Signals an @@ -689,7 +689,7 @@ error if {{RECORD}} is not a record structure. ==== record->vector - [procedure] (record->vector RECORD) +<procedure>(record->vector RECORD)</procedure> Returns a new vector with the type and the elements of the record structure {{RECORD}}. Signals an error if {{RECORD}} is not a record structure. @@ -700,7 +700,7 @@ Returns a new vector with the type and the elements of the record structure ==== object-become! - [procedure] (object-become! ALIST) +<procedure>(object-become! ALIST)</procedure> Changes the identity of the value of the car of each pair in {{ALIST}} to the value of the cdr. Both values may not be immediate (i.e. exact integers, @@ -723,7 +723,7 @@ is undefined. ==== mutate-procedure - [procedure] (mutate-procedure OLD PROC) +<procedure>(mutate-procedure OLD PROC)</procedure> Replaces the procedure {{OLD}} with the result of calling the one-argument procedure {{PROC}}. {{PROC}} will receive a copy of {{OLD}} that will be diff --git a/manual/Unit posix b/manual/Unit posix index 74f61649..55993bbb 100644 --- a/manual/Unit posix +++ b/manual/Unit posix @@ -17,58 +17,64 @@ of kind {{(exn i/o file)}}. ==== File-control Commands -===== fcntl/dupfd -===== fcntl/getfd -===== fcntl/setfd -===== fcntl/getfl -===== fcntl/setfl +<constant>fcntl/dupfd</constant><br> +<constant>fcntl/getfd</constant><br> +<constant>fcntl/setfd</constant><br> +<constant>fcntl/getfl</constant><br> +<constant>fcntl/setfl</constant> + +Operations used with {{file-control}}. ==== Standard I/O file-descriptors -===== fileno/stdin -===== fileno/stdout -===== fileno/stderr +<constant>fileno/stdin</constant><br> +<constant>fileno/stdout</constant><br> +<constant>fileno/stderr</constant> + +Standard I/O file descriptor numbers, used with procedures +such as {{open-input-file*}} which take file descriptors. ==== Open flags -===== open/rdonly -===== open/wronly -===== open/rdwr -===== open/read -Synonym for {{open/rdonly}}. - -===== open/write -Synonym for {{open/wronly}}. - -===== open/creat -===== open/append -===== open/excl -===== open/noctty -===== open/nonblock -===== open/trunc -===== open/sync -===== open/fsync -===== open/binary -===== open/text +<constant>open/rdonly</constant><br> +<constant>open/wronly</constant><br> +<constant>open/rdwr</constant><br> +<constant>open/read</constant><br> +<constant>open/write</constant><br> +<constant>open/creat</constant><br> +<constant>open/append</constant><br> +<constant>open/excl</constant><br> +<constant>open/noctty</constant><br> +<constant>open/nonblock</constant><br> +<constant>open/trunc</constant><br> +<constant>open/sync</constant><br> +<constant>open/fsync</constant><br> +<constant>open/binary</constant><br> +<constant>open/text</constant> + +Open flags used with the {{file-open}} procedure. {{open/read}} is a +convenience synonym for {{open/rdonly}}, as is {{open/write}} +for {{open/wronly}}. ==== Permission bits -===== perm/irusr -===== perm/iwusr -===== perm/ixusr -===== perm/irgrp -===== perm/iwgrp -===== perm/ixgrp -===== perm/iroth -===== perm/iwoth -===== perm/ixoth -===== perm/irwxu -===== perm/irwxg -===== perm/irwxo -===== perm/isvtx -===== perm/isuid -===== perm/isgid - +<constant>perm/irusr</constant><br> +<constant>perm/iwusr</constant><br> +<constant>perm/ixusr</constant><br> +<constant>perm/irgrp</constant><br> +<constant>perm/iwgrp</constant><br> +<constant>perm/ixgrp</constant><br> +<constant>perm/iroth</constant><br> +<constant>perm/iwoth</constant><br> +<constant>perm/ixoth</constant><br> +<constant>perm/irwxu</constant><br> +<constant>perm/irwxg</constant><br> +<constant>perm/irwxo</constant><br> +<constant>perm/isvtx</constant><br> +<constant>perm/isuid</constant><br> +<constant>perm/isgid</constant> + +Permission bits used with, for example, {{file-open}}. === Directories @@ -112,7 +118,8 @@ Files beginning with {{.}} are included only if {{SHOW-DOTFILES?}} is given and <procedure>(directory? NAME)</procedure> Returns {{#t}} if there exists a file with the name {{NAME}} -and if that file is a directory, or {{#f}} otherwise. +and if that file is a directory or a symbolic link pointing +to a directory. Otherwise, it returns {{#f}}. ==== glob @@ -137,7 +144,7 @@ If the current process has no root permissions, the operation will fail. ==== call-with-input-pipe ==== call-with-output-pipe -<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure> +<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure><br> <procedure>(call-with-output-pipe CMDLINE PROC [MODE])</procedure> Call {{PROC}} with a single argument: a input- or output port @@ -148,7 +155,7 @@ are returned. ==== close-input-pipe ==== close-output-pipe -<procedure>(close-input-pipe PORT)</procedure> +<procedure>(close-input-pipe PORT)</procedure><br> <procedure>(close-output-pipe PORT)</procedure> Closes the pipe given in {{PORT}} and waits until the connected @@ -188,7 +195,7 @@ atomically into a pipe or FIFO. ==== with-input-from-pipe ==== with-output-to-pipe -<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure> +<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br> <procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure> Temporarily set the value of @@ -340,7 +347,7 @@ meaningful depending on the {{COMMAND}}. ==== open-input-file* ==== open-output-file* -<procedure>(open-input-file* FILENO [OPENMODE])</procedure> +<procedure>(open-input-file* FILENO [OPENMODE])</procedure><br> <procedure>(open-output-file* FILENO [OPENMODE])</procedure> Opens file for the file-descriptor {{FILENO}} for input or output @@ -363,8 +370,8 @@ this port. Otherwise an error is signaled. ==== file-change-time ==== file-modification-time -<procedure>(file-access-time FILE)</procedure> -<procedure>(file-change-time FILE)</procedure> +<procedure>(file-access-time FILE)</procedure><br> +<procedure>(file-change-time FILE)</procedure><br> <procedure>(file-modification-time FILE)</procedure> Returns time (in seconds) of the last access, modification or change of {{FILE}}. {{FILE}} @@ -433,8 +440,8 @@ values. {{FILE}} may be a filename or a file-descriptor. ==== file-write-access? ==== file-execute-access? -<procedure>(file-read-access? FILENAME)</procedure> -<procedure>(file-write-access? FILENAME)</procedure> +<procedure>(file-read-access? FILENAME)</procedure><br> +<procedure>(file-write-access? FILENAME)</procedure><br> <procedure>(file-execute-access? FILENAME)</procedure> These procedures return {{#t}} if the current user has read, @@ -446,9 +453,9 @@ write or execute permissions on the file named {{FILENAME}}. ==== fifo? ==== socket? -<procedure>(character-device? FILENAME)</procedure> -<procedure>(block-device? FILENAME)</procedure> -<procedure>(fifo? FILENAME)</procedure> +<procedure>(character-device? FILENAME)</procedure><br> +<procedure>(block-device? FILENAME)</procedure><br> +<procedure>(fifo? FILENAME)</procedure><br> <procedure>(socket? FILENAME)</procedure> These procedures return {{#t}} if the {{FILENAME}} given is of the @@ -468,7 +475,7 @@ or a file-descriptor. ==== set-file-position! -<procedure>(set-file-position! FILE POSITION [WHENCE])</procedure> +<procedure>(set-file-position! FILE POSITION [WHENCE])</procedure><br> <procedure>(set! (file-position FILE) POSITION)</procedure> Sets the current read/write position of {{FILE}} to @@ -543,7 +550,7 @@ with no arguments and terminates. ==== process-run -<procedure>(process-run COMMANDLINE)</procedure> +<procedure>(process-run COMMANDLINE)</procedure><br> <procedure>(process-run COMMAND ARGUMENT-LIST)</procedure> Creates a new child process. The PID of the new process is returned. @@ -577,7 +584,7 @@ returns three values: ==== process -<procedure>(process COMMANDLINE)</procedure> +<procedure>(process COMMANDLINE)</procedure><br> <procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST])</procedure> Creates a subprocess and returns three values: an input port from @@ -596,7 +603,7 @@ Not using the shell may be preferrable for security reasons. ==== process* -<procedure>(process* COMMANDLINE)</procedure> +<procedure>(process* COMMANDLINE)</procedure><br> <procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST])</procedure> Like {{process}} but returns 4 values: an input port from @@ -830,31 +837,33 @@ Masks (blocks) the signal for the code {{SIGNUM}}. Unmasks (unblocks) the signal for the code {{SIGNUM}}. -==== signal/term -==== signal/kill -==== signal/int -==== signal/hup -==== signal/fpe -==== signal/ill -==== signal/segv -==== signal/abrt -==== signal/trap -==== signal/quit -==== signal/alrm -==== signal/vtalrm -==== signal/prof -==== signal/io -==== signal/urg -==== signal/chld -==== signal/cont -==== signal/stop -==== signal/tstp -==== signal/pipe -==== signal/xcpu -==== signal/xfsz -==== signal/usr1 -==== signal/usr2 -==== signal/winch +==== Signal codes + +<constant>signal/term</constant><br> +<constant>signal/kill</constant><br> +<constant>signal/int</constant><br> +<constant>signal/hup</constant><br> +<constant>signal/fpe</constant><br> +<constant>signal/ill</constant><br> +<constant>signal/segv</constant><br> +<constant>signal/abrt</constant><br> +<constant>signal/trap</constant><br> +<constant>signal/quit</constant><br> +<constant>signal/alrm</constant><br> +<constant>signal/vtalrm</constant><br> +<constant>signal/prof</constant><br> +<constant>signal/io</constant><br> +<constant>signal/urg</constant><br> +<constant>signal/chld</constant><br> +<constant>signal/cont</constant><br> +<constant>signal/stop</constant><br> +<constant>signal/tstp</constant><br> +<constant>signal/pipe</constant><br> +<constant>signal/xcpu</constant><br> +<constant>signal/xfsz</constant><br> +<constant>signal/usr1</constant><br> +<constant>signal/usr2</constant><br> +<constant>signal/winch</constant> These variables contain signal codes for use with {{process-signal}}, {{set-signal-handler!}}, {{signal-handler}}, {{signal-masked?}}, {{signal-mask!}}, or {{signal-unmask!}}. @@ -863,7 +872,7 @@ These variables contain signal codes for use with {{process-signal}}, {{set-sig ==== current-environment - [procedure] (get-environment-variables) +<procedure>(get-environment-variables)</procedure> Returns a association list of the environment variables and their current values (see also [[http://srfi.schemers.org/srfi-98/|SRFI-98]]). @@ -889,7 +898,7 @@ nothing happens. ==== memory-mapped-file? - [pocedure] (memory-mapped-file? X) +<procedure>(memory-mapped-file? X)</procedure> Returns {{#t}}, if {{X}} is an object representing a memory mapped file, or {{#f}} otherwise. @@ -1002,7 +1011,7 @@ The {{FORMAT}} string follows the rules for the C library procedure {{strftime}} ==== string->time - [procedure] (string->time TIME [FORMAT]) +<procedure>(string->time TIME [FORMAT])</procedure> Converts a string of the form represented by the {{FORMAT}} string into the broken down time represented in a 10 element vector. The @@ -1025,29 +1034,30 @@ is not called when this procedure is invoked. The optional return-code === ERRNO values -==== errno/perm -==== errno/noent -==== errno/srch -==== errno/intr -==== errno/io -==== errno/noexec -==== errno/badf -==== errno/child -==== errno/nomem -==== errno/acces -==== errno/fault -==== errno/busy -==== errno/notdir -==== errno/isdir -==== errno/inval -==== errno/mfile -==== errno/nospc -==== errno/spipe -==== errno/pipe -==== errno/again -==== errno/rofs -==== errno/exist -==== errno/wouldblock +<constant>errno/perm</constant><br> +<constant>errno/noent</constant><br> +<constant>errno/srch</constant><br> +<constant>errno/intr</constant><br> +<constant>errno/io</constant><br> +<constant>errno/noexec</constant><br> +<constant>errno/badf</constant><br> +<constant>errno/child</constant><br> +<constant>errno/nomem</constant><br> +<constant>errno/acces</constant><br> +<constant>errno/fault</constant><br> +<constant>errno/busy</constant><br> +<constant>errno/notdir</constant><br> +<constant>errno/isdir</constant><br> +<constant>errno/inval</constant><br> +<constant>errno/mfile</constant><br> +<constant>errno/nospc</constant><br> +<constant>errno/spipe</constant><br> +<constant>errno/pipe</constant><br> +<constant>errno/again</constant><br> +<constant>errno/rofs</constant><br> +<constant>errno/exist</constant><br> +<constant>errno/wouldblock</constant> + These variables contain error codes as returned by {{errno}}. @@ -1057,24 +1067,31 @@ These variables contain error codes as returned by {{errno}}. <procedure>(find-files DIRECTORY PREDICATE [ACTION [IDENTITY [LIMIT]]])</procedure> -Recursively traverses the contents of {{DIRECTORY}} (which should -be a string) and invokes the procedure {{ACTION}} for all files -in which the procedure {{PREDICATE}} is true. {{PREDICATE}} -may me a procedure of one argument or a regular-expression string. -{{ACTION}} should be a procedure of two arguments: the currently -encountered file and the result of the previous invocation of -{{ACTION}}, or, if this is the first invocation, the value -of {{IDENTITY}}. {{ACTION}} defaults to {{cons}}, -{{IDENTITY}} defaults to {{()}}. {{LIMIT}} should be a -procedure of one argument that is called for each nested directory -and which should return true, if that directory is to be traversed -recursively. {{LIMIT}} may also be an exact integer that -gives the maximum recursion depth. For example, a depth of {{0}} means that only files in the top-level, specified directory are to be traversed. In this case, all nested directories are ignored. {{LIMIT}} may also be {{#f}} (the default), -which is equivalent to {{(constantly #t)}}. +Recursively traverses the contents of {{DIRECTORY}} (which should be a +string) and invokes the procedure {{ACTION}} for all files in which +the procedure {{PREDICATE}} is true. {{PREDICATE}} may be a procedure +of one argument or a regular-expression string. {{ACTION}} should be +a procedure of two arguments: the currently encountered file and the +result of the previous invocation of {{ACTION}}, or, if this is the +first invocation, the value of {{IDENTITY}}. {{ACTION}} defaults to +{{cons}}, {{IDENTITY}} defaults to {{()}}. {{LIMIT}} should be a +procedure of one argument that is called for each nested directory and +which should return true, if that directory is to be traversed +recursively. {{LIMIT}} may also be an exact integer that gives the +maximum recursion depth. For example, a depth of {{0}} means that only +files in the top-level, specified directory are to be traversed. In +this case, all nested directories are ignored. {{LIMIT}} may also be +{{#f}} (the default), which is equivalent to {{(constantly #t)}}. Note that {{ACTION}} is called with the full pathname of each file, including the directory prefix. +Also note that {{find-files}} will traverse symbolic links pointing to +directories, which may lead to symlink loops or duplication of files. +To avoid traversing symlinks, you can pass something like this as the +{{LIMIT}} procedure: + + (lambda (x) (not (symbolic-link? x))) === Getting the hostname and system information @@ -1121,7 +1138,7 @@ Returns {{#t}} if {{PORT}} is connected to a terminal and ==== terminal-size - [procedure] (terminal-size) +<procedure>(terminal-size)</procedure> Returns two values, the number of columns and rows of the current terminal window or {{0}}, {{0}} if the terminal @@ -1231,9 +1248,9 @@ The optional parameter {{MODE}}, default {{open/binary | open/noinherit}}. This status is available. (Windows does not provide signals as an interprocess communication method.) -<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure> -<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]])</procedure> -<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]])</procedure> +<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure><br> +<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]])</procedure><br> +<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]])</procedure><br> The optional parameter {{EXACT-FLAG}}, default {{#f}}. When {{#f}} any argument string with embedded whitespace will be wrapped in quotes. When {{#t}} no such wrapping occurs. @@ -1306,7 +1323,7 @@ Returns: * the PID when asynchronous * -1 when failure ---- +---- Previous: [[Unit srfi-69]] Next: [[Unit utils]] diff --git a/manual/Unit regex b/manual/Unit regex index 23b78e56..eb8720b3 100644 --- a/manual/Unit regex +++ b/manual/Unit regex @@ -21,7 +21,7 @@ just use normal Scheme lists, with quasiquote if you like. === grep - [procedure] (grep REGEX LIST [ACCESSOR]) +<procedure>(grep REGEX LIST [ACCESSOR])</procedure> Returns all items of {{LIST}} that match the regular expression {{REGEX}}. This procedure could be defined as follows: @@ -39,7 +39,7 @@ matching. {{ACCESSOR}} defaults to the identity function. === glob->regexp - [procedure] (glob->regexp PATTERN) +<procedure>(glob->regexp PATTERN)</procedure> Converts the file-pattern {{PATTERN}} into a regular expression. @@ -59,7 +59,7 @@ Converts the file-pattern {{PATTERN}} into a regular expression. === glob? - [procedure] (glob? STRING) +<procedure>(glob? STRING)</procedure> Does the {{STRING}} have any "glob" wildcards? @@ -69,7 +69,7 @@ even though it technically is a valid "glob" file-pattern. === regexp - [procedure] (regexp STRING [IGNORECASE [IGNORESPACE [UTF8]]]) +<procedure>(regexp STRING [IGNORECASE [IGNORESPACE [UTF8]]])</procedure> Returns a precompiled regular expression object for {{string}}. The optional arguments {{IGNORECASE}}, {{IGNORESPACE}} and {{UTF8}} @@ -85,7 +85,7 @@ below. === regexp? - [procedure] (regexp? X) +<procedure>(regexp? X)</procedure> Returns {{#t}} if {{X}} is a precompiled regular expression, or {{#f}} otherwise. @@ -94,8 +94,8 @@ or {{#f}} otherwise. === string-match === string-match-positions - [procedure] (string-match REGEXP STRING [START]) - [procedure] (string-match-positions REGEXP STRING [START]) +<procedure>(string-match REGEXP STRING [START])</procedure><br> +<procedure>(string-match-positions REGEXP STRING [START])</procedure> Matches the regular expression in {{REGEXP}} (a string or a precompiled regular expression) with @@ -117,8 +117,8 @@ If invoked with a precompiled regular expression argument (by using === string-search === string-search-positions - [procedure] (string-search REGEXP STRING [START [RANGE]]) - [procedure] (string-search-positions REGEXP STRING [START [RANGE]]) +<procedure>(string-search REGEXP STRING [START [RANGE]])</procedure><br> +<procedure>(string-search-positions REGEXP STRING [START [RANGE]])</procedure> Searches for the first match of the regular expression in {{REGEXP}} with {{STRING}}. The search can be limited to @@ -127,7 +127,7 @@ Searches for the first match of the regular expression in === string-split-fields - [procedure] (string-split-fields REGEXP STRING [MODE [START]]) +<procedure>(string-split-fields REGEXP STRING [MODE [START]])</procedure> Splits {{STRING}} into a list of fields according to {{MODE}}, where {{MODE}} can be the keyword {{#:infix}} ({{REGEXP}} @@ -154,7 +154,7 @@ which is the default. === string-substitute - [procedure] (string-substitute REGEXP SUBST STRING [MODE]) +<procedure>(string-substitute REGEXP SUBST STRING [MODE])</procedure> Searches substrings in {{STRING}} that match {{REGEXP}} and substitutes them with the string {{SUBST}}. The substitution @@ -176,7 +176,7 @@ signal an error. === string-substitute* - [procedure] (string-substitute* STRING SMAP [MODE]) +<procedure>(string-substitute* STRING SMAP [MODE])</procedure> Substitutes elements of {{STRING}} with {{string-substitute}} according to {{SMAP}}. {{SMAP}} should be an association-list where each element of the list @@ -193,7 +193,7 @@ the regular expression {{MATCH}} in {{STRING}} will be replaced by the string === regexp-escape - [procedure] (regexp-escape STRING) +<procedure>(regexp-escape STRING)</procedure> Escapes all special characters in {{STRING}} with {{\}}, so that the string can be embedded into a regular expression. diff --git a/manual/Unit srfi-1 b/manual/Unit srfi-1 index 6881a6d1..a54684d4 100644 --- a/manual/Unit srfi-1 +++ b/manual/Unit srfi-1 @@ -2,8 +2,1331 @@ == Unit srfi-1 -List library, see the documentation for -[[http://srfi.schemers.org/srfi-1/srfi-1.html|SRFI-1]] +SRFI 1 (List Library) procedures. For more information, see the +[[http://srfi.schemers.org/srfi-1/srfi-1.html|SRFI 1]] document. + +[[toc:]] +=== Constructors + +<procedure>(xcons d a) -> pair</procedure><br> + + (lambda (d a) (cons a d)) + +Of utility only as a value to be conveniently passed to +higher-order procedures. + + (xcons '(b c) 'a) => (a b c) + +The name stands for "eXchanged CONS." + +<procedure>(cons* elt[1] elt[2] ...) -> object</procedure><br> + +Like list, but the last argument provides the tail of the +constructed list, returning + (cons elt[1] (cons elt[2] (cons ... elt[n]))) + +This function is called list* in Common Lisp and about half of the +Schemes that provide it, and cons* in the other half. + + (cons* 1 2 3 4) => (1 2 3 . 4) + (cons* 1) => 1 + +<procedure>(make-list n [fill]) -> list</procedure><br> +Returns an n-element list, whose elements are all the value fill. +If the fill argument is not given, the elements of the list may be +arbitrary values. + + (make-list 4 'c) => (c c c c) + +<procedure>(list-tabulate n init-proc) -> list</procedure><br> + +Returns an n-element list. Element i of the list, where 0 <= i < n, +is produced by (init-proc i). No guarantee is made about the +dynamic order in which init-proc is applied to these indices. + + (list-tabulate 4 values) => (0 1 2 3) + +<procedure>(list-copy flist) -> flist</procedure><br> + +Copies the spine of the argument. + +<procedure>(circular-list elt[1] elt[2] ...) -> list</procedure><br> + +Constructs a circular list of the elements. + + (circular-list 'z 'q) => (z q z q z q ...) + +<procedure>(iota count [start step]) -> list</procedure><br> + +Returns a list containing the elements + + (start start+step ... start+(count-1)*step) + +The start and step parameters default to 0 and 1, respectively. +This procedure takes its name from the APL primitive. + + (iota 5) => (0 1 2 3 4) + (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4) + +=== Predicates + +Note: the predicates proper-list?, circular-list?, and dotted-list? +partition the entire universe of Scheme values. + +<procedure>(proper-list? x) -> boolean</procedure><br> + +Returns true iff x is a proper list -- a finite, nil-terminated +list. + +More carefully: The empty list is a proper list. A pair whose cdr +is a proper list is also a proper list: + + <proper-list> ::= () (Empty proper list) + | (cons <x> <proper-list>) (Proper-list pair) + +Note that this definition rules out circular lists. This function +is required to detect this case and return false. + +Nil-terminated lists are called "proper" lists by R5RS and Common +Lisp. The opposite of proper is improper. + +R5RS binds this function to the variable list?. + + (not (proper-list? x)) = (or (dotted-list? x) (circular-list? x)) + +<procedure>(circular-list? x) -> boolean</procedure><br> + +True if x is a circular list. A circular list is a value such that +for every n >= 0, cdr^n(x) is a pair. + +Terminology: The opposite of circular is finite. + + (not (circular-list? x)) = (or (proper-list? x) (dotted-list? x)) + +<procedure>(dotted-list? x) -> boolean</procedure><br> + +True if x is a finite, non-nil-terminated list. That is, there +exists an n >= 0 such that cdr^n(x) is neither a pair nor (). This +includes non-pair, non-() values (e.g. symbols, numbers), which are +considered to be dotted lists of length 0. + + (not (dotted-list? x)) = (or (proper-list? x) (circular-list? x)) + +<procedure>(not-pair? x) -> boolean</procedure><br> + + (lambda (x) (not (pair? x))) + +Provided as a procedure as it can be useful as the termination +condition for list-processing procedures that wish to handle all +finite lists, both proper and dotted. + +<procedure>(list= elt= list[1] ...) -> boolean</procedure><br> + +Determines list equality, given an element-equality procedure. +Proper list A equals proper list B if they are of the same length, +and their corresponding elements are equal, as determined by elt=. +If the element-comparison procedure's first argument is from list +[i], then its second argument is from list[i+1], i.e. it is always +called as (elt= a b) for a an element of list A, and b an element +of list B. + +In the n-ary case, every list[i] is compared to list[i+1] (as +opposed, for example, to comparing list[1] to every list[i], for i> +1). If there are no list arguments at all, list= simply returns +true. + +It is an error to apply list= to anything except proper lists. +While implementations may choose to extend it to circular lists, +note that it cannot reasonably be extended to dotted lists, as it +provides no way to specify an equality procedure for comparing the +list terminators. + +Note that the dynamic order in which the elt= procedure is applied +to pairs of elements is not specified. For example, if list= is +applied to three lists, A, B, and C, it may first completely +compare A to B, then compare B to C, or it may compare the first +elements of A and B, then the first elements of B and C, then the +second elements of A and B, and so forth. + +The equality procedure must be consistent with eq?. That is, it +must be the case that + + (eq? x y) => (elt= x y). + +Note that this implies that two lists which are eq? are always list=, +as well; implementations may exploit this fact to "short-cut" +the element-by-element comparisons. + + (list= eq?) => #t ; Trivial cases + (list= eq? '(a)) => #t + +=== Selectors + +<procedure>(first pair) -> object</procedure><br> +<procedure>(second pair) -> object</procedure><br> +<procedure>(third pair) -> object</procedure><br> +<procedure>(fourth pair) -> object</procedure><br> +<procedure>(fifth pair) -> object</procedure><br> +<procedure>(sixth pair) -> object</procedure><br> +<procedure>(seventh pair) -> object</procedure><br> +<procedure>(eighth pair) -> object</procedure><br> +<procedure>(ninth pair) -> object</procedure><br> +<procedure>(tenth pair) -> object</procedure><br> + +Synonyms for car, cadr, caddr, ... + + (third '(a b c d e)) => c + +<procedure>(car+cdr pair) -> [x y]</procedure><br> + +The fundamental pair deconstructor: + + (lambda (p) (values (car p) (cdr p))) + +This can, of course, be implemented more efficiently by a compiler. + +<procedure>(take x i) -> list</procedure><br> +<procedure>(drop x i) -> object</procedure><br> + +take returns the first i elements of list x. +drop returns all but the first i elements of list x. + + (take '(a b c d e) 2) => (a b) + (drop '(a b c d e) 2) => (c d e) + +x may be any value -- a proper, circular, or dotted list: + + (take '(1 2 3 . d) 2) => (1 2) + (drop '(1 2 3 . d) 2) => (3 . d) + (take '(1 2 3 . d) 3) => (1 2 3) + (drop '(1 2 3 . d) 3) => d + +For a legal i, take and drop partition the list in a manner which +can be inverted with append: + + (append (take x i) (drop x i)) = x + +drop is exactly equivalent to performing i cdr operations on x; the +returned value shares a common tail with x. If the argument is a +list of non-zero length, take is guaranteed to return a +freshly-allocated list, even in the case where the entire list is +taken, e.g. (take lis (length lis)). + +<procedure>(take-right flist i) -> object</procedure><br> +<procedure>(drop-right flist i) -> list</procedure><br> + +take-right returns the last i elements of flist. +drop-right returns all but the last i elements of flist. + + (take-right '(a b c d e) 2) => (d e) + (drop-right '(a b c d e) 2) => (a b c) + +The returned list may share a common tail with the argument list. + +flist may be any finite list, either proper or dotted: + + (take-right '(1 2 3 . d) 2) => (2 3 . d) + (drop-right '(1 2 3 . d) 2) => (1) + (take-right '(1 2 3 . d) 0) => d + (drop-right '(1 2 3 . d) 0) => (1 2 3) + +For a legal i, take-right and drop-right partition the list in a +manner which can be inverted with append: + + (append (take flist i) (drop flist i)) = flist + +take-right's return value is guaranteed to share a common tail with +flist. If the argument is a list of non-zero length, drop-right is +guaranteed to return a freshly-allocated list, even in the case +where nothing is dropped, e.g. (drop-right lis 0). + +<procedure>(take! x i) -> list</procedure><br> +<procedure>(drop-right! flist i) -> list</procedure><br> + +take! and drop-right! are "linear-update" variants of take and +drop-right: the procedure is allowed, but not required, to alter +the argument list to produce the result. + +If x is circular, take! may return a shorter-than-expected list: + + (take! (circular-list 1 3 5) 8) => (1 3) + (take! (circular-list 1 3 5) 8) => (1 3 5 1 3 5 1 3) + +<procedure>(split-at x i) -> [list object]</procedure><br> +<procedure>(split-at! x i) -> [list object]</procedure><br> + +split-at splits the list x at index i, returning a list of the +first i elements, and the remaining tail. It is equivalent to + + (values (take x i) (drop x i)) + +split-at! is the linear-update variant. It is allowed, but not +required, to alter the argument list to produce the result. + + (split-at '(a b c d e f g h) 3) => + (a b c) + (d e f g h) + +<procedure>(last pair) -> object</procedure><br> +<procedure>(last-pair pair) -> pair</procedure><br> + +last returns the last element of the non-empty, finite list pair. +last-pair returns the last pair in the non-empty, finite list pair. + + (last '(a b c)) => c + (last-pair '(a b c)) => (c) + +=== Miscellaneous + +<procedure>(length list) -> integer</procedure><br> +<procedure>(length+ clist) -> integer or #f</procedure><br> + +Both length and length+ return the length of the argument. It is an +error to pass a value to length which is not a proper list (finite +and nil-terminated). In particular, this means an implementation +may diverge or signal an error when length is applied to a circular +list. + +length+, on the other hand, returns #F when applied to a circular +list. + +The length of a proper list is a non-negative integer n such that +cdr applied n times to the list produces the empty list. + +<procedure>(append! list[1] ...) -> list</procedure><br> + +append! is the "linear-update" variant of append -- it is allowed, +but not required, to alter cons cells in the argument lists to +construct the result list. The last argument is never altered; the +result list shares structure with this parameter. + +<procedure>(concatenate list-of-lists) -> value</procedure><br> +<procedure>(concatenate! list-of-lists) -> value</procedure><br> + +These functions append the elements of their argument together. +That is, concatenate returns + + (apply append list-of-lists) + +or, equivalently, + + (reduce-right append '() list-of-lists) + +concatenate! is the linear-update variant, defined in terms of +append! instead of append. + +Note that some Scheme implementations do not support passing more +than a certain number (e.g., 64) of arguments to an n-ary +procedure. In these implementations, the (apply append ...) idiom +would fail when applied to long lists, but concatenate would +continue to function properly. + +As with append and append!, the last element of the input list may +be any value at all. + +<procedure>(reverse! list) -> list</procedure><br> + +reverse! is the linear-update variant of reverse. It is permitted, +but not required, to alter the argument's cons cells to produce the +reversed list. + +<procedure>(append-reverse rev-head tail) -> list</procedure><br> +<procedure>(append-reverse! rev-head tail) -> list</procedure><br> + +append-reverse returns (append (reverse rev-head) tail). It is +provided because it is a common operation -- a common +list-processing style calls for this exact operation to transfer +values accumulated in reverse order onto the front of another list, +and because the implementation is significantly more efficient than +the simple composition it replaces. (But note that this pattern of +iterative computation followed by a reverse can frequently be +rewritten as a recursion, dispensing with the reverse and +append-reverse steps, and shifting temporary, intermediate storage +from the heap to the stack, which is typically a win for reasons of +cache locality and eager storage reclamation.) + +append-reverse! is just the linear-update variant -- it is allowed, +but not required, to alter rev-head's cons cells to construct the +result. + +<procedure>(zip clist[1] clist[2] ...) -> list</procedure><br> + + (lambda lists (apply map list lists)) + +If zip is passed n lists, it returns a list as long as the shortest +of these lists, each element of which is an n-element list +comprised of the corresponding elements from the parameter lists. + + (zip '(one two three) + '(1 2 3) + '(odd even odd even odd even odd even)) + => ((one 1 odd) (two 2 even) (three 3 odd)) + + (zip '(1 2 3)) => ((1) (2) (3)) + +At least one of the argument lists must be finite: + + (zip '(3 1 4 1) (circular-list #f #t)) + => ((3 #f) (1 #t) (4 #f) (1 #t)) + +<procedure>(unzip1 list) -> list</procedure><br> +<procedure>(unzip2 list) -> [list list]</procedure><br> +<procedure>(unzip3 list) -> [list list list]</procedure><br> +<procedure>(unzip4 list) -> [list list list list]</procedure><br> +<procedure>(unzip5 list) -> [list list list list list]</procedure><br> + +unzip1 takes a list of lists, where every list must contain at +least one element, and returns a list containing the initial +element of each such list. That is, it returns (map car lists). +unzip2 takes a list of lists, where every list must contain at +least two elements, and returns two values: a list of the first +elements, and a list of the second elements. unzip3 does the same +for the first three elements of the lists, and so forth. + + (unzip2 '((1 one) (2 two) (3 three))) => + (1 2 3) + (one two three) + +<procedure>(count pred clist[1] clist[2]) -> integer</procedure><br> + +pred is a procedure taking as many arguments as there are lists and +returning a single value. It is applied element-wise to the +elements of the lists, and a count is tallied of the number of +elements that produce a true value. This count is returned. count +is "iterative" in that it is guaranteed to apply pred to the list +elements in a left-to-right order. The counting stops when the +shortest list expires. + + (count even? '(3 1 4 1 5 9 2 5 6)) => 3 + (count < '(1 2 4 8) '(2 4 6 8 10 12 14 16)) => 3 + +At least one of the argument lists must be finite: + + (count < '(3 1 4 1) (circular-list 1 10)) => 2 + +=== Fold, unfold & map + +<procedure>(fold kons knil clist[1] clist[2] ...) -> value</procedure><br> + +The fundamental list iterator. + +First, consider the single list-parameter case. If +clist[1] = (e[1] e[2] ... e[n]), then this procedure returns + + (kons e[n] ... (kons e[2] (kons e[1] knil)) ... ) + +That is, it obeys the (tail) recursion + + (fold kons knil lis) = (fold kons (kons (car lis) knil) (cdr lis)) + (fold kons knil '()) = knil + +Examples: + + (fold + 0 lis) ; Add up the elements of LIS. + (fold cons '() lis) ; Reverse LIS. + (fold cons tail rev-head) ; See APPEND-REVERSE. + + ;; How many symbols in LIS? + (fold (lambda (x count) (if (symbol? x) (+ count 1) count)) + 0 + lis) + + ;; Length of the longest string in LIS: + (fold (lambda (s max-len) (max max-len (string-length s))) + 0 + lis) + +If n list arguments are provided, then the kons function must take +n+1 parameters: one element from each list, and the "seed" or fold +state, which is initially knil. The fold operation terminates when +the shortest list runs out of values: + + (fold cons* '() '(a b c) '(1 2 3 4 5)) => (c 3 b 2 a 1) + +At least one of the list arguments must be finite. + +<procedure>(fold-right kons knil clist[1] clist[2] ...) -> value</procedure><br> + +The fundamental list recursion operator. + +First, consider the single list-parameter case. If +clist[1] = (e[1] e[2] ... e[n]), then this procedure returns + + (kons e[1] (kons e[2] ... (kons e[n] knil))) + +That is, it obeys the recursion + + (fold-right kons knil lis) = (kons (car lis) (fold-right kons knil (cdr lis))) + (fold-right kons knil '()) = knil + +Examples: + + (fold-right cons '() lis) ; Copy LIS. + + ;; Filter the even numbers out of LIS. + (fold-right (lambda (x l) (if (even? x) (cons x l) l)) '() lis)) + +If n list arguments are provided, then the kons function must take +n+1 parameters: one element from each list, and the "seed" or fold +state, which is initially knil. The fold operation terminates when +the shortest list runs out of values: + + (fold-right cons* '() '(a b c) '(1 2 3 4 5)) => (a 1 b 2 c 3) + +At least one of the list arguments must be finite. + +<procedure>(pair-fold kons knil clist[1] clist[2] ...) -> value</procedure><br> + +Analogous to fold, but kons is applied to successive sublists of +the lists, rather than successive elements -- that is, kons is +applied to the pairs making up the lists, giving this (tail) +recursion: + + (pair-fold kons knil lis) = (let ((tail (cdr lis))) + (pair-fold kons (kons lis knil) tail)) + (pair-fold kons knil '()) = knil + +For finite lists, the kons function may reliably apply set-cdr! to +the pairs it is given without altering the sequence of execution. + +Example: + + ;;; Destructively reverse a list. + (pair-fold (lambda (pair tail) (set-cdr! pair tail) pair) '() lis)) + +At least one of the list arguments must be finite. + +<procedure>(pair-fold-right kons knil clist[1] clist[2] ...) -> value</procedure><br> + +Holds the same relationship with fold-right that pair-fold holds +with fold. Obeys the recursion + + (pair-fold-right kons knil lis) = + (kons lis (pair-fold-right kons knil (cdr lis))) + (pair-fold-right kons knil '()) = knil + +Example: + + (pair-fold-right cons '() '(a b c)) => ((a b c) (b c) (c)) + +At least one of the list arguments must be finite. + +<procedure>(reduce f ridentity list) -> value</procedure><br> + +reduce is a variant of fold. + +ridentity should be a "right identity" of the procedure f -- that +is, for any value x acceptable to f, + + (f x ridentity) = x + +reduce has the following definition: + + If list = (), return ridentity; + Otherwise, return (fold f (car list) (cdr list)). + +...in other words, we compute (fold f ridentity list). + +Note that ridentity is used only in the empty-list case. You +typically use reduce when applying f is expensive and you'd like to +avoid the extra application incurred when fold applies f to the +head of list and the identity value, redundantly producing the same +value passed in to f. For example, if f involves searching a file +directory or performing a database query, this can be significant. +In general, however, fold is useful in many contexts where reduce +is not (consider the examples given in the fold definition -- only +one of the five folds uses a function with a right identity. The +other four may not be performed with reduce). + +Note: MIT Scheme and Haskell flip F's arg order for their reduce +and fold functions. + + ;; Take the max of a list of non-negative integers. + (reduce max 0 nums) ; i.e., (apply max 0 nums) + +<procedure>(reduce-right f ridentity list) -> value</procedure><br> + +reduce-right is the fold-right variant of reduce. It obeys the +following definition: + + (reduce-right f ridentity '()) = ridentity + (reduce-right f ridentity '(e[1])) = (f e[1] ridentity) = e[1] + (reduce-right f ridentity '(e[1] e[2] ...)) = + (f e[1] (reduce f ridentity (e[2] ...))) + +...in other words, we compute (fold-right f ridentity list). + + ;; Append a bunch of lists together. + ;; I.e., (apply append list-of-lists) + (reduce-right append '() list-of-lists) + +<procedure>(unfold p f g seed [tail-gen]) -> list</procedure><br> + +unfold is best described by its basic recursion: + + (unfold p f g seed) = + (if (p seed) (tail-gen seed) + (cons (f seed) + (unfold p f g (g seed)))) + +; p : Determines when to stop unfolding. +; f : Maps each seed value to the corresponding list element. +; g : Maps each seed value to next seed value. +; seed : The "state" value for the unfold. +; tail-gen : Creates the tail of the list; defaults to (lambda (x) '()) + +In other words, we use g to generate a sequence of seed values + seed, g(seed), g^2(seed), g^3(seed), ... + +These seed values are mapped to list elements by f, producing the +elements of the result list in a left-to-right order. P says when +to stop. + +unfold is the fundamental recursive list constructor, just as +fold-right is the fundamental recursive list consumer. While unfold +may seem a bit abstract to novice functional programmers, it can be +used in a number of ways: + + ;; List of squares: 1^2 ... 10^2 + (unfold (lambda (x) (> x 10)) + (lambda (x) (* x x)) + (lambda (x) (+ x 1)) + 1) + + (unfold null-list? car cdr lis) ; Copy a proper list. + + ;; Read current input port into a list of values. + (unfold eof-object? values (lambda (x) (read)) (read)) + + ;; Copy a possibly non-proper list: + (unfold not-pair? car cdr lis + values) + + ;; Append HEAD onto TAIL: + (unfold null-list? car cdr head + (lambda (x) tail)) + +Interested functional programmers may enjoy noting that fold-right +and unfold are in some sense inverses. That is, given operations +knull?, kar, kdr, kons, and knil satisfying + (kons (kar x) (kdr x)) = x and (knull? knil) = #t + +then + (fold-right kons knil (unfold knull? kar kdr x)) = x + +and + (unfold knull? kar kdr (fold-right kons knil x)) = x + +This combinator sometimes is called an "anamorphism;" when an +explicit tail-gen procedure is supplied, it is called an +"apomorphism." + +<procedure>(unfold-right p f g seed [tail]) -> list</procedure><br> + +unfold-right constructs a list with the following loop: + + (let lp ((seed seed) (lis tail)) + (if (p seed) lis + (lp (g seed) + (cons (f seed) lis)))) + +; p : Determines when to stop unfolding. +; f : Maps each seed value to the corresponding list element. +; g : Maps each seed value to next seed value. +; seed : The "state" value for the unfold. +; tail : list terminator; defaults to '(). + +In other words, we use g to generate a sequence of seed values + seed, g(seed), g^2(seed), g^3(seed), ... + +These seed values are mapped to list elements by f, producing the +elements of the result list in a right-to-left order. P says when +to stop. + +unfold-right is the fundamental iterative list constructor, just as +fold is the fundamental iterative list consumer. While unfold-right +may seem a bit abstract to novice functional programmers, it can be +used in a number of ways: + + ;; List of squares: 1^2 ... 10^2 + (unfold-right zero? + (lambda (x) (* x x)) + (lambda (x) (- x 1)) + 10) + + ;; Reverse a proper list. + (unfold-right null-list? car cdr lis) + + ;; Read current input port into a list of values. + (unfold-right eof-object? values (lambda (x) (read)) (read)) + + ;; (append-reverse rev-head tail) + (unfold-right null-list? car cdr rev-head tail) + +Interested functional programmers may enjoy noting that fold and +unfold-right are in some sense inverses. That is, given operations +knull?, kar, kdr, kons, and knil satisfying + (kons (kar x) (kdr x)) = x and (knull? knil) = #t + +then + (fold kons knil (unfold-right knull? kar kdr x)) = x + +and + (unfold-right knull? kar kdr (fold kons knil x)) = x + +This combinator presumably has some pretentious mathematical name; +interested readers are invited to communicate it to the author. + +<procedure>(map proc clist[1] clist[2] ...) -> list</procedure><br> + +This procedure is extended from its R5RS specification to allow the +arguments to be of unequal length; it terminates when the shortest +list runs out. + +At least one of the argument lists must be finite: + + (map + '(3 1 4 1) (circular-list 1 0)) => (4 1 5 1) + +<procedure>(for-each proc clist[1] clist[2] ...) -> unspecified</procedure><br> + +This procedure is extended from its R5RS specification to allow the +arguments to be of unequal length; it terminates when the shortest +list runs out. + +At least one of the argument lists must be finite. + +<procedure>(append-map f clist[1] clist[2] ...) -> value</procedure><br> +<procedure>(append-map! f clist[1] clist[2] ...) -> value</procedure><br> + +Equivalent to + (apply append (map f clist[1] clist[2] ...)) +and + (apply append! (map f clist[1] clist[2] ...)) + +Map f over the elements of the lists, just as in the map function. +However, the results of the applications are appended together to +make the final result. append-map uses append to append the results +together; append-map! uses append!. + +The dynamic order in which the various applications of f are made +is not specified. + +Example: + + (append-map! (lambda (x) (list x (- x))) '(1 3 8)) + => (1 -1 3 -3 8 -8) + +At least one of the list arguments must be finite. + +<procedure>(map! f list[1] clist[2] ...) -> list</procedure><br> + +Linear-update variant of map -- map! is allowed, but not required, +to alter the cons cells of list[1] to construct the result list. + +The dynamic order in which the various applications of f are made +is not specified. In the n-ary case, clist[2], clist[3], ... must +have at least as many elements as list[1]. + +<procedure>(map-in-order f clist[1] clist[2] ...) -> list</procedure><br> + +A variant of the map procedure that guarantees to apply f across +the elements of the list[i] arguments in a left-to-right order. +This is useful for mapping procedures that both have side effects +and return useful values. + +At least one of the list arguments must be finite. + +<procedure>(pair-for-each f clist[1] clist[2] ...) -> unspecific</procedure><br> + +Like for-each, but f is applied to successive sublists of the +argument lists. That is, f is applied to the cons cells of the +lists, rather than the lists' elements. These applications occur in +left-to-right order. + +The f procedure may reliably apply set-cdr! to the pairs it is +given without altering the sequence of execution. + + (pair-for-each (lambda (pair) (display pair) (newline)) '(a b c)) ==> + (a b c) + (b c) + (c) + +At least one of the list arguments must be finite. + +<procedure>(filter-map f clist[1] clist[2] ...) -> list</procedure><br> + +Like map, but only true values are saved. + + (filter-map (lambda (x) (and (number? x) (* x x))) '(a 1 b 3 c 7)) + => (1 9 49) + +The dynamic order in which the various applications of f are made +is not specified. + +At least one of the list arguments must be finite. + +=== Filtering & partitioning + +<procedure>(filter pred list) -> list</procedure><br> + +Return all the elements of list that satisfy predicate pred. The +list is not disordered -- elements that appear in the result list +occur in the same order as they occur in the argument list. The +returned list may share a common tail with the argument list. The +dynamic order in which the various applications of pred are made is +not specified. + + (filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4) + +<procedure>(partition pred list) -> [list list]</procedure><br> + +Partitions the elements of list with predicate pred, and returns +two values: the list of in-elements and the list of out-elements. +The list is not disordered -- elements occur in the result lists in +the same order as they occur in the argument list. The dynamic +order in which the various applications of pred are made is not +specified. One of the returned lists may share a common tail with +the argument list. + + (partition symbol? '(one 2 3 four five 6)) => + (one four five) + (2 3 6) + +<procedure>(remove pred list) -> list</procedure><br> + +Returns list without the elements that satisfy predicate pred: + + (lambda (pred list) (filter (lambda (x) (not (pred x))) list)) + +The list is not disordered -- elements that appear in the result +list occur in the same order as they occur in the argument list. +The returned list may share a common tail with the argument list. +The dynamic order in which the various applications of pred are +made is not specified. + + (remove even? '(0 7 8 8 43 -4)) => (7 43) + +<procedure>(filter! pred list) -> list</procedure><br> +<procedure>(partition! pred list) -> [list list]</procedure><br> +<procedure>(remove! pred list) -> list</procedure><br> + +Linear-update variants of filter, partition and remove. These +procedures are allowed, but not required, to alter the cons cells +in the argument list to construct the result lists. + +=== Searching + +<procedure>(find pred clist) -> value</procedure><br> + +Return the first element of clist that satisfies predicate pred; +false if no element does. + + (find even? '(3 1 4 1 5 9)) => 4 + +Note that find has an ambiguity in its lookup semantics -- if find +returns #f, you cannot tell (in general) if it found a #f element +that satisfied pred, or if it did not find any element at all. In +many situations, this ambiguity cannot arise -- either the list +being searched is known not to contain any #f elements, or the list +is guaranteed to have an element satisfying pred. However, in cases +where this ambiguity can arise, you should use find-tail instead of +find -- find-tail has no such ambiguity: + + (cond ((find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR) + (else ...)) ; Search failed. + +<procedure>(find-tail pred clist) -> pair or false</procedure><br> + +Return the first pair of clist whose car satisfies pred. If no pair +does, return false. + +find-tail can be viewed as a general-predicate variant of the +member function. + +Examples: + + (find-tail even? '(3 1 37 -8 -5 0 0)) => (-8 -5 0 0) + (find-tail even? '(3 1 37 -5)) => #f + + ;; MEMBER X LIS: + (find-tail (lambda (elt) (equal? x elt)) lis) + +In the circular-list case, this procedure "rotates" the list. + +Find-tail is essentially drop-while, where the sense of the +predicate is inverted: Find-tail searches until it finds an element +satisfying the predicate; drop-while searches until it finds an +element that doesn't satisfy the predicate. + +<procedure>(take-while pred clist) -> list</procedure><br> +<procedure>(take-while! pred clist) -> list</procedure><br> + +Returns the longest initial prefix of clist whose elements all +satisfy the predicate pred. + +Take-while! is the linear-update variant. It is allowed, but not +required, to alter the argument list to produce the result. + + (take-while even? '(2 18 3 10 22 9)) => (2 18) + +<procedure>(drop-while pred clist) -> list</procedure><br> + +Drops the longest initial prefix of clist whose elements all +satisfy the predicate pred, and returns the rest of the list. + + (drop-while even? '(2 18 3 10 22 9)) => (3 10 22 9) + +The circular-list case may be viewed as "rotating" the list. + +<procedure>(span pred clist) -> [list clist]</procedure><br> +<procedure>(span! pred list ) -> [list list]</procedure><br> +<procedure>(break pred clist) -> [list clist]</procedure><br> +<procedure>(break! pred list ) -> [list list]</procedure><br> + +Span splits the list into the longest initial prefix whose elements +all satisfy pred, and the remaining tail. Break inverts the sense +of the predicate: the tail commences with the first element of the +input list that satisfies the predicate. + +In other words: span finds the intial span of elements satisfying +pred, and break breaks the list at the first element satisfying +pred. + +Span is equivalent to + + (values (take-while pred clist) + (drop-while pred clist)) + +Span! and break! are the linear-update variants. They are allowed, +but not required, to alter the argument list to produce the result. + + (span even? '(2 18 3 10 22 9)) => + (2 18) + (3 10 22 9) + + (break even? '(3 1 4 1 5 9)) => + (3 1) + (4 1 5 9) + +<procedure>(any pred clist[1] clist[2] ...) -> value</procedure><br> + +Applies the predicate across the lists, returning true if the +predicate returns true on any application. + +If there are n list arguments clist[1] ... clist[n], then pred must +be a procedure taking n arguments and returning a boolean result. + +any applies pred to the first elements of the clist[i] parameters. +If this application returns a true value, any immediately returns +that value. Otherwise, it iterates, applying pred to the second +elements of the clist[i] parameters, then the third, and so forth. +The iteration stops when a true value is produced or one of the +lists runs out of values; in the latter case, any returns #f. The +application of pred to the last element of the lists is a tail +call. + +Note the difference between find and any -- find returns the +element that satisfied the predicate; any returns the true value +that the predicate produced. + +Like every, any's name does not end with a question mark -- this is +to indicate that it does not return a simple boolean (#t or #f), +but a general value. + + (any integer? '(a 3 b 2.7)) => #t + (any integer? '(a 3.1 b 2.7)) => #f + (any < '(3 1 4 1 5) + '(2 7 1 8 2)) => #t + +<procedure>(every pred clist[1] clist[2] ...) -> value</procedure><br> + +Applies the predicate across the lists, returning true if the +predicate returns true on every application. + +If there are n list arguments clist[1] ... clist[n], then pred must +be a procedure taking n arguments and returning a boolean result. + +every applies pred to the first elements of the clist[i] +parameters. If this application returns false, every immediately +returns false. Otherwise, it iterates, applying pred to the second +elements of the clist[i] parameters, then the third, and so forth. +The iteration stops when a false value is produced or one of the +lists runs out of values. In the latter case, every returns the +true value produced by its final application of pred. The +application of pred to the last element of the lists is a tail +call. + +If one of the clist[i] has no elements, every simply returns #t. + +Like any, every's name does not end with a question mark -- this is +to indicate that it does not return a simple boolean (#t or #f), +but a general value. + +<procedure>(list-index pred clist[1] clist[2] ...) -> integer or false</procedure><br> + +Return the index of the leftmost element that satisfies pred. + +If there are n list arguments clist[1] ... clist[n], then pred must +be a function taking n arguments and returning a boolean result. + +list-index applies pred to the first elements of the clist[i] +parameters. If this application returns true, list-index +immediately returns zero. Otherwise, it iterates, applying pred to +the second elements of the clist[i] parameters, then the third, and +so forth. When it finds a tuple of list elements that cause pred to +return true, it stops and returns the zero-based index of that +position in the lists. + +The iteration stops when one of the lists runs out of values; in +this case, list-index returns #f. + + (list-index even? '(3 1 4 1 5 9)) => 2 + (list-index < '(3 1 4 1 5 9 2 5 6) '(2 7 1 8 2)) => 1 + (list-index = '(3 1 4 1 5 9 2 5 6) '(2 7 1 8 2)) => #f + +<procedure>(member x list [=]) -> list</procedure><br> + +member is extended from its R5RS definition to allow the client to +pass in an optional equality procedure = used to compare keys. + +The comparison procedure is used to compare the elements e[i] of +list to the key x in this way: + (= x e[i]) ; list is (E1 ... En) + +That is, the first argument is always x, and the second argument is +one of the list elements. Thus one can reliably find the first +element of list that is greater than five with + (member 5 list <) + +Note that fully general list searching may be performed with the +find-tail and find procedures, e.g. + + (find-tail even? list) ; Find the first elt with an even key. + +=== Deletion + +<procedure>(delete x list [=]) -> list</procedure><br> +<procedure>(delete! x list [=]) -> list</procedure><br> + +delete uses the comparison procedure =, which defaults to equal?, +to find all elements of list that are equal to x, and deletes them +from list. The dynamic order in which the various applications of = +are made is not specified. + +The list is not disordered -- elements that appear in the result +list occur in the same order as they occur in the argument list. +The result may share a common tail with the argument list. + +Note that fully general element deletion can be performed with the +remove and remove! procedures, e.g.: + + ;; Delete all the even elements from LIS: + (remove even? lis) + +The comparison procedure is used in this way: (= x e[i]). That is, +x is always the first argument, and a list element is always the +second argument. The comparison procedure will be used to compare +each element of list exactly once; the order in which it is applied +to the various e[i] is not specified. Thus, one can reliably remove +all the numbers greater than five from a list with + (delete 5 list <) + +delete! is the linear-update variant of delete. It is allowed, but +not required, to alter the cons cells in its argument list to +construct the result. + +<procedure>(delete-duplicates list [=]) -> list</procedure><br> +<procedure>(delete-duplicates! list [=]) -> list</procedure><br> + +delete-duplicates removes duplicate elements from the list +argument. If there are multiple equal elements in the argument +list, the result list only contains the first or leftmost of these +elements in the result. The order of these surviving elements is +the same as in the original list -- delete-duplicates does not +disorder the list (hence it is useful for "cleaning up" association +lists). + +The = parameter is used to compare the elements of the list; it +defaults to equal?. If x comes before y in list, then the +comparison is performed (= x y). The comparison procedure will be +used to compare each pair of elements in list no more than once; +the order in which it is applied to the various pairs is not +specified. + +Implementations of delete-duplicates are allowed to share common +tails between argument and result lists -- for example, if the list +argument contains only unique elements, it may simply return +exactly this list. + +Be aware that, in general, delete-duplicates runs in time O(n^2) +for n-element lists. Uniquifying long lists can be accomplished in +O(n lg n) time by sorting the list to bring equal elements +together, then using a linear-time algorithm to remove equal +elements. Alternatively, one can use algorithms based on +element-marking, with linear-time results. + +delete-duplicates! is the linear-update variant of +delete-duplicates; it is allowed, but not required, to alter the +cons cells in its argument list to construct the result. + + (delete-duplicates '(a b a c a b c z)) => (a b c z) + + ;; Clean up an alist: + (delete-duplicates '((a . 3) (b . 7) (a . 9) (c . 1)) + (lambda (x y) (eq? (car x) (car y)))) + => ((a . 3) (b . 7) (c . 1)) + +=== Association lists + +An "association list" (or "alist") is a list of pairs. The car of each +pair contains a key value, and the cdr contains the associated data +value. They can be used to construct simple look-up tables in Scheme. +Note that association lists are probably inappropriate for +performance-critical use on large data; in these cases, hash tables or +some other alternative should be employed. + +<procedure>(assoc key alist [=]) -> pair or #f</procedure><br> + +assoc is extended from its R5RS definition to allow the client to +pass in an optional equality procedure = used to compare keys. + +The comparison procedure is used to compare the elements e[i] of +list to the key parameter in this way: + (= key (car e[i])) ; list is (E1 ... En) +That is, the first argument is always key, and the second argument +is one of the list elements. Thus one can reliably find the first +entry of alist whose key is greater than five with + (assoc 5 alist <) + +Note that fully general alist searching may be performed with the +find-tail and find procedures, e.g. + + ;; Look up the first association in alist with an even key: + (find (lambda (a) (even? (car a))) alist) + +<procedure>(alist-cons key datum alist) -> alist</procedure><br> + + (lambda (key datum alist) (cons (cons key datum) alist)) + +Cons a new alist entry mapping key -> datum onto alist. +<procedure>(alist-copy alist) -> alist</procedure><br> +Make a fresh copy of alist. This means copying each pair that forms +an association as well as the spine of the list, i.e. + + (lambda (a) (map (lambda (elt) (cons (car elt) (cdr elt))) a)) + +<procedure>(alist-delete key alist [=]) -> alist</procedure><br> +<procedure>(alist-delete! key alist [=]) -> alist</procedure><br> + +alist-delete deletes all associations from alist with the given +key, using key-comparison procedure =, which defaults to equal?. +The dynamic order in which the various applications of = are made +is not specified. + +Return values may share common tails with the alist argument. The +alist is not disordered -- elements that appear in the result alist +occur in the same order as they occur in the argument alist. + +The comparison procedure is used to compare the element keys k[i] +of alist's entries to the key parameter in this way: (= key k[i]). +Thus, one can reliably remove all entries of alist whose key is +greater than five with (alist-delete 5 alist <) + +alist-delete! is the linear-update variant of alist-delete. It is +allowed, but not required, to alter cons cells from the alist +parameter to construct the result. + +=== Set operations on lists + +Be aware that these procedures typically run in time O(n * m) for n- +and m-element list arguments. Performance-critical applications +operating upon large sets will probably wish to use other data +structures and algorithms. + +<procedure>(lset<= = list[1] ...) -> boolean</procedure><br> + +Returns true iff every list[i] is a subset of list[i+1], using = +for the element-equality procedure. List A is a subset of list B if +every element in A is equal to some element of B. When performing +an element comparison, the = procedure's first argument is an +element of A; its second, an element of B. + + (lset<= eq? '(a) '(a b a) '(a b c c)) => #t + (lset<= eq?) => #t ; Trivial cases + (lset<= eq? '(a)) => #t + +<procedure>(lset= = list[1] list[2] ...) -> boolean</procedure><br> + +Returns true iff every list[i] is set-equal to list[i+1], using = +for the element-equality procedure. "Set-equal" simply means that +list[i] is a subset of list[i+1], and list[i+1] is a subset of list +[i]. The = procedure's first argument is an element of list[i]; its +second is an element of list[i+1]. + + (lset= eq? '(b e a) '(a e b) '(e e b a)) => #t + (lset= eq?) => #t ; Trivial cases + (lset= eq? '(a)) => #t + +<procedure>(lset-adjoin = list elt[1] ...) -> list</procedure><br> + +Adds the elt[i] elements not already in the list parameter to the +result list. The result shares a common tail with the list +parameter. The new elements are added to the front of the list, but +no guarantees are made about their order. The = parameter is an +equality procedure used to determine if an elt[i] is already a +member of list. Its first argument is an element of list; its +second is one of the elt[i]. + +The list parameter is always a suffix of the result -- even if the +list parameter contains repeated elements, these are not reduced. + + (lset-adjoin eq? '(a b c d c e) 'a 'e 'i 'o 'u) => (u o i a b c d c e) + +<procedure>(lset-union = list[1] ...) -> list</procedure><br> + +Returns the union of the lists, using = for the element-equality +procedure. + +The union of lists A and B is constructed as follows: +* If A is the empty list, the answer is B (or a copy of B). +* Otherwise, the result is initialised to be list A (or a copy of +A). +* Proceed through the elements of list B in a left-to-right +order. If b is such an element of B, compare every element r of +the current result list to b: (= r b). If all comparisons fail, +b is consed onto the front of the result. + +However, there is no guarantee that = will be applied to every pair +of arguments from A and B. In particular, if A is eq? to B, the +operation may immediately terminate. + +In the n-ary case, the two-argument list-union operation is simply +folded across the argument lists. + + (lset-union eq? '(a b c d e) '(a e i o u)) => + (u o i a b c d e) + + ;; Repeated elements in LIST1 are preserved. + (lset-union eq? '(a a c) '(x a x)) => (x a a c) + + ;; Trivial cases + (lset-union eq?) => () + (lset-union eq? '(a b c)) => (a b c) + +<procedure>(lset-intersection = list[1] list[2] ...) -> list</procedure><br> + +Returns the intersection of the lists, using = for the +element-equality procedure. + +The intersection of lists A and B is comprised of every element of +A that is = to some element of B: (= a b), for a in A, and b in B. +Note this implies that an element which appears in B and multiple +times in list A will also appear multiple times in the result. + +The order in which elements appear in the result is the same as +they appear in list[1] -- that is, lset-intersection essentially +filters list[1], without disarranging element order. The result may +share a common tail with list[1]. + +In the n-ary case, the two-argument list-intersection operation is +simply folded across the argument lists. However, the dynamic order +in which the applications of = are made is not specified. The +procedure may check an element of list[1] for membership in every +other list before proceeding to consider the next element of list +[1], or it may completely intersect list[1] and list[2] before +proceeding to list[3], or it may go about its work in some third +order. + + (lset-intersection eq? '(a b c d e) '(a e i o u)) => (a e) + + ;; Repeated elements in LIST1 are preserved. + (lset-intersection eq? '(a x y a) '(x a x z)) => '(a x a) + + (lset-intersection eq? '(a b c)) => (a b c) ; Trivial case + +<procedure>(lset-difference = list[1] list[2] ...) -> list</procedure><br> + +Returns the difference of the lists, using = for the +element-equality procedure -- all the elements of list[1] that are +not = to any element from one of the other list[i] parameters. + +The = procedure's first argument is always an element of list[1]; +its second is an element of one of the other list[i]. Elements that +are repeated multiple times in the list[1] parameter will occur +multiple times in the result. The order in which elements appear in +the result is the same as they appear in list[1] -- that is, +lset-difference essentially filters list[1], without disarranging +element order. The result may share a common tail with list[1]. The +dynamic order in which the applications of = are made is not +specified. The procedure may check an element of list[1] for +membership in every other list before proceeding to consider the +next element of list[1], or it may completely compute the +difference of list[1] and list[2] before proceeding to list[3], or +it may go about its work in some third order. + + (lset-difference eq? '(a b c d e) '(a e i o u)) => (b c d) + (lset-difference eq? '(a b c)) => (a b c) ; Trivial case + +<procedure>(lset-xor = list[1] ...) -> list</procedure><br> + +Returns the exclusive-or of the sets, using = for the +element-equality procedure. If there are exactly two lists, this is +all the elements that appear in exactly one of the two lists. The +operation is associative, and thus extends to the n-ary case -- the +elements that appear in an odd number of the lists. The result may +share a common tail with any of the list[i] parameters. + +More precisely, for two lists A and B, A xor B is a list of +* every element a of A such that there is no element b of B such +that (= a b), and +* every element b of B such that there is no element a of A such +that (= b a). + +However, an implementation is allowed to assume that = is symmetric-- +that is, that + (= a b) => (= b a). + +This means, for example, that if a comparison (= a b) produces true +for some a in A and b in B, both a and b may be removed from +inclusion in the result. + +In the n-ary case, the binary-xor operation is simply folded across +the lists. + + (lset-xor eq? '(a b c d e) '(a e i o u)) => (d c b i o u) + + ;; Trivial cases. + (lset-xor eq?) => () + (lset-xor eq? '(a b c d e)) => (a b c d e) + +<procedure>(lset-diff+intersection = list[1] list[2] ...) -> [list list]</procedure><br> + +Returns two values -- the difference and the intersection of the +lists. Is equivalent to + + (values (lset-difference = list[1] list[2] ...) + (lset-intersection = list[1] + (lset-union = list[2] ...))) + +but can be implemented more efficiently. + +The = procedure's first argument is an element of list[1]; its +second is an element of one of the other list[i]. + +Either of the answer lists may share a common tail with list[1]. +This operation essentially partitions list[1]. + +<procedure>(lset-union! = list[1] ...) -> list</procedure><br> +<procedure>(lset-intersection! = list[1] list[2] ...) -> list</procedure><br> +<procedure>(lset-difference! = list[1] list[2] ...) -> list</procedure><br> +<procedure>(lset-xor! = list[1] ...) -> list</procedure><br> +<procedure>(lset-diff+intersection! = list[1] list[2] ...) -> [list list]</procedure><br> + +These are linear-update variants. They are allowed, but not +required, to use the cons cells in their first list parameter to +construct their answer. lset-union! is permitted to recycle cons +cells from any of its list arguments. + --- Previous: [[Unit regex]] diff --git a/manual/Unit srfi-18 b/manual/Unit srfi-18 index eacf6ea3..1386f814 100644 --- a/manual/Unit srfi-18 +++ b/manual/Unit srfi-18 @@ -40,7 +40,7 @@ The following procedures are provided, in addition to the procedures defined in === thread-signal! - [procedure] (thread-signal! THREAD X) +<procedure>(thread-signal! THREAD X)</procedure> This will cause {{THREAD}} to signal the condition {{X}} once it is scheduled for execution. After signalling the condition, the thread continues with its normal @@ -48,32 +48,32 @@ execution. === thread-quantum - [procedure] (thread-quantum THREAD) +<procedure>(thread-quantum THREAD)</procedure> Returns the quantum of {{THREAD}}, which is an exact integer specifying the approximate time-slice of the thread in milliseconds. === thread-quantum-set! - [procedure] (thread-quantum-set! THREAD QUANTUM) +<procedure>(thread-quantum-set! THREAD QUANTUM)</procedure> Sets the quantum of {{THREAD}} to {{QUANTUM}}. === thread-suspend! - [procedure] (thread-suspend! THREAD) +<procedure>(thread-suspend! THREAD)</procedure> Suspends the execution of {{THREAD}} until resumed. === thread-resume! - [procedure] (thread-resume! THREAD) +<procedure>(thread-resume! THREAD)</procedure> Readies the suspended thread {{THREAD}}. === thread-wait-for-i/o! - [procedure] (thread-wait-for-i/o! FD [MODE]) +<procedure>(thread-wait-for-i/o! FD [MODE])</procedure> Suspends the current thread until input ({{MODE}} is {{#:input}}), output ({{MODE}} is {{#:output}}) or both ({{MODE}} is {{#:all}}) is available. {{FD}} should be a file-descriptor (not a port!) open @@ -81,14 +81,14 @@ for input or output, respectively. === time->milliseconds - [procedure] (time->milliseconds TIME) +<procedure>(time->milliseconds TIME)</procedure> Converts a time object (as created via {{current-time}}) into an exact integer representing the number of milliseconds since process startup. === milliseconds->time - [procedure] (milliseconds->time ms) +<procedure>(milliseconds->time ms)</procedure> Converts into a time object an exact integer representing the number of milliseconds since process startup. diff --git a/manual/Unit srfi-4 b/manual/Unit srfi-4 index 6e629199..ee1ab668 100644 --- a/manual/Unit srfi-4 +++ b/manual/Unit srfi-4 @@ -11,7 +11,7 @@ collected memory: === make-XXXvector - [procedure] (make-XXXvector SIZE [INIT NONGC FINALIZE]) +<procedure>(make-XXXvector SIZE [INIT NONGC FINALIZE])</procedure> Creates a SRFI-4 homogenous number vector of length {{SIZE}}. If {{INIT}} is given, it specifies the initial value for each slot in the vector. The optional arguments {{NONGC}} and {{FINALIZE}} define whether the @@ -41,22 +41,22 @@ Additionally, the following procedures are provided: === f32vector->blob/shared === f64vector->blob/shared - [procedure] (u8vector->blob U8VECTOR) - [procedure] (s8vector->blob S8VECTOR) - [procedure] (u16vector->blob U16VECTOR) - [procedure] (s16vector->blob S16VECTOR) - [procedure] (u32vector->blob U32VECTOR) - [procedure] (s32vector->blob S32VECTOR) - [procedure] (f32vector->blob F32VECTOR) - [procedure] (f64vector->blob F64VECTOR) - [procedure] (u8vector->blob/shared U8VECTOR) - [procedure] (s8vector->blob/shared S8VECTOR) - [procedure] (u16vector->blob/shared U16VECTOR) - [procedure] (s16vector->blob/shared S16VECTOR) - [procedure] (u32vector->blob/shared U32VECTOR) - [procedure] (s32vector->blob/shared S32VECTOR) - [procedure] (f32vector->blob/shared F32VECTOR) - [procedure] (f64vector->blob/shared F64VECTOR) +<procedure>(u8vector->blob U8VECTOR)</procedure><br> +<procedure>(s8vector->blob S8VECTOR)</procedure><br> +<procedure>(u16vector->blob U16VECTOR)</procedure><br> +<procedure>(s16vector->blob S16VECTOR)</procedure><br> +<procedure>(u32vector->blob U32VECTOR)</procedure><br> +<procedure>(s32vector->blob S32VECTOR)</procedure><br> +<procedure>(f32vector->blob F32VECTOR)</procedure><br> +<procedure>(f64vector->blob F64VECTOR)</procedure><br> +<procedure>(u8vector->blob/shared U8VECTOR)</procedure><br> +<procedure>(s8vector->blob/shared S8VECTOR)</procedure><br> +<procedure>(u16vector->blob/shared U16VECTOR)</procedure><br> +<procedure>(s16vector->blob/shared S16VECTOR)</procedure><br> +<procedure>(u32vector->blob/shared U32VECTOR)</procedure><br> +<procedure>(s32vector->blob/shared S32VECTOR)</procedure><br> +<procedure>(f32vector->blob/shared F32VECTOR)</procedure><br> +<procedure>(f64vector->blob/shared F64VECTOR)</procedure> Each of these procedures return the contents of the given vector as a 'packed' blob. The byte order in that vector is platform-dependent @@ -81,22 +81,22 @@ variants return a blob that shares memory with the contents of the vector. === blob->f32vector/shared === blob->f64vector/shared - [procedure] (blob->u8vector BLOB) - [procedure] (blob->s8vector BLOB) - [procedure] (blob->u16vector BLOB) - [procedure] (blob->s16vector BLOB) - [procedure] (blob->u32vector BLOB) - [procedure] (blob->s32vector BLOB) - [procedure] (blob->f32vector BLOB) - [procedure] (blob->f64vector BLOB) - [procedure] (blob->u8vector/shared BLOB) - [procedure] (blob->s8vector/shared BLOB) - [procedure] (blob->u16vector/shared BLOB) - [procedure] (blob->s16vector/shared BLOB) - [procedure] (blob->u32vector/shared BLOB) - [procedure] (blob->s32vector/shared BLOB) - [procedure] (blob->f32vector/shared BLOB) - [procedure] (blob->f64vector/shared BLOB) +<procedure>(blob->u8vector BLOB)</procedure><br> +<procedure>(blob->s8vector BLOB)</procedure><br> +<procedure>(blob->u16vector BLOB)</procedure><br> +<procedure>(blob->s16vector BLOB)</procedure><br> +<procedure>(blob->u32vector BLOB)</procedure><br> +<procedure>(blob->s32vector BLOB)</procedure><br> +<procedure>(blob->f32vector BLOB)</procedure><br> +<procedure>(blob->f64vector BLOB)</procedure><br> +<procedure>(blob->u8vector/shared BLOB)</procedure><br> +<procedure>(blob->s8vector/shared BLOB)</procedure><br> +<procedure>(blob->u16vector/shared BLOB)</procedure><br> +<procedure>(blob->s16vector/shared BLOB)</procedure><br> +<procedure>(blob->u32vector/shared BLOB)</procedure><br> +<procedure>(blob->s32vector/shared BLOB)</procedure><br> +<procedure>(blob->f32vector/shared BLOB)</procedure><br> +<procedure>(blob->f64vector/shared BLOB)</procedure> Each of these procedures return a vector where the argument {{BLOB}} is taken as a 'packed' representation of the contents @@ -113,14 +113,14 @@ shares memory with the contents of the blob. === subf32vector === subf64vector - [procedure] (subu8vector U8VECTOR FROM TO) - [procedure] (subu16vector U16VECTOR FROM TO) - [procedure] (subu32vector U32VECTOR FROM TO) - [procedure] (subs8vector S8VECTOR FROM TO) - [procedure] (subs16vector S16VECTOR FROM TO) - [procedure] (subs32vector S32VECTOR FROM TO) - [procedure] (subf32vector F32VECTOR FROM TO) - [procedure] (subf64vector F64VECTOR FROM TO) +<procedure>(subu8vector U8VECTOR FROM TO)</procedure><br> +<procedure>(subu16vector U16VECTOR FROM TO)</procedure><br> +<procedure>(subu32vector U32VECTOR FROM TO)</procedure><br> +<procedure>(subs8vector S8VECTOR FROM TO)</procedure><br> +<procedure>(subs16vector S16VECTOR FROM TO)</procedure><br> +<procedure>(subs32vector S32VECTOR FROM TO)</procedure><br> +<procedure>(subf32vector F32VECTOR FROM TO)</procedure><br> +<procedure>(subf64vector F64VECTOR FROM TO)</procedure> Creates a number vector of the same type as the argument vector with the elements at the positions {{FROM}} up to but not including {{TO}}. @@ -130,7 +130,7 @@ SRFI-17 Setters for {{XXXvector-ref}} are defined. === read-u8vector - [procedure] (read-u8vector LENGTH [PORT]) +<procedure>(read-u8vector LENGTH [PORT])</procedure> Reads {{LENGTH}} bytes from the {{PORT}} and returns a fresh {{u8vector}} or less if end-of-file is encountered. {{PORT}} defaults to the @@ -140,7 +140,7 @@ If {{LENGTH}} is {{#f}}, the vector will be filled completely until end-of-file === read-u8vector! - [procedure] (read-u8vector! LENGTH U8VECTOR [PORT [START]]) +<procedure>(read-u8vector! LENGTH U8VECTOR [PORT [START]])</procedure> Reads {{LENGTH}} bytes from the {{PORT}} writing the read input into {{U8VECTOR}} beginning at {{START}} (or 0 if not given). {{PORT}} defaults @@ -151,7 +151,7 @@ This procedure returns the number of bytes read. === write-u8vector - [procedure] (write-u8vector U8VECTOR [PORT [START [END]]]) +<procedure>(write-u8vector U8VECTOR [PORT [START [END]]])</procedure> Writes the bytes {{U8VECTOR}} between the indices {{START}} (inclusive) and {{END}} (exclusive) to {{PORT}}. {{PORT}} defaults to the value of {{(current-output-port)}}. diff --git a/manual/Unit srfi-69 b/manual/Unit srfi-69 index c215ee30..a584af57 100644 --- a/manual/Unit srfi-69 +++ b/manual/Unit srfi-69 @@ -13,7 +13,7 @@ CHICKEN implements SRFI 69 with SRFI 90 extensions. For more information, see ==== make-hash-table - [procedure] (make-hash-table [TEST HASH SIZE] [#:test TEST] [#:hash HASH] [#:size SIZE] [#:initial INITIAL] [#:min-load MIN-LOAD] [#:max-load MAX-LOAD] [#:weak-keys WEAK-KEYS] [#:weak-values WEAK-VALUES]) +<procedure>(make-hash-table [TEST HASH SIZE] [#:test TEST] [#:hash HASH] [#:size SIZE] [#:initial INITIAL] [#:min-load MIN-LOAD] [#:max-load MAX-LOAD] [#:weak-keys WEAK-KEYS] [#:weak-values WEAK-VALUES])</procedure> Returns a new {{HASH-TABLE}} with the supplied configuration. @@ -29,7 +29,7 @@ Returns a new {{HASH-TABLE}} with the supplied configuration. ==== alist->hash-table - [procedure] (alist->hash-table A-LIST [#:test TEST] [#:hash HASH] [#:size SIZE] [#:initial INITIAL] [#:min-load MIN-LOAD] [#:max-load MAX-LOAD] [#:weak-keys WEAK-KEYS] [#:weak-values WEAK-VALUES]) +<procedure>(alist->hash-table A-LIST [#:test TEST] [#:hash HASH] [#:size SIZE] [#:initial INITIAL] [#:min-load MIN-LOAD] [#:max-load MAX-LOAD] [#:weak-keys WEAK-KEYS] [#:weak-values WEAK-VALUES])</procedure> Returns a new {{HASH-TABLE}}. The {{HASH-TABLE}} is populated from the {{A-LIST}}. The keyword arguments are per {{make-hash-table}}. @@ -37,91 +37,91 @@ Returns a new {{HASH-TABLE}}. The {{HASH-TABLE}} is populated from the ==== hash-table? - [procedure] (hash-table? OBJECT) +<procedure>(hash-table? OBJECT)</procedure> Is the {{OBJECT}} a {{hash-table}}? ==== hash-table-size - [procedure] (hash-table-size HASH-TABLE) +<procedure>(hash-table-size HASH-TABLE)</procedure> The {{HASH-TABLE}} size. ==== hash-table-equivalence-function - [procedure] (hash-table-equivalence-function HASH-TABLE) +<procedure>(hash-table-equivalence-function HASH-TABLE)</procedure> The {{HASH-TABLE}} {{equivalence-function}}. ==== hash-table-hash-function - [procedure] (hash-table-hash-function HASH-TABLE) +<procedure>(hash-table-hash-function HASH-TABLE)</procedure> The {{HASH-TABLE}} {{hash-function}}. ==== hash-table-min-load - [procedure] (hash-table-min-load HASH-TABLE) +<procedure>(hash-table-min-load HASH-TABLE)</procedure> The {{HASH-TABLE}} minimum load factor. ==== hash-table-max-load - [procedure] (hash-table-max-load HASH-TABLE) +<procedure>(hash-table-max-load HASH-TABLE)</procedure> The {{HASH-TABLE}} maximum load factor. ==== hash-table-weak-keys - [procedure] (hash-table-weak-keys HASH-TABLE) +<procedure>(hash-table-weak-keys HASH-TABLE)</procedure> Does the {{HASH-TABLE}} weak references for keys? ==== hash-table-weak-values - [procedure] (hash-table-weak-values HASH-TABLE) +<procedure>(hash-table-weak-values HASH-TABLE)</procedure> Does the {{HASH-TABLE}} weak references for values? ==== hash-table-has-initial? - [procedure] (hash-table-has-initial? HASH-TABLE) +<procedure>(hash-table-has-initial? HASH-TABLE)</procedure> Does the {{HASH-TABLE}} have a default initial value? ==== hash-table-initial - [procedure] (hash-table-initial HASH-TABLE) +<procedure>(hash-table-initial HASH-TABLE)</procedure> The {{HASH-TABLE}} default initial value. ==== hash-table-keys - [procedure] (hash-table-keys HASH-TABLE) +<procedure>(hash-table-keys HASH-TABLE)</procedure> Returns a list of the keys in the {{HASH-TABLE}} population. ==== hash-table-values - [procedure] (hash-table-values HASH-TABLE) +<procedure>(hash-table-values HASH-TABLE)</procedure> Returns a list of the values in the {{HASH-TABLE}} population. ==== hash-table->alist - [procedure] (hash-table->alist HASH-TABLE) +<procedure>(hash-table->alist HASH-TABLE)</procedure> Returns the population of the {{HASH-TABLE}} as an {{a-list}}. @@ -129,7 +129,7 @@ Returns the population of the {{HASH-TABLE}} as an {{a-list}}. ==== hash-table-ref - [procedure] (hash-table-ref HASH-TABLE KEY) +<procedure>(hash-table-ref HASH-TABLE KEY)</procedure> Returns the {{VALUE}} for the {{KEY}} in the {{HASH-TABLE}}. @@ -138,7 +138,7 @@ Aborts with an exception when the {{KEY}} is missing. ==== hash-table-ref/default - [procedure] (hash-table-ref/default HASH-TABLE KEY DEFAULT) +<procedure>(hash-table-ref/default HASH-TABLE KEY DEFAULT)</procedure> Returns the {{VALUE}} for the {{KEY}} in the {{HASH-TABLE}}, or the {{DEFAULT}} when the {{KEY}} is missing. @@ -146,14 +146,14 @@ when the {{KEY}} is missing. ==== hash-table-exists? - [procedure] (hash-table-exists? HASH-TABLE KEY) +<procedure>(hash-table-exists? HASH-TABLE KEY)</procedure> Does the {{KEY}} exist in the {{HASH-TABLE}}? ==== hash-table-set! - [procedure] (hash-table-set! HASH-TABLE KEY VALUE) +<procedure>(hash-table-set! HASH-TABLE KEY VALUE)</procedure> Set the {{VALUE}} for the {{KEY}} in the {{HASH-TABLE}}. @@ -172,7 +172,7 @@ is equivalent to ==== hash-table-update! - [procedure] (hash-table-update! HASH-TABLE KEY [UPDATE-FUNCTION [DEFAULT-VALUE-FUNCTION]]) +<procedure>(hash-table-update! HASH-TABLE KEY [UPDATE-FUNCTION [DEFAULT-VALUE-FUNCTION]])</procedure> Sets or replaces the {{VALUE}} for {{KEY}} in the {{HASH-TABLE}}. @@ -188,7 +188,7 @@ Returns the new {{VALUE}}. ==== hash-table-update!/default - [procedure] (hash-table-update! HASH-TABLE KEY UPDATE-FUNCTION DEFAULT-VALUE) +<procedure>(hash-table-update!/default HASH-TABLE KEY UPDATE-FUNCTION DEFAULT-VALUE)</procedure> Sets or replaces the {{VALUE}} for {{KEY}} in the {{HASH-TABLE}}. @@ -202,21 +202,21 @@ Returns the new {{VALUE}}. ==== hash-table-copy - [procededure] (hash-table-copy HASH-TABLE) +<procedure>(hash-table-copy HASH-TABLE)</procedure> Returns a shallow copy of the {{HASH-TABLE}}. ==== hash-table-delete! - [procedure] (hash-table-delete! HASH-TABLE KEY) +<procedure>(hash-table-delete! HASH-TABLE KEY)</procedure> Deletes the entry for {{KEY}} in the {{HASH-TABLE}}. ==== hash-table-remove! - [procedure] (hash-table-remove! HASH-TABLE PROC) +<procedure>(hash-table-remove! HASH-TABLE PROC)</procedure> Calls {{PROC}} for all entries in {{HASH-TABLE}} with the key and value of each entry. If {{PROC}} returns true, then that entry is removed. @@ -224,14 +224,14 @@ entry. If {{PROC}} returns true, then that entry is removed. ==== hash-table-clear! - [procedure] (hash-table-clear! HASH-TABLE) +<procedure>(hash-table-clear! HASH-TABLE)</procedure> Deletes all entries in {{HASH-TABLE}}. ==== hash-table-merge - [procedure] (hash-table-merge HASH-TABLE-1 HASH-TABLE-2) +<procedure>(hash-table-merge HASH-TABLE-1 HASH-TABLE-2)</procedure> Returns a new {{HASH-TABLE}} with the union of {{HASH-TABLE-1}} and {{HASH-TABLE-2}}. @@ -239,7 +239,7 @@ Returns a new {{HASH-TABLE}} with the union of {{HASH-TABLE-1}} and ==== hash-table-merge! - [procedure] (hash-table-merge! HASH-TABLE-1 HASH-TABLE-2) +<procedure>(hash-table-merge! HASH-TABLE-1 HASH-TABLE-2)</procedure> Returns {{HASH-TABLE-1}} as the union of {{HASH-TABLE-1}} and {{HASH-TABLE-2}}. @@ -247,7 +247,7 @@ Returns {{HASH-TABLE-1}} as the union of {{HASH-TABLE-1}} and ==== hash-table-map - [procedure] (hash-table-map HASH-TABLE FUNC) +<procedure>(hash-table-map HASH-TABLE FUNC)</procedure> Calls {{FUNC}} for all entries in {{HASH-TABLE}} with the key and value of each entry. @@ -257,7 +257,7 @@ Returns a list of the results of each call. ==== hash-table-fold - [procedure] (hash-table-fold HASH-TABLE FUNC INIT) +<procedure>(hash-table-fold HASH-TABLE FUNC INIT)</procedure> Calls {{FUNC}} for all entries in {{HASH-TABLE}} with the key and value of each entry, and the current folded value. The initial folded value is {{INIT}}. @@ -267,7 +267,7 @@ Returns the final folded value. ==== hash-table-for-each - [procedure] (hash-table-for-each HASH-TABLE PROC) +<procedure>(hash-table-for-each HASH-TABLE PROC)</procedure> Calls {{PROC}} for all entries in {{HASH-TABLE}} with the key and value of each entry. @@ -275,7 +275,7 @@ entry. ==== hash-table-walk - [procedure] (hash-table-walk HASH-TABLE PROC) +<procedure>(hash-table-walk HASH-TABLE PROC)</procedure> Calls {{PROC}} for all entries in {{HASH-TABLE}} with the key and value of each entry. @@ -288,35 +288,35 @@ All hash functions return a {{fixnum}} in the range [0 {{BOUND}}). ==== number-hash - [procedure] (number-hash NUMBER [BOUND]) +<procedure>(number-hash NUMBER [BOUND])</procedure> For use with {{=}} as a {{hash-table-equivalence-function}}. ==== object-uid-hash - [procedure] (object-uid-hash OBJECT [BOUND]) +<procedure>(object-uid-hash OBJECT [BOUND])</procedure> Currently a synonym for {{equal?-hash}}. ==== symbol-hash - [procedure] (symbol-hash SYMBOL [BOUND]) +<procedure>(symbol-hash SYMBOL [BOUND])</procedure> For use with {{eq?}} as a {{hash-table-equivalence-function}}. ==== keyword-hash - [procedure] (keyword-hash KEYWORD [BOUND]) +<procedure>(keyword-hash KEYWORD [BOUND])</procedure> For use with {{eq?}} as a {{hash-table-equivalence-function}}. ==== string-hash - [procedure] (string-hash STRING [BOUND START END]) +<procedure>(string-hash STRING [BOUND START END])</procedure> For use with {{string=?}} as a {{hash-table-equivalence-function}}. The optional {{START}} and {{END}} arguments may be given to limit @@ -325,43 +325,43 @@ the hash calculation to a specific sub-section of {{STRING}}. ==== string-ci-hash - [procedure] (string-hash-ci STRING [BOUND START END]) - [procedure] (string-ci-hash STRING [BOUND START END]) +<procedure>(string-hash-ci STRING [BOUND START END])</procedure><br> +<procedure>(string-ci-hash STRING [BOUND START END])</procedure> For use with {{string-ci=?}} as a {{hash-table-equivalence-function}}. ==== eq?-hash - [procedure] (eq?-hash OBJECT [BOUND]) +<procedure>(eq?-hash OBJECT [BOUND])</procedure> For use with {{eq?}} as a {{hash-table-equivalence-function}}. ==== eqv?-hash - [procedure] (eqv?-hash OBJECT [BOUND]) +<procedure>(eqv?-hash OBJECT [BOUND])</procedure> For use with {{eqv?}} as a {{hash-table-equivalence-function}}. ==== equal?-hash - [procedure] (equal?-hash OBJECT [BOUND]) +<procedure>(equal?-hash OBJECT [BOUND])</procedure> For use with {{equal?}} as a {{hash-table-equivalence-function}}. ==== hash - [procedure] (hash OBJECT [BOUND]) +<procedure>(hash OBJECT [BOUND])</procedure> Synonym for {{equal?-hash}}. ==== hash-by-identity - [procedure] (hash-by-identity OBJECT [BOUND]) +<procedure>(hash-by-identity OBJECT [BOUND])</procedure> Synonym for {{eq?-hash}}. diff --git a/manual/Unit tcp b/manual/Unit tcp index f4ec584d..cb6bfd31 100644 --- a/manual/Unit tcp +++ b/manual/Unit tcp @@ -129,7 +129,7 @@ without breaking the connection. === tcp-buffer-size - [parameter] tcp-buffer-size +<parameter>tcp-buffer-size</parameter> Sets the size of the output buffer. By default no output-buffering for TCP output is done, but to improve performance by minimizing the @@ -145,7 +145,7 @@ Closing the output port will flush automatically. === tcp-read-timeout - [parameter] tcp-read-timeout +<parameter>tcp-read-timeout</parameter> Determines the timeout for TCP read operations in milliseconds. A timeout of {{#f}} disables timeout checking. The default read timeout is 60000, i.e. @@ -155,7 +155,7 @@ is thrown. === tcp-write-timeout - [parameter] tcp-write-timeout +<parameter>tcp-write-timeout</parameter> Determines the timeout for TCP write operations in milliseconds. A timeout of {{#f}} disables timeout checking. The default write timeout is 60000, i.e. @@ -165,7 +165,7 @@ is thrown. === tcp-connect-timeout - [parameter] tcp-connect-timeout +<parameter>tcp-connect-timeout</parameter> Determines the timeout for {{tcp-connect}} operations in milliseconds. A timeout of {{#f}} disables timeout checking and is the default. @@ -175,7 +175,7 @@ is thrown. === tcp-accept-timeout - [parameter] tcp-accept-timeout +<parameter>tcp-accept-timeout</parameter> Determines the timeout for {{tcp-accept}} operations in milliseconds. A timeout of {{#f}} disables timeout checking and is the default. diff --git a/manual/Unit utils b/manual/Unit utils index 8e5b88e4..f7622b93 100644 --- a/manual/Unit utils +++ b/manual/Unit utils @@ -15,7 +15,7 @@ This unit uses the {{extras}} and {{srfi-13}} units. ==== system* - [procedure] (system* FORMATSTRING ARGUMENT1 ...) +<procedure>(system* FORMATSTRING ARGUMENT1 ...)</procedure> Similar to {{(system (sprintf FORMATSTRING ARGUMENT1 ...))}}, but signals an error if the invoked program should return a nonzero @@ -25,7 +25,7 @@ exit status. ==== read-all - [procedure] (read-all [FILE-OR-PORT]) +<procedure>(read-all [FILE-OR-PORT])</procedure> If {{FILE-OR-PORT}} is a string, then this procedure returns the contents of the file as a string. If {{FILE-OR-PORT}} is a port, all remaining input is read and returned as @@ -37,7 +37,7 @@ port that is the current value of {{(current-input-port)}}. ==== qs - [procedure] (qs STRING [PLATFORM]) +<procedure>(qs STRING [PLATFORM])</procedure> Escapes {{STRING}} suitably for passing to a shell command on {{PLATFORM}}. {{PLATFORM}} defaults to the value of {{(build-platform)}} and indicates in diff --git a/manual/Using the interpreter b/manual/Using the interpreter index 04c09dcb..fec1ab56 100644 --- a/manual/Using the interpreter +++ b/manual/Using the interpreter @@ -156,7 +156,7 @@ procedure: === toplevel-command - [procedure] (toplevel-command SYMBOL PROC [HELPSTRING]) +<procedure>(toplevel-command SYMBOL PROC [HELPSTRING])</procedure> Defines or redefines a toplevel interpreter command which can be invoked by entering {{,SYMBOL}}. {{PROC}} will be invoked when the command is entered and may @@ -174,7 +174,7 @@ Note that the value returned is implicitly quoted. === set-describer! - [procedure] (set-describer! TAG PROC) +<procedure>(set-describer! TAG PROC)</procedure> Sets a custom description handler that invokes {{PROC}} when the {{,d}} command is invoked with a record-type object that has the type {{TAG}} (a symbol). {{PROC}} is called withTrap