~ chicken-core (chicken-5) b095c04336eb10b4c12c2fb37953d649312a4798
commit b095c04336eb10b4c12c2fb37953d649312a4798 Author: Peter Bex <peter@more-magic.net> AuthorDate: Sat Jun 9 19:44:02 2018 +0200 Commit: Peter Bex <peter@more-magic.net> CommitDate: Sat Jun 9 19:45:42 2018 +0200 Update manual manifest diff --git a/distribution/manifest b/distribution/manifest index 46ee5989..5a8fdfd7 100644 --- a/distribution/manifest +++ b/distribution/manifest @@ -385,10 +385,8 @@ scripts/make-wrapper.scm scripts/makedist.scm manual-html/Accessing external objects.html manual-html/Acknowledgements.html -manual-html/Basic mode of operation.html manual-html/Bibliography.html manual-html/Bugs and limitations.html -manual-html/Callbacks.html manual-html/C interface.html manual-html/Cross development.html manual-html/Data representation.html @@ -398,7 +396,6 @@ manual-html/Deployment.html manual-html/Deviations from the standard.html manual-html/Egg specification format.html manual-html/Embedding.html -manual-html/Exceptions.html manual-html/Extensions.html manual-html/Extensions to the standard.html manual-html/Extension tools.html @@ -406,8 +403,6 @@ manual-html/Foreign type specifiers.html manual-html/Getting started.html manual-html/Included modules.html manual-html/Interface to external functions and variables.html -manual-html/Locations.html -manual-html/Macros.html manual-html/manual.css manual-html/Module (chicken base).html manual-html/Module (chicken bitwise).html @@ -455,29 +450,8 @@ manual-html/Module r5rs.html manual-html/Module scheme.html manual-html/Modules.html manual-html/Module srfi-4.html -manual-html/Non-standard macros and special forms.html -manual-html/Non-standard read syntax.html -manual-html/Other support procedures.html -manual-html/Parameters.html -manual-html/Supported language.html -manual-html/The R5RS standard.html manual-html/The User's Manual.html manual-html/Types.html -manual-html/Unit continuation.html -manual-html/Unit data-structures.html -manual-html/Unit eval.html -manual-html/Unit expand.html -manual-html/Unit extras.html -manual-html/Unit files.html -manual-html/Unit irregex.html -manual-html/Unit library.html -manual-html/Unit lolevel.html -manual-html/Unit ports.html -manual-html/Unit posix.html -manual-html/Unit read-syntax.html -manual-html/Unit repl.html manual-html/Units and linking model.html -manual-html/Unit srfi-4.html -manual-html/Unit tcp.html manual-html/Using the compiler.html manual-html/Using the interpreter.html diff --git a/manual/Basic mode of operation b/manual/Basic mode of operation deleted file mode 100644 index 32332257..00000000 --- a/manual/Basic mode of operation +++ /dev/null @@ -1,59 +0,0 @@ -[[tags: manual]] - -== Basic mode of operation - -The compiler translates Scheme source code into fairly portable C that -can be compiled and linked with most available C compilers. CHICKEN supports -the generation of executables and libraries, linked either statically or -dynamically. Compiled Scheme code can be loaded dynamically, or can be -embedded in applications written in other languages. Separate compilation -of modules is fully supported. - -The most portable way of creating separately linkable entities is -supported by so-called ''unit''s. A unit is a single -compiled object module that contains a number of toplevel expressions that -are executed either when the unit is the ''main'' unit or if the -unit is ''used''. To use a unit, the unit has to be ''declare''d -as used, like this: - -<enscript highlight=scheme> -(declare (uses UNITNAME)) -</enscript> - -The toplevel expressions of used units are executed in the order in -which the units appear in the {{uses}} declaration. Units -may be used multiple times and {{uses}} declarations may -be circular (the unit is initialized at most once). To compile a file -as a unit, add a {{unit}} declaration: - -<enscript highlight=scheme> -(declare (unit UNITNAME)) -</enscript> - -When compiling different object modules, make sure to have one main -unit. This unit is called initially and initializes all used units -before executing its toplevel expressions. The main-unit has no -{{unit}} declaration. - -Another method of using definitions in separate source files is to -''include'' them. This simply inserts the code in a given file into -the current file: - -<enscript highlight=scheme> -(include "FILENAME") -</enscript> - -Macro definitions are only available when processed by {{include}} or -{{import}}. Macro definitions in separate units are not available, -since they are defined at compile time, i.e the time when that other -unit was compiled (macros can optionally be available at runtime, see -{{define-syntax}} in [[Non-standard macros and special forms|Substitution forms and macros]]). - -On platforms that support dynamic loading of compiled code (Windows, most ELF based -systems like Linux or BSD, MacOS X, and others) code can be compiled into a shared object {{.dll}}, {{.so}}, {{.dylib}}) and loaded -dynamically into a running application. - ---- -Previous: [[Getting started]] - -Next: [[Using the compiler]] diff --git a/manual/Callbacks b/manual/Callbacks deleted file mode 100644 index de53a8d3..00000000 --- a/manual/Callbacks +++ /dev/null @@ -1,100 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Callbacks - - -To enable an external C function to call back to Scheme, the form -{{foreign-safe-lambda}} (or {{foreign-safe-lambda*}}) -has to be used. This generates special code to save and restore important -state information during execution of C code. There are two ways of -calling Scheme procedures from C: the first is to invoke the runtime -function {{C_callback}} with the closure to be called and the number -of arguments. The second is to define an externally visible wrapper -function around a Scheme procedure with the {{define-external}} -form. - -Note: the names of all functions, variables and macros exported by the -CHICKEN runtime system start with {{C_}}. It is advisable to -use a different naming scheme for your own code to avoid name clashes. -Callbacks (defined by {{define-external}}) -do not capture the lexical environment. - -Non-local exits leaving the scope of the invocation of a callback from Scheme into C -will not remove the C call-frame from the stack (and will result in a memory -leak). '''Note:''' The same applies to -SRFI-18 threading, which is implemented with {{call/cc}}; -additionally, if you enter one callback, switch threads and then exit -a different callback, your program is likely to crash. - - -=== define-external - -<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 -string, represents a legal C identifier. {{ARGUMENTTYPE1 ...}} and -{{RETURNTYPE}} are foreign type specifiers for the argument variables -{{VAR1 ...}} and the result, respectively. {{QUALIFIERS}} -is an optional qualifier for the foreign procedure definition, like -{{__stdcall}}. - -<enscript highlight=scheme> -(define-external (foo (c-string x)) int (string-length x)) -</enscript> - -The second form of {{define-external}} can be used to define -variables that are accessible from foreign code. It declares -a global variable named by the symbol {{NAME}} that -has the type {{TYPE}}. {{INIT}} can be an arbitrary -expression that is used to initialize the variable. {{NAME}} is -accessible from Scheme just like any other foreign variable defined by -{{define-foreign-variable}}. - -<enscript highlight=scheme> -(define-external foo int 42) -((foreign-lambda* int () - "C_return(foo);")) ==> 42 -</enscript> - -'''Note:''' don't be tempted to -assign strings or bytevectors to external variables. Garbage collection -moves those objects around, so it is a very bad idea to assign pointers -to heap-data. If you have to do so, then copy the data object into -statically allocated memory (for example by using {{object-evict}}). - -Results of type {{scheme-object}} returned by {{define-external}} -are always allocated in the secondary heap, that is, not in the stack. - -=== C_callback - - [C function] C_word C_callback (C_word closure, int argc) - -This function can be used to invoke the Scheme procedure {{closure}}. -{{argc}} should contain the number of arguments that are passed to -the procedure on the temporary stack. Values are put onto the temporary -stack with the {{C_save}} macro. - -=== C_callback_adjust_stack - - [C function] void C_callback_adjust_stack (C_word *ptr, int size) - -The runtime-system uses the stack as a special allocation area and -internally holds pointers to estimated limits to distinguish between -Scheme data objects inside the stack from objects outside of it. If -you invoke callbacks at wildly differing stack-levels, these limits -may shift from invocation to invocation. Callbacks defined with -{{define-external}} will perform appropriate adjustments -automatically, but if you invoke {{C_callback}} manually, you should -perform a {{C_callback_adjust_stack}} to make sure the internal limits -are set properly. {{ptr}} should point to some data object on the -stack and {{size}} is the number of words contained in the data object -(or some estimate). The call will make sure the limits are adjusted so -that the value pointed to by {{ptr}} is located in the stack. - ---- -Previous: [[Embedding]] - -Next: [[Locations]] diff --git a/manual/Exceptions b/manual/Exceptions deleted file mode 100644 index d8022633..00000000 --- a/manual/Exceptions +++ /dev/null @@ -1,383 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Exceptions - -CHICKEN's exception handling is based on the -[[http://srfi.schemers.org/srfi-12/srfi-12.html|SRFI-12]] exception -system. This document contains the core of the SRFI-12 spec -as well as CHICKEN implementation specifics. - -== CHICKEN implementation - -=== System conditions - -All error-conditions signaled by the system are of kind {{exn}}. -The following composite conditions are additionally defined: - -<table> - -<tr><td> (exn arity) </td><td> - -Signaled when a procedure is called with the wrong number of arguments. - -</td></tr><tr><td> (exn type) </td><td> - -Signaled on type-mismatch errors, for example when an argument of the wrong -type is passed to a built-in procedure. - -</td></tr><tr><td> (exn arithmetic) </td><td> - -Signaled on arithmetic errors, like division by zero. - -</td></tr><tr><td> (exn i/o) </td><td> - -Signaled on input/output errors. - -</td></tr><tr><td> (exn i/o file) </td><td> - -Signaled on file-related errors. - -</td></tr><tr><td> (exn i/o net) </td><td> - -Signaled on network errors. - -</td></tr><tr><td> (exn bounds) </td><td> - -Signaled on errors caused by accessing non-existent elements of a collection. - -</td></tr><tr><td> (exn runtime) </td><td> - -Signaled on low-level runtime-system error-situations. - -</td></tr><tr><td> (exn runtime limit) </td><td> - -Signaled when an internal limit is exceeded (like running out of memory). - -</td></tr><tr><td> (exn match) </td><td> - -Signaled on errors raised by failed matches (see the section on {{match}}). - -</td></tr><tr><td> (exn syntax) </td><td> - -Signaled on syntax errors. - -</td></tr> - -</table> - -=== Notes - -* All error-exceptions (of the kind {{exn}}) are non-continuable. - -* Error-exceptions of the {{exn}} kind have additional {{arguments}} and -{{location}} properties that contain the arguments passed to the -exception-handler and the name of the procedure where the error occurred (if -available). - -* When the {{posix}} unit is available and used, then a user-interrupt -({{signal/int}}) signals an exception of the kind {{user-interrupt}}. - -* The procedure {{condition-property-accessor}} accepts an optional third -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. - -* On platforms that support the {{sigprocmask(3)}} POSIX API function, -the signals {{SIGSEGV}}, {{SIGFPE}}, {{SIGBUS}} and {{SIGILL}} will be -caught and trigger an exception instead of aborting the process, if -possible. If the unwinding and handling of the signal raises one of -these signals once again, the process will abort with an error -message. - -=== Additional API - -<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: - - CLAUSE = ([VARIABLE] (KIND ...) BODY ...) - -If provided, {{VARIABLE}} will be bound to the signaled exception -object. {{BODY ...}} is executed when the exception is a property- -or composite condition with the kinds given {{KIND ...}} (unevaluated). -If no clause applies, the exception is re-signaled in the same dynamic -context as the {{condition-case}} form. - -<enscript highlight=scheme> -(define (check thunk) - (condition-case (thunk) - [(exn file) (print "file error")] - [(exn) (print "other error")] - [var () (print "something else")] ) ) - -(check (lambda () (open-input-file ""))) ; -> "file error" -(check (lambda () some-unbound-variable)) ; -> "othererror" -(check (lambda () (signal 99))) ; -> "something else" - -(condition-case some-unbound-variable - ((exn file) (print "ignored")) ) ; -> signals error -</enscript> - -<procedure>(get-condition-property CONDITION KIND PROPERTY [DEFAULT])</procedure> - -A slightly more convenient condition property accessor, equivalent to - - ((condition-property-accessor KIND PROPERTY [DEFAULT]) CONDITION) - - -<procedure>(condition->list CONDITION)</procedure> - -This procedure converts a condition object into a list holding all the -conditions that are represented by the ''CONDITION'' object. It is -formatted as follows: - - ((KIND1 (PROPERTY1 VALUE1) (PROPERTY2 VALUE2) ...) (KIND2 ... ) ... ) - -There is no guaranteed order within the list. - -{{condition->list}} was introduced in CHICKEN 4.7.0. - -== SRFI-12 specification - -A Scheme implementation ("the system") raises an exception whenever an -error is to be signaled or whenever the system determines that evaluation -cannot proceed in a manner consistent with the semantics of Scheme. A -program may also explicitly raise an exception. - -Whenever the system raises an exception, it invokes the current exception -handler with a condition object (encapsulating information about the -exception) as its only argument. Any procedure accepting one argument -may serve as an exception handler. When a program explicitly raises an -exception, it may supply any object to the exception handler. - -An exception is either continuable or non-continuable. When the current -exception handler is invoked for a continuable exception, the continuation -uses the handler's result(s) in an exception-specific way to continue. -When an exception handler is invoked for a non-continuable exception, -the continuation raises a non-continuable exception indicating that the -exception handler returned. On CHICKEN, system error exceptions -(of kind {{exn}}) are non-continuable. - -=== Exception Handlers - -<parameter>(current-exception-handler [PROCEDURE])</parameter><br> - -Sets or returns the current exception handler, a procedure of one -argument, the exception object. - -<procedure>(with-exception-handler handler thunk)</procedure><br> - -Returns the result(s) of invoking ''thunk''. The ''handler'' procedure -is installed as the current exception handler in the dynamic context of -invoking ''thunk''. - -Example: - -<enscript highlight=scheme> -(call-with-current-continuation - (lambda (k) - (with-exception-handler (lambda (x) (k '())) - (lambda () (car '()))))) -;=> '() -</enscript> - -Note that the handler procedure must somehow return non-locally out of -the dynamic extent of the {{with-exception-handler}} form, because -returning normally will signal yet another exception and thus result -in non-termination. - -<macro>(handle-exceptions var handle-expr expr1 expr2 ...)</macro><br> - -Evaluates the body expressions ''expr1'', ''expr2'', ... in sequence with -an exception handler constructed from ''var'' and ''handle-expr''. Assuming -no exception is raised, the result(s) of the last body expression is(are) -the result(s) of the {{handle-exceptions}} expression. - -The exception handler created by {{handle-exceptions}} restores the dynamic -context (continuation, exception handler, etc.) of the {{handle-exceptions}} -expression, and then evaluates ''handle-expr'' with ''var'' bound to the -value provided to the handler. - -Examples: - -<enscript highlight=scheme> -(handle-exceptions exn - (begin - (display "Went wrong") - (newline)) - (car '())) -; displays "Went wrong" - -(handle-exceptions exn - (cond - ((eq? exn 'one) 1) - (else (abort exn))) - (case (random 3) - [(0) 'zero] - [(1) (abort 'one)] - [else (abort "Something else")])) -;=> 'zero, 1, or (abort "Something else") -</enscript> - -=== Raising Exceptions - -<procedure>(abort obj)</procedure><br> - -Raises a non-continuable exception represented by ''obj''. The {{abort}} -procedure can be implemented as follows: - -<enscript highlight=scheme> -(define (abort obj) - ((current-exception-handler) obj) - (abort (make-property-condition - 'exn - 'message - "Exception handler returned"))) -</enscript> - -The {{abort}} procedure does not ensure that its argument is a condition. -If its argument is a condition, {{abort}} does not ensure that the condition -indicates a non-continuable exception. - -<procedure>(signal obj)</procedure><br> - -Raises a continuable exception represented by ''obj''. The {{signal}} procedure -can be implemented as follows: - -<enscript highlight=scheme> -(define (signal exn) - ((current-exception-handler) exn)) -</enscript> - -The {{signal}} procedure does not ensure that its argument is a condition. -If its argument is a condition, {{signal}} does not ensure that the condition -indicates a continuable exception. - -=== Condition Objects - -<procedure>(condition? obj)</procedure><br> - -Returns #t if ''obj'' is a condition, otherwise returns #f. If any of -the predicates listed in Section 3.2 of the R5RS is true of ''obj'', then -{{condition?}} is false of ''obj''. - -Rationale: Any Scheme object may be passed to an exception handler. This -would cause ambiguity if conditions were not disjoint from all of Scheme's -standard types. - -<procedure>(make-property-condition kind-key prop-key value ...)</procedure><br> - -This procedure accepts any even number of arguments after ''kind-key'', -which are regarded as a sequence of alternating ''prop-key'' and ''value'' -objects. Each ''prop-key'' is regarded as the name of a property, and -each ''value'' is regarded as the value associated with the ''key'' that -precedes it. Returns a ''kind-key'' condition that associates the given -''prop-key''s with the given ''value''s. - -<procedure>(make-composite-condition condition ...)</procedure><br> - -Returns a newly-allocated condition whose components correspond to the the -given ''condition''s. A predicate created by {{condition-predicate}} returns -true for the new condition if and only if it returns true for one or more -of its component conditions. - -<procedure>(condition-predicate kind-key)</procedure><br> - -Returns a predicate that can be called with any object as its argument. -Given a condition that was created by {{make-property-condition}}, the -predicate returns #t if and only if ''kind-key'' is EQV? to the kind key -that was passed to {{make-property-condition}}. Given a composite condition -created with {{make-composite-condition}}, the predicate returns #t if and only -if the predicate returns #t for at least one of its components. - -<procedure>(condition-property-accessor kind-key prop-key [default])</procedure><br> - -Returns a procedure that can be called with any condition that satisfies -{{(condition-predicate ''kind-key'')}}. Given a condition that was created -by {{make-property-condition}} and ''kind-key'', the procedure returns the -value that is associated with ''prop-key''. Given a composite condition -created with {{make-composite-condition}}, the procedure returns the value that -is associated with ''prop-key'' in one of the components that satisfies -{{(condition-predicate ''kind-key'')}}. - -On CHICKEN, this procedure accepts an optional third argument -DEFAULT. 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. - -When the system raises an exception, the condition it passes to the -exception handler includes the {{'exn}} kind with the following -properties: - -; message : the error message -; arguments: the arguments passed to the exception handler -; location: the name of the procedure where the error occurred (if available) - -Thus, if ''exn'' is a condition representing a system exception, -then - -<enscript highlight=scheme> - ((condition-property-accessor 'exn 'message) exn) -</enscript> - -extracts the error message from ''exn''. Example: - -<enscript highlight=scheme> -(handle-exceptions exn - (begin - (display "Went wrong: ") - (display - ((condition-property-accessor 'exn 'message) exn)) - (newline)) - (car '())) -; displays something like "Went wrong: can't take car of nil" -</enscript> - -=== More Examples - -<enscript highlight=scheme> -(define (try-car v) - (let ((orig (current-exception-handler))) - (with-exception-handler - (lambda (exn) - (orig (make-composite-condition - (make-property-condition - 'not-a-pair - 'value - v) - exn))) - (lambda () (car v))))) - -(try-car '(1)) -;=> 1 - -(handle-exceptions exn - (if ((condition-predicate 'not-a-pair) exn) - (begin - (display "Not a pair: ") - (display - ((condition-property-accessor 'not-a-pair 'value) exn)) - (newline)) - (abort exn)) - (try-car 0)) -; displays "Not a pair: 0" - -(let* ((cs-key (list 'color-scheme)) - (bg-key (list 'background)) - (color-scheme? (condition-predicate cs-key)) - (color-scheme-background - (condition-property-accessor cs-key bg-key)) - (condition1 (make-property-condition cs-key bg-key 'green)) - (condition2 (make-property-condition cs-key bg-key 'blue)) - (condition3 (make-composite-condition condition1 condition2))) - (and (color-scheme? condition1) - (color-scheme? condition2) - (color-scheme? condition3) - (color-scheme-background condition3))) -; => 'green or 'blue -</enscript> - ----- -Previous: [[Parameters]] Next: [[Unit library]] \ No newline at end of file diff --git a/manual/Locations b/manual/Locations deleted file mode 100644 index 0ac54caa..00000000 --- a/manual/Locations +++ /dev/null @@ -1,83 +0,0 @@ -[[tags: manual]] - -[[toc:]] - - -== Locations - -It is also possible to define variables containing unboxed C data, -so called ''locations''. It should be noted that locations may -only contain simple data, that is: everything that fits into a -machine word, and double-precision floating point values. - - - -=== define-location - -<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 -declared {{static}}). - -=== let-location - -<macro>(let-location ((NAME TYPE [INIT]) ...) BODY ...)</macro> - -Defines a lexically bound location. - -=== location - -<macro>(location NAME)</macro><br> -<macro>(location X)</macro> -<read>#$</read> - -This form returns a pointer object -that contains the address of the variable {{NAME}}. -If the argument to {{location}} is not a location defined by {{define-location}}, -{{define-external}} or {{let-location}}, then - - (location X) - -is essentially equivalent to - - (make-locative X) - -(See the [[Unit lolevel#locatives|manual section on locatives]] for more -information about locatives) - -Note that {{(location X)}} may be abbreviated as {{#$X}}. - -<enscript highlight=scheme> -(define-external foo int) -((foreign-lambda* void (((c-pointer int) ip)) "*ip = 123;") - (location foo)) -foo ==> 123 -</enscript> - -This facility is especially useful in situations, where a C function -returns more than one result value: - -<enscript highlight=scheme> -#> -#include <math.h> -<# - -(define modf - (foreign-lambda double "modf" double (c-pointer double)) ) - -(let-location ([i double]) - (let ([f (modf 1.99 (location i))]) - (print "i=" i ", f=" f) ) ) -</enscript> - -See [[/location-and-c-string-star|location and c-string*]] -for a tip on returning a {{c-string*}} type. - -{{location}} returns a value of type {{c-pointer}}, when given -the name of a callback-procedure defined with {{define-external}}. - ---- -Previous: [[Callbacks]] - -Next: [[Other support procedures]] diff --git a/manual/Macros b/manual/Macros deleted file mode 100644 index 36be848b..00000000 --- a/manual/Macros +++ /dev/null @@ -1,316 +0,0 @@ -[[tags: manual]] -[[toc:]] - - -== Macros - - -CHICKEN supports standard R5RS {{syntax-rules}} macros and a low-level -macro system based on ''explicit renaming''. - - -=== Macro definitions - -==== define-syntax - -<macro>(define-syntax IDENTIFIER TRANSFORMER)</macro> - -Defines a macro named {{IDENTIFIER}} that will transform an expression -with {{IDENTIFIER}} in operator position according to {{TRANSFORMER}}. -The transformer expression must the result of a call -to{{er-macro-transformer}} or {{ir-macro-transformer}}, or it must be -a {{syntax-rules}} form. If {{syntax-rules}} is used, the usual R5RS -semantics apply. If {{TRANSFORMER}} is a transformer, then its -transformer procedure will be called on expansion with the complete -s-expression of the macro invocation, a rename procedure that -hygienically renames identifiers and a comparison procedure that -compares (possibly renamed) identifiers (see the section "Explicit -renaming macros" below for a detailed explanation on non-R5RS macros). - -{{define-syntax}} may be used to define local macros that are visible -throughout the rest of the body in which the definition occurred, i.e. - - (let () - ... - (define-syntax foo ...) - (define-syntax bar ...) - ...) - -is expanded into - - (let () - ... - (letrec-syntax ((foo ...) (bar ...)) - ...) ) - -{{syntax-rules}} supports [[http://srfi.schemers.org/srfi-46/|SRFI-46]] -in allowing the ellipsis identifier to be user-defined by passing it as the first -argument to the {{syntax-rules}} form. Also, "tail" patterns of the form - - (syntax-rules () - ((_ (a b ... c) - ... - -are supported. - -The effect of destructively modifying the s-expression passed to a -transformer procedure is undefined. - - -==== er-macro-transformer - -<procedure>(er-macro-transformer PROCEDURE)</procedure> - -Returns an explicit-remnaming transformer object wrapping the -syntax-transformer procedure {{PROCEDURE}}. The procedure will be -called with the form to be expanded and rename and compare procedures -and perform explicit renaming to maintain hygiene. See below for -more information about explicit renaming macros. - - -==== ir-macro-transformer - -<procedure>(ir-macro-transformer PROCEDURE)</procedure> - -Returns a implicit-renaming transformer object wrapping the -syntax-transformer procedure {{PROCEDURE}}. The procedure will be -called with the form to be expanded and an inject and compare -procedure and perform implicit renaming to maintain hygiene. See -below for more information about implicit renaming macros. - - -==== strip-syntax - -<procedure>(strip-syntax EXPRESSION)</procedure> - -Strips all syntactical information from {{EXPRESSION}}, returning a new expression -where symbols have all context-information removed. - - -=== Explicit renaming macros - -The low-level macro facility that CHICKEN provides is called "explicit -renaming" and allows writing hygienic or non-hygienic macros -procedurally. When given a the return value of the one of the -procedures {{er-macro-transformer}} or {{ir-macro-transformer}} -instead of a {{syntax-rules}} form, {{define-syntax}} evaluates the -procedure in a distinct expansion environment (initially having access -to the exported identifiers of the {{scheme}} module). The procedure -takes an expression and two other arguments and returns a transformed -expression. - -For example, the transformation procedure for a {{call}} macro such -that {{(call proc arg ...)}} expands into {{(proc arg ...)}} can be -written as - - (er-macro-transformer - (lambda (exp rename compare) - (cdr exp))) - -Expressions are represented as lists in the traditional manner, -except that identifiers are represented as special uninterned symbols. - -The second argument to a transformation procedure is a renaming procedure that -takes the representation of an identifier as its argument and returns the -representation of a fresh identifier that occurs nowhere else in the -program. For example, the transformation procedure for a simplified -version of the {{let}} macro might be written as - - (er-macro-transformer - (lambda (exp rename compare) - (let ((vars (map car (cadr exp))) - (inits (map cadr (cadr exp))) - (body (cddr exp))) - `((lambda ,vars ,@body) - ,@inits)))) - -This would not be hygienic, however. A hygienic {{let}} macro must -rename the identifier {{lambda}} to protect it from being captured by -a local binding. The renaming effectively creates a fresh alias for -{{lambda}}, one that cannot be captured by any subsequent binding: - - (er-macro-transformer - (lambda (exp rename compare) - (let ((vars (map car (cadr exp))) - (inits (map cadr (cadr exp))) - (body (cddr exp))) - `((,(rename 'lambda) ,vars ,@body) - ,@inits)))) - -The expression returned by the transformation procedure will be -expanded in the syntactic environment obtained from the syntactic -environment of the macro application by binding any fresh identifiers -generated by the renaming procedure to the denotations of the original -identifiers in the syntactic environment in which the macro was -defined. This means that a renamed identifier will denote the same -thing as the original identifier unless the transformation procedure -that renamed the identifier placed an occurrence of it in a binding -position. - -Identifiers obtained from any two calls to the renaming procedure with -the same argument will necessarily be the same, but will denote the -same syntactical binding. It is an error if the renaming procedure is -called after the transformation procedure has returned. - -The third argument to a transformation procedure is a comparison -predicate that takes the representations of two identifiers as its -arguments and returns true if and only if they denote the same thing -in the syntactic environment that will be used to expand the -transformed macro application. For example, the transformation -procedure for a simplified version of the {{cond}} macro can be written -as - - (er-macro-transformer - (lambda (exp rename compare) - (let ((clauses (cdr exp))) - (if (null? clauses) - `(,(rename 'quote) unspecified) - (let* ((first (car clauses)) - (rest (cdr clauses)) - (test (car first))) - (cond ((and (symbol? test) - (compare test (rename 'else))) - `(,(rename 'begin) ,@(cdr first))) - (else `(,(rename 'if) - ,test - (,(rename 'begin) ,@(cdr first)) - (,(r 'cond) ,@rest))))))))) - -In this example the identifier {{else}} is renamed before being passed -to the comparison predicate, so the comparison will be true if and -only if the test expression is an identifier that denotes the same -thing in the syntactic environment of the expression being transformed -as {{else}} denotes in the syntactic environment in which the {{cond}} -macro was defined. If {{else}} were not renamed before being passed to -the comparison predicate, then it would match a local variable that -happened to be named {{else}}, and the macro would not be hygienic. -The final recursive call to {{cond}} also needs to be renamed because -someone might create an alias for this macro and use it in a {{let}} -where {{cond}} is an ordinary variable. - -Some macros are non-hygienic by design. For example, the -following defines a {{loop}} macro that implicitly binds {{exit}} to an -escape procedure. The binding of {{exit}} is intended to capture free -references to {{exit}} in the body of the loop, so {{exit}} is not -renamed. - - (define-syntax loop - (er-macro-transformer - (lambda (x r c) - (let ((body (cdr x))) - `(,(r 'call-with-current-continuation) - (,(r 'lambda) (exit) - (,(r 'let) ,(r 'f) () ,@body (,(r 'f))))))))) - -Suppose a {{while}} macro is implemented using {{loop}}, with the intent -that {{exit}} may be used to escape from the {{while}} loop. The {{while}} -macro cannot be written as - - (define-syntax while - (syntax-rules () - ((while test body ...) - (loop (if (not test) (exit #f)) - body ...)))) - -because the reference to {{exit}} that is inserted by the {{while}} macro -is intended to be captured by the binding of {{exit}} that will be -inserted by the {{loop}} macro. In other words, this {{while}} macro is -not hygienic. Like {{loop}}, it must be written using procedurally: - - (define-syntax while - (er-macro-transformer - (lambda (x r c) - (let ((test (cadr x)) - (body (cddr x))) - `(,(r 'loop) - (,(r 'if) (,(r 'not) ,test) (exit #f)) - ,@body))))) - -Think about it: If we ''did'' rename {{exit}}, it would refer to an -{{exit}} procedure existing in the context of the macro's definition. -That one [[Unit library#exit|actually exists]]; it is the procedure -that exits the Scheme interpreter. Definitely ''not'' the one we want :) -So now we make it refer to an {{exit}} that's locally bound in the -environment where the macro is expanded. - -Note: this implementation of explicit-renaming macros allows passing -arbitrary expressions to the renaming and comparison procedures. When -being renamed, a fresh copy of the expression will be produced, with all -identifiers renamed appropriately. Comparison also supports arbitrary -expressions as arguments. - -=== Implicit renaming macros - -Explicit renaming macros generally require the user to perform quite a -few renames, because most identifiers that aren't taken from the input -expression should generally be inserted hygienically. It would make -more sense to give the output expression as-is, and only explicitly -convert those identifiers that you want to treat as ''unhygienic''. - -This can be done with implicit renaming macros. They just swap the -default insertion "mode" from unhygienic to hygienic, so to speak. -Here's the {{cond}} example from the previous section as an ir-macro: - - - (ir-macro-transformer - (lambda (exp inject compare) - (let ((clauses (cdr exp))) - (if (null? clauses) - `(quote unspecified) - (let* ((first (car clauses)) - (rest (cdr clauses)) - (test (car first))) - (cond ((and (symbol? test) - (compare test 'else)) - `(begin ,@(cdr first))) - (else `(if ,test - (begin ,@(cdr first)) - (cond ,@rest))))))))) - -In this example the identifier {{else}} does ''not'' need to be renamed -before being passed to the comparison predicate because it is already -''implicitly'' renamed. This comparison will also be true if and -only if the test expression is an identifier that denotes the same -thing in the syntactic environment of the expression being transformed -as {{else}} denotes in the syntactic environment in which the {{cond}} -macro was defined. If {{else}} were not renamed before being passed to -the comparison predicate, then it would match a local variable that -happened to be named {{else}}, and the macro would not be hygienic. - -As you can see, the code is a lot clearer because it isn't obscured -by excessive renaming. - -Here's the {{loop}} macro so you can see how hygiene can be broken -with implicit renaming macros: - - (define-syntax loop - (ir-macro-transformer - (lambda (expr inject compare) - (let ((body (cdr expr))) - `(call-with-current-continuation - (lambda (,(inject 'exit)) - (let f () ,@body (f)))))))) - -The {{while}} macro is a little trickier: do we inject the call to -{{exit}} or not? Just like the explicit renaming macro version -did ''not'' rename it, we must inject it to allow it to be captured -by the {{loop}} macro: - - (define-syntax while - (ir-macro-transformer - (lambda (expr inject compare) - (let ((test (cadr expr)) - (body (cddr expr))) - `(loop - (if (not ,test) (,(inject 'exit) #f)) - ,@body))))) - -Note: Just like explicit renaming macros, this implementation of -implicit renaming macros allow passing arbitrary expressions to -the injection and comparison procedures. The injection procedure -also return fresh copies of its input. - ---- -Previous: [[Non-standard macros and special forms]] - -Next: [[Modules]] diff --git a/manual/Non-standard macros and special forms b/manual/Non-standard macros and special forms deleted file mode 100644 index 2072ebc2..00000000 --- a/manual/Non-standard macros and special forms +++ /dev/null @@ -1,646 +0,0 @@ -[[tags: manual]] - -[[toc:]] - -== Non-standard macros and special forms - -=== Making extra libraries and extensions available - -==== require-extension - -<macro>(require-extension ID ...)</macro> - -This is equivalent to {{(require-library ID ...)}} but performs an implicit -{{import}}, if necessary. Since version 4.4.0, {{ID}} may also be an import specification -(using {{rename}}, {{only}}, {{except}} or {{prefix}}). - -To make long matters short - just use {{require-extension}} and it will normally figure everything out for dynamically -loadable extensions and core library units. - -This implementation of {{require-extension}} is compliant with [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]] -(see the [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]] document for more information). - -==== require-library - -<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 -code for loading/linking with core library modules or separately installed -extensions. - -During interpretation/evaluation {{require-library}} performs one of the -following: - -* If {{ID}} names a built-in feature {{chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55}}, then nothing is done. -* If {{ID}} names one of the syntactic extensions {{chicken-syntax chicken-ffi-syntax}}, then this extension will be loaded. -* If {{ID}} names one of the core library units shipped with CHICKEN, then a {{(load-library 'ID)}} will be performed. -* If {{ID}} names an installed extension with the {{syntax}} or {{require-at-runtime}} attribute, then the extensions is loaded at compile-time, probably doing a run-time {{(require ...)}} for any run-time requirements. -* Otherwise, {{(require-library ID)}} is equivalent to {{(require 'ID)}}. - -During compilation, one of the following happens instead: - -* If {{ID}} names a built-in feature {{chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55}}, then nothing is done. -* If {{ID}} names one of the syntactic extensions {{chicken-syntax chicken-ffi-syntax}}, then this extension will be loaded at compile-time, making the syntactic extensions available in compiled code. -* If {{ID}} names one of the core library units shipped with CHICKEN, or if the option {{-uses ID}} has been passed to the compiler, then a {{(declare (uses ID))}} is generated. -* If {{ID}} names an installed extension with the {{syntax}} or {{require-at-runtime}} attribute, then the extension is loaded at compile-time, and code is emitted to {{(require ...)}} any needed run-time requirements. -* Otherwise {{(require-library ID)}} is equivalent to {{(require 'ID)}}. - -{{ID}} should be a pure extension name and should not contain any path prefixes (for example {{dir/lib...}} is illegal). - -{{ID}} may also be a list that designates an extension-specifier. Currently the following extension specifiers are -defined: - -* {{(srfi NUMBER ...)}} is required for SRFI-55 compatibility and is fully implemented -* {{(version ID NUMBER)}} is equivalent to {{ID}}, but checks at compile-time whether the extension named {{ID}} is installed and whether its version is equal or higher than {{NUMBER}}. {{NUMBER}} may be a string or a number, the comparison is done lexicographically (using {{string>=?}}). - -==== use - -<macro>(use ID ...)</macro> - -{{use}} is just a shorter alias for {{require-extension}}. - -==== require-extension-for-syntax - -<macro>(require-extension-for-syntax ID ...)</macro> - -An abbreviation for the idiom: - -<enscript highlight=scheme> -(begin-for-syntax (require-library ID ...)) ; load extension at expansion-time -(import-for-syntax ID ...) ; import extension for use in syntax-transformers -</enscript> - - -==== use-for-syntax - -<macro>(use-for-syntax ID ...)</macro> - -{{use}} is just a shorter alias for {{require-extension-for-syntax}} (which is quite a mouthful). - - -=== Binding forms for optional arguments - -==== optional - -<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 -returned, otherwise the first element of the list {{ARGS}}. It is -an error if {{ARGS}} contains more than one value. - -<enscript highlight=scheme> -(define (incr x . i) (+ x (optional i 1))) -(incr 10) ==> 11 -(incr 12 5) ==> 17 -</enscript> -==== case-lambda - -<macro>(case-lambda (LAMBDA-LIST1 EXP1 ...) ...)</macro> - -Expands into a lambda that invokes the body following the first -matching lambda-list. - -<enscript highlight=scheme> -(define plus - (case-lambda - (() 0) - ((x) x) - ((x y) (+ x y)) - ((x y z) (+ (+ x y) z)) - (args (apply + args)))) - -(plus) ==> 0 -(plus 1) ==> 1 -(plus 1 2 3) ==> 6 -</enscript> - -For more information see the documentation for -[[http://srfi.schemers.org/srfi-16/srfi-16.html|SRFI-16]] - -==== let-optionals - -<macro> (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...)</macro> - -Binding constructs for optional procedure arguments. {{ARGS}} is normally -a rest-parameter taken from a lambda-list. {{let-optionals}} -binds {{VAR1 ...}} to available arguments in parallel, or -to {{DEFAULT1 ...}} if not enough arguments were provided. -{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every -variable sees the previous ones. it is an error if any excess -arguments are provided. - -<enscript highlight=scheme> -(let-optionals '(one two) ((a 1) (b 2) (c 3)) - (list a b c) ) ==> (one two 3) -</enscript> - -==== let-optionals* - -<macro> (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)</macro> - -Binding constructs for optional procedure arguments. {{ARGS}} is normally -a rest-parameter taken from a lambda-list. {{let-optionals}} -binds {{VAR1 ...}} to available arguments in parallel, or -to {{DEFAULT1 ...}} if not enough arguments were provided. -{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every -variable sees the previous ones. If a single variable {{RESTVAR}} -is given, then it is bound to any remaining arguments, otherwise it is -an error if any excess arguments are provided. - -<enscript highlight=scheme> -(let-optionals* '(one two) ((a 1) (b 2) (c a)) - (list a b c) ) ==> (one two one) -</enscript> - - -=== Other binding forms - -==== and-let* - -<macro>(and-let* (BINDING ...) EXP1 EXP2 ...)</macro> - -Bind sequentially and execute body. {{BINDING}} can -be a list of a variable and an expression, a list with a single -expression, or a single variable. If the value of an expression -bound to a variable is {{#f}}, the {{and-let*}} form -evaluates to {{#f}} (and the subsequent bindings and the body -are not executed). Otherwise the next binding is performed. If -all bindings/expressions evaluate to a true result, the body is -executed normally and the result of the last expression is the -result of the {{and-let*}} form. See also the documentation for -[[http://srfi.schemers.org/srfi-2/srfi-2.html|SRFI-2]]. - -==== letrec* - -<macro>(letrec* ((VARIABLE EXPRESSION) ...) BODY ...)</macro> - -Implements R6RS/R7RS {{letrec*}}. {{letrec*}} is similar to {{letrec}} but -binds the variables sequentially and is to {{letrec}} what {{let*}} is to {{let}}. - -==== rec - -<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 ...)}} -is the same as {{(letrec ((NAME (lambda (VARIABLE ...) BODY ...))) NAME)}}. - -==== cut - -<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 - -<macro>(define-values (NAME ...) VALUEEXP)</macro> -<macro>(define-values (NAME1 ... NAMEn . NAMEn+1) VALUEEXP)</macro> -<macro>(define-values NAME VALUEEXP)</macro> - -Defines several variables at once, with the result values of expression -{{VALUEEXP}}, similar to {{set!-values}}. - -==== fluid-let - -<macro>(fluid-let ((VAR1 X1) ...) BODY ...)</macro> - -Binds the variables {{VAR1 ...}} dynamically to the values {{X1 ...}} -during execution of {{BODY ...}}. -This implements [[http://srfi.schemers.org/srfi-15/srfi-15.html|SRFI-15]]. - -==== let-values - -<macro>(let-values (((NAME ...) VALUEEXP) ...) BODY ...)</macro> - -Binds multiple variables to the result values of {{VALUEEXP ...}}. -All variables are bound simultaneously. Like {{define-values}}, the -{{(NAME ...)}} expression can be any basic lambda list (dotted tail -notation is supported). -This implements [[http://srfi.schemers.org/srfi-11/srfi-11.html|SRFI-11]]. - -==== let*-values - -<macro>(let*-values (((NAME ...) VALUEEXP) ...) BODY ...)</macro> - -Binds multiple variables to the result values of {{VALUEEXP ...}}. -The variables are bound sequentially. Like {{let-values}}, the -{{(NAME ...)}} expression can be any basic lambda list (dotted tail -notation is supported). -This is also part of [[http://srfi.schemers.org/srfi-11/srfi-11.html|SRFI-11]]. - -<enscript highlight=scheme> -(let*-values (((a b) (values 2 3)) - ((p) (+ a b)) ) - p) ==> 5 -</enscript> - -==== letrec-values - -<macro>(letrec-values (((NAME ...) VALUEEXP) ...) BODY ...)</macro> - -Binds the result values of {{VALUEEXP ...}} to multiple variables at once. -All variables are mutually recursive. Like {{let-values}}, the -{{(NAME ...)}} expression can be any basic lambda list (dotted tail -notation is supported). - -<enscript highlight=scheme> -(letrec-values (((odd even) - (values - (lambda (n) (if (zero? n) #f (even (sub1 n)))) - (lambda (n) (if (zero? n) #t (odd (sub1 n)))) ) ) ) - (odd 17) ) ==> #t -</enscript> - -==== parameterize - -<macro>(parameterize ((PARAMETER1 X1) ...) BODY ...)</macro> - -Binds the parameters {{PARAMETER1 ...}} dynamically to the values -{{X1 ...}} during execution of {{BODY ...}}. (see also: -{{make-parameter}} in [[Parameters]]). Note that {{PARAMETER}} may be any -expression that evaluates to a parameter procedure. - -==== receive - -<macro>(receive (NAME ...) VALUEEXP BODY ...)</macro><br> -<macro>(receive (NAME1 ... NAMEn . NAMEn+1) VALUEEXP BODY ...)</macro><br> -<macro>(receive NAME VALUEEXP BODY ...)</macro><br> -<macro>(receive VALUEEXP)</macro> - -[[http://srfi.schemers.org/srfi-8/srfi-8.html|SRFI-8]]. -Syntactic sugar for {{call-with-values}}. Binds variables -to the result values of {{VALUEEXP}} and evaluates {{BODY ...}}, -similar {{define-values}} but lexically scoped. - -{{(receive VALUEEXP)}} is equivalent to {{(receive _ VALUEEXP _)}}. -This shortened form is not described by SRFI-8. - -==== set!-values - -<macro>(set!-values (NAME ...) VALUEEXP)</macro> -<macro>(set!-values (NAME1 ... NAMEn . NAMEn+1) VALUEEXP)</macro> -<macro>(set!-values NAME VALUEEXP)</macro> - -Assigns the result values of expression {{VALUEEXP}} to multiple -variables, similar to {{define-values}}. - -=== Substitution forms and macros - -==== define-constant - -<macro>(define-constant NAME CONST)</macro> - -Defines a variable with a constant value, evaluated at compile-time. -Any reference to such a constant should appear textually '''after''' -its definition. This construct is equivalent to {{define}} when -evaluated or interpreted. Constant definitions should only appear at -toplevel. Note that constants are local to the current compilation -unit and are not available outside of the source file in which they -are defined. Names of constants still exist in the Scheme namespace -and can be lexically shadowed. If the value is mutable, then the -compiler is careful to preserve its identity. {{CONST}} may be any -constant expression, and may also refer to constants defined via -{{define-constant}} previously, but it must be possible to -evaluate the expression at compile-time. - -==== define-inline - -<macro>(define-inline (NAME VAR ...) BODY ...)</macro><br> -<macro>(define-inline (NAME VAR ... . VAR) 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 ...)}}. This is similar -to a macro, but variable names and scope are handled correctly. - -Inline substitutions take place '''after''' macro-expansion, and any -reference to {{NAME}} should appear textually '''after''' its -definition. Inline procedures are local to the current compilation unit -and are not available outside of the source file in which they are -defined. Names of inline procedures still exist in the Scheme namespace -and can be lexically shadowed. Inline definitions should only appear at -the toplevel. - -Note that the {{inline-limit}} compiler option does not affect inline -procedure expansion, and self-referential inline procedures may cause -the compiler to enter an infinite loop. - -In the third form, {{EXP}} must be a lambda expression. - -This construct is equivalent to {{define}} when evaluated or -interpreted. - -==== define-for-syntax - -<macro>(define-for-syntax (NAME VAR ...) EXP1 ...)</macro><br> -<macro>(define-for-syntax (NAME VAR1 ... VARn . VARn+1) EXP1 ...)</macro><br> -<macro>(define-for-syntax NAME [VALUE])</macro> - -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, -for example. - -Note that {{define-for-syntax}} definitions within a module are implicitly -added to that module's import library. Refer to the documentation on -[[/man/4/Modules#import-libraries|import libraries]] for more information. - -==== define-compiler-syntax - -<macro>(define-compiler-syntax NAME)</macro><br> -<macro>(define-compiler-syntax NAME TRANSFORMER)</macro><br> - -Defines what is usually called a ''compiler macro'' in Lisp: {{NAME}} should be the -name of a globally or locally bound procedure. Any direct call to this procedure -will be transformed before compilation, which allows arbitrary rewritings -of function calls. - -{{TRANSFORMER}} can be a {{syntax-rules}} expression or a transformer -procedure (as returned by {{er-macro-transformer}} or -{{ir-macro-transformer}}). Returning the original form in an -explicit/implicit-renaming macro or simply "falling trough" all patterns in a -{{syntax-rules}} form will keep the original expression and compile it -normally. - -In the interpreter this form does nothing and returns an unspecified value. - -Compiler-syntax is always local to the current compilation unit and can not be -exported. Compiler-syntax defined inside a module is not visible outside of that -module. - -{{define-compiler-syntax}} should only be used at top-level. Local compiler-syntax -can be defined with {{let-compiler-syntax}}. - -<enscript highlight=scheme> -(define-compiler-syntax + - (syntax-rules () - ((_) 1) - ((_ x 0) x) ) ) -</enscript> - -If no transformer is given, then {{(define-compiler-syntax NAME)}} removes -any compiler-syntax definitions for {{NAME}}. - - -==== let-compiler-syntax - -<macro>(let-compiler-syntax ((NAME [TRANSFORMER]) ...) BODY ...)</macro> - -Allows definition local compiler macros, which are only applicable inside {{BODY ...}}. -By not providing a {{TRANSFORMER}} expression, compiler-syntax for specific identifiers -can be temporarily disabled. - - -=== Conditional forms - -==== select - -<macro>(select EXP ((KEY ...) EXP1 ...) ... [(else EXPn ...)])</macro> - -This is similar to {{case}}, but the keys are evaluated. - -==== unless - -<macro>(unless TEST EXP1 EXP2 ...)</macro> - -Equivalent to: - -<enscript highlight=scheme> -(if (not TEST) (begin EXP1 EXP2 ...)) -</enscript> - -==== when - -<macro>(when TEST EXP1 EXP2 ...)</macro> - -Equivalent to: - -<enscript highlight=scheme> -(if TEST (begin EXP1 EXP2 ...)) -</enscript> - - -=== Record structures - -==== define-record - -<macro>(define-record NAME SLOTNAME ...)</macro> - -Defines a record type. This defines a number of procedures for -creating, accessing, and modifying record members. - -Call {{make-NAME}} to create an instance -of the structure (with one initialization-argument for each slot, in -the listed order). - -{{(NAME? STRUCT)}} tests any object for being an instance of this -structure. - -Slots are accessed via {{(NAME-SLOTNAME STRUCT)}} -and updated using {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}. - -<enscript highlight=scheme> -(define-record point x y) -(define p1 (make-point 123 456)) -(point? p1) ==> #t -(point-x p1) ==> 123 -(point-y-set! p1 99) -(point-y p1) ==> 99 -</enscript> - -===== SRFI-17 setters - -{{SLOTNAME}} may alternatively also be of the form - - (setter SLOTNAME) - -In this case the slot can be read with {{(NAME-SLOTNAME STRUCT)}} as usual, -and modified with {{(set! (NAME-SLOTNAME STRUCT) VALUE)}} (the slot-accessor -has an associated SRFI-17 "setter" procedure) instead of -the usual {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}. - - -<enscript highlight=scheme> -(define-record point (setter x) (setter y)) -(define p1 (make-point 123 456)) -(point? p1) ==> #t -(point-x p1) ==> 123 -(set! (point-y p1) 99) -(point-y p1) ==> 99 -</enscript> - -==== define-record-type - -<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]]. - -As an extension the {{MODIFIER}} may have the form {{(setter PROCEDURE)}}, -which will define a SRFI-17 setter-procedure for the given {{PROCEDURE}} -that sets the field value. Usually {{PROCEDURE}} has the same name -is {{ACCESSOR}} (but it doesn't have to). - - -==== define-record-printer - -<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 -type is written using {{display, write}} or {{print}}, then -the procedure is called with two arguments: the record to be printed -and an output-port. - -<enscript highlight=scheme> -(define-record-type foo (make-foo x y z) foo? - (x foo-x) - (y foo-y) - (z foo-z)) -(define f (make-foo 1 2 3)) -(define-record-printer (foo x out) - (fprintf out "#,(foo ~S ~S ~S)" - (foo-x x) (foo-y x) (foo-z x)) ) -(define-reader-ctor 'foo make-foo) -(define s (with-output-to-string - (lambda () (write f)))) -s ==> "#,(foo 1 2 3)" -(equal? f (with-input-from-string - s read))) ==> #t -</enscript> - -=== Other forms - -==== assert - -<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 -more informative error-message. If compiled in ''unsafe'' mode (either -by specifying the {{-unsafe}} compiler option or by declaring -{{(unsafe)}}), then this expression expands to an unspecified value. -The result is the value of {{EXP}}. - - -==== begin-for-syntax - -<macro>(begin-for-syntax EXP ...)</macro> - -Equivalent to {{(begin EXP ...)}}, but performs the evaluation of -the expression during macro-expansion time. - - -==== cond-expand - -<macro>(cond-expand FEATURE-CLAUSE ...)</macro> - -Expands by selecting feature clauses. This form is allowed to appear in non-toplevel expressions. - -Predefined feature-identifiers are "situation" specific: - -; compile : {{chicken}}, {{compiling}}, {{library}}, {{eval}}, {{extras}}, {{regex}}, {{srfi-0}}, {{srfi-2}}, {{srfi-4}}, {{srfi-6}}, {{srfi-8}}, {{srfi-9}}, {{srfi-10}}, {{srfi-11}}, {{srfi-12}}, {{srfi-15}}, {{srfi-16}}, {{srfi-17}}, {{srfi-23}}, {{srfi-26}}, {{srfi-28}}, {{srfi-30}}, {{srfi-31}}, {{srfi-39}}, {{srfi-55}}, {{srfi-61}}, {{srfi-62}} - -; load : {{chicken}}, {{extras}}, {{srfi-0}}, {{srfi-2}}, {{srfi-6}}, {{srfi-8}}, {{srfi-9}}, {{srfi-10}}, {{srfi-12}}, {{srfi-17}}, {{srfi-23}}, {{srfi-28}}, {{srfi-30}}, {{srfi-39}}, {{srfi-55}}, {{srfi-61}}, {{srfi-62}}. {{library}} is implicit. - -; eval : {{csi}}, {{chicken}}, {{extras}}, {{srfi-0}}, {{srfi-2}}, {{srfi-6}}, {{srfi-8}}, {{srfi-9}}, {{srfi-10}}, {{srfi-11}}, {{srfi-12}}, {{srfi-15}}, {{srfi-16}}, {{srfi-17}}, {{srfi-23}}, {{srfi-26}}, {{srfi-28}}, {{srfi-30}}, {{srfi-31}}, {{srfi-39}}, {{srfi-55}}, {{srfi-61}}, {{srfi-62}}. {{library}} is implicit. - -The following feature-identifier classes are available in all situations: -{{(machine-byte-order)}}, {{(machine-type)}}, {{(software-type)}}, -{{(software-version)}}, where the actual feature-identifier is platform -dependent. - -In addition the following feature-identifiers may exist: {{cross-chicken}}, -{{dload}}, {{manyargs}}, {{ptables}}. - -For further information, see the documentation for -[[http://srfi.schemers.org/srfi-0/srfi-0.html|SRFI-0]]. - -=== delay-force - -CHICKEN supports the R7RS {{delay-force}} syntax which allows for -iterative lazy algorithms to be expressed in bounded space. - -For more information regarding this behaviour, see the -[[http://srfi.schemers.org/srfi-45/srfi-45.html|SRFI-45]] rationale. - -==== ensure - -<macro>(ensure PREDICATE EXP [ARGUMENTS ...])</macro> - -Evaluates the expression {{EXP}} and applies the one-argument -procedure {{PREDICATE}} to the result. If the predicate returns -{{#f}} an error is signaled, otherwise the result of {{EXP}} -is returned. If compiled in ''unsafe'' mode (either by specifying -the {{-unsafe}} compiler option or by declaring {{(unsafe)}}), -then this expression expands to an unspecified value. If specified, -the optional {{ARGUMENTS}} are used as arguments to the invocation -of the error-signalling code, as in {{(error ARGUMENTS ...)}}. If -no {{ARGUMENTS}} are given, a generic error message is displayed -with the offending value and {{PREDICATE}} expression. - -==== eval-when - -<macro>(eval-when (SITUATION ...) EXP ...)</macro> - -Controls evaluation/compilation of subforms. {{SITUATION}} should -be one of the symbols {{eval}}, {{compile}} or {{load}}. -When encountered in the evaluator, and the situation specifier -{{eval}} is not given, then this form is not evaluated and an -unspecified value is returned. When encountered while compiling code, -and the situation specifier {{compile}} is given, then this form is -evaluated at compile-time. When encountered while compiling code, and the -situation specifier {{load}} is not given, then this form is ignored -and an expression resulting into an unspecified value is compiled instead. - -The following table should make this clearer: - -<table> -<tr><th></th><th>In compiled code</th><th>In interpreted code</th></tr> -<tr><td>{{eval}}</td><td>ignore</td><td>evaluate</td></tr> -<tr><td>{{compile}}</td><td>evaluate at compile time</td><td>ignore</td></tr> -<tr><td>{{load}}</td><td>compile as normal</td><td>ignore</td></tr> -</table> - -==== include - -<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 -{{.scm}}, then it may be omitted. The file is searched for in the -current directory and all directories specified by the {{-include-path}} -option. - -==== include-relative - -<macro>(include-relative STRING)</macro> - -Works like {{include}}, but the filename is searched for relative to the -including file rather than the current directory. - -==== nth-value - -<macro>(nth-value N EXP)</macro> - -Returns the {{N}}th value (counting from zero) of the values returned -by expression {{EXP}}. - -==== time - -<macro>(time EXP1 ...)</macro> - -Performs a major garbage collection, evaluates {{EXP1 ...}} and prints -elapsed CPU time and some values about GC use, like time spent in major -GCs, number of minor and major GCs. The output is sent to the port -that is the current value of {{(current-error-port)}}. Nested invocations -of this form will give incorrect results for all output but the innermost. - ---- -Previous: [[Non-standard read syntax]] - -Next: [[Macros]] diff --git a/manual/Non-standard read syntax b/manual/Non-standard read syntax deleted file mode 100644 index 04707b99..00000000 --- a/manual/Non-standard read syntax +++ /dev/null @@ -1,196 +0,0 @@ -[[tags: manual]] - -[[toc:]] - -== Non-standard read syntax - -=== Escapes in symbols - -{{| ... |}} may be used to escape a sequence of characters when reading a symbol. -{{\X}} escapes a single character in a symbols name: - - (symbol->string '|abc def|) => "abc def" - (symbol->string '|abc||def|) => "abcdef" - (symbol->string '|abc|xyz|def|) => "abcxyzdef" - (symbol->string '|abc\|def|) => "abc|def" - (symbol->string 'abc\ def) => "abc def" - -=== Multiline Block Comment - -<read>#|</read> - - #| ... |# - -A multiline ''block'' comment. May be nested. Implements [[http://srfi.schemers.org/srfi-30/srfi-30.html|SRFI-30]]. - -=== Expression Comment - -<read>#;</read> - - #;EXPRESSION - -Treats {{EXPRESSION}} as a comment. That is, the comment runs through the whole S-expression, regardless of newlines, which saves you from having to comment out every line, or add a newline in the middle of your parens to make the commenting of the last line work, or other things like that. Implements [[http://srfi.schemers.org/srfi-62/srfi-62.html|SRFI-62]]. - -=== External Representation - -<read>#,</read> - - #,(CONSTRUCTORNAME DATUM ...) - -Allows user-defined extension of external representations. (For more information see the documentation for -[[http://srfi.schemers.org/srfi-10/srfi-10.html|SRFI-10]]) - -=== Location Expression - - #$EXPRESSION - -An abbreviation for {{(location EXPRESSION)}}. - -=== Blob literals - -<read>#${</read> - - #${ HEX ... } - -Syntax for literal "blobs" (byte-sequences). Expects hexadecimal digits and ignores -any whitespace characters: - - #;1> ,d '#${deadbee f} - blob of size 4: - 0: de ad be ef .... - -=== Keyword - -<read>#:</read> - - #:SYMBOL - SYMBOL: - :SYMBOL - -Syntax for keywords. Keywords are symbols that evaluate to themselves, and as such don't have to be quoted. Either {{SYMBOL:}} or {{:SYMBOL}} is accepted, depending on the setting of the {{keyword-style}} parameter, but never both. {{#:SYMBOL}} is always accepted. - -=== Multiline String Constant - -<read>#<<</read> - - #<<TAG - -Specifies a multiline string constant. Anything up to a line equal to {{TAG}} (or end of file) will be returned as a single string: - - (define msg #<<END - "Hello, world!", she said. - END - ) - -is equivalent to - - (define msg "\"Hello, world!\", she said.") - -=== Multiline String Constant with Embedded Expressions - -<read>#<#</read> - - #<#TAG - -Similar to {{#<<}}, but allows substitution of embedded Scheme expressions prefixed with {{#}} and optionally enclosed in curly brackets. Two consecutive {{#}}s are translated to a single {{#}}: - - (define three 3) - (display #<#EOF - This is a simple string with an embedded `##' character - and substituted expressions: (+ three 99) ==> #(+ three 99) - (three is "#{three}") - EOF - ) - -prints - - This is a simple string with an embedded `#' character - and substituted expressions: (+ three 99) ==> 102 - (three is "3") - -=== Foreign Declare - -<read>#></read> - - #> ... <# - -Abbreviation for {{(foreign-declare " ... ")}}. - -=== String escape sequences - -String-literals may contain the following escape sequences: - -<table style="margin-top: 1em; max-width: 40em"> -<tr><th>Escape sequence</th><th>Character</th></tr> -<tr><td>{{\n}}</td><td>line feed / newline</td></tr> -<tr><td>{{\t}}</td><td>tab</td></tr> -<tr><td>{{\r}}</td><td>carriage return</td></tr> -<tr><td>{{\b}}</td><td>backspace</td></tr> -<tr><td>{{\a}}</td><td>bell</td></tr> -<tr><td>{{\v}}</td><td>vertical tab</td></tr> -<tr><td>{{\f}}</td><td>form feed</td></tr> -<tr><td>{{\x}}''XX''</td><td>hexadecimal 8-bit character code</td></tr> -<tr><td>{{\u}}''XXXX''</td><td>hexadecimal 16-bit Unicode character code</td></tr> -<tr><td>{{\U}}''XXXXXXXX''</td><td>hexadecimal 32-bit Unicode character code</td></tr> -<tr><td>{{\}}''OOO''</td><td>octal 8-bit character code</td></tr> -<tr><td>{{\|}} Â Â {{\"}} Â Â {{\\}} Â Â {{\'}}</td><td>the escaped character</td></tr> -</table> - - -=== Sharp Prefixed Symbol - -<read>#%</read> - - #%... - -Reads like a normal symbol. - -=== Bang - -<read>#!</read> - - #!... - -Interpretation depends on the directly following characters. Only the following are recognized. Any other case results in a read error. - -; Line Comment : If followed by whitespace or a slash, then everything up the end of the current line is ignored - -; Eof Object : If followed by the character sequence {{eof}}, then the (self-evaluating) end-of-file object is returned - -; DSSSL Formal Parameter List Annotation : If followed by any of the character sequences {{optional}}, {{rest}} or {{key}}, then a symbol with the same name (and prefixed with {{#!}}) is returned - -; Read Mark Invocation : If a ''read mark'' with the same name as the token is registered, then its procedure is called and the result of the read-mark procedure will be returned - -=== Case Sensitive Expression - -<read>#cs</read> - - #cs... - -Read the next expression in case-sensitive mode (regardless of the current global setting). - -=== Case Insensitive Expression - -<read>#ci</read> - - #ci... - -Read the next expression in case-insensitive mode (regardless of the current global setting). - -=== Conditional Expansion - -<read>#+</read> - - #+FEATURE EXPR - -Rewrites to - - (cond-expand (FEATURE EXPR) (else)) - -and performs the feature test at macroexpansion time. Therefore, it may not -work as expected when used within a macro form. - ---- -Previous: [[Extensions to the standard]] - -Next: [[Non-standard macros and special forms]] diff --git a/manual/Other support procedures b/manual/Other support procedures deleted file mode 100644 index 2866a38f..00000000 --- a/manual/Other support procedures +++ /dev/null @@ -1,16 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Other support procedures - -=== 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. - ---- -Previous: [[Locations]] - -Next: [[C interface]] diff --git a/manual/Parameters b/manual/Parameters deleted file mode 100644 index 2e2b806b..00000000 --- a/manual/Parameters +++ /dev/null @@ -1,184 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Parameters - -Parameters are CHICKEN's form of dynamic variables, except that they are -procedures rather than actual variables. A parameter is a procedure of -zero or one arguments. To retrieve the value of a parameter call the -parameter-procedure with zero arguments. To change the setting of the -parameter, call the parameter-procedure with the new value as argument: - -<enscript highlight=scheme> -(define foo (make-parameter 123)) -(foo) ==> 123 -(foo 99) -(foo) ==> 99 -</enscript> - -Parameters are fully thread-local, each thread of execution -owns a local copy of a parameters' value. - -CHICKEN implements [[http://srfi.schemers.org/srfi-39/srfi-39.html|SRFI-39]]. - - - -=== make-parameter - -<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 -procedure with one argument changes its value to the value of that -argument and returns the new value (subsequent invocations with zero -parameters return the new value). {{GUARD}} should be a procedure of a -single argument. Any new values of the parameter (even the initial -value) are passed to this procedure. The guard procedure should check -the value and/or convert it to an appropriate form. - - -== Built-in parameters - -Certain behavior of the interpreter and compiled programs can be -customized via the following built-in parameters: - -=== case-sensitive - -<parameter>(case-sensitive)</parameter> - -If true, then {{read}} reads symbols and identifiers in -case-sensitive mode and uppercase characters in symbols are printed -escaped. Defaults to {{#t}}. - - -=== dynamic-load-libraries - -<parameter>(dynamic-load-libraries)</parameter> - -A list of strings containing shared libraries that should be checked -for explicitly loaded library units (this facility is not available on -all platforms). See {{load-library}}. - - -=== command-line-arguments - -<parameter>(command-line-arguments)</parameter> - -Contains the list of arguments passed to this program, with the name of -the program and any runtime options (all options starting with {{-:}}) -removed. - - -=== current-read-table - -<parameter>(current-read-table)</parameter> - -A read-table object that holds read-procedures for special non-standard -read-syntax (see {{set-read-syntax!}} for more information). - - -=== exit-handler - -<parameter>(exit-handler)</parameter> - -A procedure of a single optional argument. When {{exit}} is called, -then this procedure will be invoked with the exit-code as argument. The -default behavior is to terminate the program. - - -=== eval-handler - -<parameter>(eval-handler)</parameter> - -A procedure of one or two arguments. When {{eval}} is invoked, it -calls the value of this parameter with the same arguments. The default -behavior is to evaluate the argument expression and to ignore the -second parameter. - - -=== force-finalizers - -<parameter>(force-finalizers)</parameter> - -If true, force and execute all pending finalizers before exiting the -program (either explicitly by {{exit}} or implicitly when the last -toplevel expression has been executed). Default is {{#t}}. - - -=== implicit-exit-handler - -<parameter>(implicit-exit-handler)</parameter> - -A procedure of no arguments. When the last toplevel expression of the -program has executed, then the value of this parameter is called. The -default behaviour is to invoke all pending finalizers. - - -=== keyword-style - -<parameter>(keyword-style)</parameter> - -Enables alternative keyword syntax, where {{STYLE}} may be either -{{#:prefix}} (as in Common Lisp), which recognizes symbols beginning -with a colon as keywords, or {{#:suffix}} (as in DSSSL), which recognizes -symbols ending with a colon as keywords. -Any other value disables the alternative syntaxes. In the interpreter -the default is {{#:suffix}}. - - -=== parenthesis-synonyms - -<parameter>(parenthesis-synonyms)</parameter> - -If true, then the list delimiter synonyms {{#\[}} {{#\]}} and {{#\{}} {{#\}}} are enabled. Defaults to {{#t}}. - - -=== symbol-escape - -<parameter>(symbol-escape)</parameter> - -If true, then the symbol escape {{#\|}} {{#\|}} is enabled. Defaults to {{#t}}. - - -=== load-verbose - -<parameter>(load-verbose)</parameter> - -A boolean indicating whether loading of source files, compiled code -(if available) and compiled libraries should display a message. - - -=== program-name - -<parameter>(program-name)</parameter> - -The name of the currently executing program. This is equivalent to -{{(car (argv))}} for compiled programs or the filename following the -{{-script}} option in interpreted scripts. - - -=== reset-handler - -<parameter>(reset-handler)</parameter> - -A procedure of zero arguments that is called via {{reset}}. The -default behavior in compiled code is to invoke the value of -{{(exit-handler)}}. The default behavior in the interpreter is to -abort the current computation and to restart the read-eval-print loop. - - -=== recursive-hash-max-depth - -<parameter>(recursive-hash-max-depth)</parameter> - -The maximum structure depth to follow when computing a hash value. The default is {{4}}. - - -=== recursive-hash-max-length - -<parameter>(recursive-hash-max-length)</parameter> - -The maximum vector length to follow when computing a hash value. The default is {{4}}. - ----- -Previous: [[Declarations]] Next: [[Exceptions]] diff --git a/manual/Supported language b/manual/Supported language deleted file mode 100644 index 1a77c80f..00000000 --- a/manual/Supported language +++ /dev/null @@ -1,35 +0,0 @@ -[[tags: manual]] - -== Supported language - -* [[The R5RS standard]] -* [[Deviations from the standard]] -* [[Extensions to the standard]] -* [[Non-standard read syntax]] -* [[Non-standard macros and special forms]] -* [[Macros]] -* [[Modules]] -* [[Types]] -* [[Declarations]] -* [[Parameters]] -* [[Exceptions]] -* [[Unit library]] Basic Scheme definitions -* [[Unit eval]] Evaluation -* [[Unit repl]] Read-print-eval loop -* [[Unit expand]] Modules and macros handling -* [[Unit data-structures]] Data structures -* [[Unit ports]] I/O ports -* [[Unit files]] File and pathname operations -* [[Unit extras]] Useful utility definitions -* [[Unit irregex]] Regular expressions -* [[Unit srfi-4]] Homogeneous numeric vectors -* [[Unit posix]] Unix-like services -* [[Unit tcp]] Basic TCP-sockets -* [[Unit lolevel]] Low-level operations -* [[Unit continuation]] Continuations -* [[Unit read-syntax]] Reader extensions - ---- -Previous: [[Using the interpreter]] - -Next: [[Debugging]] diff --git a/manual/The R5RS standard b/manual/The R5RS standard deleted file mode 100644 index 28db52dc..00000000 --- a/manual/The R5RS standard +++ /dev/null @@ -1,3295 +0,0 @@ -== The R5RS standard - -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:]] - -== 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. The distinction which R5RS makes between primitive -and derived is unimportant and does not necessarily reflect how it's -implemented in CHICKEN itself. - -=== Primitive expression types - -==== Variable references - -<macro><variable></macro><br> - -An expression consisting of a variable 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. 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 - -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!. -In the current implementation of CHICKEN, identical constants don't -share memory and it is possible to mutate them, but this may change in -the future. - -==== 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. Procedure calls may return any number of values (see the -{{values}} procedure [[#control-features|below]]). - -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. - -==== 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 [[#booleans|the section -about booleans]] below), 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. For reference purposes, -these macro definitions will convert most of the constructs described -in this section into the primitive constructs described in the -previous section. This does not necessarily mean that's exactly how -it's implemented in CHICKEN. - -==== 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 [[#booleans|the section about -booleans]] below). 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. -Alternatively, as per R7RS, a <clause> may be of the form - - ((<datum[1]> ...) => <expression>). - -All the <datum>s must be distinct. The last <clause> may be an -"else clause," which has one of the following two forms: - - (else <expression[1]> <expression[2]> ...) - (else => <expression>). ; R7RS extension - -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 [[#equivalence-predicates|below]]) 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 selected -<clause> uses the => alternate form (an R7RS extension), 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 <key> -and the value(s) returned by this procedure is(are) returned by 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 -[[#booleans|the section about booleans]]) 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 -[[#booleans|the section about booleans]]) 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", [[#iteration|below]]. - -<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 [[#booleans|the section about booleans]]), 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 {{<expression>}} may return -multiple values, which will be correctly memoized and returned by -subsequent calls to {{force}}. This is a CHICKEN extension to R5RS. - -See the description of {{force}} (under [[#control-features|Control -features]], below) for a more complete description of {{delay}}. - -<macro>(delay-force <expression>)</macro><br> - -The expression {{(delay-force expression)}} is conceptually similar to -{{(delay (force expression))}}, with the difference that forcing the -result of {{delay-force}} will in effect result in a tail call to -{{(force expression)}}, while forcing the result of -{{(delay (force expression))}} might not. - -Thus iterative lazy algorithms that might result in a long series of -chains of delay and force can be rewritten using delay-force to -prevent consuming unbounded space during evaluation. - -The {{delay-force}} macro is a CHICKEN extension to R5RS, taken from -R7RS. - -See the description of force (under [[#control-features|Control -features]], below) for a more complete description of delayed -evaluation. - -<procedure>(make-promise obj)</procedure> - -The make-promise procedure returns a promise which, when forced, will -return {{obj}} . It is similar to {{delay}}, but does not delay its -argument: it is a procedure rather than syntax. If {{obj}} is already -a promise, it is returned. - -This procedure is a CHICKEN extension to R5RS, taken from R7RS. - -==== 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; - this depends on whether the binding already existed before (in which - case its value will be overridden). - -* 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. - -<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 usual, 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 - -=== Programs - -A Scheme program consists of a sequence of expressions, definitions, -and syntax definitions. Expressions are described in chapter 4; -definitions and syntax definitions are the subject of the rest of the -present chapter. - -Programs are typically stored in files or entered interactively to a -running Scheme system, although other paradigms are possible; -questions of user interface lie outside the scope of this -report. (Indeed, Scheme would still be useful as a notation for -expressing computational methods even in the absence of a mechanical -implementation.) - -Definitions and syntax definitions occurring at the top level of a -program can be interpreted declaratively. They cause bindings to be -created in the top level environment or modify the value of existing -top-level bindings. Expressions occurring at the top level of a -program are interpreted imperatively; they are executed in order when -the program is invoked or loaded, and typically perform some kind of -initialization. - -At the top level of a program (begin <form1> ...) is equivalent to the -sequence of expressions, definitions, and syntax definitions that form -the body of the begin. - -=== Definitions - -Definitions are valid in some, but not all, contexts where expressions -are allowed. They are valid only at the top level of a <program> and -at the beginning of a <body>. - -A definition should have one of the following forms: - -<macro>(define <variable> <expression>)</macro><br> -<macro>(define (<variable> <formals>) <body>)</macro><br> - -<Formals> should be either a sequence of zero or more variables, or a -sequence of one or more variables followed by a space-delimited period -and another variable (as in a lambda expression). This form is -equivalent to - - (define <variable> - (lambda (<formals>) <body>)). - -<macro>(define (<variable> . <formal>) <body>)</macro><br> - -<Formal> should be a single variable. This form is equivalent to - - (define <variable> - (lambda <formal> <body>)). - -==== Top level definitions - -At the top level of a program, a definition - - (define <variable> <expression>) - -has essentially the same effect as the assignment expression - - (set! <variable> <expression>) - -if <variable> is bound. If <variable> is not bound, however, then the -definition will bind <variable> to a new location before performing -the assignment, whereas it would be an error to perform a set! on an -unbound variable. - - (define add3 - (lambda (x) (+ x 3))) - (add3 3) ===> 6 - (define first car) - (first '(1 2)) ===> 1 - -Some implementations of Scheme use an initial environment in which all -possible variables are bound to locations, most of which contain -undefined values. Top level definitions in such an implementation are -truly equivalent to assignments. - -==== Internal definitions - -Definitions may occur at the beginning of a <body> (that is, the body -of a lambda, let, let*, letrec, let-syntax, or letrec-syntax -expression or that of a definition of an appropriate form). Such -definitions are known as internal definitions as opposed to the top -level definitions described above. The variable defined by an internal -definition is local to the <body>. That is, <variable> is bound rather -than assigned, and the region of the binding is the entire <body>. For -example, - - (let ((x 5)) - (define foo (lambda (y) (bar x y))) - (define bar (lambda (a b) (+ (* a b) a))) - (foo (+ x 3))) ===> 45 - -A <body> containing internal definitions can always be converted into -a completely equivalent letrec expression. For example, the let -expression in the above example is equivalent to - - (let ((x 5)) - (letrec ((foo (lambda (y) (bar x y))) - (bar (lambda (a b) (+ (* a b) a)))) - (foo (+ x 3)))) - -Just as for the equivalent letrec expression, it must be possible to -evaluate each <expression> of every internal definition in a <body> -without assigning or referring to the value of any <variable> being -defined. - -Wherever an internal definition may occur (begin <definition1> ...) is -equivalent to the sequence of definitions that form the body of the -begin. - -=== Syntax definitions - -Syntax definitions are valid only at the top level of a -<program>. They have the following form: - - (define-syntax <keyword> <transformer spec>) - -<Keyword> is an identifier, and the <transformer spec> should be an -instance of syntax-rules. The top-level syntactic environment is -extended by binding the <keyword> to the specified transformer. - -There is no define-syntax analogue of internal definitions. - -Although macros may expand into definitions and syntax definitions in -any context that permits them, it is an error for a definition or -syntax definition to shadow a syntactic keyword whose meaning is -needed to determine whether some form in the group of forms that -contains the shadowing definition is in fact a definition, or, for -internal definitions, is needed to determine the boundary between the -group and the expressions that follow the group. For example, the -following are errors: - - (define define 3) - - (begin (define begin list)) - - (let-syntax - ((foo (syntax-rules () - ((foo (proc args ...) body ...) - (define proc - (lambda (args ...) - body ...)))))) - (let ((x 3)) - (foo (plus x y) (+ x y)) - (define foo x) - (plus foo x))) - -== 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 -[[#assignments|assignments]], above). 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 the section on [[#symbols|symbols]]. 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 =, - under [[#numerical-operations|numerical operations]]), 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 (see "[[#characters|characters]]"). - -* 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. - -* obj[1] and obj[2] are procedures whose location tags are equal - (see "[[#procedures|procedures]]"). - -The eqv? procedure returns #f if: - -* obj[1] and obj[2] are of different types. - -* 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 [[#implementation-restrictions|the next section]]. - -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 under "[[#numerical-types|Numerical types]]", -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 - -For a complete formal description of the syntax of the written -representations for numbers, see the R5RS report. 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 numerical routines described below have argument restrictions, -which are encoded in the naming conventions of the arguments as -given in the procedure's signature. The conventions are as follows: - -; {{obj}} : any object -; {{list, list1, ... listj, ... list : (see "[[#pairs-and-lists|Pairs and lists]]" below) -; {{z, z1, ... zj, ...}} : complex number (currently not supported by CHICKEN core, see the "[[/egg/numbers|numbers]]" egg) -; {{x, x1, ... xj, ...}} : real number -; {{y, y1, ... yj, ...}} : real number -; {{q, q1, ... qj, ...}} : rational number (NOTE: fractional numbers are not supported by CHICKEN core, see the "[[/egg/numbers|numbers]]" egg) -; {{n, n1, ... nj, ...}} : integer -; {{k, k1, ... kj, ...}} : exact non-negative integer - -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 "[[#implementation-restrictions|Implementation restrictions]]". - -==== 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>. -Among other things, this permits the use of the read procedure to -parse Scheme programs. - -<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>(cdar pair)</procedure><br> -<procedure>(cddr pair)</procedure><br> -<procedure>(caaar pair)</procedure><br> -<procedure>(caadr pair)</procedure><br> -<procedure>(cadar pair)</procedure><br> -<procedure>(caddr pair)</procedure><br> -<procedure>(cdaar pair)</procedure><br> -<procedure>(cdadr pair)</procedure><br> -<procedure>(cddar pair)</procedure><br> -<procedure>(cdddr pair)</procedure><br> -<procedure>(caaaar pair)</procedure><br> -<procedure>(caaadr pair)</procedure><br> -<procedure>(caadar pair)</procedure><br> -<procedure>(caaddr pair)</procedure><br> -<procedure>(cadaar pair)</procedure><br> -<procedure>(cadadr pair)</procedure><br> -<procedure>(caddar pair)</procedure><br> -<procedure>(cadddr pair)</procedure><br> -<procedure>(cdaaar pair)</procedure><br> -<procedure>(cdaadr pair)</procedure><br> -<procedure>(cdadar pair)</procedure><br> -<procedure>(cdaddr pair)</procedure><br> -<procedure>(cddaar pair)</procedure><br> -<procedure>(cddadr 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))))). - -<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. - -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 (see -"[[#literal-expressions|literal expressions]]") 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 - -Note that {{integer->char}} does currently not detect -a negative argument and will quietly convert {{-1}} to -{{#x1ffff}} in CHICKEN. - -<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 "[[#delayed-evaluation|delayed -evaluation]]"). 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 either the exact integer 4 or 5, corresponding to the -respective revisions of the Scheme report (the Revised^N 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. - -The environments specified by scheme-report-environment and -null-environment are 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 also "[[#pairs-and-lists|pairs and lists]]"). 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 continuation b/manual/Unit continuation deleted file mode 100644 index 6c82d86a..00000000 --- a/manual/Unit continuation +++ /dev/null @@ -1,62 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit continuation - -This unit provides a more powerful interface for continuations than that -provided by {{call/cc}}. - -More information about this continuation API can be found in the paper -[[http://repository.readscheme.org/ftp/papers/sw2001/feeley.pdf]] ''A Better -API for first class Continuations'' by Marc Feeley. - - -=== Continuations API - -==== continuation-capture - -<procedure>(continuation-capture PROCEDURE)</procedure> - -Creates a continuation object representing the current continuation and -tail-calls {{PROCEDURE}} with this continuation as the single argument. - - - -==== continuation? - -<procedure>(continuation? X)</procedure> - -Returns {{#t}} if {{X}} is a continuation object, or {{#f}} otherwise. Please -note that this applies only to continuations created by the Continuation API, -but not by call/cc, i.e.: {{(call-with-current-continuation continuation?)}} -returns {{#f}}, whereas {{(continuation-capture continuation?)}} returns -{{#t}}. - - -==== continuation-graft - -<procedure>(continuation-graft CONT THUNK)</procedure> - -Calls the procedure {{THUNK}} with no arguments and the implicit continuation -{{CONT}}. - - -==== continuation-return - -<procedure>(continuation-return CONT VALUE ...)</procedure> - -Returns the value(s) to the continuation {{CONT}}. {{continuation-return}} could -be implemented like this: - -<enscript highlight=scheme> -(define (continuation-return k . vals) - (continuation-graft - k - (lambda () (apply values vals)))) -</enscript> - - ----- -Previous: [[Unit lolevel]] - -Next: [[Unit read-syntax]] diff --git a/manual/Unit data-structures b/manual/Unit data-structures deleted file mode 100644 index ee5a6147..00000000 --- a/manual/Unit data-structures +++ /dev/null @@ -1,481 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit data-structures - -This unit contains a collection of procedures related to data -structures. This unit is used by default, unless the program is -compiled with the {{-explicit-use}} option. - - -=== Lists - - -==== alist-ref - -<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}}). - - -==== alist-update - -<procedure>(alist-update KEY VALUE ALIST [TEST])</procedure> -<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 -{{alist-update}} returns {{((KEY . VALUE) . ALIST)}}. The optional argument -{{TEST}} specifies the comparison procedure to search a matching pair in {{ALIST}} -and defaults to {{eqv?}}. {{alist-update!}} is the destructive version of {{alist-update}}. - - -==== atom? - -<procedure>(atom? X)</procedure> - -Returns {{#t}} if {{X}} is not a pair. - - -==== rassoc - -<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?}}. - - -==== butlast - -<procedure>(butlast LIST)</procedure> - -Returns a fresh list with all elements but the last of {{LIST}}. - - -==== chop - -<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 -a multiple of {{N}}, then the last sublist contains the remaining -elements. - -<enscript highlight=scheme> -(chop '(1 2 3 4 5 6) 2) ==> ((1 2) (3 4) (5 6)) -(chop '(a b c d) 3) ==> ((a b c) (d)) -</enscript> - - -==== compress - -<procedure>(compress BLIST LIST)</procedure> - -Returns a new list with elements taken from {{LIST}} with -corresponding true values in the list {{BLIST}}. - -<enscript highlight=scheme> -(define nums '(99 100 110 401 1234)) -(compress (map odd? nums) nums) ==> (99 401) -</enscript> - - -==== flatten - -<procedure>(flatten LIST1 ...)</procedure> - -Returns {{LIST1 ...}} concatenated together, with nested lists -removed (flattened). - - -==== intersperse - -<procedure>(intersperse LIST X)</procedure> - -Returns a new list with {{X}} placed between each element. - - -==== join - -<procedure>(join LISTOFLISTS [LIST])</procedure> - -Concatenates the lists in {{LISTOFLISTS}} with {{LIST}} placed -between each sublist. {{LIST}} defaults to the empty list. - -<enscript highlight=scheme> -(join '((a b) (c d) (e)) '(x y)) ==> (a b x y c d x y e) -(join '((p q) () (r (s) t)) '(-)) ==> (p q - - r (s) t) -</enscript> - -{{join}} could be implemented as follows: - -<enscript highlight=scheme> -(define (join lstoflsts #!optional (lst '())) - (apply append (intersperse lstoflists lst)) ) -</enscript> - - -==== tail? - -<procedure>(tail? X LIST)</procedure> - -Returns true if {{X}} is one of the tails (cdr's) of {{LIST}}. - - -=== Sorting - - -==== merge - -<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, -that returns true if the first argument is to be ordered before the -second argument. - - -==== sort - -<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. - - -==== sorted? - -<procedure>(sorted? SEQUENCE LESS?)</procedure> - -Returns true if the list or vector {{SEQUENCE}} is already sorted. - -==== topological-sort - -<procedure>(topological-sort DAG PRED)</procedure> - -Sorts the directed acyclic graph dag {{DAG}} so that for every edge from vertex -u to v, u will come before v in the resulting list of vertices. - -{{DAG}} is a list of sublists. The car of each sublist is a -vertex. The cdr is the adjacency list of that vertex, i.e. a list of -all vertices to which there exists an edge from the car vertex. -{{pred}} is procedure of two arguments that should compare vertices -for equality. - -Time complexity: O (|V| + |E|) - -<enscript highlight=scheme> -(topological-sort - '((shirt tie belt) - (tie jacket) - (belt jacket) - (watch) - (pants shoes belt) - (undershorts pants shoes) - (socks shoes)) - eq?) - -=> - -(socks undershorts pants shoes watch shirt belt tie jacket) -</enscript> - -If a cycle is detected during the sorting process, an exception of the -condition kinds {{(exn runtime cycle)}} is thrown. - - -=== Strings - - -==== conc - -<procedure>(conc X ...)</procedure> - -Returns a string with the string-represenation of all arguments concatenated -together. {{conc}} could be implemented as - -<enscript highlight=scheme> -(define (conc . args) - (apply string-append (map ->string args)) ) -</enscript> - - - -==== ->string - -<procedure>(->string X)</procedure> - -Returns a string-representation of {{X}}. - - -==== string-chop - -<procedure>(string-chop STRING LENGTH)</procedure> - -Returns a list of substrings taken by ''chopping'' {{STRING}} every {{LENGTH}} -characters: - -<enscript highlight=scheme> -(string-chop "one two three" 4) ==> ("one " "two " "thre" "e") -</enscript> - - - -==== string-chomp - -<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"}}. - - -==== string-compare3 - -<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 -than {{STRING2}}, {{0}} if it is equal, or {{1}} if it s greater. -{{string-compare3-ci}} performs a case-insensitive comparison. - - -==== string-intersperse - -<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 -defaults to {{" "}}. - -<enscript highlight=scheme> -(string-intersperse '("one" "two") "three") -</enscript> - -is equivalent to - -<enscript highlight=scheme> -(apply string-append (intersperse '("one" "two") "three")) -</enscript> - - -==== string-split - -<procedure>(string-split STRING [DELIMITER-STRING [KEEPEMPTY]])</procedure> - -Split string into substrings delimited by any of the characters given in the delimiter string. If -no delimiters are specified, a string comprising the tab, newline and space characters -is assumed. If the -parameter {{KEEPEMPTY}} is given and not {{#f}}, then empty -substrings are retained: - -<enscript highlight=scheme> -(string-split "one two three") ==> ("one" "two" "three") -(string-split "foo:bar::baz:" ":" #t) ==> ("foo" "bar" "" "baz" "") -(string-split "foo:bar:baz,quux,zot" ":," ) ==> ("foo" "bar" "baz" "quux" "zot") -</enscript> - - -==== string-translate - -<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 -matching characters are removed. {{FROM}} and {{TO}} may be -a character, a string or a list. If both {{FROM}} and {{TO}} -are strings, then the character at the same position in {{TO}} -as the matching character in {{FROM}} is substituted. - - -==== string-translate* - -<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 -is a pair of the form {{(MATCH . REPLACEMENT)}}. Every occurrence of -the string {{MATCH}} in {{STRING}} will be replaced by the string -{{REPLACEMENT}}: - -<enscript highlight=scheme> -(string-translate* - "<h1>this is a \"string\"</h1>" - '(("<" . "<") (">" . ">") ("\"" . """)) ) -=> "<h1>this is a "string"</h1>" -</enscript> - - -==== substring=? - -<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. -The comparison starts at the positions {{START1}} and {{START2}} (which default -to 0), comparing {{LENGTH}} characters (which defaults to the minimum of the remaining -length of both strings). - - -==== substring-index - -<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, -then the search starts at that index. {{substring-index-ci}} -is a case-insensitive version of {{substring-index}}. - - -==== reverse-string-append - -<procedure>(reverse-string-append LIST)</procedure> - -{{(apply string-append (reverse LIST))}} - - -=== Combinators - - -==== any? - -<procedure>(any? X)</procedure> - -Ignores its argument and always returns {{#t}}. This is actually useful sometimes. - - -==== constantly - -<procedure>(constantly X ...)</procedure> - -Returns a procedure that always returns the values {{X ...}} regardless of the number and value of its arguments. - -<enscript highlight=scheme> -(constantly X) <=> (lambda args X) -</enscript> - - -==== complement - -<procedure>(complement PROC)</procedure> - -Returns a procedure that returns the boolean inverse of {{PROC}}. - -<enscript highlight=scheme> -(complement PROC) <=> (lambda (x) (not (PROC x))) -</enscript> - - -==== compose - -<procedure>(compose PROC1 PROC2 ...)</procedure> - -Returns a procedure that represents the composition of the -argument-procedures {{PROC1 PROC2 ...}}. - -<enscript highlight=scheme> -(compose F G) <=> (lambda args - (call-with-values - (lambda () (apply G args)) - F)) -</enscript> - -{{(compose)}} is equivalent to {{values}}. - - -==== conjoin - -<procedure>(conjoin PRED ...)</procedure> - -Returns a procedure that returns {{#t}} if its argument satisfies the -predicates {{PRED ...}}. -<enscript highlight=scheme> -((conjoin odd? positive?) 33) ==> #t -((conjoin odd? positive?) -33) ==> #f -</enscript> - - -==== disjoin - -<procedure>(disjoin PRED ...)</procedure> - -Returns a procedure that returns {{#t}} if its argument satisfies any -predicate {{PRED ...}}. -<enscript highlight=scheme> -((disjoin odd? positive?) 32) ==> #t -((disjoin odd? positive?) -32) ==> #f -</enscript> - - -==== each - -<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 - -<enscript highlight=scheme> -(each pp eval) -</enscript> - -is equivalent to - -<enscript highlight=scheme> -(lambda args - (apply pp args) - (apply eval args) ) -</enscript> - -{{(each PROC)}} is equivalent to {{PROC}} and {{(each)}} is equivalent to -{{void}}. - - -==== flip - -<procedure>(flip PROC)</procedure> - -Returns a two-argument procedure that calls {{PROC}} with its -arguments swapped: -<enscript highlight=scheme> -(flip PROC) <=> (lambda (x y) (PROC y x)) -</enscript> - - -==== identity - -<procedure>(identity X)</procedure> - -Returns its sole argument {{X}}. - - -==== list-of? - -<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 -{{PRED}}, or {{#f}} otherwise. - -<enscript highlight=scheme> -((list-of? even?) '(1 2 3)) ==> #f -((list-of? number?) '(1 2 3)) ==> #t -</enscript> - - -==== o - -<procedure>(o PROC ...)</procedure> - -A single value version of {{compose}} (slightly faster). {{(o)}} is equivalent -to {{identity}}. - - ---- -Previous: [[Unit expand]] - -Next: [[Unit ports]] diff --git a/manual/Unit eval b/manual/Unit eval deleted file mode 100644 index 25e863b8..00000000 --- a/manual/Unit eval +++ /dev/null @@ -1,184 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit eval - -This unit has support for evaluation and macro-handling. This unit is used -by default, unless the program is compiled with the {{-explicit-use}} -option. - -=== Loading code - -==== load - -<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 {{EVALPROC}} -(which defaults to {{eval}}). On platforms that support it (currently BSD, -Haiku, MacOS X, Linux, Solaris, and Windows), {{load}} can be used to load -compiled programs: - - % cat x.scm - (define (hello) (print "Hello!")) - % csc -s x.scm - % csi -q - #;1> (load "x.so") - ; loading x.so ... - #;2> (hello) - Hello! - #;3> - -The second argument to {{load}} is ignored when loading compiled -code. -If source code is loaded from a port, then that port is closed after -all expressions have been read. - -A compiled file can only be loaded once. Subsequent attempts to load the -same file have no effect. - -==== load-relative - -<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> - -As {{load}} but the result(s) of each evaluated toplevel-expression -is written to standard output. If {{EVALUATOR}} is given and not {{#f}}, -then each expression is evaluated by calling this argument with the read -expression as argument. If {{TIME}} is given and not false, then -the execution time of each expression is shown (as with the {{time}} macro). -If {{PRINTER}} is given and not false, then each expression is -printed before evaluation by applying the expression to the value of this -argument, which should be a one-argument procedure. - -See also the [[Parameters#load-verbose|load-verbose]] parameter. - -==== load-library - -<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 -string {{LIBRARYFILE}} is given, then the given shared library will -be loaded and the toplevel code of the specified unit will be executed. -If no {{LIBRARYFILE}} argument is given, then the libraries given in the -parameter {{dynamic-load-libraries}} are searched for the required unit. -If the unit is not found, an error is signaled. - -Note that {{LIBRARYFILE}} is considered relative to the {{dlopen(3)}} -search path by default. In order to use a file relative to the current -working directory, a relative or absolute pathname must be used, i.e. -{{LIBRARYFILE}} must contain at least one slash ({{"/"}}). - -==== set-dynamic-load-mode! - -<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 -fine-tune the behaviour of the dynamic linker. {{MODE}} should be a list of -symbols (or a single symbol) taken from the following set: - -; {{local}} : If {{local}} is given, then any C/C++ symbols defined in the dynamically loaded file are not available for subsequently loaded files and libraries. Use this if you have linked foreign code into your dynamically loadable file and if you don't want to export them (for example because you want to load another file that defines the same symbols). -; {{global}} : The default is {{global}}, which means all C/C++ symbols are available to code loaded at a later stage. -; {{now}} : If {{now}} is specified, all symbols are resolved immediately. -; {{lazy}} : Unresolved symbols are resolved as code from the file is executed. This is the default. - -Note that this procedure does not control the way Scheme variables are handled - -this facility is mainly of interest when accessing foreign code. - - -=== Loading extension libraries - -This functionality is only available on platforms that support dynamic -loading of compiled code. Currently Linux, BSD, Solaris, Windows (with -Cygwin) and HP/UX are supported. - -==== load-extension - -<procedure>(load-extension ID)</procedure> - -If the extension library {{ID}} is not already loaded into the -system, then {{load-extension}} will look up the location of the shared -extension library and load it. If {{ID}} names a library-unit of the -base system, then it is loaded via {{load-library}}. If no extension -library is available for the given ID, then an attempt is made to load -the file {{ID.so}} or {{ID.scm}} (in that order) from one of the -following locations: - -* the current directory -* the current repository path (see {{repository-path}}) - -{{ID}} should be a symbol. - -==== repository-path - -<parameter>repository-path</parameter> - -Contains a string naming the paths to the extension repository, which -defaults to -either the value of the environment variable {{CHICKEN_REPOSITORY_PATH}} -or the default library path -(usually {{/usr/local/lib/chicken}} on UNIX systems). If multiple -directories are given, then they should be separated by {{:}} -(or {{;}} on Windows.) - -==== installation-repository - -<parameter>installation-repository</parameter> - -Contains the name of the directory where extensions are installed -(as opposed to the possible locations where they can be loaded or -linked at runtime.) - -==== require - -<procedure>(require ID ...)</procedure> - -An alias for {{load-extension}} that allows multiple extension -identifiers to be provided. - -==== provide - -<procedure>(require ID ...)</procedure> - -Registers the extension IDs {{ID ...}} as loaded. This is mainly -intended to provide aliases for certain library identifiers. - -==== provided? - -procedure: (provided? ID ...) - -Returns {{#t}} if extension with the IDs {{ID ...}} are currently -loaded, or {{#f}} otherwise. - - -=== System information - -==== chicken-home - -<procedure>(chicken-home)</procedure> - -Returns a string which represents the installation directory (usually {{/usr/local/share/chicken}} on UNIX-like systems). - - -=== Eval - -==== eval - -<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)}}. - - ---- -Previous: [[Unit library]] - -Next: [[Unit repl]] diff --git a/manual/Unit expand b/manual/Unit expand deleted file mode 100644 index add35003..00000000 --- a/manual/Unit expand +++ /dev/null @@ -1,80 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit expand - -This unit has support for syntax- and module handling. This unit is used -by default, unless the program is compiled with the {{-explicit-use}} -option. - -=== Macros - -==== get-line-number - -<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 the associated source file and line number as a string. If -line-number information is not available, then {{#f}} is returned. -Note that line-number information for expressions is only available in -the compiler. - -==== expand - -<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> - -Signals an exception of the kind {{(exn syntax)}}. Otherwise identical to -{{error}}. - - -==== er-macro-transformer - -<procedure>(er-macro-transformer TRANSFORMER)</procedure> - -Returns an explicit-renaming macro transformer procedure created from -the procedural macro body {{TRANSFORMER}}, which is a procedure of -three arguments. - -Implementation note: this procedure currently just returns its -argument unchanged and is available for writing low-level macros in a -more portable fashion, without hard-coding the signature of a -transformer procedure. - -==== ir-macro-transformer - -<procedure>(ir-macro-transformer TRANSFORMER)</procedure> - -This procedure accepts a ''reverse'' syntax transformer, also known as -an ''implicit renaming macro transformer''. This is a transformer which -works almost like er-macro-transformer, except the rename and compare -procedures it receives work a little differently. - -The rename procedure is now called {{inject}} and instead of renaming -the identifier to be resolved in the macro's definition environment, -it will explicitly ''inject'' the identifier to be resolved in the -expansion environment. Any non-injected identifiers in the output -expression produced by the transformer will be implicitly renamed to -refer to the macro's environment instead. All identifiers in the -input expression are of course implicitly injected just like with -explicit renaming macros. - -To compare an input identifier you can generally compare to the bare -symbol and only free identifiers will match. In practice, this means -that when you would call e.g. {{(compare (cadr expression) (rename 'x))}} -in an ER macro, you simply call {{(compare (cadr expression) 'x)}} in the -IR macro. Likewise, an ''unhygienic'' ER macro's comparison -{{(compare sym 'abc)}} should be written as {{(compare sym (inject 'abc))}} -in an IR macro. - ---- -Previous: [[Unit library]] - -Next: [[Unit data-structures]] diff --git a/manual/Unit extras b/manual/Unit extras deleted file mode 100644 index 63ea0b12..00000000 --- a/manual/Unit extras +++ /dev/null @@ -1,192 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit extras - -This unit contains a collection of useful utility definitions. The unit is -used in {{csi}} by default. - -=== Random numbers - -These procedures are provided by the {{(chicken random)}} module. - -==== randomize - -<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 -random number generator is initialized with the current time. - - -==== random - -<procedure>(random N)</procedure> - -Returns a pseudo-random {{integer}} in {{[0, N-1]}}. {{N}} is an {{integer}}. - -On Windows, {{N}} and the random value are {{exact integer}}. - -'''Warning''': This procedure uses ''rand(3)'' internally and exhibits -its deficiencies, including low quality pseudo-randomness: - -* On Windows and Solaris, only 32768 unique random values can be -generated in the range {{[0, N-1]}}. If {{N >= 32768}}, there -will be gaps in the result set. -* On Mac OS X, Windows and some other platforms, little variance in output is seen -with nearby seeds. Since the random generator is seeded -with {{current-seconds}} at startup, new processes may see similar or -identical random sequences for up to a minute. -* On Linux, ''rand(3)'' is an alias to ''random(3)'', which provides -output of reasonable quality. - - -=== Formatted output - -These procedures are provided by the {{(chicken format)}} module. - -==== printf -==== fprintf -==== sprintf - -<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 -({{sprintf}}). The {{FORMATSTRING}} can contain any sequence -of characters. There must be at least as many {{ARG}} arguments given as there are format directives that require an argument in {{FORMATSTRING}}. Extra {{ARG}} arguments are ignored. The character `~' prefixes special formatting directives: - -<table> -<tr><td>~%</td><td> -write newline character -</td></tr><tr><td> ~N</td><td> -the same as {{~%}} -</td></tr><tr><td> ~S</td><td> -write the next argument -</td></tr><tr><td> ~A</td><td> -display the next argument -</td></tr><tr><td> ~\n</td><td> -skip all whitespace in the format-string until the next non-whitespace character -</td></tr><tr><td> ~B</td><td> -write the next argument as a binary number -</td></tr><tr><td> ~O</td><td> -write the next argument as an octal number -</td></tr><tr><td> ~X</td><td> -write the next argument as a hexadecimal number -</td></tr><tr><td> ~C</td><td> -write the next argument as a character -</td></tr><tr><td> ~~</td><td> -display `~' -</td></tr><tr><td> ~!</td><td> -flush all pending output -</td></tr><tr><td> ~?</td><td> -invoke formatted output routine recursively with the next two arguments as format-string and list of parameters -</td></tr></table> - - -==== format - -<procedure>(format [DESTINATION] FORMATSTRING [ARG...])</procedure> - -The parameters {{FORMATSTRING}} and {{ARG...}} are as for {{printf}}. - -The optional {{DESTINATION}}, when supplied, performs: - -; {{#f}} : {{sprintf}} -; {{#t}} : {{printf}} -; {{output-port}} : {{fprintf}} -; : {{sprintf}} - - -=== Pretty-printing - -These procedures are provided by the {{(chicken pretty-print)}} module. - -==== pretty-print - -<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)}}. - - -==== pretty-print-width -<parameter>pretty-print-width</parameter> - -Specifies the maximal line-width for pretty printing, after which line -wrap will occur. - - -=== Input/Output extensions - -These procedures are provided by the {{(chicken io)}} module. - -==== read-byte -==== write-byte - -<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-line -==== write-line - -<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)}}, -respectively. If the optional argument {{LIMIT}} is given and -not {{#f}}, then {{read-line}} reads at most {{LIMIT}} -characters per line. {{read-line}} returns a string without the terminating newline and {{write-line}} adds a terminating newline before outputting. - - -==== read-lines - -<procedure>(read-lines [PORT [MAX]])</procedure> - -Read {{MAX}} or fewer lines from {{PORT}}. {{PORT}} defaults to the -value of {{(current-input-port)}}. Returns a list of strings, each -string representing a line read, not including any line separation -character(s). - - -==== read-string -==== read-string! -==== write-string - -<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. - -If {{NUM}} is {{#f}} or not given, then all data up to the end-of-file is -read, or, in the case of {{write-string}} the whole string is written. If no -more input is available, {{read-string}} returns {{#!eof}}. - -{{read-string!}} reads destructively into the given {{STRING}} argument, but -never more characters than would fit into {{STRING}}. If {{START}} is given, -then the read characters are stored starting at that position. -{{read-string!}} returns the actual number of characters read. - - -==== read-token - -<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 -false. Returns a string with the accumulated characters. - ---- -Previous: [[Unit files]] - -Next: [[Unit irregex]] diff --git a/manual/Unit files b/manual/Unit files deleted file mode 100644 index ce0d969d..00000000 --- a/manual/Unit files +++ /dev/null @@ -1,175 +0,0 @@ -[[tags: manual]] -[[toc:]] - - -== Unit files - -This unit contains file- and pathname-oriented procedures. It uses the {{regex}} unit. - - -=== Pathname operations - -==== absolute-pathname? - -<procedure>(absolute-pathname? PATHNAME)</procedure> - -Returns {{#t}} if the string {{PATHNAME}} names an absolute -pathname, and returns {{#f}} otherwise. - -==== decompose-pathname - -<procedure>(decompose-pathname PATHNAME)</procedure> - -Returns three values: the directory-, filename- and extension-components -of the file named by the string {{PATHNAME}}. -For any component that is not contained in {{PATHNAME}}, {{#f}} is returned. - -==== make-pathname -==== make-absolute-pathname - -<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 -components {{DIRECTORY, FILENAME}} and (optionally) -{{EXTENSION}} with {{SEPARATOR}} being the directory separation indicator -(usually {{/}} on UNIX systems and {{\}} on Windows, defaulting to whatever -platform this is running on). -{{DIRECTORY}} can be {{#f}} (meaning no -directory component), a string or a list of strings. {{FILENAME}} -and {{EXTENSION}} should be strings or {{#f}}. -{{make-absolute-pathname}} returns always an absolute pathname. - -==== pathname-directory -==== pathname-file -==== 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 -==== pathname-replace-file -==== 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 -==== 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}} -stripped. - -==== normalize-pathname - -<procedure>(normalize-pathname PATHNAME [PLATFORM])</procedure> - -Performs a simple "normalization" on the {{PATHNAME}}, suitably for -{{PLATFORM}}, which should be one of the symbols {{windows}} -or {{unix}} and defaults to on whatever platform is currently -in use. All relative path elements and duplicate separators are processed -and removed. If {{NAME}} ends with -a {{/}} or is empty, the appropriate slash is appended to the tail. - -No directories or files are actually tested for existence; this -procedure only canonicalises path syntax. - -==== directory-null? - -<procedure>(directory-null? DIRECTORY)</procedure> - -Does the {{DIRECTORY}} consist only of path separators and the period? - -{{DIRECTORY}} may be a string or a list of strings. - -==== decompose-directory - -<procedure>(decompose-directory DIRECTORY)</procedure> - -Returns 3 values: the {{base-origin}}, {{base-directory}}, and the -{{directory-elements}} for the {{DIRECTORY}}. - -; {{base-origin}} : a {{string}} or {{#f}}. The drive, if any. -; {{base-directory}} : a {{string}} or {{#f}}. A directory-separator when {{DIRECTORY}} is an {{absolute-pathname}}. -; {{directory-elements}} : a {{list-of string}} or {{#f}}. The non-directory-separator bits. - -{{DIRECTORY}} is a {{string}}. - -* On Windows {{(decompose-directory "c:foo/bar")}} => {{"c:" #f ("foo" "bar")}} - - -=== Temporary files and directories - -==== create-temporary-file - -<procedure>(create-temporary-file [EXTENSION])</procedure> - -Creates an empty temporary file and returns its pathname. If -{{EXTENSION}} is not given, then {{.tmp}} is used. If the -environment variable {{TMPDIR, TEMP}} or {{TMP}} is set, -then the pathname names a file in that directory. If none of -the environment variables is given the location of the -temporary file defaults to {{/tmp}} if it exists or the -current-directory - - -==== create-temporary-directory - -<procedure>(create-temporary-directory)</procedure> - -Creates an empty temporary directory and returns its pathname. If the -environment variable {{TMPDIR, TEMP}} or {{TMP}} is set, then the -temporary directory is created at that location. - - -=== Deleting a file without signalling an error - -==== delete-file* - -<procedure>(delete-file* FILENAME)</procedure> - -If the file {{FILENAME}} exists, it is deleted and {{#t}} -is returned. If the file does not exist, nothing happens and {{#f}} -is returned. - - -=== File move/copy - -==== file-copy - -<procedure>(file-copy ORIGFILE NEWFILE #!optional CLOBBER BLOCKSIZE)</procedure> - -Copies {{ORIGFILE}} (a string denoting some filename) to {{NEWFILE}}, -{{BLOCKSIZE}} bytes at a time. {{BLOCKSIZE}} defaults to 1024, and must be -a positive integer. Returns the number of bytes copied on success, or errors -on failure. {{CLOBBER}} determines the behaviour of {{file-copy}} when -{{NEWFILE}} is already extant. When set to {{#f}} (default), an error is -signalled. When set to any other value, {{NEWFILE}} is overwritten. -{{file-copy}} will work across filesystems and devices and is not -platform-dependent. - -==== file-move - -<procedure>(file-move ORIGFILE NEWFILE #!optional CLOBBER BLOCKSIZE)</procedure> - -Moves {{ORIGFILE}} (a string denoting some filename) to {{NEWFILE}}, with -the same semantics as {{file-copy}}, above. {{file-move}} is safe across -filesystems and devices (unlike {{rename-file}}). It is possible for an -error to be signalled despite partial success if {{NEWFILE}} could be created -and fully written but removing {{ORIGFILE}} fails. - ---- -Previous: [[Unit ports]] - -Next: [[Unit extras]] diff --git a/manual/Unit irregex b/manual/Unit irregex deleted file mode 100644 index 063a918b..00000000 --- a/manual/Unit irregex +++ /dev/null @@ -1,835 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit irregex - -This library unit provides support for regular expressions, using the -powerful ''irregex'' regular expression engine by Alex Shinn. It -supports both POSIX syntax with various (irregular) PCRE extensions, -as well as SCSH's SRE syntax, with various aliases for commonly used -patterns. DFA matching is used when possible, otherwise a -closure-compiled NFA approach is used. Matching may be performed over -standard Scheme strings, or over arbitrarily chunked streams of -strings. - -On systems that support dynamic loading, the {{irregex}} unit can -be made available in the CHICKEN interpreter ({{csi}}) by entering - -<enscript highlight=scheme> -(require-extension irregex) -</enscript> - -=== Specification - -==== Procedures - -===== irregex -===== string->irregex -===== sre->irregex - -<procedure>(irregex <posix-string-or-sre> [<options> ...])</procedure><br> -<procedure>(string->irregex <posix-string> [<options> ...])</procedure><br> -<procedure>(sre->irregex <sre> [<options> ...])</procedure><br> - -Compiles a regular expression from either a POSIX-style regular -expression string (with most PCRE extensions) or an SCSH-style SRE. -There is no {{(rx ...)}} syntax - just use normal Scheme lists, with -{{quasiquote}} if you like. - -Technically a string by itself could be considered a valid (though -rather silly) SRE, so if you want to just match a literal string you -should use something like {{(irregex `(: ,str))}}, or use the explicit -{{(sre->irregex str)}}. - -The options are a list of any of the following symbols: - -; {{'i}}, {{'case-insensitive}} : match case-insensitively -; {{'m}}, {{'multi-line}} : treat string as multiple lines (effects {{^}} and {{$}}) -; {{'s}}, {{'single-line}} : treat string as a single line ({{.}} can match newline) -; {{'utf8}} : utf8-mode (assumes strings are byte-strings) -; {{'fast}} : try to optimize the regular expression -; {{'small}} : try to compile a smaller regular expression -; {{'backtrack}} : enforce a backtracking implementation - -The {{'fast}} and {{'small}} options are heuristic guidelines and will -not necessarily make the compiled expression faster or smaller. - -===== string->sre -===== maybe-string->sre - -<procedure>(string->sre <str>)</procedure><br> -<procedure>(maybe-string->sre <obj>)</procedure><br> - -For backwards compatibility, procedures to convert a POSIX string into -an SRE. - -{{maybe-string->sre}} does the same thing, but only if the argument is -a string, otherwise it assumes {{<obj>}} is an SRE and returns it -as-is. This is useful when you want to provide an API that allows -either a POSIX string or SRE (like {{irregex}} or {{irregex-search}} -below) - it ensures the result is an SRE. - -===== irregex? - -<procedure>(irregex? <obj>)</procedure><br> - -Returns {{#t}} iff the object is a regular expression. - -===== irregex-search - -<procedure>(irregex-search <irx> <str> [<start> <end>])</procedure> - -Searches for any instances of the pattern {{<irx>}} (a POSIX string, SRE -sexp, or pre-compiled regular expression) in {{<str>}}, optionally between -the given range. If a match is found, returns a match object, -otherwise returns {{#f}}. - -Match objects can be used to query the original range of the string or -its submatches using the {{irregex-match-*}} procedures below. - -Examples: - -<enscript highlight=scheme> -(irregex-search "foobar" "abcFOOBARdef") => #f - -(irregex-search (irregex "foobar" 'i) "abcFOOBARdef") => #<match> - -(irregex-search '(w/nocase "foobar") "abcFOOBARdef") => #<match> -</enscript> - -Note, the actual match result is represented by a vector in the -default implementation. Throughout this manual, we'll just write -{{#<match>}} to show that a successful match was returned when the -details are not important. - -Matching follows the POSIX leftmost, longest semantics, when -searching. That is, of all possible matches in the string, -{{irregex-search}} will return the match at the first position -(leftmost). If multiple matches are possible from that same first -position, the longest match is returned. - -===== irregex-match - -<procedure>(irregex-match <irx> <str> [<start> <end>])</procedure> - -Like {{irregex-search}}, but performs an anchored match against the -beginning and end of the substring specified by {{<start>}} and {{<end>}}, -without searching. - -Examples: - -<enscript highlight=scheme> -(irregex-match '(w/nocase "foobar") "abcFOOBARdef") => #f - -(irregex-match '(w/nocase "foobar") "FOOBAR") => #<match> -</enscript> - -===== irregex-match-data? - -<procedure>(irregex-match-data? <obj>)</procedure> - -Returns {{#t}} iff the object is a successful match result from -{{irregex-search}} or {{irregex-match}}. - -===== irregex-num-submatches -===== irregex-match-num-submatches - -<procedure>(irregex-num-submatches <irx>)</procedure><br> -<procedure>(irregex-match-num-submatches <match>)</procedure> - -Returns the number of numbered submatches that are defined in the -irregex or match object. - -===== irregex-names -===== irregex-match-names - -<procedure>(irregex-names <irx>)</procedure><br> -<procedure>(irregex-match-names <match>)</procedure> - -Returns an association list of named submatches that are defined in -the irregex or match object. The {{car}} of each item in this list is -the name of a submatch, the {{cdr}} of each item is the numerical -submatch corresponding to this name. If a named submatch occurs -multiple times in the irregex, it will also occur multiple times in -this list. - -===== irregex-match-valid-index? - -<procedure>(irregex-match-valid-index? <match> <index-or-name>)</procedure><br> - -Returns {{#t}} iff the {{index-or-name}} named submatch or index is -defined in the {{match}} object. - -===== irregex-match-substring -===== irregex-match-start-index -===== irregex-match-end-index - -<procedure>(irregex-match-substring <match> [<index-or-name>])</procedure><br> -<procedure>(irregex-match-start-index <match> [<index-or-name>])</procedure><br> -<procedure>(irregex-match-end-index <match> [<index-or-name>])</procedure> - -Fetches the matched substring (or its start or end offset) at the -given submatch index, or named submatch. The entire match is index 0, -the first 1, etc. The default is index 0. - -===== irregex-match-subchunk - -<procedure>(irregex-match-subchunk <match> [<index-or-name>])</procedure> - -Generates a chunked data-type for the given match item, of the same -type as the underlying chunk type (see Chunked String Matching below). -This is only available if the chunk type specifies the get-subchunk -API, otherwise an error is raised. - -===== irregex-replace -===== irregex-replace/all - -<procedure>(irregex-replace <irx> <str> [<replacements> ...])</procedure><br> -<procedure>(irregex-replace/all <irx> <str> [<replacements> ...])</procedure> - -Matches a pattern in a string, and replaces it with a (possibly empty) -list of substitutions. Each {{<replacement>}} can be either a string -literal, a numeric index, a symbol (as a named submatch), or a -procedure which takes one argument (the match object) and returns a -string. - -Examples: - -<enscript highlight=scheme> -(irregex-replace "[aeiou]" "hello world" "*") => "h*llo world" - -(irregex-replace/all "[aeiou]" "hello world" "*") => "h*ll* w*rld" - -(irregex-replace "(.)(.)" "ab" 2 1 "*") => "ba*" - -(irregex-replace "...bar" "xxfoobar" (lambda (m) - (string-reverse (irregex-match-substring m)))) => "xxraboof" - -(irregex-replace "(...)(bar)" "xxfoobar" 2 (lambda (m) - (string-reverse (irregex-match-substring m 1)))) => "xxbaroof" -</enscript> -===== irregex-split -===== irregex-extract - -<procedure>(irregex-split <irx> <str> [<start> <end>])</procedure><br> -<procedure>(irregex-extract <irx> <str> [<start> <end>])</procedure> - -{{irregex-split}} splits the string {{<str>}} into substrings divided -by the pattern in {{<irx>}}. {{irregex-extract}} does the opposite, -returning a list of each instance of the pattern matched disregarding -the substrings in between. - -===== irregex-fold - -<procedure>(irregex-fold <irx> <kons> <knil> <str> [<finish> <start> <end>])</procedure> - -This performs a fold operation over every non-overlapping place -{{<irx>}} occurs in the string {{str}}. - -The {{<kons>}} procedure takes the following signature: - -<enscript highlight=scheme> -(<kons> <from-index> <match> <seed>) -</enscript> - -where {{<from-index>}} is the index from where we started searching -(initially {{<start>}} and thereafter the end index of the last -match), {{<match>}} is the resulting match-data object, and {{<seed>}} -is the accumulated fold result starting with {{<knil>}}. - -The rationale for providing the {{<from-index>}} (which is not -provided in the SCSH {{regexp-fold}} utility), is because this -information is useful (e.g. for extracting the unmatched portion of -the string before the current match, as needed in -{{irregex-replace}}), and not otherwise directly accessible. - -The optional {{<finish>}} takes two arguments: - -<enscript highlight=scheme> -(<finish> <from-index> <seed>) -</enscript> - -which simiarly allows you to pick up the unmatched tail of the string, -and defaults to just returning the {{<seed>}}. - -{{<start>}} and {{<end>}} are numeric indices letting you specify the -boundaries of the string on which you want to fold. - -To extract all instances of a match out of a string, you can use - -<enscript highlight=scheme> -(map irregex-match-substring - (irregex-fold <irx> - (lambda (i m s) (cons m s)) - '() - <str> - (lambda (i s) (reverse s)))) -</enscript> - -==== Extended SRE Syntax - -Irregex provides the first native implementation of SREs (Scheme -Regular Expressions), and includes many extensions necessary both for -minimal POSIX compatibility, as well as for modern extensions found in -libraries such as PCRE. - -The following table summarizes the SRE syntax, with detailed -explanations following. - - ;; basic patterns - <string> ; literal string - (seq <sre> ...) ; sequence - (: <sre> ...) - (or <sre> ...) ; alternation - - ;; optional/multiple patterns - (? <sre> ...) ; 0 or 1 matches - (* <sre> ...) ; 0 or more matches - (+ <sre> ...) ; 1 or more matches - (= <n> <sre> ...) ; exactly <n> matches - (>= <n> <sre> ...) ; <n> or more matches - (** <from> <to> <sre> ...) ; <n> to <m> matches - (?? <sre> ...) ; non-greedy (non-greedy) pattern: (0 or 1) - (*? <sre> ...) ; non-greedy kleene star - (**? <from> <to> <sre> ...) ; non-greedy range - - ;; submatch patterns - (submatch <sre> ...) ; numbered submatch - ($ <sre> ...) - (submatch-named <name> <sre> ...) ; named submatch - (=> <name> <sre> ...) - (backref <n-or-name>) ; match a previous submatch - - ;; toggling case-sensitivity - (w/case <sre> ...) ; enclosed <sre>s are case-sensitive - (w/nocase <sre> ...) ; enclosed <sre>s are case-insensitive - - ;; character sets - <char> ; singleton char set - (<string>) ; set of chars - (or <cset-sre> ...) ; set union - (~ <cset-sre> ...) ; set complement (i.e. [^...]) - (- <cset-sre> ...) ; set difference - (& <cset-sre> ...) ; set intersection - (/ <range-spec> ...) ; pairs of chars as ranges - - ;; named character sets - any - nonl - ascii - lower-case lower - upper-case upper - alphabetic alpha - numeric num - alphanumeric alphanum alnum - punctuation punct - graphic graph - whitespace white space - printing print - control cntrl - hex-digit xdigit - - ;; assertions and conditionals - bos eos ; beginning/end of string - bol eol ; beginning/end of line - bow eow ; beginning/end of word - nwb ; non-word-boundary - (look-ahead <sre> ...) ; zero-width look-ahead assertion - (look-behind <sre> ...) ; zero-width look-behind assertion - (neg-look-ahead <sre> ...) ; zero-width negative look-ahead assertion - (neg-look-behind <sre> ...) ; zero-width negative look-behind assertion - (atomic <sre> ...) ; for (?>...) independent patterns - (if <test> <pass> [<fail>]) ; conditional patterns - commit ; don't backtrack beyond this (i.e. cut) - - ;; backwards compatibility - (posix-string <string>) ; embed a POSIX string literal - -===== Basic SRE Patterns - -The simplest SRE is a literal string, which matches that string -exactly. - -<enscript highlight=scheme> -(irregex-search "needle" "hayneedlehay") => #<match> -</enscript> - -By default the match is case-sensitive, though you can control this -either with the compiler flags or local overrides: - -<enscript highlight=scheme> -(irregex-search "needle" "haynEEdlehay") => #f - -(irregex-search (irregex "needle" 'i) "haynEEdlehay") => #<match> - -(irregex-search '(w/nocase "needle") "haynEEdlehay") => #<match> -</enscript> - -You can use {{w/case}} to switch back to case-sensitivity inside a -{{w/nocase}} or when the SRE was compiled with {{'i}}: - -<enscript highlight=scheme> -(irregex-search '(w/nocase "SMALL" (w/case "BIG")) "smallBIGsmall") => #<match> - -(irregex-search '(w/nocase "small" (w/case "big")) "smallBIGsmall") => #f -</enscript> - -''Important:'' characters outside the ASCII range (ie, UTF8 chars) are -'''not''' matched case insensitively! - -Of course, literal strings by themselves aren't very interesting -regular expressions, so we want to be able to compose them. The most -basic way to do this is with the {{seq}} operator (or its abbreviation -{{:}}), which matches one or more patterns consecutively: - -<enscript highlight=scheme> -(irregex-search '(: "one" space "two" space "three") "one two three") => #<match> -</enscript> - -As you may have noticed above, the {{w/case}} and {{w/nocase}} -operators allowed multiple SREs in a sequence - other operators that -take any number of arguments (e.g. the repetition operators below) -allow such implicit sequences. - -To match any one of a set of patterns use the {{or}} alternation -operator: - -<enscript highlight=scheme> -(irregex-search '(or "eeney" "meeney" "miney") "meeney") => #<match> - -(irregex-search '(or "eeney" "meeney" "miney") "moe") => #f -</enscript> - -===== SRE Repetition Patterns - -There are also several ways to control the number of times a pattern -is matched. The simplest of these is {{?}} which just optionally -matches the pattern: - -<enscript highlight=scheme> -(irregex-search '(: "match" (? "es") "!") "matches!") => #<match> - -(irregex-search '(: "match" (? "es") "!") "match!") => #<match> - -(irregex-search '(: "match" (? "es") "!") "matche!") => #f -</enscript> - -To optionally match any number of times, use {{*}}, the Kleene star: - -<enscript highlight=scheme> -(irregex-search '(: "<" (* (~ #\>)) ">") "<html>") => #<match> - -(irregex-search '(: "<" (* (~ #\>)) ">") "<>") => #<match> - -(irregex-search '(: "<" (* (~ #\>)) ">") "<html") => #f -</enscript> - -Often you want to match any number of times, but at least one time is -required, and for that you use {{+}}: - -<enscript highlight=scheme> -(irregex-search '(: "<" (+ (~ #\>)) ">") "<html>") => #<match> - -(irregex-search '(: "<" (+ (~ #\>)) ">") "<a>") => #<match> - -(irregex-search '(: "<" (+ (~ #\>)) ">") "<>") => #f -</enscript> - -More generally, to match at least a given number of times, use {{>=}}: - -<enscript highlight=scheme> -(irregex-search '(: "<" (>= 3 (~ #\>)) ">") "<table>") => #<match> - -(irregex-search '(: "<" (>= 3 (~ #\>)) ">") "<pre>") => #<match> - -(irregex-search '(: "<" (>= 3 (~ #\>)) ">") "<tr>") => #f -</enscript> - -To match a specific number of times exactly, use {{=}}: - -<enscript highlight=scheme> -(irregex-search '(: "<" (= 4 (~ #\>)) ">") "<html>") => #<match> - -(irregex-search '(: "<" (= 4 (~ #\>)) ">") "<table>") => #f -</enscript> - -And finally, the most general form is {{**}} which specifies a range -of times to match. All of the earlier forms are special cases of this. - -<enscript highlight=scheme> -(irregex-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric)) "192.168.1.10") => #<match> - -(irregex-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric)) "192.0168.1.10") => #f -</enscript> - -There are also so-called "non-greedy" variants of these repetition -operators, by convention suffixed with an additional {{?}}. Since the -normal repetition patterns can match any of the allotted repetition -range, these operators will match a string if and only if the normal -versions matched. However, when the endpoints of which submatch -matched where are taken into account (specifically, all matches when -using irregex-search since the endpoints of the match itself matter), -the use of a non-greedy repetition can change the result. - -So, whereas {{?}} can be thought to mean "match or don't match," -{{??}} means "don't match or match." {{*}} typically consumes as much -as possible, but {{*?}} tries first to match zero times, and only -consumes one at a time if that fails. If you have a greedy operator -followed by a non-greedy operator in the same pattern, they can -produce surprisins results as they compete to make the match longer or -shorter. If this seems confusing, that's because it is. Non-greedy -repetitions are defined only in terms of the specific backtracking -algorithm used to implement them, which for compatibility purposes -always means the Perl algorithm. Thus, when using these patterns you -force IrRegex to use a backtracking engine, and can't rely on -efficient execution. - -===== SRE Character Sets - -Perhaps more common than matching specific strings is matching any of -a set of characters. You can use the {{or}} alternation pattern on a -list of single-character strings to simulate a character set, but this -is too clumsy for everyday use so SRE syntax allows a number of -shortcuts. - -A single character matches that character literally, a trivial -character class. More conveniently, a list holding a single element -which is a string refers to the character set composed of every -character in the string. - -<enscript highlight=scheme> -(irregex-match '(* #\-) "---") => #<match> - -(irregex-match '(* #\-) "-_-") => #f - -(irregex-match '(* ("aeiou")) "oui") => #<match> - -(irregex-match '(* ("aeiou")) "ouais") => #f -</enscript> - -Ranges are introduced with the {{/}} operator. Any strings or -characters in the {{/}} are flattened and then taken in pairs to -represent the start and end points, inclusive, of character ranges. - -<enscript highlight=scheme> -(irregex-match '(* (/ "AZ09")) "R2D2") => #<match> - -(irregex-match '(* (/ "AZ09")) "C-3PO") => #f -</enscript> - -In addition, a number of set algebra operations are provided. {{or}}, -of course, has the same meaning, but when all the options are -character sets it can be thought of as the set union operator. This -is further extended by the {{&}} set intersection, {{-}} set -difference, and {{~}} set complement operators. - -<enscript highlight=scheme> -(irregex-match '(* (& (/ "az") (~ ("aeiou")))) "xyzzy") => #<match> - -(irregex-match '(* (& (/ "az") (~ ("aeiou")))) "vowels") => #f - -(irregex-match '(* (- (/ "az") ("aeiou"))) "xyzzy") => #<match> - -(irregex-match '(* (- (/ "az") ("aeiou"))) "vowels") => #f -</enscript> - -===== SRE Assertion Patterns - -There are a number of times it can be useful to assert something about -the area around a pattern without explicitly making it part of the -pattern. The most common cases are specifically anchoring some -pattern to the beginning or end of a word or line or even the whole -string. For example, to match on the end of a word: - -<enscript highlight=scheme> -(irregex-search '(: "foo" eow) "foo") => #<match> - -(irregex-search '(: "foo" eow) "foo!") => #<match> - -(irregex-search '(: "foo" eow) "foof") => #f -</enscript> - -The {{bow}}, {{bol}}, {{eol}}, {{bos}} and {{eos}} work similarly. -{{nwb}} asserts that you are not in a word-boundary - if replaced for -{{eow}} in the above examples it would reverse all the results. - -There is no {{wb}}, since you tend to know from context whether it -would be the beginning or end of a word, but if you need it you can -always use {{(or bow eow)}}. - -Somewhat more generally, Perl introduced positive and negative -look-ahead and look-behind patterns. Perl look-behind patterns are -limited to a fixed length, however the IrRegex versions have no such -limit. - -<enscript highlight=scheme> -(irregex-search '(: "regular" (look-ahead " expression")) - "regular expression") - => #<match> -</enscript> - -The most general case, of course, would be an {{and}} pattern to -complement the {{or}} pattern - all the patterns must match or the -whole pattern fails. This may be provided in a future release, -although it (and look-ahead and look-behind assertions) are unlikely -to be compiled efficiently. - -===== SRE Utility Patterns - -The following utility regular expressions are also provided for common -patterns that people are eternally reinventing. They are not -necessarily the official patterns matching the RFC definitions of the -given data, because of the way that such patterns tend to be used. -There are three general usages for regexps: - -; searching : search for a pattern matching a desired object in a larger text - -; validation : determine whether an entire string matches a pattern - -; extraction : given a string already known to be valid, extract certain fields from it as submatches - -In some cases, but not always, these will overlap. When they are -different, {{irregex-search}} will naturally always want the searching -version, so IrRegex provides that version. - -As an example where these might be different, consider a URL. If you -want to match all the URLs in some arbitrary text, you probably want -to exclude a period or comma at the tail end of a URL, since it's more -likely being used as punctuation rather than part of the URL, despite -the fact that it would be valid URL syntax. - -Another problem with the RFC definitions is the standard itself may -have become irrelevant. For example, the pattern IrRegex provides for -email addresses doesn't match quoted local parts (e.g. -{{"first last"@domain.com}}) because these are increasingly rare, and -unsupported by enough software that it's better to discourage their use. -Conversely, technically consecutive periods -(e.g. {{first..last@domain.com}}) are not allowed in email addresses, but -most email software does allow this, and in fact such addresses are -quite common in Japan. - -The current patterns provided are: - - newline ; general newline pattern (crlf, cr, lf) - integer ; an integer - real ; a real number (including scientific) - string ; a "quoted" string - symbol ; an R5RS Scheme symbol - ipv4-address ; a numeric decimal ipv4 address - ipv6-address ; a numeric hexadecimal ipv6 address - domain ; a domain name - email ; an email address - http-url ; a URL beginning with https?:// - -Because of these issues the exact definitions of these patterns are -subject to be changed, but will be documented clearly when they are -finalized. More common patterns are also planned, but as what you -want increases in complexity it's probably better to use a real -parser. - -==== Supported PCRE Syntax - -Since the PCRE syntax is so overwhelming complex, it's easier to just -list what we *don't* support for now. Refer to the -[[http://pcre.org/pcre.txt|PCRE documentation]] for details. You -should be using the SRE syntax anyway! - -Unicode character classes ({{\P}}) are not supported, but will be -in an upcoming release. {{\C}} named characters are not supported. - -Callbacks, subroutine patterns and recursive patterns are not -supported. ({{*FOO}}) patterns are not supported and may never be. - -{{\G}} and {{\K}} are not supported. - -Octal character escapes are not supported because they are ambiguous -with back-references - just use hex character escapes. - -Other than that everything should work, including named submatches, -zero-width assertions, conditional patterns, etc. - -In addition, {{\<}} and {{\>}} act as beginning-of-word and end-of-word -marks, respectively, as in Emacs regular expressions. - -Also, two escapes are provided to embed SRE patterns inside PCRE -strings, {{"\'<sre>"}} and {{"(*'<sre>)"}}. For example, to match a -comma-delimited list of integers you could use - -<enscript highlight=scheme> -"\\'integer(,\\'integer)*" -</enscript> - -and to match a URL in angle brackets you could use - -<enscript highlight=scheme> -"<('*http-url)>" -</enscript> - -Note in the second example the enclosing {{"('*...)"}} syntax is needed -because the Scheme reader would consider the closing {{">"}} as part of -the SRE symbol. - -The following chart gives a quick reference from PCRE form to the SRE -equivalent: - - ;; basic syntax - "^" ;; bos (or eos inside (?m: ...)) - "$" ;; eos (or eos inside (?m: ...)) - "." ;; nonl - "a?" ;; (? a) - "a*" ;; (* a) - "a+" ;; (+ a) - "a??" ;; (?? a) - "a*?" ;; (*? a) - "a+?" ;; (+? a) - "a{n,m}" ;; (** n m a) - - ;; grouping - "(...)" ;; (submatch ...) - "(?:...)" ;; (: ...) - "(?i:...)" ;; (w/nocase ...) - "(?-i:...)" ;; (w/case ...) - "(?<name>...)" ;; (=> <name>...) - - ;; character classes - "[aeiou]" ;; ("aeiou") - "[^aeiou]" ;; (~ "aeiou") - "[a-z]" ;; (/ "az") or (/ "a" "z") - "[[:alpha:]]" ;; alpha - - ;; assertions - "(?=...)" ;; (look-ahead ...) - "(?!...)" ;; (neg-look-ahead ...) - "(?<=...)" ;; (look-behind ...) - "(?<!...)" ;; (neg-look-behind ...) - "(?(test)pass|fail)" ;; (if test pass fail) - "(*COMMIT)" ;; commit - -==== Chunked String Matching - -It's often desirable to perform regular expression matching over -sequences of characters not represented as a single string. The most -obvious example is a text-buffer data structure, but you may also want -to match over lists or trees of strings (i.e. ropes), over only -certain ranges within a string, over an input port, etc. With -existing regular expression libraries, the only way to accomplish this -is by converting the abstract sequence into a freshly allocated -string. This can be expensive, or even impossible if the object is a -text-buffer opened onto a 500MB file. - -IrRegex provides a chunked string API specifically for this purpose. -You define a chunking API with {{make-irregex-chunker}}: - -===== make-irregex-chunker - -<procedure>(make-irregex-chunker <get-next> <get-string> [<get-start> <get-end> <get-substring> <get-subchunk>])</procedure> - -where - -{{(<get-next> chunk) => }} returns the next chunk, or {{#f}} if there are no more chunks - -{{(<get-string> chunk) => }} a string source for the chunk - -{{(<get-start> chunk) => }} the start index of the result of {{<get-string>}} (defaults to always 0) - -{{(<get-end> chunk) => }} the end (exclusive) of the string (defaults to {{string-length}} of the source string) - -{{(<get-substring> cnk1 i cnk2 j) => }} a substring for the range between the chunk {{cnk1}} starting at index {{i}} and ending at {{cnk2}} at index {{j}} - -{{(<get-subchunk> cnk1 i cnk2 j) => }} as above but returns a new chunked data type instead of a string (optional) - -There are two important constraints on the {{<get-next>}} procedure. -It must return an {{eq?}} identical object when called multiple times -on the same chunk, and it must not return a chunk with an empty string -(start == end). This second constraint is for performance reasons - -we push the work of possibly filtering empty chunks to the chunker -since there are many chunk types for which empty strings aren't -possible, and this work is thus not needed. Note that the initial -chunk passed to match on is allowed to be empty. - -{{<get-substring>}} is provided for possible performance improvements -- without it a default is used. {{<get-subchunk>}} is optional - -without it you may not use {{irregex-match-subchunk}} described above. - -You can then match chunks of these types with the following -procedures: - -===== irregex-search/chunked -===== irregex-match/chunked - -<procedure>(irregex-search/chunked <irx> <chunker> <chunk> [<start>])</procedure><br> -<procedure>(irregex-match/chunked <irx> <chunker> <chunk> [<start>])</procedure> - -These return normal match-data objects. - -Example: - -To match against a simple, flat list of strings use: - -<enscript highlight=scheme> - (define (rope->string rope1 start rope2 end) - (if (eq? rope1 rope2) - (substring (car rope1) start end) - (let loop ((rope (cdr rope1)) - (res (list (substring (car rope1) start)))) - (if (eq? rope rope2) - (string-concatenate-reverse ; from SRFI-13 - (cons (substring (car rope) 0 end) res)) - (loop (cdr rope) (cons (car rope) res)))))) - - (define rope-chunker - (make-irregex-chunker (lambda (x) (and (pair? (cdr x)) (cdr x))) - car - (lambda (x) 0) - (lambda (x) (string-length (car x))) - rope->string)) - - (irregex-search/chunked <pat> rope-chunker <list-of-strings>) -</enscript> - -Here we are just using the default start, end and substring behaviors, -so the above chunker could simply be defined as: - -<enscript highlight=scheme> - (define rope-chunker - (make-irregex-chunker (lambda (x) (and (pair? (cdr x)) (cdr x))) car)) -</enscript> - -===== irregex-fold/chunked - -<procedure>(irregex-fold/chunked <irx> <kons> <knil> <chunker> <chunk> [<finish> [<start-index>]])</procedure> - -Chunked version of {{irregex-fold}}. - -==== Utilities - -The following procedures are also available. - -===== irregex-quote - -<procedure>(irregex-quote <str>)</procedure> - -Returns a new string with any special regular expression characters -escaped, to match the original string literally in POSIX regular -expressions. - -===== irregex-opt - -<procedure>(irregex-opt <list-of-strings>)</procedure> - -Returns an optimized SRE matching any of the literal strings -in the list, like Emacs' {{regexp-opt}}. Note this optimization -doesn't help when irregex is able to build a DFA. - -===== sre->string - -<procedure>(sre->string <sre>)</procedure> - -Convert an SRE to a PCRE-style regular expression string, if -possible. - - ---- -Previous: [[Unit extras]] - -Next: [[Unit srfi-4]] diff --git a/manual/Unit library b/manual/Unit library deleted file mode 100644 index ff93fe9a..00000000 --- a/manual/Unit library +++ /dev/null @@ -1,1288 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit library - -This unit contains basic Scheme definitions. This unit is used by default, -unless the program is compiled with the {{-explicit-use}} option. - -=== Arithmetic - - -==== add1/sub1 - -<procedure>(add1 N)</procedure> -<procedure>(sub1 N)</procedure> - -Adds/subtracts 1 from {{N}}. - - -==== Binary integer operations - -Binary integer operations are provided by the {{(chicken bitwise)}} -module. - -<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. - -==== bit-set? - -<procedure>(bit-set? N INDEX)</procedure> - -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. - -==== integer-length - -<procedure>(integer-length N)</procedure> - -Returns the number of bits needed to represent the exact integer N in -2's complement notation. - -==== exact-integer-sqrt - -<procedure>(exact-integer-sqrt K)</procedure> - -Returns two values {{s}} and {{r}}, where {{s^2 + r = K}} and {{K < (s+1)^2}}. -In other words, {{s}} is the closest square root we can find that's equal to or -smaller than {{K}}, and {{r}} is the rest if {{K}} isn't a neat square of two numbers. - -This procedure is compatible with the R7RS specification. - -==== exact-integer-nth-root - -<procedure>(exact-integer-nth-root K N)</procedure> - -Like {{exact-integer-sqrt}}, but with any base value. Calculates -{{\sqrt[N]{K}}}, the {{N}}th root of {{K}} and returns two values -{{s}} and {{r}} where {{s^N + r = K}} and {{K < (s+1)^N}}. - - -==== fixnum? - -<procedure>(fixnum? X)</procedure> - -Returns {{#t}} if {{X}} is a fixnum, or {{#f}} otherwise. - -==== flonum? - -<procedure>(flonum? X)</procedure> - -Returns {{#t}} if {{X}} is a flonum, or {{#f}} otherwise. - -==== bignum? - -<procedure>(bignum? X)</procedure> - -Returns {{#t}} if {{X}} is a bignum (integer larger than fits in a -fixnum), or {{#f}} otherwise. - -==== exact-integer? - -<procedure>(exact-integer? X)</procedure> - -Returns {{#t}} if {{X}} is an exact integer (i.e., a fixnum or a -bignum), or {{#f}} otherwise. - -==== cplxnum? - -<procedure>(cplxnum? X)</procedure> - -Returns {{#t}} if {{X}} is a true complex number (it has an imaginary -component), or {{#f}} otherwise. - -Please note that {{complex?}} will always return {{#t}} for any number -type supported by CHICKEN, so you can use this predicate if you want -to know the representational type of a number. - -==== ratnum? - -<procedure>(ratnum? X)</procedure> - -Returns {{#t}} if {{X}} is a true rational number (it is a fraction -with a denominator that's not 1), or {{#f}} otherwise. - -Please note that {{rational?}} will always return {{#t}} for any -number type supported by CHICKEN except complex numbers and non-finite -flonums, so you can use this predicate if you want to know the -representational type of a number. - -==== Division with quotient and remainder - -<procedure>(quotient&remainder X Y)</procedure> -<procedure>(quotient&modulo X Y)</procedure> - -Returns two values: the quotient and the remainder (or modulo) of -{{X}} divided by {{Y}}. Could be defined as {{(values (quotient X Y) -(remainder X Y))}}, but is much more efficient when dividing very -large numbers. - -==== Arithmetic fixnum operations - -The following procedures are provided by the {{(chicken fixnum)}} -module. - -<procedure>(fx+ N1 N2)</procedure> -<procedure>(fx- N1 N2)</procedure> -<procedure>(fx* N1 N2)</procedure> -<procedure>(fx/ N1 N2)</procedure> -<procedure>(fxmod N1 N2)</procedure> -<procedure>(fxrem N1 N2)</procedure> -<procedure>(fxneg N)</procedure> -<procedure>(fxmin N1 N2)</procedure> -<procedure>(fxmax N1 N2)</procedure> -<procedure>(fxand N1 N2)</procedure> -<procedure>(fxior N1 N2)</procedure> -<procedure>(fxxor N1 N2)</procedure> -<procedure>(fxnot N)</procedure> -<procedure>(fxshl N1 N2)</procedure> -<procedure>(fxshr N1 N2)</procedure> -<procedure>(fxgcd 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/}}, {{fxmod}} and {{fxrem}} signal a -condition of kind {{(exn arithmetic)}}. - -{{fxshl}} and {{fxshr}} perform arithmetic shift left and right, -respectively. - -==== Fixnum comparison and predicates - -<procedure>(fxodd? N)</procedure> -<procedure>(fxeven? N)</procedure> -<procedure>(fx= N1 N2)</procedure> -<procedure>(fx> N1 N2)</procedure> -<procedure>(fx< N1 N2)</procedure> -<procedure>(fx>= N1 N2)</procedure> -<procedure>(fx<= N1 N2)</procedure> - -Comparison of fixnums and predicates on them. - -==== Fixnum limits - -<constant>most-positive-fixnum</constant><br> -<constant>most-negative-fixnum</constant><br> -<constant>fixnum-bits</constant><br> -<constant>fixnum-precision</constant><br> - -Platform-specific fixnum limits. - -==== Arithmetic floating-point operations - -These procedures are provided by the {{(chicken flonum)}} module. - -<procedure>(fp+ X Y)</procedure> -<procedure>(fp- X Y)</procedure> -<procedure>(fp* X Y)</procedure> -<procedure>(fp/ X Y)</procedure> -<procedure>(fpgcd X Y)</procedure> -<procedure>(fpneg X)</procedure> -<procedure>(fpmin X Y)</procedure> -<procedure>(fpmax X Y)</procedure> -<procedure>(fp= X Y)</procedure> -<procedure>(fp> X Y)</procedure> -<procedure>(fp< X Y)</procedure> -<procedure>(fp>= X Y)</procedure> -<procedure>(fp<= X Y)</procedure> -<procedure>(fpfloor X)</procedure> -<procedure>(fpceiling X)</procedure> -<procedure>(fptruncate X)</procedure> -<procedure>(fpround X)</procedure> -<procedure>(fpsin X)</procedure> -<procedure>(fpcos X)</procedure> -<procedure>(fptan X)</procedure> -<procedure>(fpasin X)</procedure> -<procedure>(fpacos X)</procedure> -<procedure>(fpatan X)</procedure> -<procedure>(fpatan2 X Y)</procedure> -<procedure>(fplog X)</procedure> -<procedure>(fpexp X)</procedure> -<procedure>(fpexpt X Y)</procedure> -<procedure>(fpsqrt X)</procedure> -<procedure>(fpabs X)</procedure> -<procedure>(fpinteger? X)</procedure> - -Arithmetic floating-point operations. - -In safe mode, these procedures throw a type error when given non-float -arguments. In unsafe mode, these procedures do not check their -arguments. A non-flonum argument in unsafe mode can crash the -application. - -Note: {{fpround}} uses the rounding mode that your C library -implements, which is usually different from R5RS. - -==== Flonum limits - -<constant>maximum-flonum</constant><br> -<constant>minimum-flonum</constant><br> -<constant>flonum-radix</constant><br> -<constant>flonum-epsilon</constant><br> -<constant>flonum-precision</constant><br> -<constant>flonum-decimal-precision</constant><br> -<constant>flonum-maximum-exponent</constant><br> -<constant>flonum-minimum-exponent</constant><br> -<constant>flonum-maximum-decimal-exponent</constant><br> -<constant>flonum-minimum-decimal-exponent</constant><br> - -Platform-specific flonum limits. - -<procedure>(flonum-print-precision [PRECISION])</procedure> - -Gets and sets the number of significant digits printed for a floating-point -number. {{PRECISION}} must be a positive {{fixnum}}. Returns -the setting that was previously in effect. - -The default print precision is 15 on nearly all systems, and 7 -on the rare system on which the {{double}} type is only single-precision. - -'''Note:''' To ensure read/write invariance for ''all'' floating-point -numbers, you must increase print precision from 15 to 17 (or from 7 to -9). For example: - - > (define a (expt 2 -53)) - > (define b (+ a (* 2 (expt 10 -32)))) - > (eqv? a b) - #f - > (flonum-print-precision 15) - > (cons a b) - (1.11022302462516e-16 . - 1.11022302462516e-16) ;; same printed representation - > (flonum-print-precision 17) - > (cons a b) - (1.1102230246251565e-16 . - 1.1102230246251568e-16) ;; differs in last place - -On the downside, this will result in unnecessarily precise -representations of many numbers: - - > (flonum-print-precision 17) - > 0.1 - 0.10000000000000001 - -The maximum number of decimal digits required to uniquely represent -all floating-point numbers of a certain precision is given by the -formula {{ceil(1+N*log10(2))}}, where N is the number of bits of -precision; for double-precision, {{N=53}}. - -==== nan? - -<procedure>(nan? N)</procedure> - -Returns {{#t}} if {{N}} is not a number (a IEEE flonum NaN-value). If -{{N}} is a complex number, it's considered nan if it has a real or -imaginary component that's nan. - -==== finite? - -<procedure>(infinite? N)</procedure> - -Returns {{#t}} if {{N}} is negative or positive infinity, and {{#f}} -otherwise. If {{N}} is a complex number, it's considered infinite if -it has a real or imaginary component that's infinite. - -==== finite? - -<procedure>(finite? N)</procedure> - -Returns {{#t}} if {{N}} represents a finite number and {{#f}} -otherwise. Positive and negative infinity as well as NaNs are not -considered finite. If {{N}} is a complex number, it's considered -finite if both the real and imaginary components are finite. - -==== signum - -<procedure>(signum N)</procedure> - -For real numbers, returns {{1}} if {{N}} is positive, {{-1}} if {{N}} -is negative or {{0}} if {{N}} is zero. {{signum}} is exactness -preserving. - -For complex numbers, returns a complex number of the same angle but -with magnitude 1. - -=== File Input/Output - -==== current-output-port - -<procedure>(current-output-port [PORT])</procedure> - -Returns default output port. If {{PORT}} is given, then that port is selected -as the new current output port. - -Note that the default output port is not buffered. Use [[Unit posix#Setting the -file buffering mode|{{set-buffering-mode!}}]] if you need a different behavior. - -==== current-error-port - -<procedure>(current-error-port [PORT])</procedure> - -Returns default error output port. If {{PORT}} is given, then that port is -selected as the new current error output port. - -Note that the default error output port is not buffered. Use [[Unit -posix#Setting the file buffering mode|{{set-buffering-mode!}}]] if you need a -different behavior. - -==== flush-output - -<procedure>(flush-output [PORT])</procedure> - -Write buffered output to the given output-port. {{PORT}} defaults -to the value of {{(current-output-port)}}. - -==== input-port-open? - -<procedure>(input-port-open? PORT)</procedure> - -Is the given {{PORT}} open for input? - -<procedure>(output-port-open? PORT)</procedure> - -Is the given {{PORT}} open for output? - -==== port-closed? - -<procedure>(port-closed? PORT)</procedure> - -Is the given {{PORT}} closed (in all directions)? - -==== port-name - -<procedure>(port-name [PORT])</procedure> - -Fetch filename from {{PORT}}. This returns the filename that was used to open -this file. Returns a special tag string, enclosed into parentheses for -non-file ports. {{PORT}} defaults to the value of {{(current-input-port)}}. - - -==== port-position - -<procedure>(port-position [PORT])</procedure> - -Returns the current position of {{PORT}} as two values: row and column number. -If the port does not support such an operation an error is signaled. This -procedure is currently only available for input ports. {{PORT}} defaults to the -value of {{(current-input-port)}}. - - -==== set-port-name! - -<procedure>(set-port-name! PORT STRING)</procedure> - -Sets the name of {{PORT}} to {{STRING}}. - - - -=== Files - -==== delete-file - -<procedure>(delete-file STRING)</procedure> - -Deletes the file with the pathname {{STRING}}. If the file does -not exist, an error is signaled. - - -==== directory-exists? - -<procedure>(directory-exists? STRING)</procedure> - -Returns {{STRING}} if a directory with the given pathname exists, or -{{#f}} otherwise. - - -==== file-exists? - -<procedure>(file-exists? STRING)</procedure> - -Returns {{STRING}} if a file or directory with the given pathname exists, or -{{#f}} otherwise. - - -==== rename-file - -<procedure>(rename-file OLD NEW)</procedure> - -Renames the file or directory with the pathname {{OLD}} to -{{NEW}}. If the operation does not succeed, an error is signaled. - - -=== String ports - -==== get-output-string - -<procedure>(get-output-string PORT)</procedure> - -Returns accumulated output of a port created with -{{(open-output-string)}}. - - -==== open-input-string - -<procedure>(open-input-string STRING)</procedure> - -Returns a port for reading from {{STRING}}. - - -==== open-output-string - -<procedure>(open-output-string)</procedure> - -Returns a port for accumulating output in a string. - - - - - -=== Feature identifiers - - -CHICKEN maintains a global list of ''features'' naming functionality available -in the current system. Additionally the {{cond-expand}} form accesses this -feature list to infer what features are provided. Predefined features are -{{chicken}}, and the SRFIs (Scheme Request For Implementation) provided by the -base system: {{srfi-23, srfi-30, srfi-39}}. If the {{eval}} unit -is used (the default), the features {{srfi-0, srfi-2, srfi-6, srfi-8, srfi-9}} -and {{srfi-10}} are defined. When compiling code (during compile-time) the -feature {{compiling}} is registered. When evaluating code in the interpreter -(csi), the feature {{csi}} is registered. - - -==== features - -<procedure>(features)</procedure> - -Returns a list of all registered features that will be accepted as valid -feature-identifiers by {{cond-expand}}. - - -==== feature? - -<procedure>(feature? ID ...)</procedure> - -Returns {{#t}} if all features with the given feature-identifiers {{ID ...}} -are registered. - - -==== register-feature! - -<procedure>(register-feature! FEATURE ...)</procedure> - -Register one or more features that will be accepted as valid -feature-identifiers by {{cond-expand}}. {{FEATURE ...}} may -be a keyword, string or symbol. - - -==== unregister-feature! - -<procedure>(unregister-feature! FEATURE ...)</procedure> - -Unregisters the specified feature-identifiers. {{FEATURE ...}} -may be a keyword, string or symbol. - - - - - -=== Keywords - -Keywords are special symbols prefixed with {{#:}} that evaluate -to themselves. Procedures can use keywords to accept optional named -parameters in addition to normal required parameters. Assignment to -and bindings of keyword symbols is not allowed. -The parameter {{keyword-style}} and the compiler/interpreter option -{{-keyword-style}} can be used to allow an additional keyword -syntax, either compatible to Common LISP, or to DSSSL. As long as this -parameter is set to {{#:suffix}}, CHICKEN conforms to -[[http://srfi.schemers.org/srfi-88/srfi-88.html|SRFI-88]]. - -The following procedures are provided by the {{(chicken keyword)}} -module. - - -==== get-keyword - -<procedure>(get-keyword KEYWORD ARGLIST [THUNK])</procedure> - -Returns the argument from {{ARGLIST}} specified under the keyword -{{KEYWORD}}. If the keyword is not found, then the zero-argument -procedure {{THUNK}} is invoked and the result value is returned. If -{{THUNK}} is not given, {{#f}} is returned. - -<enscript highlight=scheme> -(define (increase x . args) - (+ x (get-keyword #:amount args (lambda () 1))) ) -(increase 123) ==> 124 -(increase 123 #:amount 10) ==> 133 -</enscript> - -Note: the {{KEYWORD}} may actually be any kind of object. - - -==== keyword? - -<procedure>(keyword? X)</procedure> - -Returns {{#t}} if {{X}} is a keyword symbol, or {{#f}} -otherwise. - - -==== keyword->string - -<procedure>(keyword->string KEYWORD)</procedure> - -Transforms {{KEYWORD}} into a string. - - -==== string->keyword - -<procedure>(string->keyword STRING)</procedure> - -Returns a keyword with the name {{STRING}}. - - -=== Environment information and system interface - -==== argv - -<procedure>(argv)</procedure> - -Return a list of all supplied command-line arguments. The first item in -the list is a string containing the name of the executing program. The -other items are the arguments passed to the application. It depends on -the host-shell whether arguments are expanded ('globbed') or not. - -==== executable-pathname - -<procedure>(executable-pathname)</procedure> - -Returns a full pathname of the currently-running executable, or {{#f}} -if it couldn't be determined. When evaluating code in the interpreter, -this will be a path to {{csi}}. - -==== exit - -<procedure>(exit [CODE])</procedure> - -Exit the running process and return exit-code, which defaults to 0 -(Invokes {{exit-handler}}). - -Note that pending {{dynamic-wind}} thunks are ''not'' invoked when exiting your program in this way. - -==== build-platform - -<procedure>(build-platform)</procedure> - -Returns a symbol specifying the toolset which has been used for -building the executing system, which is one of the following: - - cygwin - mingw32 - gnu - intel - clang - sun - unknown - - -==== chicken-version - -<procedure>(chicken-version [FULL])</procedure> - -Returns a string containing the version number of the CHICKEN runtime -system. If the optional argument {{FULL}} is given and true, then -a full version string is returned. - - -==== errno - -<procedure>(errno)</procedure> - -Returns the error code of the last system call. - - -==== get-environment-variable - -<procedure>(get-environment-variable STRING)</procedure><br> - -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]]. - -==== machine-byte-order - -<procedure>(machine-byte-order)</procedure> - -Returns the symbol {{little-endian}} or {{big-endian}}, depending on the -machine's byte-order. - - -==== machine-type - -<procedure>(machine-type)</procedure> - -Returns a symbol specifying the processor on which this process is -currently running, which is one of the following: - - arm - alpha - mips - hppa - ultrasparc - sparc - ppc - ppc64 - ia64 - x86 - x86-64 - unknown - - -==== on-exit - -<procedure>(on-exit THUNK)</procedure> - -Schedules the zero-argument procedures {{THUNK}} to be executed before -the process exits, either explicitly via {{exit}} or implicitly after execution -of the last top-level form. Note that finalizers for unreferenced finalized -data are run before exit procedures. - - -==== sleep - -<procedure>(sleep SECONDS)</procedure> - -Puts the program to sleep for {{SECONDS}}. If the scheduler is loaded -(for example when srfi-18 is in use) then only the calling thread is put -to sleep and other threads may continue executing. Otherwise, the whole -process is put to sleep. - - -==== software-type - -<procedure>(software-type)</procedure> - -Returns a symbol specifying the operating system on which this process -is currently running, which is one of the following: - - android - windows - unix - ecos - unknown - - -==== software-version - -<procedure>(software-version)</procedure> - -Returns a symbol specifying the operating system version on which this -process is currently running, which is one of the following: - - linux - freebsd - netbsd - openbsd - macosx - hpux - dragonfly - haiku - solaris - sunos - aix - hurd - unknown - - -==== system - -<procedure>(system STRING)</procedure> - -Execute shell command. The functionality offered by this procedure -depends on the capabilities of the host shell. If the forking of a subprocess -failed, an exception is raised. Otherwise the return status of the -subprocess is returned unaltered. - - -On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status. It is 0 on success. To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this: - -<enscript highlight='scheme'> -;; Returns two values: #t if the process exited normally or #f otherwise; -;; and either the exit status, or the signal number if terminated via signal. -(define (process-status rc) - (define (wait-signaled? x) (not (= 0 (bitwise-and x 127)))) - (define (wait-signal x) (bitwise-and x 127)) - (define (wait-exit-status x) (arithmetic-shift x -8)) - (if (wait-signaled? rc) - (values #f (wait-signal rc)) - (values #t (wait-exit-status rc)))) - -#;> (process-status (system "exit 42")) -#t -42 -</enscript> - - -=== Execution time - - - -==== cpu-time - -<procedure>(cpu-time)</procedure> - -Returns the used CPU time of the current process in milliseconds as -two values: the time spent in user code, and the time spent in system -code. On platforms where user and system time can not be differentiated, -system time will be always be 0. - - -==== current-milliseconds - -<procedure>(current-milliseconds)</procedure> - -Returns the number of milliseconds since process- or machine startup. - - -==== current-seconds - -<procedure>(current-seconds)</procedure> - -Returns the number of seconds since midnight, Jan. 1, 1970. - - - -=== Interrupts and error-handling - - - -==== enable-warnings - -<procedure>(enable-warnings [BOOL])</procedure> - -Enables or disables warnings, depending on wether {{BOOL}} is true or false. -If called with no arguments, this procedure returns {{#t}} if warnings are -currently enabled, or {{#f}} otherwise. Note that this is not a parameter. -The current state (whether warnings are enabled or disabled) is global and not -thread-local. - - -==== error - -<procedure>(error [LOCATION] [STRING] EXP ...)</procedure> - -Prints error message, writes all extra arguments to the -value of {{(current-error-port)}} and invokes the -current exception-handler. This conforms to -[[http://srfi.schemers.org/srfi-23/srfi-23.html|SRFI-23]]. -If {{LOCATION}} is given and a symbol, it specifies the ''location'' (the name -of the procedure) where the error occurred. - - - -==== get-call-chain - -<procedure>(get-call-chain [START [THREAD]])</procedure> - -Returns a list with the call history. Backtrace information -is only generated in code compiled without {{-no-trace}} and evaluated code. -If the optional argument {{START}} is given, the backtrace starts -at this offset, i.e. when {{START}} is 1, the next to last trace-entry -is printed, and so on. If the optional argument {{THREAD}} is given, then -the call-chain will only be constructed for calls performed by this thread. - - - -==== print-call-chain - -<procedure>(print-call-chain [PORT [START [THREAD [HEADER]]]])</procedure> - -Prints a backtrace of the procedure call history to {{PORT}}, -which defaults to {{(current-output-port)}}. The output is prefixed by the -{{HEADER}}, which defaults to {{"\n\tCall history:\n"}}. - - -==== print-error-message - -<procedure>(print-error-message EXN [PORT [HEADER]])</procedure> - -Prints an appropriate error message to {{PORT}} (which defaults to the value of -{{(current-output-port)}} for the object {{EXN}}. {{EXN}} may be a condition, a -string or any other object. The output is prefixed by the {{HEADER}}, which -defaults to {{"Error:"}}. - - -==== procedure-information - -<procedure>(procedure-information PROC)</procedure> - -Returns an s-expression with debug information for the procedure {{PROC}}, or -{{#f}}, if {{PROC}} has no associated debug information. - - -==== quit - -<procedure>(quit [RESULT])</procedure> - -In the interpreter {{quit}} exits the currently active read-eval-print loop. -In compiled code, it is equivalent to calling {{exit}}. See also: {{repl}}. - - -==== reset - -<procedure>(reset)</procedure> - -Reset program (Invokes {{reset-handler}}). - - -==== warning - -<procedure>(warning STRING EXP ...)</procedure> - -Displays a warning message (if warnings are enabled with {{enable-warnings}}) and -continues execution. - - - -=== Garbage collection - -The following procedures are provided by the {{(chicken gc)}} module. - -==== gc - -<procedure>(gc [FLAG])</procedure> - -Invokes a garbage-collection and returns the number of free bytes in the heap. -The flag specifies whether a minor ({{#f}}) or major ({{#t}}) GC is to be -triggered. If no argument is given, {{#t}} is assumed. An explicit {{#t}} -argument will cause all pending finalizers to be executed. - -==== current-gc-milliseconds - -<procedure>(current-gc-milliseconds)</procedure> - -Returns the number of milliseconds spent in major garbage collections since -the last call of {{current-gc-milliseconds}} and returns an exact -integer. - -==== memory-statistics - -<procedure>(memory-statistics)</procedure> - -Performs a major garbage collection and returns a three element vector -containing the total heap size in bytes, the number of bytes currently -used and the size of the nursery (the first heap generation). Note -that the actual heap is actually twice the size given in the heap size, -because CHICKEN uses a copying semi-space collector. - - -==== set-finalizer! - -<procedure>(set-finalizer! X PROC)</procedure> - -Registers a procedure of one argument {{PROC}}, that will be -called as soon as the non-immediate data object {{X}} is about to -be garbage-collected (with that object as its argument). Note that -the finalizer will '''not''' be called while interrupts are disabled. -This procedure returns {{X}}. - -Finalizers are invoked asynchronously, in the thread that happens -to be currently running. Finalizers for data that has become garbage -are called on normal program exit. Finalizers are not run on -abnormal program exit. A normal program exit does not run finalizers -that are still reachable from global data. - -Multiple finalizers can be registered for the same object. The order -in which the finalizers run is undefined. Execution of finalizers -may be nested. - - -==== set-gc-report! - -<procedure>(set-gc-report! FLAG)</procedure> - -Print statistics after every GC, depending on {{FLAG}}. A value of -{{#t}} shows statistics after every major GC. A true value different -from {{#t}} shows statistics after every minor GC. {{#f}} -switches statistics off. - - - - - -=== Other predicates and comparison operations - - - -==== promise? - -<procedure>(promise? X)</procedure> - -Returns {{#t}} if {{X}} is a promise returned by {{delay}}, or -{{#f}} otherwise. - - -==== equal=? - -<procedure>(equal=? X y)</procedure> - -Similar to the standard procedure {{equal?}}, but compares numbers -using the {{=}} operator, so {{equal=?}} allows structural comparison -in combination with comparison of numerical data by value. - - - -=== String utilities - - -==== reverse-list->string - -<procedure>(reverse-list->string LIST)</procedure> - -Returns a string with the characters in {{LIST}} in reverse order. This is -equivalent to {{(list->string (reverse LIST))}}, but much more efficient. - - - -=== Symbols - -==== Symbol utilities - -===== symbol-append - -<procedure>(symbol-append SYMBOL1 ...)</procedure> - -Creates a new symbol from the concatenated names of the argument symbols -{{(SYMBOL1 ...)}}. - -==== Uninterned symbols ("gensyms") - -Symbols may be "interned" or "uninterned". Interned symbols are -registered in a global table, and when read back from a port are -identical to a symbol written before: - -<enscript highlight=scheme> -(define sym 'foo) - -(eq? sym (with-input-from-string - (with-output-to-string - (lambda () (write sym))) - read)) - - => #t -</enscript> - -Uninterned symbols on the other hand are not globally registered and so -multiple symbols with the same name may coexist: - -<enscript highlight=scheme> -(define sym (gensym 'foo)) ; sym is a uninterned symbol like "foo42" - -(eq? sym (with-input-from-string ; the symbol read will be an interned symbol - (with-output-to-string - (lambda () (write sym))) - read)) - - => #f - -(eq? (string->uninterned-symbol "foo") (string->uninterned-symbol "foo")) - - => #f -</enscript> - -Use uninterned symbols if you need to generate unique values that -can be compared quickly, for example as keys into a hash-table -or association list. Note that uninterned symbols lose their -uniqueness property when written to a file and read back in, as -in the example above. - - -===== gensym - -<procedure>(gensym [STRING-OR-SYMBOL])</procedure> - -Returns a newly created uninterned symbol. If an argument is provided, -the new symbol is prefixed with that argument. - - -===== string->uninterned-symbol - -<procedure>(string->uninterned-symbol STRING)</procedure> - -Returns a newly created, unique symbol with the name {{STRING}}. - - -==== Property lists - -As in other Lisp dialects, CHICKEN supports "property lists" associated with symbols. -Properties are accessible via a key that can be any kind of value but which will -be compared using {{eq?}}. - -===== get - -<procedure>(get SYMBOL PROPERTY [DEFAULT])</procedure> - -Returns the value stored under the key {{PROPERTY}} in the property -list of {{SYMBOL}}. If no such property is stored, returns -{{DEFAULT}}. The {{DEFAULT}} is optional and defaults to {{#f}}. - -===== put! - -<procedure>(put! SYMBOL PROPERTY VALUE)</procedure> -setter: (set! (get SYMBOL PROPERTY) VALUE) - -Stores {{VALUE}} under the key {{PROPERTY}} in the property list of -{{SYMBOL}} replacing any previously stored value. - -===== remprop! - -<procedure>(remprop! SYMBOL PROPERTY)</procedure> - -Deletes the first property matching the key {{PROPERTY}} in the property list -of {{SYMBOL}}. Returns {{#t}} when a deletion performed, and {{#f}} otherwise. - -===== symbol-plist - -<procedure>(symbol-plist SYMBOL)</procedure> -setter: (set! (symbol-plist SYMBOL) LST) - -Returns the property list of {{SYMBOL}} or sets it. - -===== get-properties - -<procedure>(get-properties SYMBOL PROPERTIES)</procedure> - -Searches the property list of {{SYMBOL}} for the first property with a key in -the list {{PROPERTIES}}. Returns 3 values: the matching property key, value, -and the tail of property list after the matching property. When no match found -all values are {{#f}}. - -{{PROPERTIES}} may also be an atom, in which case it is treated as a list of -one element. - - -=== Standard Input/Output - -==== port? - -<procedure>(port? X)</procedure> - -Returns {{#t}} if {{X}} is a port object or {{#f}} -otherwise. - - -==== print - -<procedure>(print [EXP1 ...])</procedure> - -Outputs the optional arguments {{EXP1 ...}} using {{display}} and -writes a newline character to the port that is the value of -{{(current-output-port)}}. Returns {{(void)}}. - - -==== print* - -<procedure>(print* [EXP1 ...])</procedure> - -Similar to {{print}}, but does not output a terminating newline -character and performs a {{flush-output}} after writing its arguments. - - - - -=== User-defined named characters - -==== char-name - -<procedure>(char-name SYMBOL-OR-CHAR [CHAR])</procedure> - -This procedure can be used to inquire about character names or to -define new ones. With a single argument the behavior is as follows: -If {{SYMBOL-OR-CHAR}} is a symbol, then {{char-name}} returns -the character with this name, or {{#f}} if no character is defined -under this name. If {{SYMBOL-OR-CHAR}} is a character, then the -name of the character is returned as a symbol, or {{#f}} if the -character has no associated name. - -If the optional argument {{CHAR}} is provided, then -{{SYMBOL-OR-CHAR}} should be a symbol that will be the new name of -the given character. If multiple names designate the same character, -then the {{write}} will use the character name that was defined last. - -<enscript highlight=scheme> -(char-name 'space) ==> #\space -(char-name #\space) ==> space -(char-name 'bell) ==> #f -(char-name (integer->char 7)) ==> #f -(char-name 'bell (integer->char 7)) -(char-name 'bell) ==> #\bell -(char->integer (char-name 'bell)) ==> 7 -</enscript> - - - -=== Blobs - -"blobs" are collections of unstructured bytes. You can't do much -with them, but allow conversion to and from SRFI-4 number vectors. - -==== make-blob - -<procedure>(make-blob SIZE)</procedure> - -Returns a blob object of {{SIZE}} bytes, aligned on an 8-byte boundary, -uninitialized. - -==== blob? - -<procedure>(blob? X)</procedure> - -Returns {{#t}} if {{X}} is a blob object, or -{{#f}} otherwise. - -==== blob-size - -<procedure>(blob-size BLOB)</procedure> - -Returns the number of bytes in {{BLOB}}. - -==== blob->string - -<procedure>(blob->string BLOB)</procedure> - -Returns a string with the contents of {{BLOB}}. - -==== string->blob - -<procedure>(string->blob STRING)</procedure> - -Returns a blob with the contents of {{STRING}}. - -==== blob=? - -<procedure>(blob=? BLOB1 BLOB2)</procedure> - -Returns {{#t}} if the two argument blobs are of the same -size and have the same content. - - -=== Lists - -==== foldl - -<procedure>(foldl PROCEDURE INIT LIST)</procedure> - -Applies {{PROCEDURE}} to the elements from {{LIST}}, beginning from the left: - -<enscript hightlight=scheme> -(foldl + 0 '(1 2 3)) ==> (+ (+ (+ 0 1) 2) 3) -</enscript> - -Note that the order of arguments taken by {{PROCEDURE}} is different -from the {{SRFI-1}} {{fold}} procedure, but matches the more natural -order used in Haskell and Objective Caml. - - -==== foldr - -<procedure>(foldr PROCEDURE INIT LIST)</procedure> - -Applies {{PROCEDURE}} to the elements from {{LIST}}, beginning from the right: - -<enscript hightlight=scheme> -(foldr + 0 '(1 2 3)) ==> (+ 1 (+ 2 (+ 3 0))) -</enscript> - - -=== Vectors - -==== vector-copy! - -<procedure>(vector-copy! VECTOR1 VECTOR2 [COUNT])</procedure> - -Copies contents of {{VECTOR1}} into {{VECTOR2}}. If the -argument {{COUNT}} is given, it specifies the maximal number of -elements to be copied. If not given, the minimum of the lengths of the -argument vectors is copied. - -Exceptions: {{(exn bounds)}} - - -==== vector-resize - -<procedure>(vector-resize VECTOR N [INIT])</procedure> - -Creates and returns a new vector with the contents of {{VECTOR}} and length -{{N}}. If {{N}} is greater than the original length of {{VECTOR}}, then all -additional items are initialized to {{INIT}}. If {{INIT}} is not specified, the -contents are initialized to some unspecified value. - - -==== subvector - -<procedure>(subvector VECTOR FROM [TO])</procedure> - -Returns a new vector with elements taken from {{VECTOR}} in the -given range. {{TO}} defaults to {{(vector-length VECTOR)}}. - -{{subvector}} was introduced in CHICKEN 4.7.3. - - -=== The unspecified value - -==== void - -<procedure>(void ARGUMENT ...)</procedure> - -Ignores {{ARGUMENT ...}} and returns an unspecified value. - - - -=== Continuations - -==== call/cc - -<procedure>(call/cc PROCEDURE)</procedure> - -An alias for {{call-with-current-continuation}}. - - -=== Setters - -SRFI-17 is fully implemented. For more information see: -[[http://srfi.schemers.org/srfi-17/srfi-17.html|SRFI-17]]. - -==== setter - -<procedure>(setter PROCEDURE)</procedure> - -Returns the setter-procedure of {{PROCEDURE}}, or signals an error if -{{PROCEDURE}} has no associated setter-procedure. - -Note that {{(set! (setter PROC) ...)}} for a procedure that has no associated -setter procedure yet is a very slow operation (the old procedure is replaced by -a modified copy, which involves a garbage collection). - - -==== getter-with-setter - -<procedure>(getter-with-setter GETTER SETTER)</procedure> - -Returns a copy of the procedure {{GETTER}} with the associated setter procedure -{{SETTER}}. Contrary to the SRFI specification, the setter of the returned -procedure may be changed. - - - ----- -Previous: [[Exceptions]] Next: [[Unit eval]] diff --git a/manual/Unit lolevel b/manual/Unit lolevel deleted file mode 100644 index 34d76532..00000000 --- a/manual/Unit lolevel +++ /dev/null @@ -1,706 +0,0 @@ -[[tags: manual internals]] -[[toc:]] - - -== Unit lolevel - -This unit provides a number of handy low-level operations. '''Use -at your own risk.''' - - -=== Foreign pointers - -The abstract class of ''pointer'' is divided into 2 categories: - -; ''pointer object'' : is a regular or [[#Tagged pointers|tagged]] foreign pointer object. - -; ''pointer-like object'' : is a closure, port, [[#Locatives|locative]], or a pointer object. - -Note that Locatives, while technically pointers, are not considered a ''pointer -object'', but a ''pointer-like object''. The distinction is artificial. - -Pointer operations are provided by the {{(chicken memory)}} module. - - -==== address->pointer - -<procedure>(address->pointer ADDRESS)</procedure> - -Creates a new foreign pointer object initialized to point to the address -given in the integer {{ADDRESS}}. - - -==== allocate - -<procedure>(allocate BYTES)</procedure> - -Returns a foreign pointer object to a freshly allocated region of static -memory. - -This procedure could be defined as follows: - -<enscript highlight=scheme> -(define allocate (foreign-lambda c-pointer "malloc" integer)) -</enscript> - - -==== free - -<procedure>(free POINTER)</procedure> - -Frees the memory pointed to by {{POINTER}}. - -This procedure could be defined as follows: - -<enscript highlight=scheme> -(define free (foreign-lambda void "free" c-pointer)) -</enscript> - - -==== object->pointer - -<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.) - -Note that data in the garbage collected heap moves during garbage collection. - - -==== pointer->object - -<procedure>(pointer->object POINTER)</procedure> - -Returns the Scheme object pointed to by the pointer object {{POINTER}}. - -Whether the {{POINTER}} actually points to a Scheme object is not guaranteed. Use -at your own risk. - -==== pointer? - -<procedure>(pointer? X)</procedure> - -Returns {{#t}} if {{X}} is a pointer object, or {{#f}} otherwise. - - -==== pointer-like? - -<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> - -Returns {{#t}} if the pointer-like objects {{POINTER*1}} and {{POINTER*2}} point -to the same address, or {{#f}} otherwise. - - -==== pointer->address - -<procedure>(pointer->address POINTER*)</procedure> - -Returns the address, to which the pointer-like object {{POINTER*}} points. - - -==== pointer+ - -<procedure>(pointer+ POINTER* N)</procedure> - -Returns a new foreign pointer object representing the pointer-like object -{{POINTER*}} address value increased by the byte-offset {{N}}. - -Use of anything other than a pointer object as an argument is questionable. - - -==== align-to-word - -<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 -platform. - -Use of anything other than an integer or pointer object as an argument is -questionable. - - -=== SRFI-4 Foreign pointers - -These procedures actually accept a pointer-like object as the {{POINTER}} argument. -However, as usual, use of anything other than a pointer object is questionable. - -SRFI-4 pointer operations are provided by the {{(chicken memory)}} module. - - -==== pointer-u8-ref - -<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> - -Returns the signed byte at the address designated by {{POINTER}}. - - -==== pointer-u16-ref - -<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> - -Returns the signed 16-bit integer at the address designated by {{POINTER}}. - - -==== pointer-u32-ref - -<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> - -Returns the signed 32-bit integer at the address designated by {{POINTER}}. - -==== pointer-u64-ref - -<procedure>(pointer-u64-ref POINTER)</procedure> - -Returns the unsigned 64-bit integer at the address designated by {{POINTER}}. - - -==== pointer-s64-ref - -<procedure>(pointer-s64-ref POINTER)</procedure> - -Returns the signed 64-bit integer at the address designated by {{POINTER}}. - - -==== pointer-f32-ref - -<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> - -Returns the 64-bit double at the address designated by {{POINTER}}. - - -==== pointer-u8-set! - -<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><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><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><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><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><br> -<procedure>(set! (pointer-s32-ref POINTER) N)</procedure> - -Stores the 32-bit integer {{N}} at the address designated by {{POINTER}}. - - -==== pointer-u64-set! - -<procedure>(pointer-u64-set! POINTER N)</procedure><br> -<procedure>(set! (pointer-u64-ref POINTER) N)</procedure> - -Stores the unsigned 64-bit integer {{N}} at the address designated by {{POINTER}}. - - -==== pointer-s64-set! - -<procedure>(pointer-s64-set! POINTER N)</procedure><br> -<procedure>(set! (pointer-s64-ref POINTER) N)</procedure> - -Stores the 64-bit integer {{N}} at the address designated by {{POINTER}}. - - -==== pointer-f32-set! - -<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><br> -<procedure>(set! (pointer-f64-ref POINTER) N)</procedure> - -Stores the 64-bit floating-point number {{N}} at the address designated by {{POINTER}}. - - - -=== Tagged pointers - -''Tagged'' pointers are foreign pointer objects with an extra tag object. - -Tagged pointer operations are provided by the {{(chicken memory)}} module. - - -==== tag-pointer - -<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. - -Use of anything other than a pointer object is questionable. - -==== tagged-pointer? - -<procedure>(tagged-pointer? X [TAG])</procedure> - -Returns {{#t}} if {{X}} is a tagged foreign pointer object, or {{#f}} otherwise. - -Further, returns {{#t}} when {{X}} has the optional tag {{TAG}} (using an -{{equal?}} comparison), or {{#f}} otherwise. - - -==== pointer-tag - -<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 -error is signalled. - - -=== Pointer vectors - -''Pointer vectors'' are specialized and space-efficient vectors for -foreign pointer objects. All procedures defined below that accept -a pointer object allow {{#f}} as an alternative representation of -the {{NULL}}-pointer. - -Pointer vectors are provided by the {{(chicken memory)}} module. - - -==== make-pointer-vector - -<procedure>(make-pointer-vector LENGTH [INIT])</procedure> - -Creates a pointer-vector of the given length and optionally initializes each -element to {{INIT}}, which should be a pointer or {{#f}}, which represents the -{{NULL}} pointer. - -==== pointer-vector? - -<procedure>(pointer-vector? X)</procedure> - -Returns {{#t}} if {{X}} is a pointer-vector or {{#f}} otherwise. - -==== pointer-vector - -<procedure>(pointer-vector POINTER ...)</procedure> - -Returns a pointer-vector from the given pointer arguments. - -==== pointer-vector-length - -<procedure>(pointer-vector-length POINTERVECTOR)</procedure> - -Returns the length of the given pointer-vector. - -==== pointer-vector-ref - -<procedure>(pointer-vector-ref POINTERVECTOR INDEX)</procedure> - -Returns the pointer at {{INDEX}} in the given pointer-vector or -{{#f}} if the element is a {{NULL}}- pointer. - -==== pointer-vector-set! - -<procedure>(pointer-vector-set! POINTERVECTOR INDEX POINTER)</procedure> - -Sets the element at the position {{INDEX}} in the given pointer-vector to -{{POINTER}}. The alternative syntax - - (set! (pointer-vector-ref POINTERVECTOR INDEX) POINTER) - -is also allowed. - - -=== Locatives - - -A ''locative'' is an object that points to an element of a containing object, -much like a ''pointer'' in low-level, imperative programming languages like ''C''. The element can -be accessed and changed indirectly, by performing access or change operations -on the locative. The container object can be computed by calling the -{{locative->object}} procedure. - -Locatives may be passed to foreign procedures that expect pointer arguments. - -The following procedures are provided by the {{(chicken locative)}} -module. - -==== make-locative - -<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, -SRFI-4 number-vector, or record structure. {{INDEX}} should be a fixnum. -{{INDEX}} defaults to 0. - - -==== make-weak-locative - -<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 -to it exist. - - -==== locative? - -<procedure>(locative? X)</procedure> - -Returns {{#t}} if {{X}} is a locative, or {{#f}} otherwise. - - -==== locative-ref - -<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. - - (locative-ref (make-locative "abc" 1)) ==> #\b - -==== locative-set! - -<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 -object has been reclaimed by garbage collection, an error is signalled. - - -==== locative->object - -<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. - - (locative->object (make-locative "abc" 1)) ==> "abc" - - - -=== Extending procedures with data - - -==== extend-procedure - -<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, -then its data slot is changed to contain {{X}} and the same procedure is -returned. Signals an error when {{PROCEDURE}} is not a procedure. - - -==== extended-procedure? - -<procedure>(extended-procedure? PROCEDURE)</procedure> - -Returns {{#t}} if {{PROCEDURE}} is an extended procedure, -or {{#f}} otherwise. - - -==== procedure-data - -<procedure>(procedure-data PROCEDURE)</procedure> - -Returns the data object contained in the extended procedure {{PROCEDURE}}, or -{{#f}} if it is not an extended procedure. - - -==== set-procedure-data! - -<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. - -<enscript highlight=scheme> -(define foo - (letrec ((f (lambda () (procedure-data x))) - (x #f) ) - (set! x (extend-procedure f 123)) - x) ) -(foo) ==> 123 -(set-procedure-data! foo 'hello) -(foo) ==> hello -</enscript> - - - -=== Low-level data access - -These procedures operate with what are known as {{vector-like objects}}. A -{{vector-like object}} is a vector, record structure, pair, symbol or keyword. - -Note that strings and blobs are not considered vector-like. - - -==== vector-like? - -<procedure>(vector-like? X)</procedure> - -Returns {{#t}} when {{X}} is a vector-like object, returns {{#f}} -otherwise. - - -==== block-ref - -<procedure>(block-ref VECTOR* INDEX)</procedure> - -Returns the contents of the {{INDEX}}th slot of the vector-like object -{{VECTOR*}}. - - -==== block-set! - -<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> - -Returns the number of slots that the vector-like object {{VECTOR*}} contains. - - -==== number-of-bytes - -<procedure>(number-of-bytes BLOCK)</procedure> - -Returns the number of bytes that the object {{BLOCK}} contains. {{BLOCK}} may -be any non-immediate value. - - -==== object-copy - -<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. - - -==== move-memory! - -<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, [[Unit srfi-4|SRFI-4 number-vectors]], memory -mapped files, foreign pointers (as obtained from a call to {{foreign-lambda}}, -for example), tagged-pointers or locatives. if {{BYTES}} is not given and the -size of the source or destination operand is known then the maximal number of -bytes will be copied. Moving memory to the storage returned by locatives will -cause havoc, if the locative refers to containers of non-immediate data, like -vectors or pairs. - -The additional fourth and fifth argument specify starting offsets (in bytes) -for the source and destination arguments. - -Signals an error if any of the above constraints is violated. - -This procedure is provided by the {{(chicken memory)}} module. - - -=== Record instance - - -==== make-record-instance - -<procedure>(make-record-instance SYMBOL ARG1 ...)</procedure> - -Returns a new instance of the record type {{SYMBOL}}, with its -slots initialized to {{ARG1 ...}}. To illustrate: - -<enscript highlight=scheme> -(define-record-type point (make-point x y) point? - (x point-x point-x-set!) - (y point-y point-y-set!)) -</enscript> - -expands into something quite similar to: - -<enscript highlight=scheme> -(begin - (define (make-point x y) - (make-record-instance 'point x y) ) - (define (point? x) - (and (record-instance? x) - (eq? 'point (block-ref x 0)) ) ) - (define (point-x p) (block-ref p 1)) - (define (point-x-set! p x) (block-set! p 1 x)) - (define (point-y p) (block-ref p 2)) - (define (point-y-set! p y) (block-set! p 1 y)) ) -</enscript> - - -==== record-instance? - -<procedure>(record-instance? X [SYMBOL])</procedure> - -Returns {{#t}} if {{X}} is a record structure, or {{#f}} otherwise. - -Further, returns {{#t}} if {{X}} is of type {{SYMBOL}}, or {{#f}} otherwise. - - -==== record-instance-type - -<procedure>(record-instance-type RECORD)</procedure> - -Returns type symbol of the record structure {{RECORD}}. Signals an error if -{{RECORD}} is not a record structure. - - -==== record-instance-length - -<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 -{{RECORD}} is not a record structure. - - -==== record-instance-slot - -<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 -record-instance-length)}}. Signals an error if {{RECORD}} is not a record -structure. - - -==== record-instance-slot-set! - -<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 -error if {{RECORD}} is not a record structure. - - -==== record->vector - -<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. - - -=== Magic - - -==== object-become! - -<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, -characters, booleans or the empty list). - -<enscript highlight=scheme> -(define x "i used to be a string") -(define y '#(and now i am a vector)) -(object-become! (list (cons x y))) -x ==> #(and now i am a vector) -y ==> #(and now i am a vector) -(eq? x y) ==> #t -</enscript> - -Note: this operation invokes a major garbage collection. - -The effect of using {{object-become!}} on evicted data (see {{object-evict}}) -is undefined. - - -==== mutate-procedure! - -<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 -identical in behaviour to the result of {{OLD}}: - -<enscript highlight=scheme> - ;;; Replace arbitrary procedure with tracing one: - - (mutate-procedure! my-proc - (lambda (new) - (lambda args - (printf "~s called with arguments: ~s~%" new args) - (apply new args) ) ) ) -</enscript> - ---- -Previous: [[Unit tcp]] - -Next: [[Unit continuation]] diff --git a/manual/Unit ports b/manual/Unit ports deleted file mode 100644 index fc8fde46..00000000 --- a/manual/Unit ports +++ /dev/null @@ -1,198 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit ports - -This unit contains various extended port definitions. This unit is -used by default, unless the program is compiled with the -{{-explicit-use}} option. - -=== Input/output port extensions - -==== with-output-to-port - -<procedure>(with-output-to-port PORT THUNK)</procedure> - -Call procedure {{THUNK}} with the current output-port temporarily -bound to {{PORT}}. - -==== make-input-port - -<procedure>(make-input-port READ-CHAR CHAR-READY? CLOSE [PEEK-CHAR [READ-STRING! [READ-LINE]]])</procedure> - -Returns a custom input port. Common operations on this port are -handled by the given parameters, which should be procedures of no -arguments. The following arguments are all different kinds of reader -procedures: - -* {{READ-CHAR}} is the most fundamental reader, and must always be -present. It is a thunk which is called when the next character is -to be read and it should return a character or {{#!eof}}. -* {{CHAR-READY?}} is a thunk which is called when {{char-ready?}} -is called on this port and should return {{#t}} or {{#f}}. -* {{CLOSE}} is a thunk which is called when the port is closed. -* {{PEEK-CHAR}} is a thunk which is called when {{peek-char}} is -called on this port and should return a character or {{#!eof}}. If it -is not provided or {{#f}}, {{READ-CHAR}} will be used instead and the -created port object handles peeking automatically (by calling {{READ}} -and buffering the character). -* {{READ-STRING!}} is called when {{read-string!}} is called (or the -higher-level non-mutating {{read-string}}). It will be invoked with 4 -arguments: the port created by {{make-input-port}}, the number of -bytes to read, a string (or sometimes a blob) to read into (which may be -assumed to be big enough to hold the data) and the offset into the -buffer at which to put the data to read. It should return the number -of bytes that have successfully been read, which should always be -equal to the requested bytes unless EOF was hit, in which case it can -be less. If this procedure is not provided or {{#f}}, the buffer will -be filled by repeated reads to {{READ-CHAR}}. -* {{READ-LINE}} is called when {{read-line}} is called. It will be -invoked with two arguments: the port created by {{make-input-port}} -and the maximum number of characters to read (or {{#f}}). If this -procedure is not provided or {{#f}}, the buffer will be filled by -repeated reads to {{READ-CHAR}}. - -All the optional procedures except for {{PEEK-CHAR}} are responsible -for updating the port's position, which currently can only be done via -low-level slot accessors like {{##sys#setslot}}; slot 4 is the row -number (ie, the line) and slot 5 is the column number (ie, the -character on the line). If the port's positions are not updated, -{{port-position}} won't work. - - -==== make-output-port - -<procedure>(make-output-port WRITE CLOSE [FLUSH])</procedure> - -Returns a custom output port. Common operations on this port are handled -by the given parameters, which should be procedures. {{WRITE}} is -called when output is sent to the port and receives a single argument, -a string. {{CLOSE}} is called when the port is closed and should -be a procedure of no arguments. {{FLUSH}} (if provided) is called -for flushing the output port. - - -==== with-error-to-port - -<procedure>(with-error-to-port PORT THUNK)</procedure> - -Call procedure {{THUNK}} with the current error output-port -temporarily bound to {{PORT}}. - - -==== with-input-from-port - -<procedure>(with-input-from-port PORT THUNK)</procedure> - -Call procedure {{THUNK}} with the current input-port temporarily -bound to {{PORT}}. - - -=== String-port extensions - -==== call-with-input-string - -<procedure>(call-with-input-string STRING PROC)</procedure> - -Calls the procedure {{PROC}} with a single argument that is a -string-input-port with the contents of {{STRING}}. - - -==== call-with-output-string - -<procedure>(call-with-output-string PROC)</procedure> - -Calls the procedure {{PROC}} with a single argument that is a -string-output-port. Returns the accumulated output-string. - - -==== with-input-from-string - -<procedure>(with-input-from-string STRING THUNK)</procedure> - -Call procedure {{THUNK}} with the current input-port temporarily -bound to an input-string-port with the contents of {{STRING}}. - - -==== with-output-to-string - -<procedure>(with-output-to-string THUNK)</procedure> - -Call procedure {{THUNK}} with the current output-port temporarily -bound to a string-output-port and return the accumulated output string. - -==== with-error-to-string - -<procedure>(with-error-to-string THUNK)</procedure> - -Call procedure {{THUNK}} with the current error output-port -temporarily bound to a string-output-port and return the accumulated -output string. - - -=== Port iterators - -==== port-for-each - -<procedure>(port-for-each FN THUNK)</procedure> - -Apply {{FN}} to successive results of calling the zero argument procedure {{THUNK}} (typically {{read}}) until it returns {{#!eof}}, discarding the results. - -==== port-map - -<procedure>(port-map FN THUNK)</procedure> - -Apply {{FN}} to successive results of calling the zero argument procedure {{THUNK}} (typically {{read}}) until it returns {{#!eof}}, returning a list of the collected results. - -==== port-fold - -<procedure>(port-fold FN ACC THUNK)</procedure> - -Apply {{FN}} to successive results of calling the zero argument procedure {{THUNK}}, (typically {{read}}) passing the {{ACC}} value as the second argument. The {{FN}} result becomes the new {{ACC}} value. When {{THUNK}} returns {{#!eof}}, the last {{FN}} result is returned. - -==== copy-port - -<procedure>(copy-port FROM TO [READ [WRITE]])</procedure> - -Reads all remaining data from port {{FROM}} using the reader procedure -{{READ}} and writes it to port {{TO}} using the writer procedure -{{WRITE}}. {{READ}} defaults to {{read-char}} and {{WRITE}} to -{{write-char}}. Note that this procedure does not check {{FROM}} and -{{TO}} for being ports, so the reader and writer procedures may -perform arbitrary operations as long as they can be invoked -as {{(READ FROM)}} and {{(WRITE X TO)}}, respectively. -{{copy-port}} returns an undefined value. - -{{copy-port}} was introduced in CHICKEN 4.6.0. - -=== Funky ports - -==== make-bidirectional-port - -<procedure>(make-bidirectional-port INPUT-PORT OUTPUT-PORT)</procedure> - -Returns a joint input/output port that proxies port operations to the -given {{INPUT-PORT}} and {{OUTPUT-PORT}}, respectively. This port -satisfies both {{input-port?}} and {{output-port?}}, and its two -directions may be closed independently. - -==== make-broadcast-port - -<procedure>(make-broadcast-port PORT ...)</procedure> - -Returns a custom output port that emits everything written into it to -the ports given as {{PORT ...}}. Closing the broadcast port does not close -any of the argument ports. - -==== make-concatenated-port - -<procedure>(make-concatenated-port PORT1 PORT2 ...)</procedure> - -Returns a custom input port that reads its input from {{PORT1}}, until it -is empty, then from {{PORT2}} and so on. Closing the concatenated port -does not close any of the argument ports. - ---- -Previous: [[Unit data-structures]] - -Next: [[Unit files]] diff --git a/manual/Unit posix b/manual/Unit posix deleted file mode 100644 index 93e107b6..00000000 --- a/manual/Unit posix +++ /dev/null @@ -1,1425 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit posix - -This unit provides services as used on many UNIX-like systems. Note that -the following definitions are not all available on non-UNIX systems like -Windows. See below for Windows specific notes. - -This unit uses the {{irregex}}, {{scheduler}}, and {{extras}} units. - -All errors related to failing file-operations will signal a condition -of kind {{(exn i/o file)}}. - - -=== Constants - -==== File-control Commands - -<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 - -<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 - -<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 - -<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 - -==== change-directory - -<procedure>(change-directory NAME)</procedure> - -Changes the current working directory to {{NAME}}. - -==== change-directory* - -<procedure>(change-directory* FD)</procedure> - -Changes the current working directory to the one represented by the -file-descriptor {{FD}}, which should be an exact integer. - - -==== current-directory - -<procedure>(current-directory [DIR])</procedure> - -Returns the name of the current working directory. If the optional argument {{DIR}} is given, -then {{(current-directory DIR)}} is equivalent to {{(change-directory DIR)}}. - -==== create-directory - -<procedure>(create-directory NAME #!optional PARENTS?)</procedure> - -Creates a directory with the pathname {{NAME}}. If the {{PARENTS?}} argument -is given and not false, any nonexistent parent directories are also created. - -Notice that if {{NAME}} exists, {{create-directory}} won't try to create it -and will return {{NAME}} (i.e., it won't raise an error when given a {{NAME}} -that already exists). - - -==== delete-directory - -<procedure>(delete-directory NAME [RECURSIVE])</procedure> - -Deletes the directory with the pathname {{NAME}}. If {{RECURSIVE}} is -not given or false, then the directory has to be empty. - -==== directory - -<procedure>(directory [PATHNAME [SHOW-DOTFILES?]])</procedure> - -Returns a list with all files that are contained in the directory with the name {{PATHNAME}} -(which defaults to the value of {{(current-directory)}}). -Files beginning with {{.}} are included only if {{SHOW-DOTFILES?}} is given and not {{#f}}. - -==== directory? - -<procedure>(directory? FILE)</procedure> - -Returns {{#t}} if {{FILE}} designates directory. Otherwise, it returns {{#f}}. -{{FILE}} may be a pathname, a file-descriptor or a port object. - -==== glob - -<procedure>(glob PATTERN1 ...)</procedure> - -Returns a list of the pathnames of all existing files matching -{{PATTERN1 ...}}, which should be strings containing the usual -file-patterns (with {{*}} matching zero or more characters and -{{?}} matching zero or one character). - -==== set-root-directory! - -<procedure>(set-root-directory! STRING)</procedure> - -Sets the root directory for the current process to the path given in {{STRING}} -(using the {{chroot}} function). -If the current process has no root permissions, the operation will fail. - - -=== Pipes - -==== call-with-input-pipe -==== call-with-output-pipe - -<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 -for a pipe connected to the subprocess named in {{CMDLINE}}. If -{{PROC}} returns normally, the pipe is closed and any result values -are returned. - -==== close-input-pipe -==== close-output-pipe - -<procedure>(close-input-pipe PORT)</procedure><br> -<procedure>(close-output-pipe PORT)</procedure> - -Closes the pipe given in {{PORT}} and waits until the connected -subprocess finishes. The exit-status code of the invoked process -is returned. - -==== create-pipe - -<procedure>(create-pipe)</procedure> - -The fundamental pipe-creation operator. Calls the C function -{{pipe()}} and returns 2 values: the file-descriptors of the input- -and output-ends of the pipe. - -==== open-input-pipe - -<procedure>(open-input-pipe CMDLINE [MODE])</procedure> - -Spawns a subprocess with the command-line string {{CMDLINE}} and -returns a port, from which the output of the process can be read. If -{{MODE}} is specified, it should be the keyword {{#:text}} -(the default) or {{#:binary}}. - -==== open-output-pipe - -<procedure>(open-output-pipe CMDLINE [MODE])</procedure> - -Spawns a subprocess with the command-line string {{CMDLINE}} and -returns a port. Anything written to that port is treated as the input -for the process. If {{MODE}} is specified, it should be the keyword -{{#:text}} (the default) or {{#:binary}}. - -==== pipe/buf -This variable contains the maximal number of bytes that can be written -atomically into a pipe or FIFO. - -==== with-input-from-pipe -==== with-output-to-pipe - -<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br> -<procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure> - -Temporarily set the value of -{{current-input-port/current-output-port}} to a port for a -pipe connected to the subprocess named in {{CMDLINE}} and call -the procedure {{THUNK}} with no arguments. After {{THUNK}} -returns normally the pipe is closed and the standard input-/output port -is restored to its previous value and any result values are returned. - -<enscript highlight=scheme> -(with-output-to-pipe - "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -" - (lambda () - (print #<<EOF - %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx> - /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8 - H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A - X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A - F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d - Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d - ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M - V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J - cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage - EOF - ) ) ) -</enscript> - - -=== Fifos - -==== create-fifo - -<procedure>(create-fifo FILENAME [MODE])</procedure> - -Creates a FIFO with the name {{FILENAME}} and the permission bits -{{MODE}}, which defaults to - -<enscript highlight=scheme> - (+ perm/irwxu perm/irwxg perm/irwxo) -</enscript> - -==== fifo? - -<procedure>(fifo? FILE)</procedure> - -Returns {{#t}} if {{FILE}} names a FIFO. {{FILE}} may be a filename, -a port or a file-descriptor. - - -=== File descriptors and low-level I/O - -==== duplicate-fileno - -<procedure>(duplicate-fileno OLD [NEW])</procedure> - -If {{NEW}} is given, then the file-descriptor {{NEW}} is opened -to access the file with the file-descriptor {{OLD}}. Otherwise a -fresh file-descriptor accessing the same file as {{OLD}} is returned. - -==== file-close - -<procedure>(file-close FILENO)</procedure> - -Closes the input/output file with the file-descriptor {{FILENO}}. - -==== file-open - -<procedure>(file-open FILENAME FLAGS [MODE])</procedure> - -Opens the file specified with the string {{FILENAME}} and open-flags -{{FLAGS}} using the C function {{open(2)}}. On success a -file-descriptor for the opened file is returned. - -{{FLAGS}} is a bitmask of {{open/...}} -values '''or'''ed together using {{bitwise-ior}} (or simply added -together). You must provide exactly one of the access flags {{open/rdonly}}, {{open/wronly}}, or {{open/rdwr}}. Additionally, you may provide zero or more creation flags ({{open/creat}}, {{open/excl}}, {{open/trunc}}, and {{open/noctty}}) and status flags (the remaining {{open/...}} values). For example, to open a possibly new output file for appending: - - (file-open "/tmp/hen.txt" (+ open/wronly open/append open/creat)) - -The optional {{MODE}} should be a bitmask composed of one -or more permission values like {{perm/irusr}} and is only relevant -when a new file is created. The default mode is -{{perm/irwxu | perm/irgrp | perm/iroth}}. - -==== file-mkstemp - -<procedure>(file-mkstemp TEMPLATE-FILENAME)</procedure> - -Create a file based on the given {{TEMPLATE-FILENAME}}, in which -the six last characters must be ''XXXXXX''. These will be replaced -with a string that makes the filename unique. The file descriptor of -the created file and the generated filename is returned. See the -{{mkstemp(3)}} manual page for details on how this function -works. The template string given is not modified. - -Example usage: - -<enscript highlight=scheme> - (let-values (((fd temp-path) (file-mkstemp "/tmp/mytemporary.XXXXXX"))) - (let ((temp-port (open-output-file* fd))) - (format temp-port "This file is ~A.~%" temp-path) - (close-output-port temp-port))) -</enscript> - -==== file-read - -<procedure>(file-read FILENO SIZE [BUFFER])</procedure> - -Reads {{SIZE}} bytes from the file with the file-descriptor -{{FILENO}}. If a string or bytevector is passed in the optional -argument {{BUFFER}}, then this string will be destructively modified -to contain the read data. This procedure returns a list with two values: -the buffer containing the data and the number of bytes read. - -==== file-select - -<procedure>(file-select READFDLIST WRITEFDLIST [TIMEOUT])</procedure> - -Waits until any of the file-descriptors given in the lists -{{READFDLIST}} and {{WRITEFDLIST}} is ready for input or -output, respectively. If the optional argument {{TIMEOUT}} is -given and not false, then it should specify the number of seconds after -which the wait is to be aborted (the value may be a floating point -number). This procedure returns two values: -the lists of file-descriptors ready for input and output, respectively. -{{READFDLIST}} and '''WRITEFDLIST''' may also by file-descriptors -instead of lists. In this case the returned values are booleans -indicating whether input/output is ready by {{#t}} or {{#f}} -otherwise. You can also pass {{#f}} as {{READFDLIST}} or -{{WRITEFDLIST}} argument, which is equivalent to {{()}}. - -==== file-write - -<procedure>(file-write FILENO BUFFER [SIZE])</procedure> - -Writes the contents of the string or bytevector {{BUFFER}} into -the file with the file-descriptor {{FILENO}}. If the optional -argument {{SIZE}} is given, then only the specified number of bytes -are written. - -==== file-control - -<procedure>(file-control FILENO COMMAND [ARGUMENT])</procedure> - -Performs the fcntl operation {{COMMAND}} with the given -{{FILENO}} and optional {{ARGUMENT}}. The return value is -meaningful depending on the {{COMMAND}}. - -==== open-input-file* -==== open-output-file* - -<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 -and returns a port. {{FILENO}} should be a positive exact integer. -{{OPENMODE}} specifies an additional mode for opening the file -(currently only the keyword {{#:append}} is supported, which opens -an output-file for appending). - -==== port->fileno - -<procedure>(port->fileno PORT)</procedure> - -If {{PORT}} is a file- or tcp-port, then a file-descriptor is returned for -this port. Otherwise an error is signaled. - - -=== Retrieving file attributes - -==== file-access-time -==== file-change-time -==== file-modification-time - -<procedure>(file-access-time FILE)</procedure><br> -<procedure>(file-change-time FILE)</procedure><br> -<procedure>(file-modification-time FILE)</procedure> -<procedure>(set! (file-modification-time FILE) SECONDS)</procedure> - -Returns time (in seconds) of the last access, modification or change of {{FILE}}. {{FILE}} -may be a filename or a file-descriptor. If the file does not exist, -an error is signaled. - -{{file-access-time}}, {{file-change-time}} and {{file-modification-time}} also accept a port object as their argument. - -{{(set! (file-modification-time FILE) SECONDS)}} sets the access- and modification -time of {{FILE}} to {{SECONDS}}. - -==== file-stat - -<procedure>(file-stat FILE [LINK])</procedure> - -Returns a 13-element vector with the following contents: - -<table> -<tr><th>index</th> - <th>value</th> - <th>field</th> - <th>notes</th></tr> -<tr><td>0</td> - <td>inode number</td> - <td>{{st_ino}}</td> - <td></td></tr> -<tr><td>1</td> - <td>mode</td> - <td>{{st_mode}}</td> - <td>bitfield combining file permissions and file type</td></tr> -<tr><td>2</td> - <td>number of hard links</td> - <td>{{st_nlink}}</td> - <td></td></tr> -<tr><td>3</td> - <td>UID of owner</td> - <td>{{st_uid}}</td> - <td>as with {{file-owner}}</td></tr> -<tr><td>4</td> - <td>GID of owner</td> - <td>{{st_gid}}</td> - <td></td></tr> -<tr><td>5</td> - <td>size</td> - <td>{{st_size}}</td> - <td>as with {{file-size}}</td></tr> -<tr><td>6</td> - <td>access time</td> - <td>{{st_atime}}</td> - <td>as with {{file-access-time}}</td></tr> -<tr><td>7</td> - <td>change time</td> - <td>{{st_ctime}}</td> - <td>as with {{file-change-time}}</td></tr> -<tr><td>8</td> - <td>modification time</td> - <td>{{st_mtime}}</td> - <td>as with {{file-modification-time}}</td></tr> -<tr><td>9</td> - <td>parent device ID </td> - <td>{{st_dev}}</td> - <td>ID of device on which this file resides</td></tr> -<tr><td>10</td> - <td>device ID</td> - <td>{{st_rdev}}</td> - <td>device ID for special files (i.e. the raw major/minor number)</td></tr> -<tr><td>11</td> - <td>block size</td> - <td>{{st_blksize}}</td> - <td></td></tr> -<tr><td>12</td> - <td>number of blocks allocated</td> - <td>{{st_blocks}}</td> - <td></td></tr> -</table> - -On Windows systems, the last 4 values are undefined. - -By default, symbolic links are followed and -the status of the referenced file is returned; -however, if the optional argument {{LINK}} is given and -not {{#f}}, the status of the link itself is returned. - -{{FILE}} may be a filename, port or file-descriptor. - -Note that for very large files, the {{file-size}} value may be an -inexact integer. - -==== file-position - -<procedure>(file-position FILE)</procedure> - -Returns the current file position of {{FILE}}, which should be a -port or a file-descriptor. - -==== file-size - -<procedure>(file-size FILE)</procedure> - -Returns the size of the file designated by {{FILE}}. {{FILE}} -may be a filename, a file-descriptor or a port object. If the file does not exist, -an error is signaled. Note that for very large files, {{file-size}} may -return an inexact integer. - -==== regular-file? - -<procedure>(regular-file? FILE)</procedure> - -Returns true, if {{FILE}} names a regular file (not a directory, socket, etc.) This operation follows symbolic links; use either {{symbolic-link?}} or {{file-type}} if you need to test for symlinks. {{FILE}} may refer to a filename, file descriptor or ports object. - -==== file-owner - -<procedure>(file-owner FILE)</procedure> - -Returns the user-id of {{FILE}}. {{FILE}} may be a filename, a file-descriptor -or a port object. - -==== file-permissions - -<procedure>(file-permissions FILE)</procedure> - -Returns the permission bits for {{FILE}}. You can test this value -by performing bitwise operations on the result and the {{perm/...}} -values. {{FILE}} may be a filename, a file-descriptor or a port object. - -==== file-read-access? -==== file-write-access? -==== file-execute-access? - -<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, -write or execute permissions on the file named {{FILENAME}}. - - -==== file-type - -<procedure>(file-type FILE [LINK [ERROR]])</procedure> - -Returns the file-type for {{FILE}}, which should be a filename, a file-descriptor -or a port object. If {{LINK}} is given and true, symbolic-links are -not followed: - - regular-file - directory - fifo - socket - symbolic-link - character-device - block-device - -Note that not all types are supported on every platform. -If {{ERROR}} is given and false, then {{file-type}} returns {{#f}} if the file does not exist; -otherwise, it signals an error. - - -==== character-device? -==== block-device? -==== socket? - -<procedure>(character-device? FILE)</procedure><br> -<procedure>(block-device? FILE)</procedure><br> -<procedure>(socket? FILE)</procedure> - -These procedures return {{#t}} if {{FILE}} given is of the -appropriate type. {{FILE}} may be a filename, a file-descriptor or a port object. -Note that these operations follow symbolic links. If the file does -not exist, {{#f}} is returned. - - -=== Changing file attributes - -==== file-truncate - -<procedure>(file-truncate FILE OFFSET)</procedure> - -Truncates the file {{FILE}} to the length {{OFFSET}}, -which should be an integer. If the file-size is smaller or equal to -{{OFFSET}} then nothing is done. {{FILE}} should be a filename -or a file-descriptor. - -==== set-file-position! - -<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 -{{POSITION}}, which should be an exact integer. {{FILE}} -should be a port or a file-descriptor. {{WHENCE}} specifies -how the position is to interpreted and should be one of the values -{{seek/set, seek/cur}} and {{seek/end}}. It defaults to -{{seek/set}}. - -Exceptions: {{(exn bounds)}}, {{(exn i/o file)}} - -==== change-file-mode - -<procedure>(change-file-mode FILENAME MODE)</procedure> - -Changes the current file mode of the file named {{FILENAME}} -to {{MODE}} using the {{chmod()}} system call. The -{{perm/...}} variables contain the various permission bits and can -be combinded with the {{bitwise-ior}} procedure. - -==== change-file-owner - -<procedure>(change-file-owner FILENAME UID GID)</procedure> - -Changes the owner information of the file named {{FILENAME}} to -the user- and group-ids {{UID}} and {{GID}} (which should be -exact integers) using the {{chown()}} system call. - - -==== file-creation-mode - -<procedure>(file-creation-mode [MODE])</procedure> - -Returns the initial file permissions used for newly created files -(as with {{umask(2)}}). If {{MODE}} is supplied, the mode is -changed to this value. You can set the mode by executing - - (set! (file-creation-mode) MODE) - -or - - (file-creation-mode MODE) - -where {{MODE}} is a bitwise combination of one or more of -the {{perm/...}} flags. - - -=== Processes - -==== current-process-id - -<procedure>(current-process-id)</procedure> - -Returns the process ID of the current process. - -==== parent-process-id - -<procedure>(parent-process-id)</procedure> - -Returns the process ID of the parent of the current process. - -==== process-group-id - -<procedure>(process-group-id PID)</procedure> - [setter] (set! (process-group-id PID) PGID) - -Get or set the process group ID of the process specified by {{PID}}. - -==== process-execute - -<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-ALIST]])</procedure> - -Replaces the running process with a new process image from the program -stored at {{PATHNAME}}, using the C library function {{execvp(3)}}. -If the optional argument {{ARGUMENT-LIST}} is given, then it should -contain a list of strings which are passed as arguments to the subprocess. -If the optional argument {{ENVIRONMENT-ALIST}} is supplied, then the library -function {{execve(2)}} is used, and the environment passed in -{{ENVIRONMENT-ALIST}} (which should be of the form {{(("<NAME>" . "<VALUE>") ...)}}) -is given to the invoked process. Note that {{execvp(3)}} respects the -current setting of the {{PATH}} environment variable while {{execve(3)}} does not. - -This procedure never returns; it either replaces the process with a new one -or it raises an exception in case something went wrong executing the program. - -==== process-fork - -<procedure>(process-fork [THUNK [KILLOTHERS?]])</procedure> - -Creates a new child process with the UNIX system call -{{fork()}}. Returns either the PID of the child process or 0. If -{{THUNK}} is given, then the child process calls it as a procedure -with no arguments and terminates. If {{THUNK}} is given and the -optional argument {{KILLOTHERS?}} is true, then kill all other -existing threads in the child process, leaving only the current thread -to run {{THUNK}} and terminate. - -==== process-run - -<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. - -* The single parameter version passes the {{COMMANDLINE}} to the system shell, so usual -argument expansion can take place. -* The multiple parameter version directly invokes the {{COMMAND}} with the {{ARGUMENT-LIST}}. - -==== process-signal - -<procedure>(process-signal PID [SIGNAL])</procedure> - -Sends {{SIGNAL}} to the process with the id {{PID}} using the -UNIX system call {{kill()}}. {{SIGNAL}} defaults to the value -of the variable {{signal/term}}. - -==== process-wait - -<procedure>(process-wait [PID [NOHANG]])</procedure> - -Suspends the current process until the child process with -the id {{PID}} has terminated using the UNIX system call -{{waitpid()}}. If {{PID}} is not given, then this procedure -waits for any child process. If {{NOHANG}} is given and not -{{#f}} then the current process is not suspended. This procedure -returns three values: - -* {{PID}} or 0, if {{NOHANG}} is true and the child process has not terminated yet. -* {{#t}} if the process exited normally or {{#f}} otherwise. -* either the exit status, if the process terminated normally or the signal number that terminated/stopped the process. - -Note that suspending the current process implies that all threads -are suspended as well. - -==== process - -<procedure>(process COMMANDLINE)</procedure><br> -<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST])</procedure> - -Creates a subprocess and returns three values: an input port from -which data written by the sub-process can be read, an output port from -which any data written to will be received as input in the sub-process -and the process-id of the started sub-process. Blocking reads and writes -to or from the ports returned by {{process}} only block the current -thread, not other threads executing concurrently. - -Standard error for the subprocess is linked up to the current -process's standard error (see {{process*}} if you want to reify -its standard error into a separate port). - -* The single parameter version passes the string {{COMMANDLINE}} to the host-system's shell that -is invoked as a subprocess. -* The multiple parameter version directly invokes the {{COMMAND}} as a subprocess. The {{ARGUMENT-LIST}} -is directly passed, as is {{ENVIRONMENT-ALIST}}. - -Not using the shell may be preferrable for security reasons. - -Once both the input- and output ports are closed, an implicit -{{waitpid(3)}} is done to wait for the subprocess to finish or to reap -a subprocess that has terminated. If the subprocess has not finished, -waiting for it will necessarily block all executing threads. - -==== process* - -<procedure>(process* COMMANDLINE)</procedure><br> -<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-LIST])</procedure> - -Like {{process}} but returns 4 values: an input port from -which data written by the sub-process can be read, an output port from -which any data written to will be received as input in the sub-process, -the process-id of the started sub-process, and an input port from -which data written by the sub-process to {{stderr}} can be read. - -==== process-sleep - -<procedure>(process-sleep SECONDS)</procedure> - -Puts the process to sleep for {{SECONDS}}. Returns either 0 if -the time has completely elapsed, or the number of remaining seconds, -if a signal occurred. - -==== create-session - -<procedure>(create-session)</procedure> - -Creates a new session if the calling process is not a process group leader and returns -the session ID. - - -=== Shell commands - -==== system* - -<procedure>(system* STRING)</procedure> - -Similar to {{(system STRING)}}, but signals an error should the invoked -program return a nonzero exit status. - -==== qs - -<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 -which style the argument should be quoted. On Windows systems, the string -is simply enclosed in double-quote ({{"}}) characters, on UNIXish systems, -characters that would have a special meaning to the shell are escaped -using backslash ({{\}}). - - -=== Hard and symbolic links - -==== symbolic-link? - -<procedure>(symbolic-link? FILE)</procedure> - -Returns true, if {{FILE}} names a symbolic link. If no such file exists, {{#f}} -is returned. This operation does not follow symbolic links itself. -{{FILE}} could be a filename, file descriptor or port object. - -==== create-symbolic-link - -<procedure>(create-symbolic-link OLDNAME NEWNAME)</procedure> - -Creates a symbolic link with the filename {{NEWNAME}} that points -to the file named {{OLDNAME}}. - -==== read-symbolic-link - -<procedure>(read-symbolic-link FILENAME [CANONICALIZE])</procedure> - -Returns the filename to which the symbolic link {{FILENAME}} points. -If {{CANONICALIZE}} is given and true, then symbolic links are -resolved repeatedly until the result is not a link. - -==== file-link - -<procedure>(file-link OLDNAME NEWNAME)</procedure> - -Creates a hard link from {{OLDNAME}} to {{NEWNAME}} (both strings). - - -=== Retrieving user & group information - -==== current-user-id - -<procedure>(current-user-id)</procedure> - [setter] (set! (current-user-id) UID) - -Get or set the real user-id of the current process. The procedure corresponds to the getuid and setuid C functions. - -==== current-effective-user-id - -<procedure>(current-effective-user-id)</procedure> - [setter] (set! (current-effective-user-id) UID) - -Get or set the effective user-id of the current process. - -==== user-information - -<procedure>(user-information USER [AS-VECTOR])</procedure> - -If {{USER}} specifes a valid username (as a string) or user ID, then the user -database is consulted and a list of 7 values are returned: the user-name, the -encrypted password, the user ID, the group ID, a user-specific string, the home -directory and the default shell. When {{AS-VECTOR}} is {{#t}} a vector of 7 -elements is returned instead of a list. If no user with this name or id then -{{#f}} is returned. - -Note: on Android systems, the user-specific string is always {{""}}, -since {{pw_gecos}} is not available in the C {{passwd}} struct on that -platform. - -==== current-group-id - -<procedure>(current-group-id)</procedure> - [setter] (set! (current-group-id) GID) - -Get or set the real group-id of the current process. - -==== current-effective-group-id - -<procedure>(current-effective-group-id)</procedure> - [setter] (set! (current-effective-group-id) GID) - -Get or set the effective group-id of the current process. -ID can be found, then {{#f}} is returned. - - -=== Record locking - -==== file-lock - -<procedure>(file-lock PORT [START [LEN]])</procedure> - -Locks the file associated with {{PORT}} for reading or -writing (according to whether {{PORT}} is an input- or -output-port). {{START}} specifies the starting position in the -file to be locked and defaults to 0. {{LEN}} specifies the length -of the portion to be locked and defaults to {{#t}}, which means -the complete file. {{file-lock}} returns a ''lock''-object. - -==== file-lock/blocking - -<procedure>(file-lock/blocking PORT [START [LEN]])</procedure> - -Similar to {{file-lock}}, but if a lock is held on the file, -the current process blocks (including all threads) until the lock is released. - -==== file-test-lock - -<procedure>(file-test-lock PORT [START [LEN]])</procedure> - -Tests whether the file associated with {{PORT}} is locked for reading -or writing (according to whether {{PORT}} is an input- or output-port) -and returns either {{#f}} or the process-id of the locking process. - -==== file-unlock - -<procedure>(file-unlock LOCK)</procedure> - -Unlocks the previously locked portion of a file given in {{LOCK}}. - - -=== Signal handling - -==== set-alarm! - -<procedure>(set-alarm! SECONDS)</procedure> - -Sets an internal timer to raise the {{signal/alrm}} -after {{SECONDS}} are elapsed. You can use the -{{set-signal-handler!}} procedure to write a handler for this signal. - -==== set-signal-handler! - -==== signal-handler - -<procedure>(signal-handler SIGNUM)</procedure> - -Returns the signal handler for the code {{SIGNUM}} or {{#f}}. - -<procedure>(set-signal-handler! SIGNUM PROC)</procedure> - -Establishes the procedure of one argument {{PROC}} as the handler -for the signal with the code {{SIGNUM}}. {{PROC}} is called -with the signal number as its sole argument. If the argument {{PROC}} is {{#f}} -then any signal handler will be removed, and the corresponding signal set to {{SIG_IGN}}. - -Notes - -* it is unspecified in which thread of execution the signal handler will be invoked. - -* when signals arrive in quick succession (specifically, before the handler for a signal has been started), then signals will be queued (up to a certain limit); the order in which the queued signals will be handled is not specified - -* {{(set! (signal-handler SIG) PROC)}} can be used as an alternative to {{(set-signal-handler! SIG PROC)}} - -* Any signal handlers for the signals {{signal/segv}}, {{signal/bus}}, {{signal/fpe}} and {{signal/ill}} will be ignored and these signals will always trigger an exception, unless the executable was started with the {{-:S}} runtime option. This feature is only available on platforms that support the {{sigprocmask(3)}} POSIX API function. - -==== set-signal-mask! - -<procedure>(set-signal-mask! SIGLIST)</procedure> - -Sets the signal mask of the current process to block all signals given -in the list {{SIGLIST}}. Signals masked in that way will not be -delivered to the current process. - -==== signal-mask - -<procedure>(signal-mask)</procedure> - -Returns the signal mask of the current process. - -==== signal-masked? - -<procedure>(signal-masked? SIGNUM)</procedure> - -Returns whether the signal for the code {{SIGNUM}} is currently masked. - -==== signal-mask! - -<procedure>(signal-mask! SIGNUM)</procedure> - -Masks (blocks) the signal for the code {{SIGNUM}}. - -==== signal-unmask! - -<procedure>(signal-unmask! SIGNUM)</procedure> - -Unmasks (unblocks) the signal for the code {{SIGNUM}}. - -==== 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/bus</constant><br> -<constant>signal/winch</constant> -<constant>signal/break</constant> - -These variables contain signal codes for use with {{process-signal}}, {{set-signal-handler!}}, {{signal-handler}}, {{signal-masked?}}, {{signal-mask!}}, or {{signal-unmask!}}. - - -=== Environment access - -==== 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]]). - -==== set-environment-variable! - -<procedure>(set-environment-variable! VARIABLE VALUE)</procedure> - -Sets the environment variable named {{VARIABLE}} to -{{VALUE}}. Both arguments should be strings. If the variable is -not defined in the environment, a new definition is created. - -==== unset-environment-variable! - -<procedure>(unset-environment-variable! VARIABLE)</procedure> - -Removes the definition of the environment variable {{VARIABLE}} from -the environment of the current process. If the variable is not defined, -nothing happens. - - -=== Date and time routines - -==== seconds->local-time - -<procedure>(seconds->local-time [SECONDS])</procedure> - -Breaks down the time value represented in {{SECONDS}} into a 10 -element vector of the form {{#(seconds minutes hours mday month -year wday yday dstflag timezone)}}, in the following format: - -; seconds (0) : the number of seconds after the minute (0 - 59) -; minutes (1) : the number of minutes after the hour (0 - 59) -; hours (2) : the number of hours past midnight (0 - 23) -; mday (3) : the day of the month (1 - 31) -; month (4) : the number of months since january (0 - 11) -; year (5) : the number of years since 1900 -; wday (6) : the number of days since Sunday (0 - 6) -; yday (7) : the number of days since January 1 (0 - 365) -; dstflag (8) : a flag that is true if Daylight Saving Time is in effect at the time described. -; timezone (9) : the difference between UTC and the latest local standard time, in seconds west of UTC. - -{{SECONDS}} defaults to -the value of {{(current-seconds)}}. - -==== local-time->seconds - -<procedure>(local-time->seconds VECTOR)</procedure> - -Converts the ten-element vector {{VECTOR}} representing the time value relative to -the current timezone into -the number of seconds since the first of January, 1970 UTC. - -==== local-timezone-abbreviation - -<procedure>(local-timezone-abbreviation)</procedure> - -Returns the abbreviation for the local timezone as a string. - -==== seconds->string - -<procedure>(seconds->string [SECONDS])</procedure> - -Converts the time represented in {{SECONDS}} into a local-time string -of the form {{"Tue May 21 13:46:22 1991"}}. {{SECONDS}} defaults to -the value of {{(current-seconds)}}. - -==== seconds->utc-time - -<procedure>(seconds->utc-time [SECONDS])</procedure> - -Similar to {{seconds->local-time}}, but interpretes {{SECONDS}} -as UTC time. {{SECONDS}} defaults to -the value of {{(current-seconds)}}. - -==== utc-time->seconds - -<procedure>(utc-time->seconds VECTOR)</procedure> - -Converts the ten-element vector {{VECTOR}} representing the UTC time value into -the number of seconds since the first of January, 1970 UTC. - -==== time->string - -<procedure>(time->string VECTOR [FORMAT])</procedure> - -Converts the broken down time represented in the 10 element vector -{{VECTOR}} into a string of the form represented by the {{FORMAT}} -string. The default time form produces something like {{"Tue May 21 13:46:22 1991"}}. - -The {{FORMAT}} string follows the rules for the C library procedure {{strftime}}. The default {{FORMAT}} string is "%a %b %e %H:%M:%S %Z %Y". - -==== string->time - -<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 -default time form understands something like {{"Tue May 21 13:46:22 1991"}}. - -The {{FORMAT}} string follows the rules for the C library procedure {{strptime}}. The default {{FORMAT}} string is "%a %b %e %H:%M:%S %Z %Y". - - -=== Raw exit - -==== emergency-exit - -<procedure>(emergency-exit [CODE])</procedure> - -Exits the current process without flushing any buffered output (using -the C function {{_exit}}). Note that the {{exit-handler}} is not called -when this procedure is invoked. The optional exit status code {{CODE}} -defaults to {{0}}. - - -=== ERRNO values - -<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}}. - -They are provided by the {{(chicken errno)}} module. - -=== Finding files - -==== find-files - -<procedure>(find-files DIRECTORY #!key test action seed limit dotfiles follow-symlinks)</procedure> - -Recursively traverses the contents of {{DIRECTORY}} (which should be a -string) and invokes the procedure {{action}} for all files in which -the procedure {{test}} is true. - -{{test}} may be a procedure of one argument or an irregex object, -regex string or SRE expression that will be matched with a full -pathname using {{irregex-match}}. {{test}} defaults to {{(constantly -#t)}}. - - -{{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 -{{seed}}. {{action}} defaults to {{cons}}, {{seed}} 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)}}. - -If {{dotfiles}} is given and true, then files starting with a "{{.}}" -character will not be ignored (but note that "{{.}}" and "{{..}}" are -always ignored). if {{follow-symlinks}} is given and true, then the -traversal of a symbolic link that points to a directory will -recursively traverse the latter. By default, symbolic links are not -followed. - -Note that {{action}} is called with the full pathname of each file, -including the directory prefix. - -This procedure's signature was changed in CHICKEN 4.6. In older versions, {{find-files}} -has a different signature: - - (find-files DIRECTORY [TEST [ACTION [SEED [LIMIT]]]]) - -The old signature was supported until CHICKEN 4.7.3 for compatibility reasons, -at which point it became invalid. The optional arguments are ignored -and use their default values, and no warning is issued. One symptom is -that your {{TEST}} does not work, returning every file. - -=== Getting the hostname and system information - -==== get-host-name - -<procedure>(get-host-name)</procedure> - -Returns the hostname of the machine that this process is running on. - -==== system-information - -<procedure>(system-information)</procedure> - -Invokes the UNIX system call {{uname()}} and returns a list of 5 values: -system-name, node-name, OS release, OS version and machine. - -=== Setting the file buffering mode - -==== set-buffering-mode! - -<procedure>(set-buffering-mode! PORT MODE [BUFSIZE])</procedure> - -Sets the buffering-mode for the file associated with {{PORT}} to -{{MODE}}, which should be one of the keywords {{#:full}}, -{{#:line}} or {{#:none}}. If {{BUFSIZE}} is specified it -determines the size of the buffer to be used (if any). - - -=== Terminal ports - -==== terminal-name - -<procedure>(terminal-name PORT)</procedure> - -Returns the name of the terminal that is connected to {{PORT}}. - -==== terminal-port? - -<procedure>(terminal-port? PORT)</procedure> - -Returns {{#t}} if {{PORT}} is connected to a terminal and -{{#f}} otherwise. - - -==== terminal-size - -<procedure>(terminal-size PORT)</procedure> - -Returns two values, the number of columns and rows of the terminal -that is connected to {{PORT}} or {{0}}, {{0}} if the terminal size can -not be obtained. On Windows, this procedure always returns {{0}}, -{{0}}. - - -=== How Scheme procedures relate to UNIX C functions - -; {{change-directory}} : {{chdir}} -; {{change-directory*}} : {{fchdir}} -; {{change-file-mode}} : {{chmod}} -; {{change-file-owner}} : {{chown}} -; {{create-directory}} : {{mkdir}} -; {{create-fifo}} : {{mkfifo}} -; {{create-pipe}} : {{pipe}} -; {{create-session}} : {{setsid}} -; {{create-symbolic-link}} : {{link}} -; {{current-directory}} : {{curdir}} -; {{current-effective-group-id}} : {{getegid}} -; {{current-effective-user-id}} : {{geteuid}} -; {{current-group-id}} : {{getgid}} -; {{current-parent-id}} : {{getppid}} -; {{current-process-id}} : {{getpid}} -; {{current-user-id}} : {{getuid}} -; {{delete-directory}} : {{rmdir}} -; {{duplicate-fileno}} : {{dup/dup2}} -; {{emergency-exit}} : {{_exit}} -; {{file-close}} : {{close}} -; {{file-access-time}} : {{stat}} -; {{file-change-time}} : {{stat}} -; {{file-creation-mode}} : {{umask}} -; {{file-modification-time}} : {{stat}} -; {{file-execute-access?}} : {{access}} -; {{file-open}} : {{open}} -; {{file-lock}} : {{fcntl}} -; {{file-position}} : {{ftell/lseek}} -; {{file-read}} : {{read}} -; {{file-read-access?}} : {{access}} -; {{file-select}} : {{select}} -; {{file-control}} : {{fcntl}} -; {{file-stat}} : {{stat}} -; {{file-test-lock}} : {{fcntl}} -; {{file-truncate}} : {{truncate/ftruncate}} -; {{file-unlock}} : {{fcntl}} -; {{file-write}} : {{write}} -; {{file-write-access?}} : {{access}} -; {{get-host-name}} : {{gethostname}} -; {{local-time->seconds}} : {{mktime}} -; {{local-timezone-abbreviation}} : {{localtime}} -; {{open-input-file*}} : {{fdopen}} -; {{open-output-file*}} : {{fdopen}} -; {{open-input-pipe}} : {{popen}} -; {{open-output-pipe}} : {{popen}} -; {{port->fileno}} : {{fileno}} -; {{process-execute}} : {{execvp}} -; {{process-fork}} : {{fork}} -; {{process-group-id}} : {{getpgid}} -; {{process-signal}} : {{kill}} -; {{process-sleep}} : {{sleep}} -; {{process-wait}} : {{waitpid}} -; {{close-input-pipe}} : {{pclose}} -; {{close-output-pipe}} : {{pclose}} -; {{read-symbolic-link}} : {{readlink}} -; {{seconds->local-time}} : {{localtime}} -; {{seconds->string}} : {{ctime}} -; {{seconds->utc-time}} : {{gmtime}} -; {{set-alarm!}} : {{alarm}} -; {{set-buffering-mode!}} : {{setvbuf}} -; {{set-file-position!}} : {{fseek/seek}} -; {{set-signal-mask!}} : {{sigprocmask}} -; {{set-group-id!}} : {{setgid}} -; {{set-user-id!}} : {{setuid}} -; {{set-root-directory!}} : {{chroot}} -; {{set-environment-variable!}} : {{setenv/putenv}} -; {{system-information}} : {{uname}} -; {{terminal-name}} : {{ttyname}} -; {{terminal-port?}} : {{isatty}} -; {{time->string}} : {{asctime}} -; {{unset-environment-variable!}} : {{unsetenv/putenv}} -; {{user-information}} : {{getpwnam/getpwuid}} -; {{utc-time->seconds}} : {{timegm}} - - -=== Windows specific notes - -Use of UTF8 encoded strings is for pathnames is not supported. Windows uses a -16-bit UNICODE encoding with special system calls for wide-character support. -Only single-byte string encoding can be used. - -==== Procedure Changes - -Exceptions to the above procedure definitions. - -<procedure>(create-pipe [MODE])</procedure> - -The optional parameter {{MODE}}, default {{open/binary | open/noinherit}}. This can be {{open/binary}} or -{{open/text}}, optionally or'ed with {{open/noinherit}}. - -<procedure>(process-wait [PID [NOHANG]])</procedure> - -{{process-wait}} always returns {{#t}} for a terminated process and only the exit -status is available. (Windows does not provide signals as an interprocess -communication method.) - -<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. - -==== Unsupported Definitions - -The following definitions are not supported for native Windows builds (compiled with the -Microsoft tools or with MinGW): - - open/noctty open/nonblock open/fsync open/sync - perm/isvtx perm/isuid perm/isgid - file-select file-control - signal/... (except signal/term, signal/int, signal/fpe, signal/ill, signal/segv, signal/abrt, signal/break) - set-signal-mask! signal-mask signal-masked? signal-mask! signal-unmask! - user-information - errno/wouldblock - change-directory* - change-file-owner - current-user-id current-group-id current-effective-user-id current-effective-group-id - set-user-id! set-group-id! - create-session - process-group-id - create-symbolic-link read-symbolic-link - file-truncate - file-lock file-lock/blocking file-unlock file-test-lock - create-fifo fifo? - set-alarm! - terminal-port? terminal-name - process-fork process-signal - parent-process-id - set-root-directory! - utc-time->seconds - -==== Additional Definitions - -Only available for Windows - -* open/noinherit - -This variable is a mode value for {{create-pipe}}. Useful when spawning a child process. - -* spawn/overlay -* spawn/wait -* spawn/nowait -* spawn/nowaito -* spawn/detach - -These variables contains special flags that specify the exact semantics of {{process-spawn}}: -{{spawn/overlay}} replaces the current process with the new one. -{{spawn/wait}} suspends execution of the current process until the spawned process returns. -{{spawn/nowait}} does the opposite ({{spawn/nowaito}} is identical, according to the Microsoft -documentation) and runs the process asynchronously. -{{spawn/detach}} runs the new process in the background, without being attached to a console. - -==== process-spawn - -<procedure>(process-spawn MODE COMMAND [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure> - -Creates and runs a new process with the given {{COMMAND}} filename and the optional -{{ARGUMENT-LIST}} and {{ENVIRONMENT-LIST}}. {{MODE}} specifies how exactly the process -should be executed and must be one or more of the {{spawn/...}} flags defined above. - -The {{EXACT-FLAG}}, default {{#f}}, controls quote-wrapping of argument strings. When {{#t}} -quote-wrapping is not performed. - -Returns: -* the exit status when synchronous -* the PID when asynchronous -* -1 when failure - ----- -Previous: [[Unit srfi-4]] - -Next: [[Unit tcp]] diff --git a/manual/Unit read-syntax b/manual/Unit read-syntax deleted file mode 100644 index 861873a7..00000000 --- a/manual/Unit read-syntax +++ /dev/null @@ -1,91 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit read-syntax - -=== Reader extensions - -The following procedures are provided by the {{(chicken read-syntax)}} -module. - -==== define-reader-ctor - -<procedure>(define-reader-ctor SYMBOL PROC)</procedure> - -Define new read-time constructor for {{#,}} read syntax. For further information, see -the documentation for [[http://srfi.schemers.org/srfi-10/srfi-10.html|SRFI-10]]. - - -==== set-read-syntax! - -<procedure>(set-read-syntax! CHAR-OR-SYMBOL PROC)</procedure> - -When the reader encounters the non-whitespace character {{CHAR}} while reading -an expression from a given port, then the procedure {{PROC}} will be called with -that port as its argument. The procedure should return a value that will be returned -to the reader: - -<enscript highlight=scheme> - ; A simple RGB color syntax: - - (set-read-syntax! #\% - (lambda (port) - (apply vector - (map (cut string->number <> 16) - (string-chop (read-string 6 port) 2) ) ) ) ) - - (with-input-from-string "(1 2 %f0f0f0 3)" read) - ; ==> (1 2 #(240 240 240) 3) -</enscript> - -If {{CHAR-OR-SYMBOL}} is a symbol, then a so-called ''read-mark'' handler is defined. -In that case the handler procedure will be called when a character-sequence of the -form {{#!SYMBOL}} is encountered. - -You can undo special handling of read-syntax by passing {{#f}} as the second argument -(if the syntax was previously defined via {{set-read-syntax!}}). - -As a special case, your handler can return zero values, via {{(values)}}. This causes -the reader to completely ignore whatever input you've read, rather than returning some -possibly unspecified value. This can be useful in macro context, reading comments, -conditional compilation, and so forth. Available in CHICKEN 4.6.6 and later. - -Note that all of CHICKEN's special non-standard read-syntax is handled directly by the reader. -To disable built-in read-syntax, define a handler that triggers an error (for example). - - -==== set-sharp-read-syntax! - -<procedure>(set-sharp-read-syntax! CHAR-OR-SYMBOL PROC)</procedure> - -Similar to {{set-read-syntax!}}, but allows defining new {{#<CHAR> ...}} reader syntax. -If the first argument is a symbol, then this procedure is equivalent to {{set-read-syntax!}}. - -{{PROC}} may be {{#f}} to disable previously defined "sharp" read syntax. - - -==== set-parameterized-read-syntax! - -<procedure>(set-parameterized-read-syntax! CHAR-OR-SYMBOL PROC)</procedure> - -Similar to {{set-sharp-read-syntax!}}, but intended for defining reader syntax of the -form {{#<NUMBER><CHAR> ...}}. The handler procedure {{PROC}} will be called with two -arguments: the input port and the number preceding -the dispatching character. -If the first argument is a symbol, then this procedure is equivalent to {{set-read-syntax!}}. - -{{PROC}} may be {{#f}} to disable previously defined parameterized read syntax. - - -==== copy-read-table - -<procedure>(copy-read-table READ-TABLE)</procedure> - -Returns a copy of the given read-table. You can access the currently active read-table -with {{(current-read-table)}}. - - ---- -Previous: [[Unit continuation]] - -Next: [[Interface to external functions and variables]] diff --git a/manual/Unit repl b/manual/Unit repl deleted file mode 100644 index d695317b..00000000 --- a/manual/Unit repl +++ /dev/null @@ -1,36 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit repl - -This unit provides CHICKEN's read-print-eval loop. - - -=== repl - -<procedure>(repl [EVALUATOR])</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 -changes the current exception-handler to display a message, write -any arguments to the value of {{(current-error-port)}} and reset. - -If {{EVALUATOR}} is given, it should be a procedure of one argument that -is used in place of {{eval}} to evaluate each entered expression. - -You can use {{quit}} to terminate the current read-eval-print loop. - - -=== repl-prompt - -<parameter>(repl-prompt)</parameter> - -A procedure that should evaluate to a string that will be printed before -reading interactive input from the user in a read-eval-print loop. -Defaults to {{(lambda () "#;N> ")}}. - - ---- -Previous: [[Unit eval]] - -Next: [[Unit expand]] diff --git a/manual/Unit srfi-4 b/manual/Unit srfi-4 deleted file mode 100644 index b0673405..00000000 --- a/manual/Unit srfi-4 +++ /dev/null @@ -1,355 +0,0 @@ -[[tags: manual]] - -== Unit srfi-4 - -Homogeneous numeric vector datatypes. Also see the [[http://srfi.schemers.org/srfi-4/srfi-4.html|original SRFI-4 document]]. - -[[toc:]] - -== CHICKEN implementation - -* Procedures for blob conversion, subvectors and vector I/O are provided. -* SRFI-17 setters for {{XXXvector-ref}} are defined. -* Constructors allow allocating the storage in non garbage collected memory. - -=== Blob conversions - -<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>(u64vector->blob U64VECTOR)</procedure><br> -<procedure>(s64vector->blob S64VECTOR)</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>(u64vector->blob/shared U64VECTOR)</procedure><br> -<procedure>(s64vector->blob/shared S64VECTOR)</procedure><br> -<procedure>(f32vector->blob/shared F32VECTOR)</procedure><br> -<procedure>(f64vector->blob/shared F64VECTOR)</procedure><br> - -Each of these procedures return the contents of the given vector as a -'packed' blob. The byte order in that vector is platform-dependent -(for example little-endian on an '''Intel''' processor). The {{/shared}} -variants return a blob that shares memory with the contents of the vector. - -<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->u64vector BLOB)</procedure><br> -<procedure>(blob->s64vector 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->u64vector/shared BLOB)</procedure><br> -<procedure>(blob->s64vector/shared BLOB)</procedure><br> -<procedure>(blob->f32vector/shared BLOB)</procedure><br> -<procedure>(blob->f64vector/shared BLOB)</procedure><br> - -Each of these procedures return a vector where the argument -{{BLOB}} is taken as a 'packed' representation of the contents -of the vector. The {{/shared}} variants return a vector that -shares memory with the contents of the blob. - -=== Subvectors - -<procedure>(subu8vector U8VECTOR FROM TO)</procedure><br> -<procedure>(subu16vector U16VECTOR FROM TO)</procedure><br> -<procedure>(subu32vector U32VECTOR FROM TO)</procedure><br> -<procedure>(subu64vector 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>(subs64vector S32VECTOR FROM TO)</procedure><br> -<procedure>(subf32vector F32VECTOR FROM TO)</procedure><br> -<procedure>(subf64vector F64VECTOR FROM TO)</procedure><br> - -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}}. - -=== Vector I/O - -<procedure>(read-u8vector [LENGTH [PORT]])</procedure> - -Reads {{LENGTH}} bytes from the {{PORT}} and returns a fresh -{{u8vector}}, or as many as are available before end-of-file is -encountered. {{PORT}} defaults to the value of {{(current-input-port)}}. -If no bytes are available before the end-of-file, {{#!eof}} is returned. - -If {{LENGTH}} is {{#f}}, the vector will be filled completely until -end-of-file is reached. - -<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 -to the value of {{(current-input-port)}}. - -If {{LENGTH}} is {{#f}}, the vector will be filled completely until end-of-file is reached. -This procedure returns the number of bytes read. - -<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)}}. - -== SRFI-4 specification - -SRFI-4 describes a set of datatypes for vectors whose elements are -of the same numeric type (signed or unsigned exact integer or inexact -real of a given precision). These datatypes support operations analogous -to the Scheme vector type, but they are distinct datatypes. An external -representation is specified which must be supported by the {{read}} and -{{write}} procedures and by the program parser (i.e. programs can contain -references to literal homogeneous vectors). - -=== Datatypes - -There are 8 datatypes of exact integer homogeneous vectors (which will be -called integer vectors): - -<table> -<tr><th>Datatype</th><th>Type of elements</th></tr> -<tr><td>{{s8vector}}</td><td>signed exact integer in the range -(2^7) to (2^7)-1</td></tr> -<tr><td>{{u8vector}}</td><td>unsigned exact integer in the range 0 to (2^8)-1</td></tr> -<tr><td>{{s16vector}}</td><td>signed exact integer in the range -(2^15) to (2^15)-1</td></tr> -<tr><td>{{u16vector}}</td><td>unsigned exact integer in the range 0 to (2^16)-1</td></tr> -<tr><td>{{s32vector}}</td><td>signed exact integer in the range -(2^31) to (2^31)-1</td></tr> -<tr><td>{{u32vector}}</td><td>unsigned exact integer in the range 0 to (2^32)-1</td></tr> -<tr><td>{{s64vector}}</td><td>signed exact integer in the range -(2^31) to (2^31)-1</td></tr> -<tr><td>{{u64vector}}</td><td>unsigned exact integer in the range 0 to (2^64)-1</td></tr> -<tr><td>{{s64vector}}</td><td>signed exact integer in the range -(2^63) to (2^63)-1</td></tr> -<tr><td>{{u64vector}}</td><td>unsigned exact integer in the range 0 to (2^64)-1</td></tr></table> - -There are 2 datatypes of inexact real homogeneous vectors (which will be -called float vectors): - -<table> -<tr><th>Datatype</th><th>Type of elements</th></tr> -<tr><td>{{f32vector}}</td><td>inexact real</td></tr> -<tr><td>{{f64vector}}</td><td>inexact real</td></tr></table> - -The only difference between the two float vector types is that -{{f64vector}}s preserve at least as much precision as {{f32vector}}s. - -Each homogeneous vector datatype has an external representation which -is supported by the {{read}} and {{write}} procedures and by the program -parser. Each datatype also has a set of associated predefined procedures -analogous to those available for Scheme's heterogeneous vectors. - -=== External representation - -<read>#u8</read><br> -<read>#u16</read><br> -<read>#u32</read><br> -<read>#s8</read><br> -<read>#s16</read><br> -<read>#s32</read><br> -<read>#f32</read><br> -<read>#f64</read><br> - -The external representation of instances of the datatype {{XXXvector}} -is {{#XXX( ...elements... )}}. - -For example, - - #u8(0 #e1e2 #xff)}} ; a {{u8vector}} of length 3 containing 0, 100, 255 - #f64(-1.5) ; a {{f64vector}} of length 1 containing -1.5. - -This external representation is also available in program source code. For example, - - (set! x '#u8(1 2 3)) - -will set {{x}} to the object {{#u8(1 2 3)}}. Since CHICKEN 4.9.0, literal homogeneous vectors do not have to be quoted. Homogeneous vectors can appear in quasiquotations but must not contain {{unquote}} or {{unquote-splicing}} forms. ''I.e.'', - - `(,x #u8(1 2)) ; legal - `#u8(1 ,x 2) ; illegal - -=== Predicates - -<procedure>(u8vector? OBJ)</procedure><br> -<procedure>(s8vector? OBJ)</procedure><br> -<procedure>(u16vector? OBJ)</procedure><br> -<procedure>(s16vector? OBJ)</procedure><br> -<procedure>(u32vector? OBJ)</procedure><br> -<procedure>(s32vector? OBJ)</procedure><br> -<procedure>(u64vector? OBJ)</procedure><br> -<procedure>(s64vector? OBJ)</procedure><br> -<procedure>(f32vector? OBJ)</procedure><br> -<procedure>(f64vector? OBJ)</procedure><br> - -Return {{#t}} if {{obj}} is an object of the specified type or {{#f}} if not. - -<procedure>(number-vector? OBJ)</procedure> - -Return {{#t}} if {{obj}} is a number vector, {{#f}} if not. A "number vector" is any of the homogeneous number vector types defined by SRFI-4, ie it's one of {{u8vector}}, {{s8vector}}, {{u16vector}}, {{s16vector}}, {{u32vector}}, {{s32vector}}, {{u64vector}}, {{s64vector}}, {{f32vector}} or {{f64vector}}). - - -=== Constructors - -<procedure>(make-u8vector N [U8VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-s8vector N [S8VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-u16vector N [U16VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-s16vector N [S16VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-u32vector N [U32VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-s32vector N [S32VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-u64vector N [U64VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-s64vector N [S64VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-f32vector N [F32VALUE NONGC FINALIZE])</procedure><br> -<procedure>(make-f64vector N [F64VALUE NONGC FINALIZE])</procedure><br> - -Return a newly-allocated SRFI-4 homogeneous number vector of length N. - -If the optional fill VALUE is specified, it specifies the initial -value for each slot in the vector. If not, the content of the vector -is unspecified but individual elements of the vector are guaranteed to -be in the range of values permitted for that type of vector. - -The type of the fill value must be compatible with the elements of the -vector datatype. It is an error if otherwise -- for example, if an -inexact integer is passed to {{make-u8vector}}. - -On CHICKEN, these procedures have been extended to allow allocating -the storage in non-garbage collected memory, as follows: - -The optional arguments {{NONGC}} and {{FINALIZE}} define whether the -vector should be allocated in a memory area not subject to garbage -collection and whether the associated storage should be automatically -freed (using finalization) when there are no references from Scheme -variables and data. {{NONGC}} defaults to {{#f}} (the vector will be -located in normal garbage collected memory) and {{FINALIZE}} defaults -to {{#t}}. Note that the {{FINALIZE}} argument is only used when -{{NONGC}} is true. - -<procedure>(u8vector U8VALUE ...)</procedure><br> -<procedure>(s8vector S8VALUE ...)</procedure><br> -<procedure>(u16vector U16VALUE ...)</procedure><br> -<procedure>(s16vector S16VALUE ...)</procedure><br> -<procedure>(u32vector U32VALUE ...)</procedure><br> -<procedure>(s32vector S32VALUE ...)</procedure><br> -<procedure>(u64vector U64VALUE ...)</procedure><br> -<procedure>(s64vector S64VALUE ...)</procedure><br> -<procedure>(f32vector F32VALUE ...)</procedure><br> -<procedure>(f64vector F64VALUE ...)</procedure><br> - -Return a newly-allocated SRFI-4 homogeneous number vector of the specified -type, composed of the arguments. - -=== Length - -<procedure>(u8vector-length U8VECTOR)</procedure><br> -<procedure>(s8vector-length S8VECTOR)</procedure><br> -<procedure>(u16vector-length U16VECTOR)</procedure><br> -<procedure>(s16vector-length S16VECTOR)</procedure><br> -<procedure>(u32vector-length U32VECTOR)</procedure><br> -<procedure>(s32vector-length S32VECTOR)</procedure><br> -<procedure>(u64vector-length U64VECTOR)</procedure><br> -<procedure>(s64vector-length S64VECTOR)</procedure><br> -<procedure>(f32vector-length F32VECTOR)</procedure><br> -<procedure>(f64vector-length F64VECTOR)</procedure><br> - -Returns the length of the SRFI-4 homogeneous number VECTOR. - -=== Getters - -<procedure>(u8vector-ref U8VECTOR I)</procedure><br> -<procedure>(s8vector-ref S8VECTOR i)</procedure><br> -<procedure>(u16vector-ref U16VECTOR I)</procedure><br> -<procedure>(s16vector-ref S16VECTOR I)</procedure><br> -<procedure>(u32vector-ref U32VECTOR I)</procedure><br> -<procedure>(s32vector-ref S32VECTOR I)</procedure><br> -<procedure>(u64vector-ref U64VECTOR I)</procedure><br> -<procedure>(s64vector-ref S64VECTOR I)</procedure><br> -<procedure>(f32vector-ref F32VECTOR I)</procedure><br> -<procedure>(f64vector-ref F64VECTOR I)</procedure><br> - -Return the value of the ''i''th element of the SRFI-4 homogeneous -number vector, where {{I}} is a nonnegative exact integer less -than the length of the vector. - -=== Setters - -<procedure>(u8vector-set! U8VECTOR I U8VALUE)</procedure><br> -<procedure>(s8vector-set! S8VECTOR I S8VALUE)</procedure><br> -<procedure>(u16vector-set! U16VECTOR I U16VALUE)</procedure><br> -<procedure>(s16vector-set! S16VECTOR I S16VALUE)</procedure><br> -<procedure>(u32vector-set! U32VECTOR I U32VALUE)</procedure><br> -<procedure>(s32vector-set! S32VECTOR I S32VALUE)</procedure><br> -<procedure>(u64vector-set! U64VECTOR I U64VALUE)</procedure><br> -<procedure>(s64vector-set! S64VECTOR I S64VALUE)</procedure><br> -<procedure>(f32vector-set! F32VECTOR I F32VALUE)</procedure><br> -<procedure>(f64vector-set! F64VECTOR I F64VALUE)</procedure><br> - -Set the {{i}}th element of the SRFI-4 homogeneous number VECTOR to -VALUE. {{I}} is a nonnegative exact integer less than the length of -the vector and VALUE must be the same type as the elements of the -vector datatype. - -Additionally, SRFI-17 setters are defined on all {{xxxvector-ref}} -procedures. For example, to set the {{i}}th element of SRFI-4 -{{u8vector}} to {{u8value}}: - - (set! (u8vector-ref u8vector i) u8value) - -=== Conversions - -<procedure>(u8vector->list U8VECTOR)</procedure><br> -<procedure>(s8vector->list S8VECTOR)</procedure><br> -<procedure>(u16vector->list U16VECTOR)</procedure><br> -<procedure>(s16vector->list S16VECTOR)</procedure><br> -<procedure>(u32vector->list U32VECTOR)</procedure><br> -<procedure>(s32vector->list S32VECTOR)</procedure><br> -<procedure>(u64vector->list U64VECTOR)</procedure><br> -<procedure>(s64vector->list S64VECTOR)</procedure><br> -<procedure>(f32vector->list F32VECTOR)</procedure><br> -<procedure>(f64vector->list F64VECTOR)</procedure><br> - -Return a list consisting of the elements of SRFI-4 homogeneous number -VECTOR. - -<procedure>(list->u8vector U8LIST)</procedure><br> -<procedure>(list->s8vector S8LIST)</procedure><br> -<procedure>(list->u16vector U16LIST)</procedure><br> -<procedure>(list->s16vector S16LIST)</procedure><br> -<procedure>(list->u32vector U32LIST)</procedure><br> -<procedure>(list->s32vector S32LIST)</procedure><br> -<procedure>(list->u64vector U64LIST)</procedure><br> -<procedure>(list->s64vector S64LIST)</procedure><br> -<procedure>(list->f32vector F32LIST)</procedure><br> -<procedure>(list->f64vector F64LIST)</procedure><br> - -Return a newly-allocated SRFI-4 homogeneous number VECTOR consisting -of the elements of LIST. Each element of LIST must be compatible -with the datatype of VECTOR. - -=== Release number vectors allocated in static memory - -<procedure>(release-number-vector NVECTOR)</procedure> - -Release the storage of a SRFI-4 vector that was allocated in -non-garbage collected memory (for example using the {{NONGC}} argument -for one of the {{make-XXXvector}} constructor procedures). The effect -of calling this procedure with a number vector allocated in normal -garbage collected memory is undefined. - - ---- -Previous: [[Unit extras]] - -Next: [[Unit posix]] diff --git a/manual/Unit tcp b/manual/Unit tcp deleted file mode 100644 index cfb90b4a..00000000 --- a/manual/Unit tcp +++ /dev/null @@ -1,220 +0,0 @@ -[[tags: manual]] -[[toc:]] - -== Unit tcp - -This unit provides basic facilities for communicating over TCP sockets. -The socket interface should be mostly compatible to the one found in -PLT Scheme. - -This unit uses the {{extras}} unit. - -All errors related to failing network operations will raise a condition -of kind {{(exn i/o net)}}. - - -=== tcp-listen - -<procedure>(tcp-listen TCPPORT [BACKLOG [HOST]])</procedure> - -Creates and returns a TCP listener object that listens for connections on {{TCPPORT}}, which -should be an exact integer. {{BACKLOG}} specifies the number of maximally pending -connections (and defaults to 100). If the optional argument {{HOST}} is given and not -{{#f}}, then only incoming connections for the given host (or IP) are accepted. - - -=== tcp-listener? - -<procedure>(tcp-listener? X)</procedure> - -Returns {{#t}} if {{X}} is a TCP listener object, or {{#f}} otherwise. - - -=== tcp-close - -<procedure>(tcp-close LISTENER)</procedure> - -Reclaims any resources associated with {{LISTENER}}. - - -=== tcp-accept - -<procedure>(tcp-accept LISTENER)</procedure> - -Waits until a connection is established on the port on which -{{LISTENER}} is listening and returns two values: an input- and -output-port that can be used to communicate with the remote -process. The current value of {{tcp-accept-timeout}} is used to -determine the maximal number of milliseconds (if any) to wait -until a connection is established. When a client connects any -read- and write-operations on the returned ports will use the -current values (at the time of the connection) of {{tcp-read-timeout}} -and {{tcp-write-timeout}}, respectively, to determine the maximal -number of milliseconds to wait for input/output before a timeout -error is signalled. - -Note: this operation and any I/O on the ports returned will not block -other running threads. - - -=== tcp-accept-ready? - -<procedure>(tcp-accept-ready? LISTENER)</procedure> - -Returns {{#t}} if there are any connections pending on {{LISTENER}}, or {{#f}} -otherwise. - - -=== tcp-listener-port - -<procedure>(tcp-listener-port LISTENER)</procedure> - -Returns the port number assigned to {{LISTENER}} (If you pass {{0}} to {{tcp-listen}}, -then the system will choose a port-number for you). - -=== tcp-listener-fileno - -<procedure>(tcp-listener-fileno LISTENER)</procedure> - -Returns the file-descriptor associated with {{LISTENER}}. - - -=== tcp-connect - -<procedure>(tcp-connect HOSTNAME [TCPPORT])</procedure> - -Establishes a client-side TCP connection to the machine with the name -{{HOSTNAME}} (a string) at {{TCPPORT}} (an exact integer) and returns -two values: an input- and output-port for communicating with the -remote process. The current value of {{tcp-connect-timeout}} is used -to determine the maximal number of milliseconds (if any) to wait until -the connection is established. When the connection takes place any -read- and write-operations on the returned ports will use the current -values (at the time of the call to {{tcp-connect}}) of {{tcp-read-timeout}} and -{{tcp-write-timeout}}, respectively, to determine the maximal number -of milliseconds to wait for input/output before a timeout error is -signalled. - -If the {{TCPPORT}} is omitted, the port is parsed from the {{HOSTNAME}} string. The format expected is {{HOSTNAME:PORT}}. The {{PORT}} can either be a string representation of an integer or a service name which is translated to an integer using the POSIX function [[http://www.opengroup.org/onlinepubs/009695399/functions/getservbyname.html|{{getservbyname}}]]. - -Note: any I/O on the ports returned will not block other running threads. - - -=== tcp-addresses - -<procedure>(tcp-addresses PORT)</procedure> - -Returns two values for the input- or output-port {{PORT}} (which should be a port returned -by either {{tcp-accept}} or {{tcp-connect}}): the IP address of the local and the remote -machine that are connected over the socket associated with {{PORT}}. The returned addresses -are strings in {{XXX.XXX.XXX.XXX}} notation. - - -=== tcp-port-numbers - -<procedure>(tcp-port-numbers PORT)</procedure> - -Returns two values for the input- or output-port {{PORT}} (which should be a port returned -by either {{tcp-accept}} or {{tcp-connect}}): the TCP port numbers of the local and the remote -machine that are connected over the socket associated with {{PORT}}. - - -=== tcp-abandon-port - -<procedure>(tcp-abandon-port PORT)</procedure> - -Marks the socket port {{PORT}} as abandoned. This is mainly useful to close down a port -without breaking the connection. - - -=== 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 -number of TCP packets, buffering may be turned on by setting this -parameter to an exact integer greater zero. A buffer size of zero or {{#f}} -turns buffering off. The setting of this parameter takes effect at the time -when the I/O ports for a particular socket are created, i.e. when {{tcp-connect}} -or {{tcp-accept}} is called. - -Note that since output is not immediately written to the associated socket, you -may need to call {{flush-output}}, once you want the output to be transmitted. -Closing the output port will flush automatically. - -=== 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. -1 minute. -If timeout occurs while reading, a condition object of kinds {{(exn i/o net timeout)}} -is thrown. - -=== 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. -1 minute. -If timeout occurs while writing, a condition object of kinds {{(exn i/o net timeout)}} -is thrown. - -=== 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. -If timeout occurs while trying to connect, a condition object of kinds {{(exn i/o net timeout)}} -is thrown. - - -=== 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. -If timeout occurs while waiting for connections, a condition object of kinds {{(exn i/o net timeout)}} -is thrown. - - -=== Example - -A very simple example follows. Say we have the two files {{client.scm}} -and {{server.scm}}: - -<enscript highlight=scheme> - ; client.scm - (declare (uses tcp)) - (define-values (i o) (tcp-connect "localhost" 4242)) - (write-line "Good Bye!" o) - (print (read-line i)) -</enscript> - -<enscript highlight=scheme> - ; server.scm - (declare (uses tcp)) - (define l (tcp-listen 4242)) - (define-values (i o) (tcp-accept l)) - (write-line "Hello!" o) - (print (read-line i)) - (close-input-port i) - (close-output-port o) -</enscript> - - % csc server.scm - % csc client.scm - % ./server & - % ./client - Good Bye! - Hello! - ---- -Previous: [[Unit posix]] - -Next: [[Unit lolevel]]Trap