~ chicken-core (chicken-5) ddd8d393745dc48c8c465c71af78d44f2d5848be
commit ddd8d393745dc48c8c465c71af78d44f2d5848be Author: Peter Bex <peter@more-magic.net> AuthorDate: Sat Jun 9 19:39:49 2018 +0200 Commit: Peter Bex <peter@more-magic.net> CommitDate: Sat Jun 9 19:39:49 2018 +0200 Copy over new manual from wiki diff --git a/distribution/manifest b/distribution/manifest index 2e8f0b77..b7575744 100644 --- a/distribution/manifest +++ b/distribution/manifest @@ -430,7 +430,6 @@ manual-html/Unit srfi-4.html manual-html/Unit tcp.html manual-html/Using the compiler.html manual-html/Using the interpreter.html -manual-html/faq.html manual-html/chicken.png manual-html/index.html manual-html/manual.css diff --git a/manual/Accessing external objects b/manual/Accessing external objects index 8f83edaf..7ab819e3 100644 --- a/manual/Accessing external objects +++ b/manual/Accessing external objects @@ -2,200 +2,21 @@ [[toc:]] -== Accessing external objects +== Accessing externally defined data -=== foreign-code - -<macro>(foreign-code STRING ...)</macro> - -Executes the embedded C/C++ code {{STRING ...}}, which should -be a sequence of C statements, which are executed and return an unspecified result. - -<enscript highlight=scheme> -(foreign-code "doSomeInitStuff();") => #<unspecified> -</enscript> - -Code wrapped inside {{foreign-code}} may not invoke callbacks into Scheme. - - -=== foreign-value - -<macro>(foreign-value CODE TYPE)</macro> - -Evaluates the embedded C/C++ expression {{CODE}} (which may be a string or symbol), returning a value of type given -in the foreign-type specifier {{TYPE}}. - -<enscript highlight=scheme> -(print (foreign-value "my_version_string" c-string)) -</enscript> - - -=== foreign-declare - -<macro>(foreign-declare STRING ...)</macro> - -Include given strings verbatim into header of generated file. - - -=== define-foreign-type - -<macro>(define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])</macro> - -Defines an alias for {{TYPE}} with the name {{NAME}} (a symbol). -{{TYPE}} may be a type-specifier or a string naming a C type. The -namespace of foreign type specifiers is separate from the normal -Scheme namespace. The optional arguments {{ARGCONVERT}} and -{{RETCONVERT}} should evaluate to procedures that map argument- and -result-values to a value that can be transformed to {{TYPE}}: - -<enscript highlight=scheme> -(define-foreign-type char-vector - nonnull-c-string - (compose list->string vector->list) - (compose list->vector string->list) ) - -(define strlen - (foreign-lambda int "strlen" char-vector) ) - -(strlen '#(#\a #\b #\c)) ==> 3 - -(define memset - (foreign-lambda char-vector "memset" char-vector char int) ) - -(memset '#(#_ #_ #_) #\X 3) ==> #(#\X #\X #\X) -</enscript> - -Foreign type-definitions are only visible in the compilation-unit in which -they are defined, so use {{include}} to use the same definitions -in multiple files. - - -=== foreign-type-size - -<macro>(foreign-type-size TYPE)</macro> - -Returns the size of the storage required to hold values of the -given foreign type {{TYPE}}. This is basically equivalent to - -<enscript highlight=scheme> -(foreign-value "sizeof(TYPE)" size_t) -</enscript> - -but also handles user-defined types and allows "TYPE" to be a string, -which will be given literally to the {{sizeof}} operator. - - -=== define-foreign-variable - -<macro>(define-foreign-variable NAME TYPE [STRING])</macro> - -Defines a foreign variable of name {{NAME}} (a symbol). {{STRING}} -should be the real name of a foreign variable or parameterless -macro. If {{STRING}} is not given, then the variable name {{NAME}} -will be converted to a string and used instead. All references and -assignments (via {{set!}}) are modified to correctly convert values -between Scheme and C representation. This foreign variable can only be -accessed in the current compilation unit, but the name can be -lexically shadowed. Note that {{STRING}} can name an arbitrary C -expression. If no assignments are performed, then {{STRING}} doesn't -even have to specify an lvalue. -See that {{define-foreign-variable}} will not generate C declarations -or memory allocation code; use it to include references to variables -in external C code. To actually create Scheme variables visible from C, -use {{define-external}} (see the Manual section on -[[/man/4/Callbacks|Callbacks]]). -For example, the following code: -<enscript lang="scheme"> -(import foreign) -(define-foreign-variable x double "var_x") -(print x) -</enscript> -will not work, because a reference to {{var_x}} will be inserted in the C code, -but no declaration will be included (this can be easily verified by translating -the program into C with {{csc -t program.scm}}). Changing the second line to -{{(define-external x double 0.5)}} will work (and the value 0.5 will be printed). -=== foreign-lambda - -<macro>(foreign-lambda RETURNTYPE NAME ARGTYPE ...)</macro> - -Represents a -binding to an external routine. This form can be used in the position -of an ordinary {{lambda}} expression. {{NAME}} specifies the -name of the external procedure and should be a string or a symbol. - - -=== foreign-lambda* - -<macro>(foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)</macro> - -Similar to {{foreign-lambda}}, but instead of generating code to -call an external function, the body of the C procedure is directly given -in {{STRING ...}}: - -<enscript highlight=scheme> -(define my-strlen - (foreign-lambda* int ((c-string str)) - "int n = 0; - while(*(str++)) ++n; - C_return(n);") ) - -(my-strlen "one two three") ==> 13 -</enscript> - -For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement -to return a result from the foreign lambda body as some cleanup code has to be run before execution -commences in the calling code. - -=== foreign-safe-lambda - -<macro>(foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)</macro> - -This is similar to {{foreign-lambda}}, but also allows the called -function to call Scheme functions. See [[Callbacks]]. - - -=== foreign-safe-lambda* - -<macro>(foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)</macro> - -This is similar to {{foreign-lambda*}}, but also allows the called -function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]]. - - - -=== foreign-primitive - -<macro>(foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)</macro> - -This is also similar to {{foreign-lambda*}} but the code will be -executed in a ''primitive'' CPS context, which means it will not -actually return, but call its continuation on exit. This means that code -inside this form may allocate Scheme data on the C stack (the -''nursery'') with {{C_alloc}} (see below). You can return multiple -values inside the body of the {{foreign-primitive}} form by using -the following C code: - -<enscript highlight=scheme> -C_word av[N + 2] = { C_SCHEME_UNDEFINED, C_k, X1, ... }; -C_values(N + 2, av); -</enscript> - -where {{N}} is the number of values to be returned, and {{X1, ...}} -are the results, which should be Scheme data objects. When returning -multiple values, the return-type should be omitted. Of course, if you -have to dynamically compute the values, you do not have to use C's -array initialization syntax, but you can just assign them one by one. - -Returning just a single value can still be done via the {{C_return(...)}} macro. +For a list of the special forms that allow definition of Scheme procedures +that access native C/C++ code, consult the documentation on the +[[Module (chicken foreign)|(chicken foreign)]] module. The remainder +of this chapter merely explains a few special cases. == Returning large objects or chunks of memory to Scheme When you call a C function which needs to return quantities of data, several issues arise: -* the size of the nursery is limited, so C_alloc can cause stack overflow +* the size of the nursery is limited, so {{C_alloc}} can cause stack overflow * if you malloc in C, and intend to leave it there, and directly access parts of that data from Scheme, you will need C accessor functions to pinpoint the parts you need and return them as Scheme objects; you will also need a finalizer if you intend for this data to be garbage-collected * building up lists or other complex Scheme structures from individual pairs, or putting non-immediate objects into vectors, is cumbersome in C -So some would advise you to just return a pointer to Scheme, use memcpy or any other function(s) which you need to get the data into CHICKEN-managed memory and into the desired kind of data structure, then free the C data. For this example, we are trying to return an array of doubles into an f64vector; we can accomplish that by adding a specialized copy function to the C library being integrated: +So some would advise you to just return a pointer to Scheme, use memcpy or any other function(s) which you need to get the data into CHICKEN-managed memory and into the desired kind of data structure, then free the C data. For this example, we are trying to return an array of doubles into an {{f64vector}}; we can accomplish that by adding a specialized copy function to the C library being integrated: <enscript highlight=C> void CopyResults(double* vector) { @@ -215,7 +36,7 @@ and the "egg" which calls the C functions can be implemented like this: <enscript highlight=scheme> (module memcpy-demo (input->output) - (import chicken scheme foreign srfi-4) + (import (chicken base) scheme (chicken foreign) srfi-4) (define CopyResults (foreign-lambda void "CopyResults" f64vector)) diff --git a/manual/Acknowledgements b/manual/Acknowledgements index cb2904d0..a962f708 100644 --- a/manual/Acknowledgements +++ b/manual/Acknowledgements @@ -21,11 +21,11 @@ Feeley, "Fizzie", Matthew Flatt, Kimura Fuyuki, Tony Garnock-Jones, Martin Gasbichler, Abdulaziz Ghuloum, Joey Gibson, Stephen C. Gilardi, Mario Domenech Goulart, Joshua Griffith, Johannes Groedem, Damian Gryski, Matt Gushee, Andreas Gustafsson, Sven Hartrumpf, Jun-ichiro -itojun Hagino, Ahdi Hargo, Matthias Heiler, Karl M. Hegbloom, William -P. Heinemann, Bill Hoffman, Bruce Hoult, Hans Hübner, Markus Hülsmann, +itojun Hagino, Ahdi Hargo, Matthias Heiler, Karl M. Hegbloom, Moritz Heidkamp, +William P. Heinemann, Bill Hoffman, Bruce Hoult, Hans Hübner, Markus Hülsmann, Götz Isenmann, Paulo Jabardo, Wietse Jacobs, David Janssens, Christian Jäger, Matt Jones, Dale Jordan, Valentin Kamyshenko, Daishi Kato, -Peter Keller, Christian Kellermann, Brad Kind, Ron Kneusel, Matthias +Peter Keller, Christian Kellermann, Brad Kind, Ron Kneusel, "Kooda", Matthias Köppe, Krysztof Kowalczyk, Andre Kühne, Todd R. Kueny Sr, Goran Krampe, David Krentzlin, Ben Kurtz, Michele La Monaca, Micky Latowicki, Kristian Lein-Mathisen, "LemonBoy", John Lenz, @@ -36,21 +36,22 @@ Perry Metzger, Scott G. Miller, Mikael, Karel Miklav, Bruce Mitchener, Fadi Moukayed, Chris Moline, Eric E. Moore, Julian Morrison, Dan Muresan, David N. Murray, Timo Myyrä, "nicktick", Lars Nilsson, Ian Oversby, "o.t.", Gene Pavlovsky, Levi Pearson, Jeronimo Pellegrini, -Nicolas Pelletier, Markus Pfeiffer, Derrell Piper, Carlos Pita, -"Pluijzer", Robin Lee Powell, Alan Post, "Pupeno", Davide Puricelli, -"presto", Doug Quale, Imran Rafique, Eric Raible, Ivan Raikov, Santosh -Rajan, Joel Reymont, "rivo", Chris Roberts, Eric Rochester, Paul -Romanchenko, Andreas Rottman, David Rush, Lars Rustemeier, Daniel -Sadilek, Otavio Salvador, Burton Samograd, "Sandro", "satori", Aleksej -Saushev, Oskar Schirmer, Vasilij Schneidermann, Reed Sheridan, Ronald -Schröder, Spencer Schumann, Ivan Shcheklein, Alexander Shendi, Alex -Shinn, Ivan Shmakov, "Shmul", Tony Sidaway, Jeffrey B. Siegal, Andrey -Sidorenko, Michele Simionato, Iruata Souza, Volker Stolz, Jon Strait, -Dorai Sitaram, Robert Skeels, Jason Songhurst, Clifford Stein, David -Steiner, Sunnan, Zbigniew Szadkowski, Rick Taube, Nathan Thern, Mike -Thomas, Minh Thu, Christian Tismer, Andre van Tonder, John Tobey, Henrik -Tramberend, Vladimir Tsichevsky, James Ursetto, Neil van Dyke, Sam -Varner, Taylor Venable, Sander Vesik, Jaques Vidrine, Panagiotis Vossos, +Nicolas Pelletier, Derrell Piper, Carlos Pita, "Pluijzer", +Robin Lee Powell, Alan Post, "Pupeno", Davide Puricelli, "presto", +Doug Quale, Imran Rafique, Eric Raible, Ivan Raikov, Santosh Rajan, +Peder Refnes, Joel Reymont, "rivo", Chris Roberts, Eric Rochester, +Paul Romanchenko, +Andreas Rottman, David Rush, Lars Rustemeier, Daniel Sadilek, +Otavio Salvador, Burton Samograd, "Sandro", "satori", Aleksej Saushev, +Oskar Schirmer, Vasilij Schneidermann, Reed Sheridan, Ronald Schröder, +Spencer Schumann, Ivan Shcheklein, Alexander Shendi, Alex Shinn, Ivan +Shmakov, "Shmul", Tony Sidaway, Jeffrey B. Siegal, Andrey Sidorenko, +Michele Simionato, Iruata Souza, Volker Stolz, Jon Strait, Dorai +Sitaram, Robert Skeels, Jason Songhurst, Clifford Stein, David Steiner, +"Sunnan", Zbigniew Szadkowski, Rick Taube, Nathan Thern, Mike Thomas, Minh +Thu, Christian Tismer, Andre van Tonder, John Tobey, Henrik Tramberend, +Vladimir Tsichevsky, James Ursetto, Neil van Dyke, Sam Varner, +Taylor Venable, Sander Vesik, Jaques Vidrine, Panagiotis Vossos, Shawn Wagner, Peter Wang, Ed Watkeys, Brad Watson, Thomas Weidner, Göran Weinholt, Matthew Welland, Drake Wilson, Jörg Wittenberger, Peter Wright, Mark Wutka, Adam Young, Richard Zidlicky, Houman Zolfaghari and @@ -60,32 +61,24 @@ Special thanks to Brandon van Every for contributing the (now defunct) [[http://www.cmake.org|CMake]] support and for helping with Windows build issues. -Thanks to [[http://www.bevuta.com|bevuta IT GmbH]] for providing serverspace -and contributing patches and support. +Thanks to Pablo Beyen and [[http://www.bevuta.com|bevuta IT GmbH]] for +their awesome support. Also special thanks to Benedikt Rosenau for his constant encouragement. Felix especially wants to thank Dunja Winkelmann for putting up with all of this -and for her awesome support. +and for her constant support. CHICKEN contains code from several people: ; Marc Feeley : pretty-printer. -; Richard Kelsey, Jonathan Rees and Taylor Campbell : {{syntax-rules}} expander -; Mikael Djurfeldt : topological sort used by compiler. -; Aubrey Jaffer : implementation of {{dynamic-wind}}. +; Richard Kelsey, Jonathan Rees and Taylor Campbell : core of the {{syntax-rules}} expander +; Aubrey Jaffer : initial implementation of {{dynamic-wind}}. ; Richard O'Keefe : sorting routines. ; Alex Shinn : the [[http://synthcode.com/scheme/irregex/|irregex]] regular expression package. -; Olin Shivers : implementation of {{let-optionals[*]}} and reference implementations of SRFI-1, SRFI-13 and SRFI-14. - -The documentation and examples for explicit renaming macros was taken from -the following paper: - -William D. Clinger. -[[ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/prop/exrename.ps.gz|''Hygienic macros through explicit renaming'']]. -Lisp Pointers. IV(4). December 1991. +; Olin Shivers : implementation of {{let-optionals[*]}}. --- -Previous: [[faq|FAQ]] +Previous: [[Bugs and limitations]] Next: [[Bibliography]] diff --git a/manual/Bibliography b/manual/Bibliography index 5ec19aba..4fde751a 100644 --- a/manual/Bibliography +++ b/manual/Bibliography @@ -6,5 +6,11 @@ Henry Baker: ''CONS Should Not CONS Its Arguments, Part II: Cheney on the M.T.A. ''Revised^5 Report on the Algorithmic Language Scheme'' [[http://www.schemers.org/Documents/Standards/R5RS]] +R. P. Brent, P. Zimmermann: ''Modern Computer Arithmetic'' [[https://members.loria.fr/PZimmermann/mca/pub226.html]] + +William D. Clinger: ''Hygienic macros through explicit renaming'', Lisp Pointers. IV(4). December 1991 +[[ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/prop/exrename.ps.gz]]. + + --- Previous: [[Acknowledgements]] diff --git a/manual/Bugs and limitations b/manual/Bugs and limitations index 59e75ef8..74563b33 100644 --- a/manual/Bugs and limitations +++ b/manual/Bugs and limitations @@ -8,9 +8,22 @@ * {{port-position}} currently works only for input ports. -* Leaf routine optimization can theoretically result in code that thrashes, if tight loops perform excessively many mutations. +* Leaf routine optimization can theoretically result in code that thrashes, if tight loops perform excessively many mutations. In practice this doesn't happen. + +* Due to the header representation of block objects, the maximum size +of a bytevector-like object (strings, blobs, srfi-4 vectors etc) is +2^24 bytes or 16MiB. On 64-bit machines the limit is less relevant, +at 2^56 bytes, or 65536 TiB (64 PiB). + +* Like above, the maximum size of vector-like objects is 2^24 slots on +32 bit machines and 2^56 slots on 64-bit machines. + +* Bignums are represented by bytevector objects instead of vector-like +objects due to the need to treat digits as opaque data. This limits +bignums to a maximum value of 2^(2^27) on 32-bit machines and 2^(2^59) +on 64-bit machines. --- -Previous: [[Data representation]] +Previous: [[Cross development]] -Next: [[faq|FAQ]] +Next: [[Acknowledgements]] diff --git a/manual/C interface b/manual/C interface index 54d025a8..0114e631 100644 --- a/manual/C interface +++ b/manual/C interface @@ -43,7 +43,7 @@ Is {{x}} a truthy value, i.e. anything except {{C_SCHEME_FALSE}}? [C macro] int C_immediatep(C_word x) Is {{x}} an immediate object? -(see [[#constructors-for-immediate-scheme-objects|below]] for a definition) +(see below for a definition) ===== C_fitsinfixnump @@ -1606,6 +1606,6 @@ The C version of {{(not (pair? x))}}. --- -Previous: [[Other support procedures]] +Previous: [[Embedding]] -Next: [[Extensions]] +Next: [[Data representation]] diff --git a/manual/Cross development b/manual/Cross development index 2d9f3d98..d1a07742 100644 --- a/manual/Cross development +++ b/manual/Cross development @@ -81,6 +81,7 @@ You should now have these files on {{~/target}}: |-- bin | |-- chicken + | |-- chicken-bug | |-- chicken-install | |-- chicken-profile | |-- chicken-status @@ -224,11 +225,11 @@ Sometimes an extension will only be compilable for the target platform case you will have to work around the problem that the host-compiler still may need compile-time information from the target-only extension, like the import library of modules. One option is to copy -the import-library into the repository of the host compiler: +the import-library source file into the repository of the host compiler: # optionally, you can compile the import library: # ~/cross-chicken/arm-csc -O3 -d0 -s target-only-extension.import.scm - cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/6 + cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/9 === Final notes @@ -241,5 +242,6 @@ extensions. ---- -Previous: [[Extensions]] -Next: [[Data representation]] +Previous: [[Deployment]] + +Next: [[Bugs and limitations]] diff --git a/manual/Data representation b/manual/Data representation index 4a871a04..fcc20c35 100644 --- a/manual/Data representation +++ b/manual/Data representation @@ -160,6 +160,6 @@ For more information see the header file {{chicken.h}}. --- -Previous: [[Cross development]] +Previous: [[C interface]] -Next: [[Bugs and limitations]] +Next: [[Modules]] diff --git a/manual/Debugging b/manual/Debugging index 67aca201..4aeeedea 100644 --- a/manual/Debugging +++ b/manual/Debugging @@ -9,7 +9,7 @@ This document describes "Feathers", a debugger for compiled CHICKEN programs. "Feathers" is a [[Tcl/Tk|http://tcl.tk]] script, installed together with all other components of the CHICKEN system. To use the debugger, Tcl/Tk version -8.5 must be installed. +8.5 or later must be installed. Once the debugger is started, it waits for a client program to connect to it. You can also run a program explicitly by pressing the {{F1}} key and diff --git a/manual/Declarations b/manual/Declarations index 7f7c7929..21d4db34 100644 --- a/manual/Declarations +++ b/manual/Declarations @@ -11,6 +11,14 @@ all) cases an associated command-line option exists. When in conflict, declarations override command-line options. When multiple declarations conflict, the one appearing textually last overrides any previous one. +Declarations can be used to improve performance and to give entities +like procedures are variables special properties that can result in +better performing code. Most of these declarations subtly change the +semantics of standard Scheme code with respect to the declared +entities, so care must be taken when using them. + +Declarations are always ignored in {{csi}} (the interpreter) or in evaluated code. + === declare @@ -60,14 +68,6 @@ also more efficient. {{(declare (hide))}} is equivalent to {{(declare (block))}} Declares that the given identifiers are always bound to procedure values. -=== check-c-syntax - - [declaration specifier] (check-c-syntax) - [declaration specifier] (not check-c-syntax) - -Enables or disables syntax-checking of embedded C/C++ code fragments. Checking C syntax is the default. - - === enforce-argument-types [declaration-specifier] (enforce-argument-types IDENTIFIER ...) @@ -97,7 +97,6 @@ option to the compiler. === disable-interrupts [declaration specifier] (disable-interrupts) - [declaration specifier] (not interrupts-enabled) Disable timer-interrupts checks in the compiled program. Threads can not be preempted in main- or library-units that contain this declaration. @@ -135,7 +134,7 @@ the given global procedures only, respectively. [declaration specifier] (inline-global IDENTIFIER ...) [declaration specifier] (not inline-global IDENTIFIER ...) -Declare that the given toplevel procedures (or all) are subject to +Declare that then given toplevel procedures (or all) are subject to cross-module inlining. Potentially inlinable procedures in the current compilation unit will be written to an external {{<source-filename>.inline}} file in the current directory. Globally @@ -154,13 +153,6 @@ Enabling global inlining implies {{(declare (inline))}}. Sets the maximum size of procedures which may potentially be inlined. The default threshold is {{20}}. -=== interrupts-enabled - - [declaration specifier] (interrupts-enabled) - -Enable timer-interrupts checks in the compiled program (the default). - - === keep-shadowed-macros [declaration specifier] (keep-shadowed-macros) @@ -372,4 +364,4 @@ knows about them. --- Previous: [[Types]] -Next: [[Parameters]] +Next: [[Extensions]] diff --git a/manual/Deployment b/manual/Deployment new file mode 100644 index 00000000..be2fce02 --- /dev/null +++ b/manual/Deployment @@ -0,0 +1,174 @@ +[[tags: manual]] +[[toc:]] + + +== Deployment + +CHICKEN generates fully native binaries that can be distributed like +normal C/C++ programs. There are various methods of deployment, +depending on platform, linkage, external dependencies and whether +the application should be built from sources or precompiled and +whether the CHICKEN runtime-libraries are expected on the destination +system or if the application should be completely self-contained. + +There are several options for distributing software written in CHICKEN for +use on other machines or by other people: + +* Distribute source code, which requires that the target system has a compatible version of CHICKEN installed +* Distribute C files generated from Scheme source code and compile them binaries on the target system - this also requires a matching CHICKEN installation on the target +* Distribute compiled binaries, either statically linked or built in such a way that all required extensions and libraries are included in the distribution + +The rest of this chapter addresses the third option, for which several options exist, +depending on your needs and how self-contained you want your deployed +binary to be. + +The simplest form of deployment is the single executable. The runtime +library ({{libchicken.so}}, {{libchicken.dylib}} or {{libchicken.dll}}) is required for these +programs to run, unless you link your application statically: + + % csc myprogram.scm + % ldd myprogram # on linux + linux-gate.so.1 => (0xb805c000) + libchicken.so.9 => /home/felix/chicken/core/lib/libchicken.so.9 (0xb7c22000) + libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bec000) + libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7be7000) + libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a84000) + /lib/ld-linux.so.2 (0xb805d000) + % ls -l myprogram + -rwxr-xr-x 1 felix felix 34839 2010-02-22 20:19 x + +=== Static linking + +Linking your application statically will include the runtime library in the executable: + + % csc -static myprogram.scm + % ldd myprogram + linux-gate.so.1 => (0xb805c000) + libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bec000) + libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7be7000) + libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a84000) + /lib/ld-linux.so.2 (0xb805d000) + +[[Extensions]] are transparently linked in statically, if you provide the {{-static}} +option to {{csc}}, provided the extension is avaiable as a static object file +(this applies to most extensions by default). + +=== Shipping the runtime library + +An alternate way of distributing compiled code is to ship the runtime library +{{libchicken.so}} together with the executable, possibly including any extensions +that you use. To make this work, any runtime linker paths compiled into +binary objects need to be deleted or changed by using a tool like {{chrpath(1)}} +or {{patchelf(1)}}, to a value that indicates that +the library lookup should start in the same location as the main program. +(e.g. {{$ORIGIN}} on Linux). Don't forget to copy any extensions from the +extension repository ({{$PREFIX/lib/chicken/$BINARYVERSION}}). + +Alternatively start your program through a separate +script that sets {{LD_LIBRARY_PATH}} (or {{DYLD_LIBRARY_PATH}} on +MacOS X). +For more details, consult +the documentation of the operating system that you use to build your +deployed binaries. + +A directory containing all binaries is fully "portable" in the sense that it will run directly +from an USB-stick or any other removable media. At runtime the program can find +out its location by invoking the {{repository-path}} procedure, which will return +the full pathname in which the application is located. + +Should the program depend on more libraries which are not available by +default on the intended target systems, and which you would like to +include in your application, you will have to track them down yourself +and place them in the application directory. + +=== Distributing compiled C files + +It is possible to create distributions of Scheme projects that +have been compiled to C. The runtime system of CHICKEN consists of only +two handcoded C files ({{runtime.c}} and {{chicken.h}}), plus the files +{{chicken-config.h}} and {{buildtag.h}}, which are generated by the +build process. All other modules of the runtime system and the extension +libraries are just compiled Scheme code. The following example shows a +minimal application, which should run without changes on most operating +systems, like Windows, Linux or FreeBSD (note however that static +binaries are not supported on Mac OS X). + +Take the following "Hello World" program: + +<enscript highlight=scheme> +; hello.scm + +(print "Hello, world!") +</enscript> + + % csc -t hello.scm -optimize-level 3 -output-file hello.c + +Compiled to C, we get {{hello.c}}. We need the files {{chicken.h}}, +{{chicken-config.h}}, {{buildtag.h}} and {{runtime.c}}, which contain +the basic runtime system, plus the library files {{build-version.c}}, +{{chicken-syntax.c}}, {{eval.c}}, {{expand.c}}, {{internal.c}}, +{{library.c}} and {{modules.c}}, which contain the same functionality as +the library that is linked into plain CHICKEN-compiled applications: + + % cd /tmp + % echo '(print "Hello World.")' > hello.scm + % csc -t hello.scm + % cp $CHICKEN_BUILD/build-version.c . + % cp $CHICKEN_BUILD/chicken-syntax.c . + % cp $CHICKEN_BUILD/eval.c . + % cp $CHICKEN_BUILD/expand.c . + % cp $CHICKEN_BUILD/internal.c . + % cp $CHICKEN_BUILD/library.c . + % cp $CHICKEN_BUILD/modules.c . + % cp $CHICKEN_BUILD/runtime.c . + % cp $CHICKEN_BUILD/chicken.h . + % cp $CHICKEN_BUILD/chicken-config.h . + % cp $CHICKEN_BUILD/buildtag.h . + % gcc -Os -fomit-frame-pointer -DHAVE_CHICKEN_CONFIG_H hello.c \ + build-version.c eval.c expand.c internal.c library.c modules.c runtime.c \ + -o hello -lm + +Once we have all the files together, we can create a tarball: + + % tar czf hello.tar.gz hello.c build-version.c chicken-syntax.c eval.c \ + expand.c internal.c library.c modules.c runtime.c chicken.h \ + chicken-config.h buildtag.h + +This is naturally rather simplistic. Things like enabling dynamic +loading and selecting supported features of the host system would need +more configuration- and build-time support. All this can be addressed +using more elaborate build-scripts, makefiles or by using +autoconf/automake. + +The {{chicken-config.h}} file may contain incorrect settings for your +deployment target. Especially when the architecture is different. In +that case you will have to adjust the values as needed. + +For more information, study the CHICKEN source code and/or ask on the CHICKEN +mailing lists to understand the implications and difficulties of this deployment +method in more detail. + +=== Platform specific notes + +==== Windows + +Deployment is fully supported on Windows. Since Windows looks up +dynamic link libraries in the programs original location by default, +adding third-party libraries to the application directory is no +problem. The freely available [[http://dependencywalker.com|Dependency +Walker]] tool is helpful to find out what DLLs your application +depends on. + +==== MacOS X + +The {{otool(1)}} program will show you dynamic libraries that your +application requires. {{DYLD_LIBRARY_PATH}} +can be set to override runtime linker paths and {{install_name_tool(1)}} +is available to patch runtime linker paths directly. All of these tools +require the Xcode command-line tools too be installed. + + +--- +Previous: [[Units and linking model]] + +Next: [[Cross development]] diff --git a/manual/Deviations from the standard b/manual/Deviations from the standard index c688e223..6001b5cf 100644 --- a/manual/Deviations from the standard +++ b/manual/Deviations from the standard @@ -1,6 +1,6 @@ [[tags: manual]] -== Confirmed deviations +== Confirmed deviations from R5RS Identifiers are by default case-sensitive (see [[Using the compiler]]). @@ -24,7 +24,7 @@ read/write invariance for inexact numbers. === Environments and non-standard syntax -In addition to the standard bindings {{scheme-report-environment}} and +In addition to the standard bindings, {{scheme-report-environment}} and {{null-environment}} contain additional non-standard bindings for the following syntactic forms: {{import}}, {{require-extension}}, {{require-library}}, {{begin-for-syntax}}, {{export}}, {{module}}, @@ -96,6 +96,6 @@ The {{transcript-on}} and {{transcript-off}} procedures are not implemented. R5RS does not require them. --- -Previous: [[The R5RS standard]] +Previous: [[Using the compiler]] Next: [[Extensions to the standard]] diff --git a/manual/Egg specification format b/manual/Egg specification format new file mode 100644 index 00000000..fe23933d --- /dev/null +++ b/manual/Egg specification format @@ -0,0 +1,338 @@ +[[tags: manual]] +[[toc:]] + + +== Format of the egg description file + +An egg description is basically an association list holding +information about the components of the egg. An egg may contain +multiple components: libraries, programs, Scheme or C include files +and arbitrary data files. Dependencies between eggs can be +specified as can be dependencies between components of an egg. + +A list of valid properties follows. + +=== Global properties + +==== version + +[egg property] (version STRING) + +Specifies version string for this egg. {{STRING}} should have +the format {{<MAJOR>.<MINOR>.<PATCHLEVEL>}}, where only the +{{<MAJOR>}} part is mandatory. + +Eggs from remote egg servers are automatically versioned - the +version is part of the protocol to retrieve the egg and does not +have to be specified in the {{.egg}} file. Eggs installed from +local directories (see below) should explicitly specify a version. + +==== synopsis + +[egg property] (synopsis STRING) + +Gives a short description of this egg. + +==== author + +[egg property] (author STRING) + +Names the author or authors of the contained code. + +==== maintainer + +[egg property] (maintainer STRING) + +Names the maintainer of this code, if different from author(s). + +==== category + +[egg property] (category NAME) + +Gives the category under which this egg should be contained. +See [[/chicken-projects/egg-index-5.html|the egg index]] +for a list of currently used categories. + +==== license + +[egg property] (license STRING) + +Names the license under which this code is available. + +==== dependencies + +[egg property] (dependencies EGG ...) + +Lists eggs that this egg depends on, and which should be +built and installed if they do not already exist in the repository. +{{EGG}} should be whether a symbol or a list of the form +{{EGGNAME VERSION}}, where the former means to install the +newest available egg with this name and the latter specifies +a specific version or higher. + +==== test-dependencies + +[egg property] (test-dependencies EGG ...) + +Lists eggs that are required for this egg to run the tests +(if tests exist.) This only has an effect if the {{-test}} +option has been given to {{chicken-install}}. + +==== build-dependencies + +[egg property] (build-dependencies EGG ...) + +Lists eggs that are build-time dependencies for this egg, +i.e. there are required to build, but not to run the contained +code. Currently this is treated identical to {{dependencies}}. + +==== foreign-dependencies + +[egg property] (foreign-dependencies NAME ...) + +Lists external dependencies like native code libraries +or system-specific packages and is currently only used for +documentation purposes. + +==== platform + +[egg property] (platform PLATFORM) + +Specifies for which platform this egg is intended. {{PLATFORM}} +should be a symbol naming the target platform ({{windows}}, {{linux}} +or {{unix}}) or a boolean combination of platform values, allowed +are {{(not PLATFORM)}}, {{(or PLATFORM ...)}} and {{(and PLATFORM ...)}}. +If the expression can not be satisfied, then installation of this +egg will abort. + +==== components + +[egg property] (components COMPONENT ...) + +Lists components (extensions, programs, include- or data files) +that this extension installs. See below for information on how +to specify component-specific information. + +==== host + +[egg property] (host PROP ...) + +Recursively process {{PROP ...}}, but only for the host (build) +platform, in case this is a "cross-chicken", a CHICKEN installation +intended for cross compilation. + +==== target + +[egg property] (target PROP ...) + +Recursively process {{PROP ...}}, but only for the target +platform, in case this is a "cross-chicken", a CHICKEN installation +intended for cross compilation. + +==== Components + +==== extension + +[egg property] (extension NAME PROP ...) + +Specifies an extension library component. The properties +{{PROP...}} are processed recursively and apply only to this +component. + +==== data + +[egg property] (data NAME PROP ...) + +Specifies one or more arbitrary data files. + +==== generated-source-file + +[egg property] (generated-source-file NAME PROP ...) + +Specifies a file that is generated during the process of building +the egg. + +==== c-include + +[egg property] (c-include NAME PROP ...) + +Specifies one or more C include files. + +==== scheme-include + +[egg property] (scheme-include NAME PROP ...) + +Specifies one or more Scheme include files. + +==== program + +[egg property] (program NAME PROP ...) + +Specifies an executable program. + +==== Component properties + +==== host + +[egg property] (host PROP ...) + +Process {{PROP ...}} recursively for the current component, but +apply the properties only to the host (build) part, when using +a CHICKEN installation intended for cross-compilation. + +==== target + +[egg property] (target PROP ...) + +Process {{PROP ...}} recursively for the current component, but +apply the properties only to the target part, when using +a CHICKEN installation intended for cross-compilation. + +==== linkage + +[egg property] (linkage LINKAGE) + +Define whether the component should be linked dynamically or +statically. {{LINKAGE}} can be {{static}} or {{dynamic}}. This +property only makes sense for extension libraries. + +==== types-file + +[egg property] (types-file [NAME]) + +Specifies that a "type-database" file should be generated and +installed for this component. This property is only used for +extension libraries. The name is optional and defaults to the +name of the extensions (with the proper extension). + +If {{NAME}} is a list of the form {{(predefined [NAME])}}, then +no types file is created during compilation and an existing types file +for this extension is assumed and installed. + +==== inline-file + +[egg property] (inline-file [NAME]) + +Specifies that an "inline" file should be generated and installed +for this component. This property is only used for extension +libraries. The name is optional and defaults to the +name of the extensions (with the proper extension). + +==== custom-build + +[egg property] (custom-build STRING) + +Specifies a custom build operation that should be executed instead of +the default build operations. This property is mandatory for +components of type {{generated-source-file}}. {{STRING}} should be the +name of a shell command (e.g., a script) and thus may be platform +sensitive. The path to the file is prepended implicitly, so you +should '''not''' prefix it with {{./}}. On Windows, a file with the +{{.bat}} extension will be picked before a plain file with no +extension. + +The script will be made executable on UNIX systems, if necessary, +and will be invoked like the {{csc}} program and +is executed with the location of the CHICKEN +binaries in the {{PATH}}. Also, the following environment variables +are set in the execution environment of the script: + +* {{CHICKEN_CC}}: name of the C compiler used for building CHICKEN +* {{CHICKEN_CXX}}: name of the C++ compiler set during the build of CHICKEN +* {{CHICKEN_CSC}}: path to {{csc}} +* {{CHICKEN_CSI}}: path to {{csi}} + + +==== csc-options + +[egg property] (csc-options OPTION ...) + +Specifies additional compiler options for {{csc}} that should be +used when building this component. If this property is not +given, the default options are used, which are {{-O2 -d1}} +for extensions and programs and {{-O2 -d0}} for import +libraries. + +Note that the options are quoted when passed to csc during the +compilation of the extension, so multiple options should be specified +as {{(csc-options "OPT1" "OPT2" ...)}} instead of {{(csc-options "OPT1 OPT2")}} +(the latter would be a single option containing a whitespace character). + +==== link-options + +[egg property] (link-options OPTION ...) + +Specifies additional link options for {{csc}} that should be +used when building this component. + +Note that the options are quoted when passed to csc during the +compilation of the extension, so multiple options should be specified +as {{(link-options "OPT1" "OPT2" ...)}} instead of {{(link-options "OPT1 OPT2")}} +(the latter would be a single option containing a whitespace character). + +==== source + +[egg property] (source NAME) + +Specifies an alternative source file, in case it has a name +distinct from the component name. By default the source file +for a component is named after the component, with the {{.scm}} +extension added. + +==== install-name + +[egg property] (install-name NAME) + +Specifies an alternative installation name of the component, +if it differs from the actual component name. This property +is most useful if an egg installs an extension and a program +of the same name, but needs to distinguish the components during +build time. + +==== component-dependencies + +[egg property] (component-dependencies NAME ...) + +Specifies dependencies to other components. {{NAME ...}} must +be the names of extension, program, scheme-include- or generated source file +components that should be built before the current component. + +==== source-dependencies + +[egg property] (source-dependencies NAME ...) + +Specifies dependencies to additional source files. {{NAME ...}} must +denote filenames of which the program or extension depends. +A program or extension implicitly depends on its source file and +and on the egg-specification file. + +==== destination + +[egg property] (destination NAME) + +Specifies an alternative installation destination for the +built component and only applies +to components of type {{data}}, {{c-include}} and {{scheme-include}}. +This property should only be used in extreme +cases, as it is recommended to use the default installation +locations, which are: + +* for C include files: {{<PREFIX>/include/chicken/}} + +* for Scheme include files: {{<PREFIX>/share/chicken/}} + +* for data files: {{<PREFIX>/share/chicken/}} + +==== files + +[egg property] (files NAME ...) + +Specifies source files for this component and only applies +to components of type {{data}}, {{c-include}} and {{scheme-include}}. + + +--- + +Previous: [[Extension tools]] + +Next: [[Units and linking model]] diff --git a/manual/Embedding b/manual/Embedding index c3cde9e3..d6cd42cc 100644 --- a/manual/Embedding +++ b/manual/Embedding @@ -55,7 +55,7 @@ compiled Scheme program. If the runtime system was not initialized before, then {{CHICKEN_initialize}} is called with default sizes. {{toplevel}} is the toplevel entry-point procedure, you usually pass {{C_toplevel}} here. The result value is the continuation that can be used to re-invoke the Scheme code from the -point after it called {{return-to-host}} (see below). +point after it called [[Module (chicken gc)#return-to-host|{{return-to-host}}]]. If you just need a Scheme interpreter, you can also pass {{CHICKEN_default_toplevel}} as the toplevel procedure, which just uses the default library units. @@ -64,19 +64,6 @@ Once {{CHICKEN_run}} has been called, Scheme code is executing until all topleve expressions have been evaluated or until {{return-to-host}} is called inside the Scheme program. -=== return-to-host - -<procedure>(return-to-host)</procedure> - -Exits the Scheme code and returns to the invoking context that called {{CHICKEN_run}} -or {{CHICKEN_continue}}. - -After {{return-to-host}} has been executed and once {{CHICKEN_run}} returns, -you can invoke callbacks which have been defined with {{define-external}}. - -The {{eval}} library unit also provides boilerplate callbacks, that simplify invoking Scheme -code embedded in a C or C++ application: - === CHICKEN_eval [C macro] int CHICKEN_eval (C_word exp, C_word *result) @@ -160,6 +147,7 @@ An example: % cat x.scm ;;; x.scm + (import (chicken platform) (chicken foreign)) (define (bar x) (gc) (* x x)) @@ -234,7 +222,7 @@ or gc-roots. Another example: % cat x.scm - (require-extension srfi-18) + (import (chicken platform) srfi-18) ;; Needs the srfi-18 egg (define m (make-mutex)) @@ -342,4 +330,4 @@ Sets the value of the global variable referenced by the GC root {{global}} to {{ --- Previous: [[Foreign type specifiers]] -Next: [[Callbacks]] +Next: [[C interface]] diff --git a/manual/Extension tools b/manual/Extension tools new file mode 100644 index 00000000..8804cefa --- /dev/null +++ b/manual/Extension tools @@ -0,0 +1,275 @@ +[[tags: manual]] +[[toc:]] + +== Extension tools + +The basic tools to install, uninstall and view "eggs" and the extensions +are {{chicken-install}}, {{chicken-uninstall}} and {{chicken-status}}. + +{{chicken-install}} can be used in two modes: first, as a simple package +manager that downloads publicly available eggs (and their dependencies, if +necessary) and compiles the contained extensions, installing them on +a user's system. + +For development of eggs, {{chicken-install}} can also be invoked +without arguments, in a directory that contains an egg specification +file and the associated source code, building all components and +installing them. + +{{chicken-status}} simply lists installed eggs, the contained extensions, +and optionally the files that where installed with a particular egg. + +Below you will find a description of the available command line options +for all three programs. A specification of the egg description file +format is [[Egg specification format|here]]. + +=== Security + +When eggs are downloaded and installed one is executing code +from potentially compromised systems. This applies also when +{{chicken-install}} executes system tests for required eggs. As +the code has been retrieved over the network effectively untrusted +code is going to be evaluated. When {{chicken-install}} is run as +''root'' the whole system is at the mercy of the build instructions +(note that this is also the case every time you install software via +{{sudo make install}}, so this is not specific to the CHICKEN +egg mechanism). + +Security-conscious users should never run {{chicken-install}} as root. +A simple remedy is to keep the repository inside a user's home +directory (see the section "Changing repository location" below). +Alternatively obtain write/execute access to the default location of the repository +(usually {{/usr/local/lib/chicken}}) to avoid running as +root. {{chicken-install}} also provides a {{-sudo}} option to perform +the last installation steps as root user, but do building and other +.setup script processing as normal. A third solution is to +override {{VARDIR}} when building the system +(for example by passing {{"VARDIR=/foo/bar"}} on the make command line, +or by modifying {{config.make}}. Eggs will then be installed in +{{$(VARDIR)/chicken/8}}. + +=== Changing the repository location + +When CHICKEN is installed a repository for eggs is created and initialized +in a default location (usually something like {{/usr/local/lib/chicken/9/}}). +It is possible to keep an egg repository in another location. This can be +configured at build-time by passing {{VARDIR=<directory>}} to {{make(3)}} +or by modifying the {{config.make}} configuration file. If you want to +override this location after chicken is installed, you can create a +repository directory, set the +{{CHICKEN_INSTALL_REPOSITORY}} and/or {{CHICKEN_REPOSITORY_PATH}} +environment variables to the full path of the new reopsitory and copy all files +from the default repository into the new one. + +Note that your binary version can differ from the one given in +the examples here, if your +chicken version is older or newer than the one used in these examples. +Check your default location for the correct binary-version number. + +{{CHICKEN_REPOSITORY_PATH}} is a directory (or a list of directories +separated by {{:}}/{{;}}) where eggs are to be +loaded from for all chicken-based programs. {{CHICKEN_INSTALL_REPOSITORY}} +is the place where eggs will be installed and which the egg-related +tools like {{chicken-install}}, {{chicken-uninstall}} and +{{chicken-status}} consult and update. Make sure the paths given in these +environment variables are absolute and not relative. + +=== Static linking + +Static linking of extensions and programs is fully supported and +should be transparent to the user. Every extension will by +default be compiled into a dynamically loadable and a statically +linkable entity. By passing {{-static}} on the {{csc}} command-line, +eggs that are available in static form will be linked instead of +the dynamically loadable version. Use the {{linkage}} egg +description property to select in what modes a component should +be built. + +To identify the necessary object files during linking of +extensions, {{csc}} +creates so-called "link files" and installs them along the +statically compiled object file in the local egg repository. +These link files specify what objects should be linked when +an application is using a static variant of an extension. + + +=== Locations + +For experimentation or in-house builds of software it may be +useful to have private egg repositories in addition to the +official CHICKEN egg repository. This can be accomplished by +defining so-called "locations", directories that contain egg +source-code and description files and which should be scanned +before trying to retrieve an egg via the network. + +The file {{<PREFIX>/share/chicken/setup.defaults}} holds various +parameters that define where eggs should be downloaded, together +with more obscure options, and can be used to customize the +sources where eggs will be retrieved from. Adding a line of +the form + +{{(location "<PATH>")}} + +will add {{<PATH>}} as an additional egg source, where {{<PATH>}} +should be a directory in the local filesystem that contains +any number of eggs, one directory for each, including the source code +and the {{.egg}} files for each egg. + +Locations are searched before trying to retrieve from the network. +Any number of locations may be defined. + + +=== The egg cache + +Eggs are downloaded and built in the so called "egg cache", an +intermediate location used for storing already downloaded source code +and for providing a temporary location for building the eggs before +they are installed. + +By default the cache is located in the directory +{{.chicken-install.cache}} is the user's home directory ({{$HOME}} on +UNIX, or {{%USERPROFILE%}} on Windows. If the respective environment +variable is not set, then {{/tmp}} or {{/Temp}} is used. + +Built extensions and programs remain in the cache, to avoid rebuilding +already compiled code and multiple downloads of eggs in case the +installation of an egg fails - the dependencies will be cached after +the first download and re-download is not needed. + +{{chicken-install}} tries to take extreme care to avoid stale binaries, +but should you be in doubt, simply delete the directory, or run +{{chicken-install -purge}} to clear the cache or parts of it. + +You can override the location of the cache by setting the +{{CHICKEN_EGG_CACHE}} environment variable. + + +=== Egg installation in detail + +==== Retrieval + +First the egg names given on the command line (or, if no arguments +are given, all eggs identified by {{.egg}} files in the current +directory, including any in a subdirectory named {{chicken}}) +must be retrieved, either from a local source or from the official +egg repository. Should the egg exist in the egg cache we check +whether this cached version is out of date. A cached egg is +considered out of date, if a) it is locally available and all cached +files belonging to the egg do not have newer timestamps than the +local files, or b) if it is a remotely retrieved egg and no +newer versions exist on the remote egg server and the last time +the cache was filled from the remote location is not later than +one hour. Additionally, if any changes in certain environment +variables that may influence the compilation of an egg, or if +the CHICKEN version changed, then retrieval of the egg sources +is enforced in any case. + +If the egg is in the current directory, or in +a "location" (as described above), the files are copied into +the cache. If the egg is remotely available, then it is retrieved +via HTTP from one of the egg servers defined in {{setup.defaults}}. + +Once the egg sources are retrieved and stored in the cache, +their {{.egg}} files are loaded and validated. After this +any egg dependencies are resolved and located in the cache, +triggering a recursive retrieval, if necessary. + +==== Preparation + +Unless the {{-retrieve}} option was given, the eggs intended +to be built and installed are now scheduled for compilation. +The egg information from the {{.egg}} files is processed and +translated into build and install scripts for the current +platform - if this CHICKEN was configured for cross compilation, +and no separate host- or target-build was selected, two sets +of build/install scripts will be generated, one for the host +system and one for the target. + +==== Building and installation + +Unless {{-dry-run}} was given on the command-line, the build- +and install scripts are now executed, ordered by the dependency +relationships between the full set of eggs that are scheduled +for compilation. If the {{-test}} option was given and a file named +{{run.scm}} exists in the {{tests}} subdirectory of the egg +sources, then this script is executed. Should it terminate with +an error or a non-zero exit code, the installation is still performed +and {{chicken-install}} does not abort. Only after all scheduled +eggs have been installed, {{chicken-install}} will terminate +with a non-zero exit code. + +Note that the build process attempts to minimize re-building +of already compiled files in the cache, using the {{chicken-do}} +program. See the manual page for {{chicken-do}} for more details. + +From the egg-information in the {{.egg}} file, the set of files +installed for a particular egg are added to the egg-information +and stored together with the build-artifacts produced by the +build scripts. + +=== chicken-install reference + +Available options: + +; {{-h -help}} : show this message and exit +; {{-version}} : show version and exit +; {{-force}} : don't ask, install even if versions don't match +; {{-k -keep}} : keep temporary files +; {{-s -sudo}} : use external command to elevate privileges when installing or removing files +; {{-no-install-deps}} : do not install dependencies +; {{-r -retrieve}} : only retrieve egg into current directory, don't install (giving -r more than once implies {{-recursive}}) +; {{-recursive}} : if {{-retrieve}} is given, retrieve also dependencies +; {{-dry-run}} : do not build or install, just print the locations of the generated build + install scripts +; {{-list-versions}} : list available version for an extension (HTTP transport only) +; {{-n -no-install}} : do not install, only build the egg. +; {{-purge}} : remove cached files for given eggs (or purge cache completely) +; {{-cached}} : install from cache, do not download +; {{-host}} : when cross-compiling, compile egg for host only +; {{-target}} : when cross-compiling, compile egg for target only +; {{-test}} : run included test-cases, if available +; {{-u -update-db}} : update export database +; {{-repository}} : print path to egg repository +; {{-override FILENAME}} : override versions for installed eggs with information given in {{FILENAME}}, which can be generated by {{-scan}} or by the {{-list}} option of the {{chicken-status}} program +; {{-from-list FILENAME}} : install eggs given in {{FILENAME}}, in the same format as produced by the {{-list}} option in {{chicken-status}}; this option may be given multiple times +; {{-v -verbose}} : be verbose +; {{ -defaults FILENAME }} : use {{FILENAME}} as defaults instead of the installed {{setup.defaults}} file + +{{chicken-install}} recognizes the {{SUDO}}, {{http_proxy}} and {{proxy_auth}} environment variables, if set. + +When running {{chicken-install}} with an argument {{NAME}}, for which +no associated {{.egg}} file exists, then it will try to download the +extension via HTTP from the CHICKEN code repository at +[[http://code.call-cc.org/svn/chicken-eggs/]]. Extensions that are +required to compile and/or use the requested extension are downloaded +and installed automatically. + + +=== chicken-uninstall reference + +; {{-h -help}} : show usage information and exit +; {{-version}} : show version and exit +; {{-force}} : don't ask, delete whatever matches +; {{-match}} : treat egg-names as glob patterns +; {{-s -sudo}} : use external command to elevate privileges for deleting files +; {{-host}} : when cross-compiling, remove eggs for host system only +; {{-target}} : when cross-compiling, remove eggs for target system only + + +=== chicken-status reference + +; {{-h -help}} : show usage information and exit +; {{-version}} : show version and exit +; {{-f -files}} : list installed files +; {{-match}} : treat egg-names as glob patterns +; {{-host}} : when cross-compiling, show eggs for host system only +; {{-target}} : when cross-compiling, show eggs for target system only +; {{-list}} : list installed egg version in format suitable for {{chicken-install -override}} or {{-from-list}} +; {{-c -components}} : list installed components +; {{-cached}} : list eggs available in the cache directory + + +--- + +Previous: [[Extensions]] + +Next: [[Egg specification format]] diff --git a/manual/Extensions b/manual/Extensions index 0b508b77..9a2e9aff 100644 --- a/manual/Extensions +++ b/manual/Extensions @@ -1,7 +1,7 @@ [[tags: manual]] [[toc:]] -== Eggs +== Introduction to extensions === Extension libraries @@ -88,316 +88,14 @@ For example, if your egg is called {{foo}}, create a directory called {{foo}} and put the egg code there. -Eggs need an egg description file {{<egg name>.egg}}. -This file indicates how -the egg is to be compiled and provides some information +Eggs need an egg description file {{<egg name>.egg}}. This file +indicates how the egg is to be compiled and provides some information about the egg (author, license, dependencies etc). -=== Format of the egg description file +The format of these files is described in full in the chapter entitled +"[[Egg specification format]]". Below we'll give a few brief +examples of simple eggs. -An egg description is basically an association list holding -information about the components of the egg. An egg may contain -multiple components: libraries, programs, Scheme or C include files -and arbitrary data files. Dependencies between eggs can be -specified as can be dependencies between components of an egg. - -A list of valid properties follows. - -==== Global properties - -===== version - -[egg property] (version STRING) - -Specifies version string for this egg. {{STRING}} should have -the format {{<MAJOR>.<MINOR>.<PATCHLEVEL>}}, where only the -{{<MAJOR>}} part is mandatory. - -Eggs from remote egg servers are automatically versioned - the -version is part of the protocol to retrieve the egg and does not -have to be specified in the {{.egg}} file. Eggs installed from -local directories (see below) should explicitly specify a version. - -===== synopsis - -[egg property] (synopsis STRING) - -Gives a short description of this egg. - -===== author - -[egg property] (author STRING) - -Names the author or authors of the contained code. - -===== maintainer - -[egg property] (maintainer STRING) - -Names the maintainer of this code, if different from author(s). - -===== category - -[egg property] (category NAME) - -Gives the category under which this egg should be contained. -See [[/chicken-projects/egg-index-5.html|the egg index]] -for a list of currently used categories. - -===== license - -[egg property] (license STRING) - -Names the license under which this code is available. - -===== dependencies - -[egg property] (dependencies EGG ...) - -Lists eggs that this egg depends on, and which should be -built and installed if they do not already exist in the repository. -{{EGG}} should be whether a symbol or a list of the form -{{EGGNAME VERSION}}, where the former means to install the -newest available egg with this name and the latter specifies -a specific version or higher. - -Note that this property -has a different meaning depending on whether it appears at -toplevel in an egg description or inside a component. - -====== test-dependencies - -[egg property] (test-dependencies EGG ...) - -Lists eggs that are required for this egg to run the tests -(if tests exist.) This only has an effect if the {{-test}} -option has been given to {{chicken-install}}. - -====== build-dependencies - -[egg property] (build-dependencies EGG ...) - -Lists eggs that are build-time dependencies for this egg, -i.e. there are required to build, but not to run the contained -code. Currently this is treated identical to {{dependencies}}. - -====== foreign-dependencies - -[egg property] (foreign-dependencies NAME ...) - -Lists external dependencies like native code libraries -or system-specific packages and is currently only used for -documentation purposes. - -====== platform - -[egg property] (platform PLATFORM) - -Specifies for which platform this egg is intended. {{PLATFORM}} -should be a symbol naming the target platform ({{windows}}, {{linux}} -or {{unix}}) or a boolean combination of platform values, allowed -are {{(not PLATFORM)}}, {{(or PLATFORM ...)}} and {{(and PLATFORM ...)}}. -If the expression can not be satisfied, then installation of this -egg will abort. - -====== components - -[egg property] (components COMPONENT ...) - -Lists components (extensions, programs, include- or data files) -that this extension installs. See below for information on how -to specify component-specific information. - -====== host - -[egg property] (host PROP ...) - -Recursively process {{PROP ...}}, but only for the host (build) -platform, in case this is a "cross-chicken", a CHICKEN installation -intended for cross compilation. - -====== target - -[egg property] (target PROP ...) - -Recursively process {{PROP ...}}, but only for the target -platform, in case this is a "cross-chicken", a CHICKEN installation -intended for cross compilation. - -===== Components - -====== extension - -[egg property] (extension NAME PROP ...) - -Specifies an extension library component. The properties -{{PROP...}} are processed recursively and apply only to this -component. - -====== data - -[egg property] (data NAME PROP ...) - -Specifies one or more arbitrary data files. - -====== generated-source-file - -[egg property] (generated-source-file NAME PROP ...) - -Specifies a file that is generated during the process of building -the egg. - -====== c-include - -[egg property] (c-include NAME PROP ...) - -Specifies one or more C include files. - -====== scheme-include - -[egg property] (scheme-include NAME PROP ...) - -Specifies one or more Scheme include files. - -====== program - -[egg property] (program NAME PROP ...) - -Specifies an executable program. - -===== Component properties - -====== host - -[egg property] (host PROP ...) - -Process {{PROP ...}} recursively for the current component, but -apply the properties only to the host (build) part, when using -a CHICKEN installation intended for cross-compilation. - -====== target - -[egg property] (target PROP ...) - -Process {{PROP ...}} recursively for the current component, but -apply the properties only to the target part, when using -a CHICKEN installation intended for cross-compilation. - -====== linkage - -[egg property] (linkage LINKAGE) - -Define whether the component should be linked dynamically or -statically. {{LINKAGE}} can be {{static}} or {{dynamic}}. This -property only makes sense for extension libraries. - -====== types-file - -[egg property] (types-file [NAME]) - -Specifies that a "type-database" file should be generated and -installed for this component. This property is only used for -extension libraries. The name is optional and defaults to the -name of the extensions (with the proper extension). - -If {{NAME}} is a list of the form {{(predefined [NAME])}}, then -no types file is created during compilation and an existing types file -for this extension is assumed and installed. - -====== inline-file - -[egg property] (inline-file [NAME]) - -Specifies that an "inline" file should be generated and installed -for this component. This property is only used for extension -libraries. The name is optional and defaults to the -name of the extensions (with the proper extension). - -====== custom-build - -[egg property] (custom-build STRING) - -Specifies a custom build operation that should be executed -instead of the default build operations. This property is mandatory -for components of type {{generated-source-file}}. {{STRING}} -usually contains a shell command and thus may be platform sensitive. - -The script will be made executable on UNIX systems, if necessary, -and will be invoked like the {{csc}} program and -is executed with the location of the CHICKEN -binaries in the {{PATH}}. Also, tjhe environment variables -{{CHICKEN_CC}} and {{CHICKEN_CXX}} are set to the -names of the C and C++ compiler that were used for building the -system. - -====== csc-options - -[egg property] (csc-options OPTION ...) - -Specifies additional compiler options for {{csc}} that should be -used when building this component. If this property is not -given, the default options are used, which are {{-O2 -d1}} -for extensions and programs and {{-O2 -d0}} for import -libraries. - -====== link-options - -[egg property] (link-options OPTION ...) - -Specifies additional link options for {{csc}} that should be -used when building this component. - -====== source - -[egg property] (source NAME) - -Specifies an alternative source file, in case it has a name -distinct from the component name. By default the source file -for a component is named after the component, with the {{.scm}} -extension added. - -====== install-name - -[egg property] (install-name NAME) - -Specifies an alternative installation name of the component, -if it differs from the actual component name. This property -is most useful if an egg installs an extension and a program -of the same name, but needs to distinguish the components during -build time. - -====== dependencies - -[egg property] (dependencies NAME ...) - -Specifies dependencies between components. Note that this use -of the {{dependencies}} property is different from the property -of the same name that is used at the "global" level of the -egg description file. - -====== destination - -[egg property] (destination NAME) - -Specifies an alternative installation destination for the -built component and only applies -to components of type {{data}}, {{c-include}} and {{scheme-include}}. -This property should only be used in extreme -cases, as it is recommended to use the default installation -locations, which are: - -* for C include files: {{<PREFIX>/include/chicken/}} - -* for Scheme include files: {{<PREFIX>/share/chicken/}} - -* for data files: {{<PREFIX>/share/chicken/}} - -====== files - -[egg property] (files NAME ...) - -Specifies source files for this component and only applies -to components of type {{data}}, {{c-include}} and {{scheme-include}}. === Examples for extensions @@ -436,7 +134,7 @@ be stored in the repository, together with a file named {{hello.egg-info}} containing an a-list with metadata (what you stored above in {{hello.egg}} plus some additional metadata). If no extension name is given to {{chicken-install}}, it will simply -process the any files with the {{.egg}} extension it can find. +process any files with the {{.egg}} extension it can find. Use it like any other CHICKEN extension: @@ -560,258 +258,16 @@ Next, it should be possible to load the library: --- 4 -==== Notes on chicken-install - -When running {{chicken-install}} with an argument {{NAME}}, for which -no associated {{.egg}} file exists, then it will try to download the -extension via HTTP from the CHICKEN code repository at -[[http://code.call-cc.org/svn/chicken-eggs/]]. Extensions that are -required to compile and/or use the requested extension are downloaded -and installed automatically. - To query the list of currently installed extensions, use {{chicken-status}}. It can list what extensions are installed and what files belong to a particular installed extension. - -=== chicken-install reference - -Available options: - -; {{-h -help}} : show this message and exit -; {{-version}} : show version and exit -; {{-force}} : don't ask, install even if versions don't match -; {{-k -keep}} : keep temporary files -; {{-s -sudo}} : use external command to elevate privileges when installing or removing files -; {{-no-install-deps}} : do not install dependencies -; {{-r -retrieve}} : only retrieve egg into current directory, don't install (giving -r more than once implies {{-recursive}}) -; {{-recursive}} : if {{-retrieve}} is given, retrieve also dependencies -; {{-dry-run}} : do not build or install, just print the locations of the generated build + install scripts -; {{-list-versions}} : list available version for an extension (HTTP transport only) -; {{-n -no-install}} : do not install, only build the egg. -; {{-purge}} : remove cached files for given eggs (or purge cache completely) -; {{-host}} : when cross-compiling, compile egg for host only -; {{-target}} : when cross-compiling, compile egg for target only -; {{-test}} : run included test-cases, if available -; {{-u -update-db}} : update export database -; {{-repository}} : print path to egg repository -; {{-override FILENAME}} : override versions for installed eggs with information given in {{FILENAME}}, which can be generated by {{-scan}} or by the {{-list}} option of the {{chicken-status}} program -: {{-from-list FILENAME}} : install eggs given in {{FILENAME}}, in the same format as produced by the {{-list}} option in {{chicken-status}}; this option may be given multiple times -; {{-v -verbose}} : be verbose -; {{-cached}} : only install from cache, do not access local or remote repositories. Use {{-force}} in addition to this option if the cached egg(s) are from older CHICKEN installations. - -{{chicken-install}} recognizes the {{SUDO}}, {{http_proxy}} and {{proxy_auth}} environment variables, if set. - - -=== chicken-uninstall reference - -; {{-h -help}} : show usage information and exit -; {{-version}} : show version and exit -; {{-force}} : don't ask, delete whatever matches -; {{-match}} : treat egg-names as glob patterns -; {{-s -sudo}} : use external command to elevate privileges for deleting files -; {{-host}} : when cross-compiling, remove eggs for host system only -; {{-target}} : when cross-compiling, remove eggs for target system only - -=== chicken-status reference - -; {{-h -help}} : show usage information and exit -; {{-version}} : show version and exit -; {{-f -files}} : list installed files -; {{-match}} : treat egg-names as glob patterns -; {{-host}} : when cross-compiling, show eggs for host system only -; {{-target}} : when cross-compiling, show eggs for target system only -; {{-list}} : list installed egg version in format suitable for {{chicken-install -override}} or {{-from-list}} -; {{-c -components}} : list installed components -; {{-cached}} : list eggs that are locally cached - - -=== Security - -When eggs are downloaded and installed one is executing code -from potentially compromised systems. This applies also when -{{chicken-install}} executes system tests for required eggs. As -the code has been retrieved over the network effectively untrusted -code is going to be evaluated. When {{chicken-install}} is run as -''root'' the whole system is at the mercy of the build instructions -(note that this is also the case every time you install software via -{{sudo make install}}, so this is not specific to the CHICKEN -egg mechanism). - -Security-conscious users should never run {{chicken-install}} as root. -A simple remedy is to keep the repository inside a user's home -directory (see the section "Changing repository location" below). -Alternatively obtain write/execute access to the default location of the repository -(usually {{/usr/local/lib/chicken}}) to avoid running as -root. {{chicken-install}} also provides a {{-sudo}} option to perform -the last installation steps as root user, but do building and other -.setup script processing as normal. A third solution is to -override {{VARDIR}} when building the system -(for example by passing {{"VARDIR=/foo/bar"}} on the make command line, -or by modifying {{config.make}}. Eggs will then be installed in -{{$(VARDIR)/chicken/8}}. - -=== Changing the repository location - -When CHICKEN is installed a repository for eggs is created and initialized -in a default location (usually something like {{/usr/local/lib/chicken/6/}}). -It is possible to keep an egg repository in another location. This can be -configured at build-time by passing {{VARDIR=<directory>}} to {{make(3)}} -or by modifying the {{config.make}} configuration file. If you want to -override this location after chicken is installed, you can create a -repository directory, set the -{{CHICKEN_INSTALL_REPOSITORY}} and/or {{CHICKEN_REPOSITORY_PATH}} -environment variables and copy all files -from the default repository into the new one. - -Note that your binary version can differ from the one given in -the examples here, if your -chicken version is older or newer than the one used in these examples. -Check your default location for the correct binary-version number. - -{{CHICKEN_REPOSITORY_PATH}} is the place where eggs are to be -loaded from for all chicken-based programs. {{CHICKEN_INSTALL_REPOSITORY}} -is the place where eggs will be installed and which the egg-related -tools like {{chicken-install}}, {{chicken-uninstall}} and -{{chicken-status}} consult and update. - - -=== Static linking - -Static linking of extensions and programs is fully supported and -should be transparent to the user. Every extension will by -default be compiled into a dynamically loadable and a statically -linkable entity. By passing {{-static}} on the {{csc}} command-line, -eggs that are available in static form will be linked instead of -the dynamically loadable version. Use the {{linkage}} egg -description property to select in what modes a component should -be built. - -To identify the necessary object files during linking of -extensions, {{csc}} -creates so-called "link files" and installs them along the -statically compiled object file in the local egg repository. -These link files specify what objects should be linked when -an application is using a static variant of an extension. - - -=== Locations - -For experimentation or in-house builds of software it may be -useful to have private egg repositories in addition to the -official CHICKEN egg repository. This can be accomplished by -defining so-called "locations", directories that contain egg -source-code and description files and which should be scanned -before trying to retrieve an egg via the network. - -The file {{<PREFIX>/share/chicken/setup.defaults}} holds various -parameters that define where eggs should be downloaded, together -with more obscure options, and can be used to customize the -sources where eggs will be retrieved from. Adding a line of -the form - -{{(location "<PATH>")}} - -will add {{<PATH>}} as an additional egg source, where {{<PATH>}} -should be a directory in the local filesystem that contains -any number of eggs, one directory for each, including the source code -and the {{.egg}} files for each egg. - -Locations are searched before trying to retrieve from the network. -Any number of locations may be defined. - - -=== The egg cache - -Eggs are downloaded and built in the so called "egg cache", an -intermediate location used for storing already downloaded source code -and for providing a temporary location for building the eggs before -they are installed. - -By default the cache is located in the directory -{{.chicken-install/cache}} is the user's home directory ({{$HOME}} on -UNIX, or {{%USERPROFILE%}} on Windows. If the respective environment -variable is not set, then {{/tmp}} or {{/Temp}} is used. - -Built extensions and programs remain in the cache, to avoid rebuilding -already compiled code and multiple downloads of eggs in case the -installation of an egg fails - the dependencies will be cached after -the first download and re-download is not needed. - -{{chicken-install}} tries to take extreme care to avoid stale binaries, -but should you be in doubt, simply delete the directory, or run -{{chicken-install -purge}} to clear the cache or parts of it. -{{chicken-status -cached}} will list the eggs that are currently -in the cache. - -You can override the location of the cache by setting the -{{CHICKEN_EGG_CACHE}} environment variable. - - -=== Egg installation in detail - -==== Retrieval - -First the egg names given on the command line (or, if no arguments -are given, all eggs identified by {{.egg}} files in the current -directory, including any in a subdirectory named {{chicken}}) -must be retrieved, either from a local source or from the official -egg repository. Should the egg exist in the egg cache we check -whether this cached version is out of date. A cached egg is -considered out of date, if a) it is locally available and all cached -files belonging to the egg do not have newer timestamps than the -local files, or b) if it is a remotely retrieved egg and no -newer versions exist on the remote egg server and the last time -the cache was filled from the remote location is not later than -one hour. Additionally, if any changes in certain environment -variables that may influence the compilation of an egg, or if -the CHICKEN version changed, then retrieval of the egg sources -is enforced in any case. - -If the egg is in the current directory, or in -a "location" (as described above), the files are copied into -the cache. If the egg is remotely available, then it is retrieved -via HTTP from one of the egg servers defined in {{setup.defaults}}. - -Once the egg sources are retrieved and stored in the cache, -their {{.egg}} files are loaded and validated. After this -any egg dependencies are resolved and located in the cache, -triggering a recursive retrieval, if necessary. - -==== Preparation - -Unless the {{-retrieve}} option was given, the eggs intended -to be built and installed are now scheduled for compilation. -The egg information from the {{.egg}} files is processed and -translated into build and install scripts for the current -platform - if this CHICKEN was configured for cross compilation, -and no separate host- or target-build was selected, two sets -of build/install scripts will be generated, one for the host -system and one for the target. - -==== Building and installation - -Unless {{-dry-run}} was given on the command-line, the build- -and install scripts are now executed, ordered by the dependency -relationships between the full set of eggs that are scheduled -for compilation. If the {{-test}} option was given and a file named -{{run.scm}} exists in the {{tests}} subdirectory of the egg -sources, then this script is executed. Should it terminate with -an error or a non-zero exit code, the installation is still performed -and {{chicken-install}} does not abort. Only after all scheduled -eggs have been installed, {{chicken-install}} will terminate -with a non-zero exit code. - -Note that the build process attempts to minimize re-building -of already compiled files in the cache, using the {{chicken-do}} -program. See the manual page for {{chicken-do}} for more details. - -From the egg-information in the {{.egg}} file, the set of files -installed for a particular egg are added to the egg-information -and stored together with the build-artifacts produced by the -build scripts. +For more information about the available tools and the various options +they provide, consult the [[Extension tools]] chapter. Again, for a +full list of allowed declarations in the {{.egg}} file, see the +[[Egg specification format]] chapter. --- -Previous: [[Interface to external functions and variables]] +Previous: [[Declarations]] -Next: [[Extensions]] +Next: [[Extension tools]] diff --git a/manual/Extensions to the standard b/manual/Extensions to the standard index 7b3e20b4..cf65756d 100644 --- a/manual/Extensions to the standard +++ b/manual/Extensions to the standard @@ -2,7 +2,7 @@ [[toc:]] -== Extensions to the standard +== Extensions to the R5RS standard === Identifiers @@ -13,187 +13,216 @@ Identifiers may contain special characters if delimited with The brackets {{[ ... ]}} and the braces {{ { ... } }} are provided as an alternative syntax for {{( ... )}}. A number of reader -extensions is provided. See [[Non-standard read syntax]]. +extensions is provided. -=== Non-standard macros +=== Non-standard procedures and syntax -Numerous non-standard macros are provided. See -[[Non-standard macros and special forms]] for more information. +CHICKEN provides numerous non-standard procedures. See the manual +sections on the included library modules ([[Included modules]]) for more information. -=== Extended DSSSL style lambda lists +=== User defined character names -Extended DSSSL style lambda lists are supported. DSSSL parameter lists are defined by the following grammar: +User defined character names are supported. See +{{char-name}}. Characters can be given +in hexadecimal notation using the ''#\xXX'' syntax where ''XX'' specifies the +character code. Character codes above 255 are supported and can be read (and are +written) using the ''#\uXXXX'' and ''#\UXXXXXXXX'' notations. - <parameter-list> ==> <required-parameter>* - [#!optional <optional-parameter>*] - [#!rest <rest-parameter>] - [#!key <keyword-parameter>*] - <required-parameter> ==> <ident> - <optional-parameter> ==> <ident> - | (<ident> <initializer>) - <rest-parameter> ==> <ident> - <keyword-parameter> ==> <ident> - | (<ident> <initializer>) - <initializer> ==> <expr> +Non-standard characters names supported are {{#\tab}}, {{#\linefeed}}, {{#\return}}, {{#\alarm}}, +{{#\vtab}}, {{#\nul}}, {{#\page}}, {{#\esc}}, {{#\delete}} and {{#\backspace}}. -When a procedure is applied to a list of arguments, the parameters and arguments are processed from left to right as follows: +=== Special characters in strings -* Required-parameters are bound to successive arguments starting with the first argument. It shall be an error if there are fewer arguments than required-parameters. -* Next, the optional-parameters are bound with the remaining arguments. If there are fewer arguments than optional-parameters, then the remaining optional-parameters are bound to the result of the evaluation of their corresponding <initializer>, if one was specified, otherwise {{#f}}. The corresponding <initializer> is evaluated in an environment in which all previous parameters have been bound. -* If there is a rest-parameter, then it is bound to a list containing all the remaining arguments left over after the argument bindings with required-parameters and optional-parameters have been made. -* If {{#!key}} was specified in the parameter-list, there should be an even number of remaining arguments. These are interpreted as a series of pairs, where the first member of each pair is a keyword specifying the parameter name, and the second member is the corresponding value. If the same keyword occurs more than once in the list of arguments, then the corresponding value of the first keyword is the binding value. If there is no argument for a particular keyword-parameter, then the variable is bound to the result of evaluating <initializer>, if one was specified, otherwise {{#f}}. The corresponding <initializer> is evaluated in an environment in which all previous parameters have been bound. +CHICKEN supports special characters preceded with +a backslash ''\'' in quoted string +constants. ''\n'' denotes the newline-character, +''\r'' carriage return, ''\b'' +backspace, ''\t'' TAB, ''\v'' vertical TAB, ''\a'' alarm, ''\f'' formfeed, +''\xXX'' a character with the code {{XX}} in hex and +''\uXXXX'' (and ''\UXXXXXXXX'') a unicode character with the code {{XXXX}}. +The latter is encoded in UTF-8 format. + +== 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> -Needing a special mention is the close relationship between the rest-parameter and possible keyword-parameters. Declaring a rest-parameter binds up all remaining arguments in a list, as described above. These same remaining arguments are also used for attempted matches with declared keyword-parameters, as described above, in which case a matching keyword-parameter binds to the corresponding value argument at the same time that both the keyword and value arguments are added to the rest parameter list. -Note that for efficiency reasons, the keyword-parameter matching does nothing more than simply attempt to match with pairs that may exist in the remaining arguments. Extra arguments that don't match are simply unused and forgotten if no rest-parameter has been declared. Because of this, the caller of a procedure containing one or more keyword-parameters cannot rely on any kind of system error to report wrong keywords being passed in. + #| ... |# -It shall be an error for an {{<ident>}} to appear more than once in a parameter-list. +A multiline ''block'' comment. May be nested. Implements [[http://srfi.schemers.org/srfi-30/srfi-30.html|SRFI-30]]. -If there is no rest-parameter and no keyword-parameters in the parameter-list, then it shall be an error for any extra arguments to be passed to the procedure. +=== Expression Comment +<read>#;</read> -Example: + #;EXPRESSION - ((lambda x x) 3 4 5 6) => (3 4 5 6) - ((lambda (x y #!rest z) z) - 3 4 5 6) => (5 6) - ((lambda (x y #!optional z #!rest r #!key i (j 1)) - (list x y z i: i j: j)) - 3 4 5 i: 6 i: 7) => (3 4 5 i: 6 j: 1) +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]]. -=== {{set!}} +=== External Representation -{{set!}} for unbound toplevel variables is allowed. {{set! (PROCEDURE ...) ...)}} -is supported, as CHICKEN implements [[http://srfi.schemers.org/srfi-17/srfi-17.html|SRFI-17]]. +<read>#,</read> -=== {{cond}} + #,(CONSTRUCTORNAME DATUM ...) -The {{cond}} form supports [[http://srfi.schemers.org/srfi-61|SRFI-61]]. +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]]) -=== {{begin}} +=== Location Expression -{{(begin)}} is allowed in non-toplevel contexts and evaluates -to an unspecified value. +<read> #$EXPRESSION</read> -=== Delayed expressions +An abbreviation for {{(location EXPRESSION)}}. -Delayed expressions may return multiple values. +=== Blob literals -=== Internal definitions +<read>#${</read> -CHICKEN extends standard semantics by allowing internal definitions -everywhere, and not only at the beginning of a body. A set of internal definitions -is equivalent to a {{letrec}} form enclosing all following expressions -in the body: + #${ HEX ... } - (let ((foo 123)) - (bar) - (define foo 456) - (baz foo) ) +Syntax for literal "blobs" (byte-sequences). Expects hexadecimal digits and ignores +any whitespace characters: -expands into + #;1> ,d '#${deadbee f} + blob of size 4: + 0: de ad be ef .... - (let ((foo 123)) - (bar) - (letrec ((foo 456)) - (baz foo) ) ) +=== Keyword -Local sequences of {{define-syntax}} forms are translated into equivalent -{{letrec-syntax}} forms that enclose the following forms as the body of -the expression. +<read>#:</read> -=== Curried definitions + #:SYMBOL + SYMBOL: + :SYMBOL -{{define}} with a single argument is allowed and initializes the toplevel or local binding -to an unspecified value. CHICKEN supports ''curried'' definitions, where the variable name -may also be a list specifying a name and a nested lambda list. So +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. - (define ((make-adder x) y) (+ x y)) +=== 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 (make-adder x) (lambda (y) (+ x y))) + (define msg "\"Hello, world!\", she said.") -=== Non-standard procedures +=== Multiline String Constant with Embedded Expressions -CHICKEN provides numerous non-standard procedures. See the manual -sections on library units for more information. +<read>#<#</read> -=== Special IEEE floating-point numbers + #<#TAG -The special IEEE floating-point numbers ''+nan'', ''+inf'' and ''-inf'' -are supported, as is negative zero. +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 {{#}}: -=== User defined character names + (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 + ) -User defined character names are supported. See -{{char-name}}. Characters can be given -in hexadecimal notation using the ''#\xXX'' syntax where ''XX'' specifies the -character code. Character codes above 255 are supported and can be read (and are -written) using the ''#\uXXXX'' and ''#\UXXXXXXXX'' notations. +prints -Non-standard characters names supported are {{#\tab}}, {{#\linefeed}}, {{#\return}}, {{#\alarm}}, -{{#\vtab}}, {{#\nul}}, {{#\page}}, {{#\esc}}, {{#\delete}} and {{#\backspace}}. + This is a simple string with an embedded `#' character + and substituted expressions: (+ three 99) ==> 102 + (three is "3") -=== Special characters in strings +=== Foreign Declare -CHICKEN supports special characters preceded with -a backslash ''\'' in quoted string -constants. ''\n'' denotes the newline-character, -''\r'' carriage return, ''\b'' -backspace, ''\t'' TAB, ''\v'' vertical TAB, ''\a'' alarm, ''\f'' formfeed, -''\xXX'' a character with the code {{XX}} in hex and -''\uXXXX'' (and ''\UXXXXXXXX'') a unicode character with the code {{XXXX}}. -The latter is encoded in UTF-8 format. +<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> + + +=== 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> -The third argument to {{substring}} is optional and defaults to the length -of the string. + #cs... -=== Number/String conversions +Read the next expression in case-sensitive mode (regardless of the current global setting). -The optional "base" argument to {{string->number}} and {{number->string}} -may be any integral value from 2 to 36. +=== Case Insensitive Expression -=== {{force}} +<read>#ci</read> -{{force}} called with an argument that is not a promise returns -that object unchanged. Captured continuations can be safely invoked -inside before- and after-thunks of a {{dynamic-wind}} form and -execute in the outer dynamic context of the {{dynamic-wind}} form. + #ci... -'''Implicit''' non-multival continuations accept multiple values by discarding all -but the first result. Zero values result in the continuation receiving an -unspecified value. Note that this slight relaxation of the behaviour of -returning mulitple values to non-multival continuations does not apply to -explicit continuations (created with {{call-with-current-continuation}}). +Read the next expression in case-insensitive mode (regardless of the current global setting). -=== {{eval}} +=== Conditional Expansion -The second argument to {{eval}} is optional and -defaults to the value of {{(interaction-environment)}}. -{{scheme-report-environment}} and {{null-environment}} accept -an optional 2nd parameter: if not {{#f}} (which is the default), -toplevel bindings to standard procedures are mutable and new toplevel -bindings may be introduced. +<read>#+</read> -=== Optional arguments for port-related procedures + #+FEATURE EXPR -If the procedures {{current-input-port}} and -{{current-output-port}} are called with an argument (which should -be a port), then that argument is selected as the new current input- and -output-port, respectively. The procedures {{open-input-file}}, -{{open-output-file}}, {{with-input-from-file}}, -{{with-output-to-file}}, {{call-with-input-file}} and -{{call-with-output-file}} accept an optional second (or third) -argument which should be one or more keywords, if supplied. These -arguments specify the mode in which the file is opened. Possible -values are the keywords {{#:text}}, {{#:binary}} or -{{#:append}}. +Rewrites to -=== {{exit}} + (cond-expand (FEATURE EXPR) (else)) -The {{exit}} procedure exits a program right away and does ''not'' invoke pending {{dynamic-wind}} thunks. +and performs the feature test at macroexpansion time. Therefore, it may not +work as expected when used within a macro form. --- Previous: [[Deviations from the standard]] -Next: [[Non-standard read syntax]] +Next: [[Included modules]] diff --git a/manual/Getting started b/manual/Getting started index c569d8a9..98ceb8ab 100644 --- a/manual/Getting started +++ b/manual/Getting started @@ -19,7 +19,7 @@ writing and running small CHICKEN programs. === Scheme Scheme is a member of the Lisp family of languages, of which Common -Lisp and Emacs Lisp are the other two widely-known members. As with +Lisp, Emacs Lisp and Clojure are other widely-known members. As with Lisp dialects, Scheme features * a wide variety of programming paradigms, including imperative, functional, and object-oriented @@ -29,7 +29,9 @@ Lisp dialects, Scheme features In contrast to Common Lisp, Scheme is very minimal, and tries to include only those features absolutely necessary in programming. In contrast to Emacs Lisp, Scheme is not anchored into a single program -(Emacs), and has a more modern language design. +(Emacs), and has a more modern and elegant language design. In contrast +to Clojure, Scheme provides only a very minimal set of concepts but allows +them to be used in very general ways with few restrictions. Scheme is defined in a document called ''The Revised^5 Report on the Algorithmic Language Scheme'', or ''R5RS'' for short. (Yes, it really @@ -37,8 +39,13 @@ has been revised five times, so an expanded version of its name would be ''The Revised Revised Revised Revised Revised Report''.) A newer report, ''R6RS'', was released in 2007, but this report has attracted considerable -controversy, and not all Scheme implementations will be made compliant -with it. CHICKEN essentially complies with R5RS. +controversy, and a number of Scheme implementations have chosen +not to be compliant +with it. Yet another report was released in 2013 ("R7RS"), that was +less ambitious than R6RS and more minimal. + +CHICKEN fully complies with R5RS and, by using a separately available +extension also with the "R7RS small" language. Even though Scheme is consciously minimalist, it is recognized that a language must be more than a minimal core in order to be @@ -52,18 +59,12 @@ A good starting point for Scheme knowledge is [[http://www.schemers.org]]. There you will find the defining reports, FAQs, lists of useful books and other resources, and the SRFIs. -The CHICKEN community is at present developing tutorials for -programmers who are new to Scheme but experienced with Python, Ruby, -or other languages. These can be found on the CHICKEN wiki. - === CHICKEN -CHICKEN is an implementation of Scheme that has many advantages. - CHICKEN Scheme combines an optimising compiler with a reasonably fast -interpreter. It supports almost all of R5RS and the important SRFIs. +interpreter. It supports almost all of R7RS and the important SRFIs. The compiler generates portable C code that supports tail recursion, -first-class continuations, and lightweight threads, and the interface to +first-class continuations and lightweight threads, and the interface to and from C libraries is flexible, efficient, and easy to use. There are hundreds of contributed CHICKEN libraries that make the programmer's task easier. The interpreter allows interactive use, fast prototyping, @@ -78,18 +79,18 @@ and participates actively. CHICKEN includes -* a Scheme interpreter that supports almost all of R5RS Scheme, with +* a Scheme interpreter that supports all of R5(7)RS Scheme, with only a few relatively minor omissions, and with many extensions * a compatible compiler whose target is C, thus making porting to new machines and architectures relatively straightforward -** the C support allows Scheme code to include `embedded' C code, - thus making it relatively easy to invoke host OS or library +* the C support allows Scheme code to include `embedded' C code, + thus making it easyto invoke host OS or library functions * a framework for language extensions, library modules that broaden the functionality of the system This package is distributed under the '''BSD license''' and as such is free -to use and modify. +to use and modify as long as the original authors are acknowledged. Scheme cognoscenti will appreciate the method of compilation and the design of the runtime-system, which follow closely Henry Baker's @@ -97,26 +98,24 @@ design of the runtime-system, which follow closely Henry Baker's CONS Its Arguments, Part II: Cheney on the M.T.A.]] paper and expose a number of interesting properties. -* Consing (creation of data on the heap) is relatively inexpensive, - because a generational garbage collection scheme is used, in which - short-lived data structures are reclaimed extremely quickly. +* Consing (creation of data on the heap) is inexpensive, + because a generational garbage collection scheme is used in combination + with allocating on the C stack, in which short-lived data structures are reclaimed + extremely quickly. -* Moreover, {{call-with-current-continuation}} is practically for free - and CHICKEN does not suffer under any performance penalties if +* Moreover, {{call-with-current-continuation}} involves only minimal + overhead and CHICKEN does not suffer under any performance penalties if first-class continuations are used in complex ways. -The generated C code is fully tail-recursive. +The generated C code fully supports tail-call optimization (TCO). Some of the features supported by CHICKEN: -* SRFIs 0, 1, 2, 4, 6, 8-18, 23, 26, 28, 30, 31, 39, 46, 55, 61, 62, 69, 85, 88 and 98. * Lightweight threads based on first-class continuations * Record structures * Extended comment- and string-literal syntaxes * Libraries for regular expressions, string handling * UNIX system calls and extended data structures -* Create interpreted or compiled shell scripts written in Scheme for - UNIX or Windows * Compiled C files can be easily distributed * Allows the creation of fully self-contained statically linked executables * On systems that support it, compiled code can be loaded dynamically @@ -124,14 +123,13 @@ Some of the features supported by CHICKEN: CHICKEN has been used in many environments ranging from embedded systems through desktop machines to large-scale server deployments. -The number of language extensions, or '''eggs''', is constantly growing. +The number of language extensions, or '''eggs''', is constantly growing: * extended language features * development tools, such as documentation generators, debugging, and automated testing libraries * interfaces to other languages such as Java, Python, and Objective-C -* interfaces to database systems, GUIs, and other large-scale - libraries, +* interfaces to database systems, GUIs, and other libraries, * network applications, such as servers and clients for ftp, smtp/pop3, irc, and http * web servers and related tools, including URL parsing, HTML @@ -142,11 +140,11 @@ This chapter provides you with an overview of the entire system, with enough information to get started writing and running small Scheme programs. -=== CHICKEN repositories, websites, and community +=== CHICKEN repositories, websites and community The master CHICKEN website is [[http://www.call-cc.org]]. Here you can find -basic information about CHICKEN, downloads, and pointers to other key +basic information about CHICKEN, downloads and pointers to other key resources. The CHICKEN wiki ([[http://wiki.call-cc.org]]) contains the most @@ -154,7 +152,8 @@ current version of the User's manual, along with various tutorials and other useful documents. The list of eggs is at [[http://wiki.call-cc.org/egg-index|http://wiki.call-cc.org/egg-index]]. -A very useful search facility for questions about CHICKEN is found at +A very useful search facility for questions about procedures and syntax +available for CHICKEN can be found at [[http://api.call-cc.org]]. The CHICKEN issue tracker is at [[http://bugs.call-cc.org]]. @@ -185,25 +184,23 @@ can pretty much ignore the C compiler once you have installed it.) installed as part of the basic operating system, or should be available through the package management system (e.g., APT, Synaptic, RPM, or Yum, depending upon your Linux distribution). -* On Macintosh OS X, you will need the XCode tools, which were shipped - on the OS X DVD with older versions of the operating system, and are - installable from the App Store with recent versions of the operating - system. +* On Macintosh OS X, you will need the XCode tools, which are + installable from the App Store. * On Windows, you have three choices: -** Cygwin ([[http://sourceware.org/cygwin/]]) provides a relatively +* Cygwin ([[http://sourceware.org/cygwin/]]) provides a relatively full-featured Unix environment for Windows. CHICKEN works substantially the same in Cygwin and Unix. -** The GNU Compiler Collection has been ported to Windows, in the +* The GNU Compiler Collection has been ported to Windows, in the MinGW system ([[http://mingw.sourceforge.net]]). Unlike Cygwin, executables produced with MinGW do not need the Cygwin DLLs in order to run. MSYS is a companion package to MinGW; it provides a minimum Unix-style development/build environment, again ported from free software. -*** You can build CHICKEN either with MinGW alone or with MinGW plus +* You can build CHICKEN either with MinGW alone or with MinGW plus MSYS. Both approaches produce a CHICKEN built against the mingw headers and libraries. The only difference is the environment where you actually run make. - {{Makefile.mingw}} is can be used in {{cmd.exe}} with the version of make + {{Makefile.mingw}} can be used in {{cmd.exe}} with the version of make that comes with mingw. {{Makefile.mingw-msys}} uses unix commands such as {{cp}} and {{rm}}. The end product is the same. @@ -220,60 +217,15 @@ for information about how to obtain them. The simplest development environment is a text editor and terminal window (Windows: Command Prompt, OSX: Terminal, Linux/Unix: xterm) for -using the interpreter and/or calling the compiler. If you install one +using the interpreter and/or invoking the compiler. If you install one of the line editing extensions (e.g., [[/egg/readline|readline]], -[[/egg/parley|parley]], [[/egg/linenoise|linenoise]], you have some +[[/egg/parley|parley]], [[/egg/linenoise|linenoise]]), you have some useful command line editing features in the interpreter (e.g., Emacs or vi-compatible line editing, customization). -You will need a text editor that knows Scheme; it's just too painful -with editors that don't do parenthesis matching and proper -indentation. Some editors allow you to execute Scheme code directly in -the editor. This makes programming very interactive: you can type in a -function and then try it right away. This feature is very highly -recommended. - -As programmers have very specific tastes about editors, the editors -listed here are shown in alphabetic order. We aren't about to tell you -which editor to use, and there may be editors not shown here that -might satisfy your needs. We would be very interested in reports of -other editors that have been used with CHICKEN, especially those that -support interactive evaluation of forms during editing. Pointers to -these (and to any editor customization files appropriate) should be -put on the CHICKEN wiki, and will likely be added to future editions -of this manual. (We have had a request for editors that support -proportional fonts, in particular.) - -* Emacs ([[http://www.gnu.org/software/emacs]]) is an -extensible, customizable, self-documenting editor available for -Linux/Unix, Macintosh, and Windows systems; See -[[http://wiki.call-cc.org/emacs|http://wiki.call-cc.org/emacs]] -for more information about the available options. - -* SciTE ([[http://scintilla.sourceforge.net/SciTE.html]]), -unlike Emacs or Vim, follows typical graphical UI design conventions -and control-key mappings, and for simple tasks is as familiar and -easy to use as Notepad, KEdit, TeachText etc. However it has many -programming features such as multiple open files, syntax -highlighting for a large number of languages (including Lisps), -matching of brackets, ability to fold sections of code based on the -matched brackets, column selections, comment/uncomment, and the -ability to run commands in the same directory as the current file -(such as make, grep, etc.) SciTE is written with the GTK toolkit -and is portable to any GTK platform, including Windows, Linux and -MacOS. It uses the Scintilla text-editing component, which lends -itself well to embedding within other IDEs and graphical toolkits. -It does not have any other Scheme-specific features, but being -open-source and modular, features like auto-formatting of -S-expressions could be added. The syntax highlighting can be -configured to use different fonts for different types of syntax, -including proportional fonts. - -* Vim ([[http://www.vim.org]]) is a highly configurable text -editor built to enable efficient and fast text editing. It is an -improved version of the vi editor distributed with most UNIX systems. -Vim comes with generic Lisp (and therefore Scheme) editing capabilities -out of the box. See [[/Vim]] for a few tips on using Vim with CHICKEN. +It will be helpful to use a text editor that knows Scheme; it can be painful +with editors that don't do parenthesis matching and automatic +indentation. In the rest of this chapter, we'll assume that you are using an editor of your choice and a regular terminal window for executing your @@ -283,16 +235,13 @@ CHICKEN code. To invoke the CHICKEN interpreter, you use the {{csi}} command. - $ csi - CHICKEN - (c) 2008-2016, The CHICKEN Team + (c) 2008-2018, The CHICKEN Team (c) 2000-2007, Felix L. Winkelmann - Version 4.11.0 (rev ce980c4) - linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ] - compiled 2016-05-28 on yves.more-magic.net (Linux) - + Version 5.0.0 (rev 6653dce) + linux-unix-gnu-x86-64 [ 64bit dload ptables ] + #;1> This brings up a brief banner, and then the prompt. You can use this @@ -344,9 +293,9 @@ Next create the scheme code in a file called ''quickrep.scm'' with the following little program: <enscript highlight=scheme> - -(import irregex) ; irregex, the regular expression library, is one of the - ; libraries included with CHICKEN. +;; irregex, the regular expression library, is one of the +;; libraries included with CHICKEN. +(import (chicken irregex)) (define (process-line line re rplc) (irregex-replace/all re line rplc)) @@ -391,6 +340,8 @@ There are several reasons you might want to compile your code. * You might want to deploy an application onto machines where the users aren't expected to have CHICKEN installed: compiled applications can be self-contained. +* Compiled code can access external libraries written in lower-level + languages that follow the C calling convention. The CHICKEN compiler is provided as the command {{chicken}}, but in almost all cases, you will want to use the {{csc}} command @@ -402,16 +353,11 @@ C# compiler. There are a number of ways of sorting this out, of which the simplest is to rename one of the two tools, and/or to organize your {{PATH}} according to the task at hand.) -Compiled code can be intermixed with interpreted code on systems that -support dynamic loading, which includes modern versions of *BSD, -Linux, Mac OS X, Solaris, and Windows. - We can compile our factorial function, producing a file named -{{fact.so}} (''shared object'' in Linux-ese, the same file type is -used in OS X and Windows, rather than {{dylib}} or {{dll}}, -respectively). +{{fact.so}} (''shared object'' in Linux-ese, the same file extension is +used in Windows, rather than {{dll}}) - chicken$ csc -dynamic fact.scm + chicken$ csc -shared fact.scm chicken$ csi -quiet #;1> (load "fact.so") ; loading fact.so ... @@ -423,6 +369,8 @@ executable. Here's a program that tells you whether its argument is a palindrome. <enscript highlight=scheme> +(import (chicken process-context)) ; for "command-line-arguments" + (define (palindrome? x) (define (check left right) (if (>= left right) @@ -430,6 +378,7 @@ palindrome. (and (char=? (string-ref x left) (string-ref x right)) (check (add1 left) (sub1 right))))) (check 0 (sub1 (string-length x)))) + (let ((arg (car (command-line-arguments)))) (display (string-append arg @@ -460,6 +409,7 @@ involve separated namespaces; namespaces can be implemented by <enscript highlight=scheme> ;;; Library pal-proc.scm (declare (unit pal-proc)) + (define (palindrome? x) (define (check left right) (if (>= left right) @@ -475,6 +425,9 @@ module. <enscript highlight=scheme> ;;; Client pal-user.scm (declare (uses pal-proc)) + +(import (chicken process-context)) + (let ((arg (car (command-line-arguments)))) (display (string-append arg @@ -493,34 +446,23 @@ into one command.) $ ./pal-separate level level is a palindrome +The "unit" mechanism is relatively low-level and requires some +familiarity with underlying mechanism used to manage compilation +units. See [[Units and linking model]] for more information. + === Installing an egg Installing eggs is quite straightforward on systems that support -dynamic loading (again, that would include *BSD, Linux, Mac OS X, +dynamic loading (that would include *BSD, Linux, Mac OS X, Solaris, and Windows). The command {{chicken-install}} will fetch an egg from the master CHICKEN repository, and install it on your local system. In this example, we install the {{uri-common}} egg, for parsing -Uniform Resource Identifiers. The installation produces a lot of -output, which we have edited for space. +Uniform Resource Identifiers. $ chicken-install uri-common - retrieving ... - resolving alias `kitten-technologies' to: http://chicken.kitten-technologies.co.uk/henrietta.cgi - connecting to host "chicken.kitten-technologies.co.uk", port 80 ... - requesting "/henrietta.cgi?name=uri-common&mode=default" ... - reading response ... - [...] - /usr/bin/csc -feature compiling-extension -setup-mode -s -O2 uri-common.scm -j uri-common - /usr/bin/csc -feature compiling-extension -setup-mode -s -O2 uri-common.import.scm - cp -r uri-common.so /usr/lib/chicken/5/uri-common.so - chmod a+r /usr/lib/chicken/5/uri-common.so - cp -r uri-common.import.so /usr/lib/chicken/5/uri-common.import.so - chmod a+r /usr/lib/chicken/5/uri-common.import.so - chmod a+r /usr/lib/chicken/5/uri-common.setup-info - {{chicken-install}} connects to a mirror of the egg repository and retrieves the egg contents. If the egg has any uninstalled dependencies, it recursively installs them. Then it builds the egg @@ -530,7 +472,7 @@ local CHICKEN repository. Now we can use our new egg. #;1> (import uri-common) - ; loading /usr/lib/chicken/5/uri-common.import.so ... + ; loading /usr/lib/chicken/9/uri-common.import.so ... ; [... other loaded files omitted for clarity ...] #;2> (uri-host (uri-reference "http://www.foobar.org/blah")) @@ -540,7 +482,7 @@ Now we can use our new egg. Because CHICKEN compiles to C, and because a foreign function interface is built into the compiler, interfacing to a C library is -quite straightforward. This means that nearly any facility available +quite straightforward. This means that any facility available on the host system is accessible from CHICKEN, with more or less work. @@ -566,6 +508,8 @@ real example would take far too much space here.) Now we can call this function from CHICKEN. ;;; fib-user.scm + (import (chicken foreign) (chicken format)) + #> extern int fib(int n); <# @@ -593,4 +537,4 @@ using the [[/egg/bind|bind egg]]. Back to [[The User's Manual]] -Next: [[Basic mode of operation]] +Next: [[Using the interpreter]] diff --git a/manual/Included modules b/manual/Included modules new file mode 100644 index 00000000..adf55e9d --- /dev/null +++ b/manual/Included modules @@ -0,0 +1,60 @@ +[[tags: manual]] +[[toc:]] + +== Included modules + +The CHICKEN system comes shipped with several modules. This section +of the manual provides a reference guide to all the modules that are +part of a standard installation. On top of these, you can install +additional modules through the [[Extensions|eggs]] system. + +* [[Module scheme]] : Standard Scheme procedures and syntax +* [[Module r5rs]] : Standard Scheme procedures and syntax (alias for scheme) +* [[Module r4rs]] : Standard procedures and syntax of an old Scheme report +* [[Module srfi-4]] : Homogeneous numeric vector datatypes +* [[Module (chicken base)]] : Core procedures and macros +* [[Module (chicken bitwise)]] : Bitwise manipulation on integers +* [[Module (chicken blob)]] : Unstructured byte data +* [[Module (chicken condition)]] : Raising and handling of exceptions, manipulation of condition objects +* [[Module (chicken continuation)]] : Feeley's "a better API for continuations" +* [[Module (chicken csi)]] : Features specific to {{csi}} +* [[Module (chicken errno)]] : Accessing the C "errno" variable +* [[Module (chicken eval)]] : Evaluation hooks +* [[Module (chicken file)]] : High-level API for file system manipulations +* [[Module (chicken file posix)]] : POSIX-specific file manipulations +* [[Module (chicken fixnum)]] : Operations on "fixnums" (small integers) +* [[Module (chicken flonum)]] : Operations on "flonums" (floating-point numbers) +* [[Module (chicken foreign)]] : Accessing C and C++ code and data +* [[Module (chicken format)]] : String formatting procedures +* [[Module (chicken gc)]] : Interacting with the garbage collector +* [[Module (chicken io)]] : Reading and writing to files and other ports +* [[Module (chicken irregex)]] : Regular expressions +* [[Module (chicken keyword)]] : Operations on keyword objects +* [[Module (chicken load)]] : Loading code from files +* [[Module (chicken locative)]] : Accessing pointer-like location objects +* [[Module (chicken memory)]] : Low-level memory operations +* [[Module (chicken memory representation)]] : Low-level operations on the memory representation of Scheme objects +* [[Module (chicken module)]] : Defining modules +* [[Module (chicken pathname)]] : Manipulating path names +* [[Module (chicken platform)]] : Information about the platform your code is running on +* [[Module (chicken plist)]] : Symbol property lists +* [[Module (chicken port)]] : Manipulating port objects +* [[Module (chicken pretty-print)]] : Pretty-printing s-expressions +* [[Module (chicken process)]] : Starting subprocesses and communicating with them +* [[Module (chicken process signal)]] : Sending and receiving POSIX process signals +* [[Module (chicken process-context)]] : Accessing the context (arguments, environment etc) of the current process +* [[Module (chicken process-context posix)]] : POSIX-specific context access +* [[Module (chicken random)]] : Generating pseudo-random number +* [[Module (chicken read-syntax)]] : Creating syntactic extensions to the reader +* [[Module (chicken repl)]] : Creating a Read-Eval-Print Loop +* [[Module (chicken sort)]] : Sorting lists and vectors +* [[Module (chicken string)]] : String operations +* [[Module (chicken syntax)]] : Creating syntactic extensions (macros) +* [[Module (chicken tcp)]] : Connecting over the network via TCP +* [[Module (chicken time)]] : Fetching information about the current time +* [[Module (chicken time posix)]] : Manipulating POSIX time + +--- +Previous: [[Extensions to the standard]] + +Next: [[Interface to external functions and variables]] diff --git a/manual/Interface to external functions and variables b/manual/Interface to external functions and variables index 50bbd089..4475704f 100644 --- a/manual/Interface to external functions and variables +++ b/manual/Interface to external functions and variables @@ -4,19 +4,17 @@ The macros in this section, such as {{define-foreign-type}} and {{define-external}}, are available in the {{foreign}} import library. To access them: - (import foreign) + (import (chicken foreign)) Note: Using the foreign library directly from the interpreter or the REPL will not work. * [[Accessing external objects]] * [[Foreign type specifiers]] * [[Embedding]] -* [[Callbacks]] -* [[Locations]] -* [[Other support procedures]] -* [[C interface]] +* [[C interface]] +* [[Data representation]] --- -Previous: [[Debugging]] +Previous: [[Included modules]] -Next: [[Extensions]] +Next: [[Modules]] diff --git a/manual/Module (chicken base) b/manual/Module (chicken base) new file mode 100644 index 00000000..4d8396c9 --- /dev/null +++ b/manual/Module (chicken base) @@ -0,0 +1,1453 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken base) + +Core procedures and macros, acting as basic extensions to the R5RS +standard and other essential features. + +This module is used by default, unless a program is compiled with +the {{-explicit-use}} option. + +=== Numeric predicates + +These allow you to make a more precise differentiation between number +types and their properties, not provided by R5RS. + +==== 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. + +This procedure is compatible with the definition from the R7RS +{{(scheme base)}} library. + +==== 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. + +==== 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. + +This procedure is compatible with the definition from the R7RS +{{(scheme inexact)}} library. + +==== 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. + +This procedure is compatible with the definition from the R7RS +{{(scheme inexact)}} library. + +==== 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. + +This procedure is compatible with the definition from the R7RS +{{(scheme inexact)}} library. + +==== 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. + + +=== Arithmetic + +==== add1/sub1 + +<procedure>(add1 N)</procedure> +<procedure>(sub1 N)</procedure> + +Adds/subtracts 1 from {{N}}. + + +==== 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 definition from the R7RS +{{(scheme base)}} library. + +==== 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}}. + + +==== 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. + +==== 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. + + +=== Lazy evaluation + +==== delay-force + +<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. + +This special form is compatible with the definition from the R7RS +{{(scheme lazy)}} library. + +See the description of force under +[[Module scheme#control-features|Control features]] in the "scheme" +module documentation for a more complete description of delayed +evaluation. + +For more information regarding the unbounded build-up of space, see +the [[http://srfi.schemers.org/srfi-45/srfi-45.html|SRFI-45]] +rationale. + +==== make-promise + +<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 compatible with the definition from the R7RS +{{(scheme lazy)}} library. + + +==== promise? + +<procedure>(promise? X)</procedure> + +Returns {{#t}} if {{X}} is a promise returned by {{delay}}, or +{{#f}} otherwise. + +This procedure is compatible with the definition from the R7RS +{{(scheme lazy)}} library. + + +=== Input/Output + +==== 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 +[[Module (chicken port)#set-buffering-mode!|{{set-buffering-mode!}}]] +if you need a different behaviour. + +==== 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. + + +=== 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"}}. + + +==== 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. + + +==== warning + +<procedure>(warning STRING EXP ...)</procedure> + +Displays a warning message (if warnings are enabled with +{{enable-warnings}}) and continues execution. + + +=== 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. + + +==== 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). + + +==== 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> + + +==== 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> + + +==== 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?}}. + + +==== tail? + +<procedure>(tail? X LIST)</procedure> + +Returns true if {{X}} is one of the tails (cdr's) of {{LIST}}. + + +=== 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)}} + +This procedure is compatible with the definition from the R7RS +{{(scheme base)}} library. + +==== 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. + + +=== Combinators + + +==== 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}}. + + +=== 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> + + +=== 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}}. + +This procedure is compatible with the definition from the R7RS +{{(scheme base)}} library. + +=== 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}}. + + +=== 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. + + +=== 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]] + +This special form is also compatible with the definition from the R7RS +{{(scheme case-lambda)}} library. + +==== 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}}. + +This special form is compatible with the definition from the R7RS +{{(scheme base)}} library. + +==== 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}}. + +This special form is compatible with the definition from the R7RS +{{(scheme base)}} library. + +==== 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 special form implements +[[http://srfi.schemers.org/srfi-11/srfi-11.html|SRFI-11]], and it is +also compatible with the definition from the R7RS {{(scheme base)}} +library. + + +==== 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]] and is also +compatible with the definition from the R7RS {{(scheme base)}} +library. + +<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> + + +==== 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}}. + +==== nth-value + +<macro>(nth-value N EXP)</macro> + +Returns the {{N}}th value (counting from zero) of the values returned +by expression {{EXP}}. + + +=== 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]], which +is also standardized by R7RS. + + +==== 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. + +This special form is compatible with the definition from the R7RS +{{(scheme base)}} library. + +==== 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. + +This special form is compatible with the definition from the R7RS +{{(scheme base)}} library. + +=== 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. + + +=== 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). + +This special form is also compatible with the definition from the R7RS +{{(scheme base)}} library. + + +==== 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 + +==== 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. + + +=== 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>=?}}). + +=== Process shutdown + +==== 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}}. + + +==== 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. + + +=== 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. + +Note that this handler is ''not'' invoked when {{emergency-exit}} is +used. + + +=== 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. + + +==== 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. + + +=== System interface + + +==== 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. + + +=== Ports + +==== 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. + + +=== File Input/Output + +==== flush-output + +<procedure>(flush-output [PORT])</procedure> + +Write buffered output to the given output-port. {{PORT}} defaults +to the value of {{(current-output-port)}}. + +=== Port predicates + +==== 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? + +<procedure>(port? X)</procedure> + +Returns {{#t}} if {{X}} is a port object or {{#f}} +otherwise. + + +=== 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}}. + + +==== 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}}. + + +--- +Previous: [[Module srfi-4]] + +Next: [[Module (chicken bitwise)]] diff --git a/manual/Module (chicken bitwise) b/manual/Module (chicken bitwise) new file mode 100644 index 00000000..9932c299 --- /dev/null +++ b/manual/Module (chicken bitwise) @@ -0,0 +1,39 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken bitwise) + +Binary integer operations are provided by the {{(chicken bitwise)}} +module. + +=== Binary integer operations + +<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->boolean + +<procedure>(bit->boolean 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. + +--- +Previous: [[Module (chicken base)]] + +Next: [[Module (chicken blob)]] diff --git a/manual/Module (chicken blob) b/manual/Module (chicken blob) new file mode 100644 index 00000000..48d7a388 --- /dev/null +++ b/manual/Module (chicken blob) @@ -0,0 +1,55 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken blob) + +This module contains procedures for dealing with "blobs". Blobs are +unstructured byte arrays (basically "binary strings"). You can't do +much with them, but they allow conversion to and from +[[Module srfi-4|SRFI-4 number vectors]] which define how to access a +blob's byte contents. + +=== 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. + + +--- +Previous: [[Module (chicken bitwise)]] + +Next: [[Module (chicken condition)]] diff --git a/manual/Module (chicken condition) b/manual/Module (chicken condition) new file mode 100644 index 00000000..f9858eeb --- /dev/null +++ b/manual/Module (chicken condition) @@ -0,0 +1,452 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken condition) + +This module provides various procedures and special forms for raising +and handling exceptions with "condition objects". Condition objects +provide a structured and composable way to encode the kind of +exception that took place, and provide the necessary context. + +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. + +There is also a {{srfi-12}} or {{(srfi 12)}} module which only +includes the standard procedures and macros from the SRFI document, +without the CHICKEN extensions. {{(chicken condition)}} offers the +complete set of procedures and macros, both CHICKEN-specific and +standard SRFI-12. + + +== 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 + +==== condition-case + +<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> + +==== get-condition-property + +<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) + +==== condition + +<procedure>(condition LST1 LST2 ...)</procedure> + +This is a more convenient constructor for conditions. Each of +{{LST1}}, {{LST2}} etc is a list of the following form: + + (KIND PROPERTY1 VALUE1 PROPERTY2 VALUE2 ...) + +In other words, the following: + + (signal (condition '(exn location foo message "hi") '(file bar 1))) + +is equivalent to the SRFI-12 code: + + (signal (make-composite-condition + (make-property-condition 'exn 'location 'foo 'message "hi") + (make-property-condition 'file 'bar 2))) + + +==== condition->list + +<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. + + +==== 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:"}}. + + + +== 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 + +==== current-exception-handler + +<parameter>(current-exception-handler [PROCEDURE])</parameter><br> + +Sets or returns the current exception handler, a procedure of one +argument, the exception object. + +==== with-exception-handler + +<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. + +==== handle-exceptions + +<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 + +==== abort + +<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. + +==== signal + +<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 + +==== condition? + +<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. + +==== make-property-condition + +<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. + +==== make-composite-condition + +<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. + +==== condition-predicate + +<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. + +==== condition-property-accessor + +<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: [[Module (chicken blob)]] + +Next: [[Module (chicken continuation)]] diff --git a/manual/Module (chicken continuation) b/manual/Module (chicken continuation) new file mode 100644 index 00000000..7018d3c7 --- /dev/null +++ b/manual/Module (chicken continuation) @@ -0,0 +1,61 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken continuation) + +This module 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: [[Module (chicken condition)]] + +Next: [[Module (chicken csi)]] diff --git a/manual/Module (chicken csi) b/manual/Module (chicken csi) new file mode 100644 index 00000000..0518ed25 --- /dev/null +++ b/manual/Module (chicken csi) @@ -0,0 +1,53 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken csi) + +This module provides procedures to access features specific to +the {{csi}} interactive interpreter. + +=== toplevel-command + +<procedure>(toplevel-command SYMBOL PROC [HELPSTRING])</procedure> + +Defines or redefines a toplevel interpreter command which can be invoked by entering +{{,SYMBOL}}. {{PROC}} will be invoked when the command is entered and may +read any required argument via {{read}} (or {{read-line}}). If the optional +argument {{HELPSTRING}} is given, it will be listed by the {{,?}} command. + + +=== set-describer! + +<procedure>(set-describer! TAG PROC)</procedure> + +Sets a custom description handler that invokes {{PROC}} when the +{{,d}} command is invoked with a record-type object that has the type +{{TAG}} (a symbol). {{PROC}} is called with two arguments: the object +to be described and an output-port. It should write a possibly useful +textual description of the object to the passed output-port. For +example: + + #;1> (define-record-type point (make-point x y) point? + (x point-x) + (y point-y)) + #;2> (set-describer! 'point + (lambda (pt o) + (with-output-to-port o + (lambda () + (print "a point with x=" (point-x pt) " and y=" (point-y pt)))))) + #;3> ,d (make-point 1 2) + a point with x=1 and y=2 + + +=== editor-command + +<parameter>editor-command</parameter> + +Holds the name of an editor that should be used when the toplevel +command {{,e}} is used. + + +--- +Previous: [[Module (chicken continuation)]] + +Next: [[Module (chicken errno)]] diff --git a/manual/Module (chicken errno) b/manual/Module (chicken errno) new file mode 100644 index 00000000..69ae3237 --- /dev/null +++ b/manual/Module (chicken errno) @@ -0,0 +1,60 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken errno) + +This module provides access to the standard C {{errno}} value. + +Be careful, if you're using threads, {{errno}} might be clobbered as +soon as another thread calls a C function. To prevent this from +happening, you can add {{(declare (disable-interrupts))}} at the top +of your file, or use the {{-disable-interrupts}} compiler option to +avoid any context switches while a procedure in this file is running. + +=== errno + +<procedure>(errno)</procedure> + +Returns the error code of the last system call. + +=== errno constants + +<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}}. + +''NOTE'': On Windows, {{EWOULDBLOCK}} does not exist. For +consistency, {{errno/wouldblock}} does exist, but it is defined as +zero. + +This does mean that in case there is no error, it looks like the +{{errno/wouldblock}} error is returned. But you have to check the +return code of a system call before accessing {{errno}} anyway, so +this should typically never happen. + +--- +Previous: [[Module (chicken continuation)]] + +Next: [[Module (chicken eval)]] diff --git a/manual/Module (chicken eval) b/manual/Module (chicken eval) new file mode 100644 index 00000000..42ba10c6 --- /dev/null +++ b/manual/Module (chicken eval) @@ -0,0 +1,44 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken eval) + +This module provides a handful of hooks that allow more fine-grained +control over how the standard procedure {{eval}} behaves. + +=== Custom eval handlers + +==== 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. + + +=== Using modules as evaluation environments + +==== module-environment + +<procedure>(module-environment MODULENAME)</procedure> + +Locates the module with the name {{MODULENAME}} and returns an +environment that can be passed as the second argument to {{eval}}. The +evaluated expressions have only access to the bindings that are +visible inside the module. Note that the environment is not mutable. + +If the module is not registered in the current process, +{{module-environment}} will try to locate meta-information about the +module by loading any existing import library with the name +{{MODULENAME.import.[scm|so]}}, if possible. + +In compiled modules, only exported bindings will be visible to +interactively entered code. In interpreted modules all bindings are +visible. + +--- +Previous: [[Module (chicken errno)]] + +Next: [[Module (chicken file)]] diff --git a/manual/Module (chicken file posix) b/manual/Module (chicken file posix) new file mode 100644 index 00000000..06cda7b1 --- /dev/null +++ b/manual/Module (chicken file posix) @@ -0,0 +1,643 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken file posix) + +This module provides various operations on files and directories that +are more POSIX-oriented than the generic higher-level operations from +[[Module (chicken file)]]. + +Note that the following definitions are not all available on non-UNIX +systems like Windows. See below for Windows specific notes. + +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}}. + +'''NOTE''': On native Windows builds (all except cygwin), these are +all defined as zero. The {{file-control}} procedure to use these with +is also unimplemented and will raise an error when called. + +==== File positions + +<constant>seek/cur</constant><br> +<constant>seek/set</constant><br> +<constant>seek/end</constant><br> + +File positions for {{set-file-position!}}. + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), +{{open/noctty}}, {{open/nonblock}}, {{open/fsync}} and {{open/sync}} +are defined as zero because the corresponding flag doesn't exist. +This means you can safely add these to any set of flags when opening a +file or pipe, but it simply won't have an effect. + +==== Open flags for create-pipe + +<constant>open/noinherit</constant> + +This variable is a mode value for {{create-pipe}}. Useful when +spawning a child process on Windows. On UNIX it is defined as zero, +so you can safely pass it there, but it will have no effect. + + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), +{{perm/isvtx}}, {{perm/isuid}} and {{perm/isgid}} are defined as zero +because the corresponding permission doesn't exist. This means you +can safely add these to any set of flags when opening a file or pipe, +but it simply won't have an effect. + + +=== Information about files + +==== directory? + +<procedure>(directory? FILE)</procedure> + +Returns {{#t}} if {{FILE}} designates a directory. Otherwise, it returns {{#f}}. +{{FILE}} may be a pathname, a file-descriptor or a port object. + + +==== 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. + +==== 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}}. + +==== 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. + + +=== 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> + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== fifo? + +<procedure>(fifo? FILE)</procedure> + +Returns {{#t}} if {{FILE}} names a FIFO. {{FILE}} may be a filename, +a port or a file-descriptor. + + +=== 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> + +Returns time (in seconds) of the last access, inode change or content +modification of {{FILE}}, respectively. {{FILE}} may be a filename, a +file-descriptor or a file-backed port. If the file does not exist, an +error is signaled. + +==== set-file-times! + +<procedure>(set-file-times! FILE [MTIME [ATIME]])</procedure> + +Sets the time of last modification {{MTIME}} and/or time of last +access {{ATIME}} (in seconds) for {{FILE}}. {{FILE}} may be a +filename, a file-descriptor or a file-backed port. If the file does +not exist, an error is signaled. + +If neither {{MTIME}} nor {{ATIME}} is supplied, the current time is +used. If only {{MTIME}} is supplied, {{ATIME}} will be set to the +same value. If an argument is {{#f}}, it will not be changed. + +Consequently, if only {{MTIME}} is passed and it is {{#f}}, {{ATIME}} +is assumed to be {{#f}} as well and neither will be changed. + + +==== 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. + +==== file-owner + +<procedure>(file-owner FILE)</procedure> + +Returns the user-id of {{FILE}} (an exact integer). {{FILE}} may be a +filename, a file-descriptor or a port object. + +==== set-file-owner! + +<procedure>(set-file-owner! FILE UID)</procedure> +<procedure>(set! (file-owner FILE) UID)</procedure> + +Changes the ownership of {{FILE}} to user-id {{UID}} (which should be +an exact integer) using the {{chown()}} system call. {{FILE}} may be +a filename, a file-descriptor or a port object. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== file-group + +<procedure>(file-group FILE)</procedure> + +Returns the group-id of {{FILE}}. {{FILE}} may be a filename, a +file-descriptor or a port object. + +==== set-file-group! + +<procedure>(set-file-group! FILE GID)</procedure> +<procedure>(set! (file-group FILE) GID)</procedure> + +Changes the group ownership of {{FILE}} to group-id {{GID}} (which +should be an exact integer) using the {{chgrp()}} system call. +{{FILE}} may be a filename, a file-descriptor or a port object. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + + +==== 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. + +==== set-file-permissions! + +<procedure>(set-file-permissions! FILE MODE)</procedure> +<procedure>(set! (file-permissions FILE) MODE)</procedure> + +Changes the current permission bits for {{FILE}} to {{MODE}} using the +{{chmod()}} system call. The {{perm/...}} variables contain the +various permission bits and can be combinded with the {{bitwise-ior}} +procedure. {{FILE}} may be a filename, a file-descriptor or a port +object, {{MODE}} should be a fixnum. + + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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)}} + + +==== 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. + + +=== Hard and symbolic links + +==== file-link + +<procedure>(file-link OLDNAME NEWNAME)</procedure> + +Creates a hard link from {{OLDNAME}} to {{NEWNAME}} (both strings). + + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + + +=== 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 {{()}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + + +=== Record locking + +These procedures are all unsupported on native Windows builds (all +except cygwin). + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== file-unlock + +<procedure>(file-unlock LOCK)</procedure> + +Unlocks the previously locked portion of a file given in {{LOCK}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +--- +Previous: [[Module (chicken file)]] + +Next: [[Module (chicken fixnum)]] + diff --git a/manual/Module (chicken file) b/manual/Module (chicken file) new file mode 100644 index 00000000..8f5a6868 --- /dev/null +++ b/manual/Module (chicken file) @@ -0,0 +1,191 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken file) + +This module provides various generic operations on files and +directories. For more specific operations, see also +[[Module (chicken file posix)]]. + +All errors related to failing file-operations will signal a condition +of kind {{(exn i/o file)}}. + +=== Basic file operations + +==== 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). + +==== copy-file + +<procedure>(copy-file 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 signaled. When set to any other value, +{{NEWFILE}} is overwritten. {{file-copy}} will work across +filesystems and devices and is not platform-dependent. + +==== move-file + +<procedure>(move-file ORIGFILE NEWFILE #!optional CLOBBER BLOCKSIZE)</procedure> + +Moves {{ORIGFILE}} (a string denoting some filename) to {{NEWFILE}}, +with the same semantics as {{copy-file}}, above. {{move-file}} is +safe across filesystems and devices (unlike {{rename-file}}). It is +possible for an error to be signaled despite partial success if +{{NEWFILE}} could be created and fully written but removing +{{ORIGFILE}} fails. + +If {{CLOBBER}} is given and not {{#f}}, {{NEWFILE}} will be replaced +when it already exists, otherwise an error is signaled. + +The {{BLOCKSIZE}} argument indicates the block size to use when +copying the file a block at a time. It must be a positive integer, +and it defaults to 1024. + +==== delete-file + +<procedure>(delete-file STRING)</procedure> + +Deletes the file with the pathname {{STRING}}. If the file does +not exist, an error is signaled. + +==== delete-file* + +<procedure>(delete-file* STRING)</procedure> + +If the file with pathname {{STRING}} exists, it is deleted and {{#t}} +is returned. If the file does not exist, nothing happens and {{#f}} +is returned. + +==== 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-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 #!optional CLOBBER)</procedure> + +Renames the file or directory with the pathname {{OLD}} to +{{NEW}}. If the operation does not succeed, an error is signaled. + +If {{CLOBBER}} is given and not {{#f}}, {{NEW}} will be replaced when +it already exists, otherwise an error is signaled. + + +=== 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. + + +=== 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. + + +==== 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). + +--- +Previous: [[Module (chicken eval)]] + +Next: [[Module (chicken file posix)]] diff --git a/manual/Module (chicken fixnum) b/manual/Module (chicken fixnum) new file mode 100644 index 00000000..53b4b9f6 --- /dev/null +++ b/manual/Module (chicken fixnum) @@ -0,0 +1,85 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken fixnum) + +Because CHICKEN supports a full numeric tower, operations can +sometimes incur a substantial overhead to simply detect the type of numbers +you're passing in. When you know you're definitely dealing only with +fixnums, you can choose to use fixnum-specific operations to avoid +this overhead. + +This is purely a performance hack. You might want to consider adding +[[Types|type annotations]] instead, this often gives the same +performance boost without having to rewrite all numeric operators in +your code. + + +=== Arithmetic fixnum operations + +<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. + +=== Overflow-aware fixnum operations + +<procedure>(fx+? N1 N2)</procedure> +<procedure>(fx-? N1 N2)</procedure> +<procedure>(fx*? N1 N2)</procedure> +<procedure>(fx/? N1 N2)</procedure> + +These procedures behave similarly to their standard counterparts with +the exception that {{#f}} is returned if an argument is not a fixnum +or the result of the operation overflows. + +Chaining of such procedures is well-defined and causes the overflow +error to be propagated. + +=== 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. + +--- +Previous: [[Module (chicken file posix)]] + +Next: [[Module (chicken flonum)]] diff --git a/manual/Module (chicken flonum) b/manual/Module (chicken flonum) new file mode 100644 index 00000000..d780185b --- /dev/null +++ b/manual/Module (chicken flonum) @@ -0,0 +1,117 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken flonum) + +Because CHICKEN supports a full numeric tower, operations can +sometimes incur a subtantial overhead to simply detect the type of numbers +you're passing in. When you know you're definitely dealing only with +flonums, you can choose to use flonum-specific operations to avoid +this overhead. + +This is purely a performance hack. You might want to consider adding +[[Types|type annotations]] instead, this often gives the same +performance boost without having to rewrite all numeric operators in +your code. + +=== Arithmetic floating-point operations + +<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}}. + + +--- +Previous: [[Module (chicken fixnum)]] + +Next: [[Module (chicken foreign)]] diff --git a/manual/Module (chicken foreign) b/manual/Module (chicken foreign) new file mode 100644 index 00000000..f2c6c483 --- /dev/null +++ b/manual/Module (chicken foreign) @@ -0,0 +1,376 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken foreign) + +This module provides a ''foreign function interface'' to access externally +defined functions and variables in C-compatible languages, as well as +operating-system specific functionality. + +Note that this interface is source-based, since CHICKEN translates +Scheme code to C. It is not binary, as in many other Scheme implementations. + +Several special forms of this interface refer to ''foreign type specifies'', +consult the [[relevant chapter|Foreign type specifies]] of this manual for +more information. + + +== Accessing external objects + +=== foreign-code + +<macro>(foreign-code STRING ...)</macro> + +Executes the embedded C/C++ code {{STRING ...}}, which should +be a sequence of C statements, which are executed and return an unspecified result. + +<enscript highlight=scheme> +(foreign-code "doSomeInitStuff();") => #<unspecified> +</enscript> + +Code wrapped inside {{foreign-code}} may not invoke callbacks into Scheme. + + +=== foreign-value + +<macro>(foreign-value CODE TYPE)</macro> + +Evaluates the embedded C/C++ expression {{CODE}} (which may be a string or symbol), returning a value of type given +in the foreign-type specifier {{TYPE}}. + +<enscript highlight=scheme> +(print (foreign-value "my_version_string" c-string)) +</enscript> + + +=== foreign-declare + +<macro>(foreign-declare STRING ...)</macro> + +Include given strings verbatim into header of generated file. + + +=== define-foreign-type + +<macro>(define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])</macro> + +Defines an alias for {{TYPE}} with the name {{NAME}} (a symbol). +{{TYPE}} may be a type-specifier or a string naming a C type. The +namespace of foreign type specifiers is separate from the normal +Scheme namespace. The optional arguments {{ARGCONVERT}} and +{{RETCONVERT}} should evaluate to procedures that map argument- and +result-values to a value that can be transformed to {{TYPE}}: + +<enscript highlight=scheme> +(define-foreign-type char-vector + nonnull-c-string + (compose list->string vector->list) + (compose list->vector string->list) ) + +(define strlen + (foreign-lambda int "strlen" char-vector) ) + +(strlen '#(#\a #\b #\c)) ==> 3 + +(define memset + (foreign-lambda char-vector "memset" char-vector char int) ) + +(memset '#(#_ #_ #_) #\X 3) ==> #(#\X #\X #\X) +</enscript> + +Foreign type-definitions are only visible in the compilation-unit in which +they are defined, so use {{include}} to use the same definitions +in multiple files. + + +=== foreign-type-size + +<macro>(foreign-type-size TYPE)</macro> + +Returns the size of the storage required to hold values of the +given foreign type {{TYPE}}. This is basically equivalent to + +<enscript highlight=scheme> +(foreign-value "sizeof(TYPE)" size_t) +</enscript> + +but also handles user-defined types and allows "TYPE" to be a string, +which will be given literally to the {{sizeof}} operator. + + +=== define-foreign-variable + +<macro>(define-foreign-variable NAME TYPE [STRING])</macro> + +Defines a foreign variable of name {{NAME}} (a symbol). {{STRING}} +should be the real name of a foreign variable or parameterless +macro. If {{STRING}} is not given, then the variable name {{NAME}} +will be converted to a string and used instead. All references and +assignments (via {{set!}}) are modified to correctly convert values +between Scheme and C representation. This foreign variable can only be +accessed in the current compilation unit, but the name can be +lexically shadowed. Note that {{STRING}} can name an arbitrary C +expression. If no assignments are performed, then {{STRING}} doesn't +even have to specify an lvalue. +See that {{define-foreign-variable}} will not generate C declarations +or memory allocation code; use it to include references to variables +in external C code. To actually create Scheme variables visible from C, +use {{define-external}} (see the Manual section on +[[Callbacks]]). +For example, the following code: +<enscript lang="scheme"> +(import foreign) +(define-foreign-variable x double "var_x") +(print x) +</enscript> +will not work, because a reference to {{var_x}} will be inserted in the C code, +but no declaration will be included (this can be easily verified by translating +the program into C with {{csc -t program.scm}}). Changing the second line to +{{(define-external x double 0.5)}} will work (and the value 0.5 will be printed). + +=== foreign-lambda + +<macro>(foreign-lambda RETURNTYPE NAME ARGTYPE ...)</macro> + +Represents a +binding to an external routine. This form can be used in the position +of an ordinary {{lambda}} expression. {{NAME}} specifies the +name of the external procedure and should be a string or a symbol. + + +=== foreign-lambda* + +<macro>(foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)</macro> + +Similar to {{foreign-lambda}}, but instead of generating code to +call an external function, the body of the C procedure is directly given +in {{STRING ...}}: + +<enscript highlight=scheme> +(define my-strlen + (foreign-lambda* int ((c-string str)) + "int n = 0; + while(*(str++)) ++n; + C_return(n);") ) + +(my-strlen "one two three") ==> 13 +</enscript> + +For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement +to return a result from the foreign lambda body as some cleanup code has to be run before execution +commences in the calling code. + +=== foreign-safe-lambda + +<macro>(foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)</macro> + +This is similar to {{foreign-lambda}}, but also allows the called +function to call Scheme functions. See [[Callbacks]]. + + +=== foreign-safe-lambda* + +<macro>(foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)</macro> + +This is similar to {{foreign-lambda*}}, but also allows the called +function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]]. + + + +=== foreign-primitive + +<macro>(foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)</macro> + +This is also similar to {{foreign-lambda*}} but the code will be +executed in a ''primitive'' CPS context, which means it will not +actually return, but call its continuation on exit. This means that code +inside this form may allocate Scheme data on the C stack (the +''nursery'') with {{C_alloc}} (see below). You can return multiple +values inside the body of the {{foreign-primitive}} form by using +the following C code: + +<enscript highlight=scheme> +C_word av[N + 2] = { C_SCHEME_UNDEFINED, C_k, X1, ... }; +C_values(N + 2, av); +</enscript> + +where {{N}} is the number of values to be returned, and {{X1, ...}} +are the results, which should be Scheme data objects. When returning +multiple values, the return-type should be omitted. Of course, if you +have to dynamically compute the values, you do not have to use C's +array initialization syntax, but you can just assign them one by one. + +Returning just a single value can still be done via the {{C_return(...)}} macro. + + +== 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. + +== 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: [[Module (chicken flonum)]] + +Next: [[Module (chicken format)]] diff --git a/manual/Module (chicken format) b/manual/Module (chicken format) new file mode 100644 index 00000000..9090e249 --- /dev/null +++ b/manual/Module (chicken format) @@ -0,0 +1,69 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken format) + +This module provides procedures for formatting output to ports and +strings. + +=== The printf family of procedures + +==== 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}} + + +--- +Previous: [[Module (chicken foreign)]] + +Next: [[Module (chicken gc)]] diff --git a/manual/Module (chicken gc) b/manual/Module (chicken gc) new file mode 100644 index 00000000..48653e3a --- /dev/null +++ b/manual/Module (chicken gc) @@ -0,0 +1,79 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken gc) + +This module provides some control over the garbage collector. + +=== 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. + + +=== 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}}. + + +=== 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. + + +--- +Previous: [[Module (chicken format)]] + +Next: [[Module (chicken io)]] diff --git a/manual/Module (chicken io) b/manual/Module (chicken io) new file mode 100644 index 00000000..08eeb682 --- /dev/null +++ b/manual/Module (chicken io) @@ -0,0 +1,93 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken io) + +This module provides various Input/Output extensions. + +=== read-list + +<procedure>(read-list [PORT [READER [MAX]]])</procedure> + +Call {{READER}} up to {{MAX}} times and collect its output in a list. If {{MAX}} is {{#f}}, read until end of file. + +The reader is called with one argument: {{PORT}}. + +{{READER}} defaults to {{read}}, {{MAX}} to {{#f}} and {{PORT}} to {{current-input-port}}, so if you call it with no arguments, it will read all remaining s-expressions from the current input port. + + +=== read-buffered + +<procedure>(read-buffered [PORT])</procedure> + +Reads any remaining data buffered after previous read operations on +{{PORT}}. If no remaining data is currently buffered, an empty string +is returned. This procedure will never block. Currently only useful +for string-, process- and tcp ports. + +=== 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: [[Module (chicken gc)]] + +Next: [[Module (chicken irregex)]] diff --git a/manual/Module (chicken irregex) b/manual/Module (chicken irregex) new file mode 100644 index 00000000..82061397 --- /dev/null +++ b/manual/Module (chicken irregex) @@ -0,0 +1,854 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken irregex) + +This module 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}} module can be +made available in the CHICKEN interpreter ({{csi}}) by entering + +<enscript highlight=scheme> +(import irregex) +</enscript> + +=== 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. + +==== glob->sre + +<procedure>(glob->sre <str>)</procedure> + +Converts a basic shell-style glob to an SRE which matches only strings +which the glob would match. The glob characters {{[}}, {{]}} {{*}} +and {{?}} are supported. + + +==== irregex? + +<procedure>(irregex? <obj>)</procedure> + +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 +==== irregex-match? + +<procedure>(irregex-match <irx> <str> [<start> <end>])</procedure> +<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. + +Where {{irregex-match}} returns a match object, {{irregex-match?}} +just returns a boolean indicating whether it matched or not. + +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 +==== irregex-match-start-chunk +==== irregex-match-end-chunk + +<procedure>(irregex-match-subchunk <match> [<index-or-name>])</procedure> +<procedure>(irregex-match-start-chunk <match> [<index-or-name>])</procedure> +<procedure>(irregex-match-end-chunk <match> [<index-or-name>])</procedure> + +Access the chunks delimiting the submatch index, or named submatch. + +{{irregex-match-subchunk}} 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: [[Module (chicken io)]] + +Next: [[Module (chicken keyword)]] diff --git a/manual/Module (chicken keyword) b/manual/Module (chicken keyword) new file mode 100644 index 00000000..7493ef5f --- /dev/null +++ b/manual/Module (chicken keyword) @@ -0,0 +1,62 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken keyword) + +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 binding 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]]. + + +==== 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}}. + + +--- +Previous: [[Module (chicken irregex)]] + +Next: [[Module (chicken load)]] diff --git a/manual/Module (chicken load) b/manual/Module (chicken load) new file mode 100644 index 00000000..f5c18668 --- /dev/null +++ b/manual/Module (chicken load) @@ -0,0 +1,132 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken load) + +This module contains various procedures for loading code. Note that +the main procedure for loading code, {{load}}, is part of +[[Module scheme]]; the {{chicken load}} module only contains +''extensions'' to the standard. + +=== A note on loading of shared extension libraries + +The functionality of loading shared objects into the runtime is only +available on platforms that support dynamic loading of compiled +code. Currently Linux, BSD, Solaris, Windows (with Cygwin) and HP/UX +are supported. Loading source files works everywhere. + +=== 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 [[#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 ({{"/"}}). + +=== require + +<procedure>(require ID ...)</procedure> + +If any of the named extension libraries {{ID}} are not already loaded +into the system, then {{require}} 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}}) + +Each {{ID}} should be a symbol. + + +=== provide + +<procedure>(provide 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. + + +=== Tuning how code is loaded + +==== 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}}. + + +==== 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. + + +==== 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. + + +--- +Previous: [[Module (chicken keyword)]] + +Next: [[Module (chicken locative)]] diff --git a/manual/Module (chicken locative) b/manual/Module (chicken locative) new file mode 100644 index 00000000..9c26a2a3 --- /dev/null +++ b/manual/Module (chicken locative) @@ -0,0 +1,74 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken locative) + +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" + +--- +Previous: [[Module (chicken load)]] + +Next: [[Module (chicken memory)]] diff --git a/manual/Module (chicken memory representation) b/manual/Module (chicken memory representation) new file mode 100644 index 00000000..48a10a79 --- /dev/null +++ b/manual/Module (chicken memory representation) @@ -0,0 +1,261 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken memory representation) + +The procedures from this module operate on the in-memory +representation of Scheme objects. These procedures ''are'' safe, so, +for example, unlike the procedures from {{(chicken memory)}} these +procedures ''will'' type-check and range-check their arguments, but +you still need to know what you're doing because the effects may be +surprising for the uninitiated. + + +=== 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: it is an aggregation of other Scheme objects. + +Note that strings and blobs are not considered vector-like (they are +considered to be ''byte vectors'', which are objects of mostly +unstructured binary data). + + +==== 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. + + +=== 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: [[Module (chicken memory)]] + +Next: [[Module (chicken module)]] diff --git a/manual/Module (chicken memory) b/manual/Module (chicken memory) new file mode 100644 index 00000000..4eedb088 --- /dev/null +++ b/manual/Module (chicken memory) @@ -0,0 +1,398 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken memory) + +The procedures from this module operate directly on memory, at a very +low level. This makes them unsafe, unlike most other Scheme +procedures. '''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. + + +==== 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. + + +==== 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. + + +==== 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. + + +==== 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. + +==== pointer-vector-fill! + +<procedure>(pointer-vector-fill! POINTERVECTOR POINTER)</procedure> + +Set every element in the {{POINTERVECTOR}} to {{POINTER}}. + + +=== Moving memory + +==== 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. + +--- +Previous: [[Module (chicken locative)]] + +Next: [[Module (chicken memory representation)]] diff --git a/manual/Module (chicken module) b/manual/Module (chicken module) new file mode 100644 index 00000000..d8f42266 --- /dev/null +++ b/manual/Module (chicken module) @@ -0,0 +1,12 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken module) + +The functionality in this module is available by default. See +[[Modules]] for more information. + +--- +Previous: [[Module (chicken memory representation)]] + +Next: [[Module (chicken pathname)]] diff --git a/manual/Module (chicken pathname) b/manual/Module (chicken pathname) new file mode 100644 index 00000000..59b70bdd --- /dev/null +++ b/manual/Module (chicken pathname) @@ -0,0 +1,118 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken pathname) + +This module provides procedures for manipulating paths. If you want +to operate on the files and directories which the paths represent, see +[[Module (chicken file)]]. + +=== 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")}} + +=== Windows specific notes + +Use of UTF8 encoded strings 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. + +--- +Previous: [[Module (chicken module)]] + +Next: [[Module (chicken platform)]] diff --git a/manual/Module (chicken platform) b/manual/Module (chicken platform) new file mode 100644 index 00000000..72f6f5cd --- /dev/null +++ b/manual/Module (chicken platform) @@ -0,0 +1,202 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken platform) + +This module provides procedures for obtaining information about the +platform on which the program is currently running. + +=== Build information + +These procedures return information about options that can be +specified at build time. + +==== 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-home + +<procedure>(chicken-home)</procedure> + +Returns a string which represents the installation directory (usually {{/usr/local/share/chicken}} on UNIX-like systems). + +==== 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. + +==== 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.) + + +=== Machine information + +These procedures return information about the type of CPU/architecture +the program is running on. + +==== 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 + +=== Software information + +These procedures return information about the type of operating system +the program is running on. + +==== 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 + + +=== 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. + + +=== Returning to the host program + +=== return-to-host + +<procedure>(return-to-host)</procedure> + +Exits the Scheme code and returns to the invoking context that called +{{CHICKEN_run}} or {{CHICKEN_continue}}. + +After {{return-to-host}} has been executed and once {{CHICKEN_run}} +returns, you can invoke callbacks which have been defined with +{{define-external}}. + + +--- +Previous: [[Module (chicken pathname)]] + +Next: [[Module (chicken plist)]] diff --git a/manual/Module (chicken plist) b/manual/Module (chicken plist) new file mode 100644 index 00000000..e85fcb51 --- /dev/null +++ b/manual/Module (chicken plist) @@ -0,0 +1,63 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken plist) + +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> +<procedure>(set! (get SYMBOL PROPERTY) VALUE)</procedure> + +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> +<procedure>(set! (symbol-plist SYMBOL) LST)</procedure> + +Returns the property list of {{SYMBOL}} or sets it. The property list +is a flat list of alternating properties and values. + +This list is not guaranteed to be a fresh copy, so avoid mutating it +directly. + +=== 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}}. + +This tail of the property list is not guaranteed to be a fresh copy, +so avoid mutating it directly. + +{{PROPERTIES}} may also be an atom, in which case it is treated as a +list of one element. + +--- +Previous: [[Module (chicken platform)]] + +Next: [[Module (chicken port)]] diff --git a/manual/Module (chicken port) b/manual/Module (chicken port) new file mode 100644 index 00000000..543eb481 --- /dev/null +++ b/manual/Module (chicken port) @@ -0,0 +1,266 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken port) + +This module contains various extended port definitions. + +=== Port attributes + +==== 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}}. + + +=== 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}}. + +On Windows, this procedure always raises an exception. + +==== 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 raises an exception. + + +=== 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-output-to-port + +<procedure>(with-error-output-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-output-to-string + +<procedure>(with-error-output-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: [[Module (chicken plist)]] + +Next: [[Module (chicken pretty-print)]] diff --git a/manual/Module (chicken pretty-print) b/manual/Module (chicken pretty-print) new file mode 100644 index 00000000..dcf79dc7 --- /dev/null +++ b/manual/Module (chicken pretty-print) @@ -0,0 +1,26 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken pretty-print) + +This module has some procedures for pretty printing s-expressions. + +=== 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. + +--- +Previous: [[Module (chicken port)]] + +Next: [[Module (chicken process)]] diff --git a/manual/Module (chicken process signal) b/manual/Module (chicken process signal) new file mode 100644 index 00000000..8e40cfdc --- /dev/null +++ b/manual/Module (chicken process signal) @@ -0,0 +1,149 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken process signal) + +This module offers procedures for dealing with POSIX process signals. + +Please note that signals are very POSIX-specific. Windows only +supports rudimentary in-process signals for dealing with user +interrupts, segmentation violations, floating-point exceptions and the +like. Inter-process signals are not supported. Therefore, most of +the procedures here are not available on native Windows builds. If +that's the case, the description contains a note. + + +=== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== signal-handler +=== set-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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== signal-mask + +<procedure>(signal-mask)</procedure> + +Returns the signal mask of the current process. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== signal-masked? + +<procedure>(signal-masked? SIGNUM)</procedure> + +Returns whether the signal for the code {{SIGNUM}} is currently masked. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== signal-mask! + +<procedure>(signal-mask! SIGNUM)</procedure> + +Masks (blocks) the signal for the code {{SIGNUM}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== signal-unmask! + +<procedure>(signal-unmask! SIGNUM)</procedure> + +Unmasks (unblocks) the signal for the code {{SIGNUM}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== 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><br> +<constant>signal/break</constant><br> +<constant>signals-list</constant><br> + +These variables contain signal codes for use with {{process-signal}}, +{{set-signal-handler!}}, {{signal-handler}}, {{signal-masked?}}, +{{signal-mask!}}, or {{signal-unmask!}}. + +'''NOTE''': On native Windows builds (all except cygwin), only +{{signal/term}}, {{signal/int}}, {{signal/fpe}}, {{signal/ill}}, +{{signal/segv}}, {{signal/abrt}}, {{signal/break}} have an actual +value. The others are all defined as zero, because those signals +don't exist on Windows. + +'''NOTE''': On UNIX builds and cygwin, {{signal/break}} is defined as +zero because it only exists on Windows. + +To get a list of signals that are known to exist on the current +platform, you can check {{signals-list}} which is a list of integers +(signal numbers). + +--- +Previous: [[Module (chicken process)]] + +Next: [[Module (chicken process-context)]] diff --git a/manual/Module (chicken process) b/manual/Module (chicken process) new file mode 100644 index 00000000..cfeaf64d --- /dev/null +++ b/manual/Module (chicken process) @@ -0,0 +1,351 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken process) + +This module offers procedures for interacting with subprocesses. + + +=== Processes + +==== 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. + +On Windows, these procedures all have an additoinal optional parameter +{{EXACT-FLAG}}, which defaults to {{#f}}. When {{#f}} is passed, any +argument string with embedded whitespace will be wrapped in +quotes. When {{#t}} no such wrapping occurs. + + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. Be careful +to properly quote arguments with the {{qs}} procedure to avoid shell +injection vulnerabilities. +* The multiple parameter version directly invokes the {{COMMAND}} with +the {{ARGUMENT-LIST}}, and is vastly preferred over the +single-parameter version because of its better safety. + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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 listed below. + +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 + +'''NOTE''': On all Unix-like builds (all except native MingW-based +Windows platforms), this procedure is unimplemented and will raise an +error. + +<constant>spawn/overlay</constant> +<constant>spawn/wait</constant> +<constant>spawn/nowait</constant> +<constant>spawn/nowaito</constant> +<constant>spawn/detach</constant> + +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-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. + +On Windows, {{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.) + + +==== 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. + + +==== 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. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== Shell commands + +The commands below are all string-based. This means you have to be +very careful to properly quote any arguments to subprocesses, to avoid +shell injection bugs which can lead to arbitrary code execution. + +You can quote arguments with the {{qs}} procedure, but it is strongly +recommended you use {{fork}} with {{process-execute}} or the +multi-argument versions of the {{process}}, {{process*}} or +{{process-run}} procedures. + +==== 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 ({{\}}). + + +==== 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> + +==== system* + +<procedure>(system* STRING)</procedure> + +Similar to {{(system STRING)}}, but signals an error should the invoked +program return a nonzero exit status. + +=== 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. + +On Windows, there is an optional parameter {{MODE}}, which defaults +to {{open/binary | open/noinherit}}. This can be {{open/binary}} or +{{open/text}}, optionally or'ed with {{open/noinherit}}. + + +==== 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 + +<constant>pipe/buf</constant> + +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> + +=== Windows specific notes + +Use of UTF8 encoded strings 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. + +--- +Previous: [[Module (chicken pretty-print)]] + +Next: [[Module (chicken process signal)]] diff --git a/manual/Module (chicken process-context posix) b/manual/Module (chicken process-context posix) new file mode 100644 index 00000000..e3fef57e --- /dev/null +++ b/manual/Module (chicken process-context posix) @@ -0,0 +1,150 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken process-context posix) + +This module provides access to POSIX-specific procedures which deal +with the current process context. + +=== Process filesystem context + +==== change-directory* + +<procedure>(change-directory* FD)</procedure> +<procedure>(set! (current-directory) FD)</procedure> + +Changes the current working directory to the one represented by the +file-descriptor {{FD}}, which should be an exact integer. + +'''NOTE''': Windows does not allow {{{open}}} on directories, so while +technically it is supported, in practice you cannot use this procedure +on native Windows builds (on cygwin it works because cygwin emulates +this). + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + + +=== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== current-user-name + +<procedure>(current-user-name)</procedure> + +Get the login name corresponding to the real user-id of the current +process from the system password database. + +On Windows, there's no user-id and no distinction between real and +effective user, but this procedure ''will'' return the username +associated with the current process, so it is safe to use. + + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== current-effective-user-name + +<procedure>(current-effective-user-name)</procedure> + +Get the login name corresponding to the effective user-id of the +current process from the system password database. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + + +=== Process identity + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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}}. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +==== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +--- +Previous: [[Module (chicken process-context)]] + +Next: [[Module (chicken random)]] diff --git a/manual/Module (chicken process-context) b/manual/Module (chicken process-context) new file mode 100644 index 00000000..f70292cb --- /dev/null +++ b/manual/Module (chicken process-context) @@ -0,0 +1,103 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken process-context) + +This module provides access to the current process context. + +=== Information about the program's invocation + +==== 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. + +==== 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. + +=== 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. + +==== 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}}. + +=== 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. + + +=== Access to environment variables + +==== 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]]). + +==== 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]]. + +==== 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. + + +=== Process filesystem context + +==== change-directory + +<procedure>(change-directory NAME)</procedure> +<procedure>(set! (current-directory) NAME)</procedure> + +Changes the current working directory to {{NAME}}. + +==== current-directory + +<procedure>(current-directory)</procedure> + +Returns the name of the current working directory. + +--- +Previous: [[Module (chicken process signal)]] + +Next: [[Module (chicken process-context posix)]] diff --git a/manual/Module (chicken random) b/manual/Module (chicken random) new file mode 100644 index 00000000..24f83028 --- /dev/null +++ b/manual/Module (chicken random) @@ -0,0 +1,59 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken random) + +This module provides access to entropy (as provided by the operating +system) and a pseudo random number generator. + +On UNIX systems entropy is by default obtained from {{/dev/urandom}}. +On Linux, the {{getrandom(2)}} system call is used instead, if available. +On OpenBSD it is {{arc4random_buf(3)}}, on Windows {{RtlGenRandom}}. + +The pseudo random number generator is an implementation of the +[[WELL512|https://en.wikipedia.org/wiki/Well_equidistributed_long-period_linear]] algorithm. + +==== set-pseudo-random-seed! + +<procedure>(set-pseudo-random-seed! SEED [SIZE])</procedure> + +Set seed for the PRNG from the at most {{SIZE}} bytes of {{SEED}}. +which should be a byte vector or a string containing random data. +If {{SIZE}} is not given, it defaults to the size of {{SEED}}. If {{SIZE}} +(or the size of {{SEED}}) is below the required size of the random +state used by the PRNG, then it will necessarily be initialized in a less +random manner as possible. + + +==== pseudo-random-integer + +<procedure>(pseudo-random-integer [RANGE])</procedure> + +Returns a uniformly distributed pseudo random integer between 0 and +{{RANGE-1}}, which may be a big integer. + + +==== pseudo-random-real + +<procedure>(pseudo-random-real)</procedure> + +Returns a uniformly distributed pseudo-random inexact number between +0 and 1. + + +==== random-bytes + +<procedure>(random-bytes [BUF [SIZE]])</procedure> + +Returns random bytes from the available entropy source. If {{BUF}} is +given, it should be a string or byte vector which will be filled with up to +{{SIZE}} random bytes. {{SIZE}} defaults to the size of the {{BUF}} +argument. If no arguments are given, {{random-bytes}} returns a +freshly allocated byte vector of sufficient size to be used as a seed +for {{set-pseudo-random-seed!}}. + + +--- +Previous: [[Module (chicken process-context)]] + +Next: [[Module (chicken read-syntax)]] diff --git a/manual/Module (chicken read-syntax) b/manual/Module (chicken read-syntax) new file mode 100644 index 00000000..00429878 --- /dev/null +++ b/manual/Module (chicken read-syntax) @@ -0,0 +1,99 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken read-syntax) + +This module provides procedures which can be used to extend the reader +with custom read syntax. + +=== 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)}}. This procedure can +be useful to restore an old read-table after temporarily introducing +new read syntax. + + +=== 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). + + +--- +Previous: [[Module (chicken random)]] + +Next: [[Module (chicken repl)]] diff --git a/manual/Module (chicken repl) b/manual/Module (chicken repl) new file mode 100644 index 00000000..2a4b5cd5 --- /dev/null +++ b/manual/Module (chicken repl) @@ -0,0 +1,61 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken repl) + +This module provides procedures you can use to create your own +Read-Eval-Print Loop (REPL). + +=== 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> ")}}. + + +=== 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 the {{repl}} procedure. + + +=== reset + +<procedure>(reset)</procedure> + +Reset program (Invokes {{reset-handler}}). + + +=== 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. + +--- +Previous: [[Module (chicken read-syntax)]] + +Next: [[Module (chicken sort)]] diff --git a/manual/Module (chicken sort) b/manual/Module (chicken sort) new file mode 100644 index 00000000..340ed472 --- /dev/null +++ b/manual/Module (chicken sort) @@ -0,0 +1,72 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken sort) + +This module contains several procedures which deal with sorting of +''sequences'' (i.e., lists and vectors). + +=== 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. + +--- +Previous: [[Module (chicken repl)]] + +Next: [[Module (chicken string)]] diff --git a/manual/Module (chicken string) b/manual/Module (chicken string) new file mode 100644 index 00000000..0790f165 --- /dev/null +++ b/manual/Module (chicken string) @@ -0,0 +1,170 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken string) + +This module contains procedures which can perform various useful +string operations. + +=== 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-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. + + +=== reverse-string-append + +<procedure>(reverse-string-append LIST)</procedure> + +{{(apply string-append (reverse LIST))}} + + +--- +Previous: [[Module (chicken sort)]] + +Next: [[Module (chicken syntax)]] diff --git a/manual/Module (chicken syntax) b/manual/Module (chicken syntax) new file mode 100644 index 00000000..b93e2c96 --- /dev/null +++ b/manual/Module (chicken syntax) @@ -0,0 +1,430 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken syntax) + +This module has support for syntax- and module handling. This module +is used by default, unless a program is compiled with the +{{-explicit-use}} option. + +=== Macro transformers + +Macro transformers are procedures you can use in a {{define-syntax}} +context to register a procedure that can transform s-expressions into +other s-expressions. Only use these when you need to break hygiene in +a controlled way; for many use cases {{syntax-rules}} is more +appropriate, as it offers stronger guarantees of hygiene, is more +high-level and is standard R5RS Scheme. + +For those situations where you need more control, however, CHICKEN +supports two kinds of low-level macros: so-called explicit renaming +and implicit renaming macros. + +==== 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. + + +===== 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. + +This 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). + +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. + +=== 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. + + +===== 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. See the section above for a more complete +explanation. + +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. + + +=== Expanding macros + +==== 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. + +=== Macro helper procedures + +==== begin-for-syntax + +<macro>(begin-for-syntax EXP ...)</macro> + +Equivalent to {{(begin EXP ...)}}, but performs the evaluation of the +expression during macro-expansion time, using the macro environment +rather than the interaction environment. + +You can use this to define your own helper procedures that you can +call from a syntax transformer. + +==== 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. + +Essentially, this is a shorthand for +{{(begin-for-syntax (define ...))}}. + +Note that {{define-for-syntax}} definitions within a module are +implicitly added to that module's import library. Refer to the +documentation on [[Modules#import-libraries|import libraries]] +for more information. + + +==== syntax + +<procedure>(syntax EXPRESSION)</procedure> + +This will quote the {{EXPRESSION}} for use in a syntax expansion. Any +syntactic information will be stripped from the {{EXPRESSION}}. + + +==== strip-syntax + +<procedure>(strip-syntax EXPRESSION)</procedure> + +Strips all syntactical information from {{EXPRESSION}}, returning a +new expression where symbols have all context-information removed. + +You should use this procedure whenever you want to manually construct +new identifiers, which an unhygienic macro can insert. In some cases +it does not ''appear'' to be necessary to strip context information +when you use the macro, but you still should do it. Sometimes +identifiers will not have been renamed (most often at toplevel), but +there may be other contexts in which identifiers ''will'' have been +renamed. + + +==== 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. + +==== syntax-error + +<procedure>(syntax-error [LOCATION] MESSAGE ARGUMENT ...)</procedure> + +Signals an exception of the kind {{(exn syntax)}}. Otherwise identical +to {{error}}. + + +=== Compiler macros + +==== 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. + +--- +Previous: [[Module (chicken string)]] + +Next: [[Module (chicken tcp)]] diff --git a/manual/Module (chicken tcp) b/manual/Module (chicken tcp) new file mode 100644 index 00000000..064ce638 --- /dev/null +++ b/manual/Module (chicken tcp) @@ -0,0 +1,217 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken tcp) + +This module provides basic facilities for communicating over TCP +sockets. + +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: [[Module (chicken syntax)]] + +Next: [[Module (chicken time)]] diff --git a/manual/Module (chicken time posix) b/manual/Module (chicken time posix) new file mode 100644 index 00000000..3e992dc7 --- /dev/null +++ b/manual/Module (chicken time posix) @@ -0,0 +1,97 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken time posix) + +This module provides procedures for conversion between seconds since +the epoch ("POSIX time"), strings and a 10-element vector type +containing the distinct time units. + + +=== 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. + +'''NOTE''': On native Windows builds (all except cygwin), this +procedure is unimplemented and will raise an error. + +=== 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". + + +--- +Previous: [[Module (chicken time)]] + +Next: [[Interface to external functions and variables]] diff --git a/manual/Module (chicken time) b/manual/Module (chicken time) new file mode 100644 index 00000000..88cf2838 --- /dev/null +++ b/manual/Module (chicken time) @@ -0,0 +1,53 @@ +[[tags: manual]] +[[toc:]] + +== Module (chicken time) + +This module provides a few basic procedures for measuring time. +For representation and manipulation of calendar time, see +[[Module (chicken time posix)]]. + +=== Retrieving timestamp information + +==== 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. + + +=== Benchmarking macros + +==== 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: [[Module (chicken tcp)]] + +Next: [[Module (chicken time posix)]] diff --git a/manual/Module r4rs b/manual/Module r4rs new file mode 100644 index 00000000..3b7c5e5b --- /dev/null +++ b/manual/Module r4rs @@ -0,0 +1,15 @@ +[[tags: manual]] +[[toc:]] + +== Module r4rs + +This module provides the subset of procedures and macros from the +{{scheme}} module which are from the R4RS standard. + +This is every procedure and macro from [[scheme|Module scheme]] except for +{{dynamic-wind}}, {{eval}}, {{call-with-values}} and {{values}}. + +--- +Previous: [[Module r5rs]] + +Next: [[Module srfi-4]] diff --git a/manual/Module r5rs b/manual/Module r5rs new file mode 100644 index 00000000..5f7e7c4d --- /dev/null +++ b/manual/Module r5rs @@ -0,0 +1,12 @@ +[[tags: manual]] +[[toc:]] + +== The r5rs module + +This module is simply an alias for the [[scheme]] module. Please see +the reference of that module for details on what it provides. + +--- +Previous: [[Module scheme]] + +Next: [[Module r4rs]] diff --git a/manual/Module scheme b/manual/Module scheme new file mode 100644 index 00000000..907736c6 --- /dev/null +++ b/manual/Module scheme @@ -0,0 +1,3526 @@ +[[tags: manual]] +[[toc:]] + +== Module scheme + +This module provides all of CHICKEN's R5RS procedures and macros. +These descriptions are based directly on the ''Revised^5 Report on the +Algorithmic Language Scheme''. + +This module is used by default, unless a program is compiled with +the {{-explicit-use}} option. + +== 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. + +As an extension to R5RS, CHICKEN also supports "extended" DSSSL style +parameter lists, which allows embedded special keywords. Such a +keyword gives a special meaning to the {{<formal>}} it precedes. +DSSSL parameter lists are defined by the following grammar: + + <parameter-list> ==> <required-parameter>* + [#!optional <optional-parameter>*] + [#!rest <rest-parameter>] + [#!key <keyword-parameter>*] + <required-parameter> ==> <ident> + <optional-parameter> ==> <ident> + | (<ident> <initializer>) + <rest-parameter> ==> <ident> + <keyword-parameter> ==> <ident> + | (<ident> <initializer>) + <initializer> ==> <expr> + +When a procedure is applied to a list of arguments, the parameters and arguments are processed from left to right as follows: + +* Required-parameters are bound to successive arguments starting with the first argument. It shall be an error if there are fewer arguments than required-parameters. +* Next, the optional-parameters are bound with the remaining arguments. If there are fewer arguments than optional-parameters, then the remaining optional-parameters are bound to the result of the evaluation of their corresponding <initializer>, if one was specified, otherwise {{#f}}. The corresponding <initializer> is evaluated in an environment in which all previous parameters have been bound. +* If there is a rest-parameter, then it is bound to a list containing all the remaining arguments left over after the argument bindings with required-parameters and optional-parameters have been made. +* If {{#!key}} was specified in the parameter-list, there should be an even number of remaining arguments. These are interpreted as a series of pairs, where the first member of each pair is a keyword specifying the parameter name, and the second member is the corresponding value. If the same keyword occurs more than once in the list of arguments, then the corresponding value of the first keyword is the binding value. If there is no argument for a particular keyword-parameter, then the variable is bound to the result of evaluating <initializer>, if one was specified, otherwise {{#f}}. The corresponding <initializer> is evaluated in an environment in which all previous parameters have been bound. + +Needing a special mention is the close relationship between the +rest-parameter and possible keyword-parameters. Declaring a +rest-parameter binds up all remaining arguments in a list, as +described above. These same remaining arguments are also used for +attempted matches with declared keyword-parameters, as described +above, in which case a matching keyword-parameter binds to the +corresponding value argument at the same time that both the keyword +and value arguments are added to the rest parameter list. Note that +for efficiency reasons, the keyword-parameter matching does nothing +more than simply attempt to match with pairs that may exist in the +remaining arguments. Extra arguments that don't match are simply +unused and forgotten if no rest-parameter has been declared. Because +of this, the caller of a procedure containing one or more +keyword-parameters cannot rely on any kind of system error to report +wrong keywords being passed in. + +It shall be an error for an {{<ident>}} to appear more than once in a +parameter-list. + +If there is no rest-parameter and no keyword-parameters in the parameter-list, then it shall be an error for any extra arguments to be passed to the procedure. + + +Example: + + ((lambda x x) 3 4 5 6) => (3 4 5 6) + ((lambda (x y #!rest z) z) + 3 4 5 6) => (5 6) + ((lambda (x y #!optional z #!rest r #!key i (j 1)) + (list x y z i: i j: j)) + 3 4 5 i: 6 i: 7) => (3 4 5 i: 6 j: 1) + + + +==== Conditionals + +<macro>(if <test> <consequent> <alternate>)</macro><br> +<macro>(if <test> <consequent>)</macro><br> + +Syntax: <Test>, <consequent>, and <alternate> may be arbitrary +expressions. + +Semantics: An if expression is evaluated as follows: first, <test> is +evaluated. If it yields a true value (see [[#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 + +As an extension to R5RS, {{set!}} for unbound toplevel variables is +allowed. Also, {{set! (PROCEDURE ...) ...)}} is supported, as CHICKEN +implements [[http://srfi.schemers.org/srfi-17/srfi-17.html|SRFI-17]]. + +=== 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 + + +As an extension to R5RS, CHICKEN also supports the +[[http://srfi.schemers.org/srfi-61|SRFI-61]] syntax: + + (<generator> <guard> => <expression>) + +In this situation, {{generator}} is ''always'' evaluated. Its +resulting value(s) are used as argument(s) for the {{guard}} +procedure. Finally, if {{guard}} returns a non-{{#f}} value, the +{{expression}} is evaluated by calling it with the result of +{{guard}}. Otherwise, evaluation procedes to the next clause. + +<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 + +As an extension to R5RS, CHICKEN also allows {{(begin)}} without body +expressions in any context, not just at toplevel. This simply +evaluates to the unspecified value. + + +==== 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}}. + +CHICKEN also supports the R7RS {{delay-force}} syntax which allows for +iterative lazy algorithms to be expressed in bounded space. See the +[[Module (chicken base)#lazy-evaluation|Lazy evaluation section]] in +the (chicken base) module documentation for more information. + + +==== 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>)</macro> + +This form is a CHICKEN extension to R5RS, and is equivalent to + + (define <variable> (void)) + +<macro>(define (<variable> . <formal>) <body>)</macro><br> + +<Formal> should be a single variable. This form is equivalent to + + (define <variable> + (lambda <formal> <body>)). + +<macro>(define ((<variable> <formal> ...) ...) <body>)</macro><br> + +As an extension to R5RS, CHICKEN allows ''curried'' definitions, where +the variable name may also be a list specifying a name and a nested +lambda list. For example, + + (define ((make-adder x) y) (+ x y)) + +is equivalent to + + (define (make-adder x) (lambda (y) (+ x y))). + +This type of curried definition can be nested arbitrarily and combined +with dotted tail notation or DSSSL keywords. + +==== 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 in standard Scheme. In CHICKEN, {{set!}} at toplevel +has the same effect as a definition, unless inside a module, in which +case it is an error. + + (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. In CHICKEN, attempting to evaluate +an unbound identifier will result in an error, but you ''can'' use +{{set!}} to bind an initial value to it. + +==== 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. + +CHICKEN extends the R5RS semantics by allowing internal definitions +everywhere, and not only at the beginning of a body. A set of internal +definitions is equivalent to a {{letrec}} form enclosing all following +expressions in the body: + + (let ((foo 123)) + (bar) + (define foo 456) + (baz foo) ) + +expands into + + (let ((foo 123)) + (bar) + (letrec ((foo 456)) + (baz foo) ) ) + +Local sequences of {{define-syntax}} forms are translated into +equivalent {{letrec-syntax}} forms that enclose the following forms as +the body of the expression. + + +=== Syntax definitions + +Syntax definitions are valid only at the top level of a +<program>. They have the following form: + +<macro>(define-syntax <keyword> <transformer spec>)</macro> + +{{<Keyword>}} is an identifier, and the {{<transformer spec>}} should +be an instance of {{syntax-rules}}. Note that CHICKEN also supports +{{er-macro-transformer}} and {{ir-macro-transformer}} here. For more +information see [[Module (chicken syntax)|the (chicken syntax) module]]. + +The top-level syntactic environment is extended by binding the +<keyword> to the specified transformer. + +In standard Scheme, there is no define-syntax analogue of internal +definitions in, but CHICKEN allows these as an extension to the +standard. This means {{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. + +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 +; {{x, x1, ... xj, ...}} : real number +; {{y, y1, ... yj, ...}} : real number +; {{q, q1, ... qj, ...}} : rational number +; {{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 [radix])</procedure> + +Radix must be an exact integer. The R5RS standard only requires +implementations to support 2, 8, 10, or 16, but CHICKEN allows any +radix between 2 and 36, inclusive. 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. + +As an extension to R5RS, CHICKEN supports reading and writing the +special IEEE floating-point numbers ''+nan'', ''+inf'' and ''-inf'', +as well as negative zero. + +<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. The R5RS standard +only requires implementations to support 2, 8, 10, or 16, but CHICKEN +allows any radix between 2 and 36, inclusive. 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. + +As an extension to R5RS, CHICKEN supports reading and writing the +special IEEE floating-point numbers ''+nan'', ''+inf'' and ''-inf'', +as well as negative zero. + +=== 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). The {{end}} argument is optional and defaults to the +length of the string, this is a non-standard extension in CHICKEN. + +<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 (this is the case in CHICKEN). + +* 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 + + In CHICKEN, promises are separate objects, so the above expressions + will both evaluate to {{#f}}. + +* 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 + + This is '''not''' the case in CHICKEN. + + +<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. However, +in CHICKEN it is safe to do this, and they will execute in the outer +dynamic context of the {{dynamic-wind}} form. + + (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 + +The {{environment-specifier}} is optional, and if not provided it +defaults to the value of {{(interaction-environment)}}. This is a +CHICKEN extension to R5RS, which, though strictly nonportable, is very +common among Scheme implementations. + +<procedure>(scheme-report-environment version [mutable])</procedure><br> +<procedure>(null-environment version [mutable])</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 by default. In CHICKEN, as an +extension to R5RS, an extra {{mutable}} argument can be passed, which +makes the environments mutable when non-{{#f}}. Mutability means new +top-level definitions are accepted and the values of existing +top-level bindings can be mutated. + +<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 [mode ...])</procedure><br> +<procedure>(call-with-output-file string proc [mode ...])</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. + +Additional {{mode}} arguments can be passed in, which should be any of +the keywords {{#:text}}, {{#:binary}} or {{#:append}}. {{#:text}} and +{{#:binary}} indicate the mode in which to open the file (this has an +effect on non-UNIX platforms only), while {{#:append}} indicates that +instead of truncating the file on open, data written to it should be +appended at the end (only for output files). The extra {{mode}} +arguments are CHICKEN extensions to the R5RS standard. + +<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 [port])</procedure><br> +<procedure>(current-output-port [port])</procedure><br> + +Returns the current default input or output port. + +If the optional {{port}} argument is passed, the current input or +output port is changed to the provided port. It can also be used with +{{parameterize}} to temporarily bind the port to another value. This +is a CHICKEN extension to the R5RS standard. + +Note that the default output port is not buffered. Use +[[Module (chicken port)#set-buffering-mode!|{{set-buffering-mode!}}]] +if you need a different behavior. + + +<procedure>(with-input-from-file string thunk [mode ...])</procedure><br> +<procedure>(with-output-to-file string thunk [mode ...])</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. + +Additional {{mode}} arguments can be passed in, which should be any of +the keywords {{#:text}}, {{#:binary}} or {{#:append}}. {{#:text}} and +{{#:binary}} indicate the mode in which to open the file (this has an +effect on non-UNIX platforms only), while {{#:append}} indicates that +instead of truncating the file on open, data written to it should be +appended at the end (only for output files). The extra {{mode}} +arguments are CHICKEN extensions to the R5RS standard. + +<procedure>(open-input-file filename [mode ...])</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. + +Additional {{mode}} arguments can be passed in, which should be any of +the keywords {{#:text}} or {{#:binary}}. These indicate the mode in +which to open the file (this has an effect on non-UNIX platforms +only). The extra {{mode}} arguments are CHICKEN extensions to the +R5RS standard. + +<procedure>(open-output-file filename [mode ...])</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. + +Additional {{mode}} arguments can be passed in, which should be any of +the keywords {{#:text}}, {{#:binary}} or {{#:append}}. {{#:text}} and +{{#:binary}} indicate the mode in which to open the file (this has an +effect on non-UNIX platforms only), while {{#:append}} indicates that +instead of truncating the file on open, data written to it should be +appended at the end. The extra {{mode}} arguments are CHICKEN +extensions to the R5RS standard. + +<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 [evalproc])</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. + +CHICKEN offers a few extensions to the R5RS definition of {{load}}: + +* The {{filename}} may also be an input port. +* The expressions which are read one by one from the source file are passed to the procedure indicated by the extra optional {{evalproc}} argument, which defaults to {{eval}}. +* On platforms that support it (currently BSD, Haiku, MacOS X, Linux, Solaris, and Windows), {{load}} can be used to load shared objects. + +Example for loading 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> + +There are some limitations and caveats to the CHICKEN extensions you +need to be aware of: + +* 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. + + +<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: [[Included modules]] + +Next: [[Module r5rs]] diff --git a/manual/Module srfi-4 b/manual/Module srfi-4 new file mode 100644 index 00000000..ccfe512d --- /dev/null +++ b/manual/Module srfi-4 @@ -0,0 +1,363 @@ +[[tags: manual]] +[[toc:]] + +== Module srfi-4 + +Homogeneous numeric vector datatypes. Also see the +[[http://srfi.schemers.org/srfi-4/srfi-4.html|original SRFI-4 document]]. + +=== CHICKEN implementation specifics and extensions + +* Procedures for [[Module (chicken blob)|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 + +As a SRFI-4 vector is basically just a [[Module (chicken blob)|blob]] +wrapped by a SRFI-4 type "header object" to structure its contents, +there are several procedures which can convert between blobs and +SRFI-4 vectors. + +<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, the others will copy the contents of the +SRFI-4 vector's internal blob object. + +<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, the others will copy 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 fresh 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: [[Module r4rs]] + +Next: [[Module (chicken base)]] diff --git a/manual/Modules b/manual/Modules index f65b41eb..ef5ae777 100644 --- a/manual/Modules +++ b/manual/Modules @@ -4,39 +4,44 @@ === Modules -To allow some control over visible bindings and to organize code at -the global level, a simple module system is available. A ''module'' +To allow control over visible bindings and to organize code in namespaces, +a module system is available. A ''module'' defines a set of toplevel expressions that are initially evaluated in an empty syntactical environment. By ''importing'' other modules, -exported value- and macro-bindings are made visible inside the +exported value- and syntax-bindings are made visible inside the environment of the module that imports them. Note that modules are purely syntactical - they do not change the control flow or delay the execution of the contained toplevel forms. The body of a module is executed at load-time, when code is -loaded or accessed via the {{uses}} declaration, just like normal -toplevel expressions. Exported macro-definitions are compiled as +loaded or imported, just like normal +toplevel expressions. Exported syntax-definitions are compiled as well, and can be accessed in interpreted or compiled code by loading and importing the compiled file that contains the module. -Imported toplevel bindings can be assigned (with {{set!}}), any modifications +Imported toplevel bindings are mutable and can be assigned +(with {{set!}}), any modifications to these will change the global value and will be visible to other modules that export or import the same toplevel binding. -A module is initially empty (has no visible bindings). You must at least +A module is initially empty (has no visible bindings with the exception +of {{import}} and {{cond-expand}}). You must at least import the {{scheme}} module to do anything useful. To access any -of the non-standard macros and procedures, import the {{chicken}} -module. +of the non-standard macros and procedures, import the {{(chicken base)}} +module. CHICKEN's module system has the following features: * Separation of compile/expansion-time and run-time code is provided, which allows cross compilation -* Module-generating code is only created, when needed * Supports batch-compilation of separate compilation units -* No separate "identifier" type is used, all identifiers appearing in code and processed in expansions are symbols -* The module system is fully optional +* Imports can be lexically scoped * Parameterized modules are supported +At toplevel and outside of a module, the initially available bindings +are everything that is exported from the [[Module scheme|scheme]], +[[Module (chicken base)|(chicken base)]] and +[[Module (chicken syntax)|(chicken syntax)]] modules. + ==== module @@ -62,7 +67,7 @@ environment. {{EXPORT}} may have any of the following forms: {{(IDENTIFIER1 ...)}} or {{(syntax: IDENTIFIER1 ...)}} exports {{IDENTIFIER1}} (which should name a macro) and also arranges for the -remaining identifiers in the list to be visible in the expansion of +remaining identifiers in the list to be visible as value bindings in the expansion of the macro (this is a hint to the module expander to export bindings referenced by syntax-definitions which make use of them, but which would normally be internal to the module - which gives more @@ -89,10 +94,10 @@ satisfying a single functor argument to {{FUNCTORNAME}}. Nested modules, modules not at toplevel (i.e. local modules) or mutually recursive modules are not supported. -When compiled, the module information, including exported macros +When compiled, the module information, including exported syntax is stored in the generated binary and available when loading it into interpreted or compiled code. Note that this is different -to normal macros (outside of module declarations), which are normally +to normal syntax (outside of module declarations), which are normally not exported from compiled code. Note that the module system is only a device for controlling the @@ -133,16 +138,6 @@ module name is either a symbol or a list of symbols and integers. An {{IMPORT}} defines a set of bindings that are to be made visible in the current scope. -Note that the imported bindings are only visible in the next toplevel -expression (regardless of whether the import appears inside or outside -a module): - - (begin - (import m1) - ...) ; imports not visible here - - ... ; imports visible here - ===== only [import specifier] (only IMPORT IDENTIFIER ...) @@ -227,66 +222,26 @@ a separate file is generated that only contains syntactical information (including macros) for a module. {{import}} will automatically find and load an import library for a currently unknown module, if the import- library is either in the extension repository or the current include -path. Import libraries may also be explicitly loaded into the -compiler by using the {{-extend}} compiler option. Interpreted code +path. Interpreted code can simply load the import library to make the module-definition -available. Macro-support definitions defined with {{define-for-syntax}} +available. Syntax-support definitions defined with {{define-for-syntax}} and expansion-time expressions of the form {{(begin-for-syntax ...)}} will be added to import libraries to make them available for exported -macros. Note that these definitions will ruthlessly pollute the +syntax. Note that these definitions will ruthlessly pollute the toplevel namespace and so they should be used sparingly. -=== Using modules as evaluation environments - -==== module-environment - -<procedure>(module-environment MODULENAME)</procedure> - -Locates the module with the name {{MODULENAME}} and returns an -environment that can be passed as the second argument to {{eval}}. The -evaluated expressions have only access to the bindings that are -visible inside the module. Note that the environment is not mutable. - -If the module is not registered in the current process, {{module-environment}} -will try to locate meta-information about the module by loading any -existing import library with the name {{MODULENAME.import.[scm|so]}}, -if possible. - -In compiled modules, only exported bindings will be visible to interactively entered code. In interpreted modules all bindings are visible. - - === Predefined modules Import libraries for the following modules are initially -available: +available outside of a module: [module] scheme - [module] r4rs - [module] r5rs - -Exports the definitions given in R4RS or R5RS. {{r5rs}} is an alias -for {{scheme}}. - - [module] chicken - -Everything from the {{library}}, {{eval}} and {{expand}} library units. - - [module] extras - [module] data-structures - [module] ports - [module] lolevel - [module] posix - [module] regex - [module] srfi-4 - [module] tcp + [module] (chicken base) + [module] (chicken syntax) -Modules exporting the bindings from the respective library units. - - [module] foreign - -Exports all macros and procedures that are used to access foreign -C/C++ code. +Every other module needs to be imported explicitly to have access to +its exported identifiers. === Examples of using modules @@ -483,8 +438,16 @@ also loads the run-time part of a module). Note that functor-instantiation creates a complete copy of the functor body. +=== current-module + +<macro>(current-module)</macro> + +This will expand to a symbol which matches the current module's name +when used inside a module. If not inside a module (i.e., at +toplevel), this expands to {{#f}}. + --- -Previous: [[Macros]] +Previous: [[Interface to external functions and variables]] Next: [[Types]] diff --git a/manual/The User's Manual b/manual/The User's Manual index 99daa289..5a470de4 100644 --- a/manual/The User's Manual +++ b/manual/The User's Manual @@ -8,32 +8,22 @@ This is the manual for CHICKEN Scheme, version 5.0.0 -; [[Getting started]] : What is CHICKEN and how do I use it? - -; [[Basic mode of operation]] : Compiling Scheme files. - -; [[Using the compiler]] : Explains how to use CHICKEN to compile programs and execute them. - -; [[Using the interpreter]] : Invocation and usage of {{csi}}, the CHICKEN interpreter. - -; [[Supported language]] : The language implemented by CHICKEN (deviations from the standard and extensions). - -; [[Debugging]] : Using "Feathers", the CHICKEN debugger. - -; [[Interface to external functions and variables]] : Accessing C and C++ code and data. - -; [[Extensions]] : Packaging and installing extension libraries. - -; [[Deployment]] : Deploying programs developed with CHICKEN. - -; [[Cross development]] : Building software for a different architecture. - -; [[Data representation]] : How Scheme data is internally represented. - -; [[Bugs and limitations]] : Things that do not work yet. - -; [[faq|FAQ]] : A list of Frequently Asked Questions about CHICKEN (and their answers). - -; [[Acknowledgements]] : A list of some of the people that have contributed to make CHICKEN what it is. - -; [[Bibliography]] : Links to documents that may be of interest. +* [[Getting started]] : What is CHICKEN and how do I use it? +* [[Using the interpreter]] : How to use the interactive interpreter, {{csi}} +* [[Using the compiler]] : How to use the batch compiler +* [[Deviations from the standard]] : Where CHICKEN deviates from R5RS +* [[Extensions to the standard]] : Extensions to R5RS that CHICKEN provides +* [[Included modules]] : A reference to CHICKEN's core module library +* [[Interface to external functions and variables]] : Accessing C/C++ code and data +* [[Modules]] : How CHICKEN manages namespaces +* [[Types]] : Optionally typed Scheme code +* [[Declarations]] : Compiler declarations +* [[Extensions]] : Packaging and installing extension libraries +* [[Extension tools]] : {{chicken-[un]install}} and {{chicken-status}} +* [[Egg specification format]] : Format of egg description files +* [[Units and linking model]] : How Scheme compilation units are mapped to C +* [[Deployment]] : How to distribute and ship CHICKEN programs and libraries +* [[Cross development]] : Using CHICKEN to cross-compile for other architectures +* [[Bugs and limitations]] : Things that do not work yet. +* [[Acknowledgements]] : A list of some of the people that have contributed to make CHICKEN what it is +* [[Bibliography]] : Links to documents that may be of interest diff --git a/manual/Types b/manual/Types index 6d5de107..4a3f3ae5 100644 --- a/manual/Types +++ b/manual/Types @@ -41,6 +41,9 @@ Type information for all core library units is available by default. User-defined global variables can be declared to have a type using the {{(declare (type ...))}} or {{:}} syntax. +All syntax described hereafter is exported from the {{(chicken type)}} +module. + ===== : @@ -234,15 +237,15 @@ code that refers to the definitions in a compiled file. The following compiler options allow saving type-declarations to a file and consulting the type declarations retained in this manner: -{{-emit-type-file FILENAME}} writes the type-information for all declared +{{-emit-types-file FILENAME}} writes the type-information for all declared definitions in an internal format to {{FILENAME}}. -{{-consult-type-file FILENAME}} loads and registers the type-information +{{-consult-types-file FILENAME}} loads and registers the type-information in {{FILENAME}} which should be a file generated though a previous use -of {{-emit-type-file}}. +of {{-emit-types-file}}. -If library code is used with {{require-extension}} or {{(declare (unit -...))}} and a {{.types}} file of the same name exists in the +If library code is used with {{import}} +and a {{.types}} file of the same name exists in the extension repository path, then it is automatically consulted. This allows code using these libraries to take advantage of type-information for library definitions. diff --git a/manual/Units and linking model b/manual/Units and linking model new file mode 100644 index 00000000..5e809b10 --- /dev/null +++ b/manual/Units and linking model @@ -0,0 +1,74 @@ +[[tags: manual]] +[[toc:]] + +== Units and the linking model + +Compiling Scheme code to standalone executables or dynamically +loadable files is the most common and simplest way of using CHICKEN. +The extension system handles straightforward cases of static linking +of modules in a mostly transparent way, which is usually sufficient +for normal situations. + +But for more advanced uses like static linking, creating dynamic +libraries or embedding compiled code into other (usually C/C++ based) +applications it is helpful to understand the internal model CHICKEN +uses to organize compiled code and separate compilation units. + +Every compiled Scheme file (from here on called a ''compilation unit'') +consists of a ''toplevel'' C function holding the compiled toplevel +expressions in the order in which they appear in the source file. Scheme +functions ({{lambda}}s) are compiled 1-to-1 into additional C functions, +including the intermediate lambda-functions that are the result of the CPS +conversion that is done by the compiler. + +The toplevel C function of a compilation unit is comparable to the +{{main}} function in C programs, and for standalone executables +the startup code inside the runtime system will eventually call this +toplevel function. Dynamically loaded compiled code is structured +in the same way, with a toplevel function that is dynamically looked +up in the loaded binary and invoked to execute the expressions from +the loaded code. Statically linked compilation units are treated similarly, +there also exists a toplevel function which is called at some stage in the +startup process to execute the forms of the file. + +For standalone executables and dynamically loaded code the toplevel +function has a fixed, predefined name ({{C_toplevel}}). For static +linking or for using multiple toplevels in a shared library that combines +multiple compilation units (like {{libchicken}}, for example), non-internal +function names have to be different to be properly +distinguished, so we assign a unique ''unit'' name to each compilation unit that +is intended to be linked with other compilation units. + +To set the name of a compilation unit, use + +<enscript highlight=scheme> +(declare (unit UNITNAME)) +</enscript> + +''Invocation'' of a unit (actually running the toplevel code contained in it) is done +automatically for standalone programs and dynamically loaded compiled code, +but must be done explicitly for uniquely named units that are part of a larger +library or when doing static linking. To do so, use + +<enscript highlight=scheme> +(declare (uses UNITNAME)) +</enscript> + +Invocation takes place at the start of the current compilation unit, so the +toplevel of any ''used'' units is executed before the toplevel of the compilation +unit that is ''using'' one. Invocation can also be done explicitly by using +{{load-library}} (from the {{(chicken load)}}) module, +which takes the name of a unit to be invoked as an +argument. + +Note that this model of using code from other compilation units does not +address syntax definitions, it's for running pure, fully expanded and compiled +code. Syntax and modules are handled at a higher level, using import +libraries, which are compiled or interpreted separate files setting up module +information to allow the compiler to properly resolve module namespaces +and imports. + +---- +Previous: [[Egg specification format]] + +Next: [[Deployment]] diff --git a/manual/Using the compiler b/manual/Using the compiler index 0fa8e364..a2fe75a8 100644 --- a/manual/Using the compiler +++ b/manual/Using the compiler @@ -14,7 +14,7 @@ on the command line for a list of options. === Compiler command line format - csc FILENAME-OR-OPTION + chicken FILENAME OPTION ... {{FILENAME}} is the pathname of the source file that is to be compiled. A filename argument of {{-}} (a single dash) specifies that @@ -24,7 +24,7 @@ the source text should be read from standard input. ; -analyze-only : Stop compilation after first analysis pass. -; -block : Enable block-compilation. When this option is specified, the compiler assumes that global variables are not modified outside this compilation-unit. Specifically, toplevel bindings are not seen by {{eval}} and unused toplevel bindings are removed. +; -block : Enable block-compilation. When this option is specified, the compiler assumes that global variables are not modified outside of this compilation-unit. Specifically, toplevel bindings are not seen by {{eval}} and unused toplevel bindings are removed. ; -case-insensitive : Enables the reader to read symbols case insensitive. The default is to read case sensitive (in violation of R5RS). This option registers the {{case-insensitive}} feature identifier. @@ -36,14 +36,9 @@ the source text should be read from standard input. ; -debug MODES : Enables one or more compiler debugging modes. {{MODES}} is a string of characters that select debugging information about the compiler that will be printed to standard output. Use {{-debug h}} to see a list of available debugging options. -; -debug-level LEVEL : Selects amount of debug-information. {{LEVEL}} should be an integer. +; -debug-level LEVEL : Selects amount of debug-information. {{LEVEL}} should be an integer, where {{0}} is equivalent to {{-no-trace -no-lambda-info}}, {{1}} is equivalent to {{-no-trace}}, {{2}} is the default behaviour and {{3}} is equivalent to {{-debug-mode}}. - -debug-level 0 is equivalent to -no-trace -no-lambda-info - -debug-level 1 is equivalent to -no-trace - -debug-level 2 is the default behaviour - -debug-level 3 is equivalent to -debug-info - -; -disable-interrupts : Equivalent to the {{(disable-interrupts)}} declaration. No interrupt-checks are generated for compiled programs. +; -disable-interrupts : Equivalent to the {{(disable-interrupts)}} declaration. No interrupt-checks are generated for compiled programs, which disables thread context switches in this (and only this) compilation unit. ; -disable-stack-overflow-checks : Disables detection of stack overflows. This is equivalent to running the compiled executable with the {{-:o}} runtime option. @@ -61,7 +56,7 @@ the source text should be read from standard input. ; -emit-link-file FILENAME : write a list of statically linked extensions to {{FILENAME}}, used for identifying the static objects that need to be linked to an executable. -; -emit-type-file FILENAME : Write type-information for declarations of user-defined and globally visible variables to a file of the given name. The generated file is suitable for use with the {{-consult-type-file}} option. +; -emit-types-file FILENAME : Write type-information for declarations of user-defined and globally visible variables to a file of the given name. The generated file is suitable for use with the {{-consult-types-file}} option. ; -explicit-use : Disables automatic use of the units {{library, eval}} and {{expand}}. Use this option if compiling a library unit instead of an application unit. @@ -69,15 +64,15 @@ the source text should be read from standard input. ; -feature SYMBOL : Registers {{SYMBOL}} to be a valid feature identifier for {{cond-expand}}. Multiple symbols may be given, if comma-separated. -; -fixnum-arithmetic : Equivalent to {{(fixnum-arithmetic)}} declaration. Assume all mathematical operations use small integer arguments. +; -fixnum-arithmetic : Equivalent to the {{(fixnum-arithmetic)}} declaration. Assume all mathematical operations use small integer arguments. -; -heap-size NUMBER : Sets a fixed heap size of the generated executable to {{NUMBER}} bytes. The parameter may be followed by a {{M}} ({{m}}) or {{K}} ({{k}}) suffix which stand for mega- and kilobytes, respectively. The default heap size is 5 kilobytes. Note that only half of it is in use at every given time. +; -heap-size NUMBER : Sets a fixed heap size of {{NUMBER}} bytes for the generated executable. The parameter may be followed by a {{M}} ({{m}}) or {{K}} ({{k}}) suffix which stand for mega- and kilobytes, respectively. The default heap size is 500 kilobytes. Note that only half of it is in use at every given time. Note also that by default the heap is dynamically resized unless this option is given. ; -help : Print a summary of available options and the format of the command line parameters and exit the compiler. -; -ignore-repository : Do not load any extensions from the repository (treat repository as empty). Also do not consult compiled (only interpreted) import libraries in {{import}} forms. +; -ignore-repository : Do not load any extensions from the repository (treat the repository as empty). Also do not consult compiled (only interpreted) import libraries in {{import}} forms. -; -include-path PATHNAME : Specifies an additional search path for files included via the {{include}} special form. This option may be given multiple times. If the environment variable {{CHICKEN_INCLUDE_PATH}} is set, it should contain a list of alternative include pathnames separated by {{:}} (unix) or {{;}} (windows). +; -include-path PATHNAME : Specifies an additional search path for files included via the {{include}} special form. This option may be given multiple times. If the environment variable {{CHICKEN_INCLUDE_PATH}} is set, it should contain a list of alternative include pathnames separated by {{:}} (UNIX) or {{;}} (Windows). ; -inline : Enable procedure inlining for known procedures of a size below the threshold (which can be set through the {{-inline-limit}} option). @@ -85,7 +80,7 @@ the source text should be read from standard input. ; -inline-limit THRESHOLD : Sets the maximum size of a potentially inlinable procedure. The default threshold is {{20}}. -; -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp, e.g. :keyword), {{suffix}} (as in DSSSL, e.g. keyword:) or {{none}}. Any other value is ignored. The default is {{suffix}}. +; -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp, e.g. :keyword), {{suffix}} (as in DSSSL, e.g. keyword:) or {{none}} (where only the {{#:KEYWORD}} is allowed). Any other value is ignored. The default is {{suffix}}. ; -keep-shadowed-macros : Do not remove macro definitions with the same name as assigned toplevel variables (the default is to remove the macro definition). @@ -101,11 +96,11 @@ the source text should be read from standard input. ; -no-bound-checks : disable bound variable checks -; -no-feature SYMBOL : Disables the predefined feature-identifier {{SYMBOL}}. Multiple symbols may be given, if comma-separated. +; -no-feature SYMBOL : Disables the predefined feature-identifier {{SYMBOL}}. Multiple comma-separated symbols may be given. -; -no-lambda-info : Don't emit additional information for each {{lambda}} expression (currently the argument-list, after alpha-conversion/renaming). +; -no-lambda-info : Do not emit additional information for each {{lambda}} expression (currently the argument-list, after alpha-conversion/renaming). -; -no-module-registration : Do not generate module-registration code in the compiled binary. Use this if you don't intend to expose modules from the currently compiled code to expressions executed via {{eval}}. +; -no-module-registration : Do not generate module-registration code in the compiled code. This is needed if you want to use an import library that is generated by other means (manually, for example), or when you do not intend to use modules in the program at runtime (using {{eval}}). ; -no-parentheses-synonyms : Disables list delimiter synonyms, [..] and {...} for (...). @@ -126,31 +121,24 @@ the source text should be read from standard input. ; -optimize-leaf-routines : Enable leaf routine optimization. -; -optimize-level LEVEL : Enables certain sets of optimization options. {{LEVEL}} should be an integer. - - -optimize-level 0 is equivalent to -no-usual-integrations -no-compiler-syntax - -optimize-level 1 is equivalent to -optimize-leaf-routines - -optimize-level 2 is equivalent to -optimize-leaf-routines -inline - -optimize-level 3 is equivalent to -optimize-leaf-routines -local -inline -inline-global -specialize - -optimize-level 4 is equivalent to -optimize-leaf-routines -local -inline -inline-global -specialize -unsafe - -optimize-level 5 is equivalent to -optimize-leaf-routines -block -inline -inline-global -specialize -unsafe -disable-interrupts -no-trace -no-lambda-info -clustering -lfa2 +; -optimize-level LEVEL : Enables certain sets of optimization options. {{LEVEL}} should be an integer. Level {{0}} is equivalent to {{-no-usual-integrations -no-compiler-syntax}} (no optimization), level {{1} is equivalent to {{-optimize-leaf-routines}} (minimal optimization), level {{2}} is equivalent to {{-optimize-leaf-routines -inline}} (enable optimizations that do not break standard compliance, this is the default), level {{3}} is equivalent to {{-optimize-leaf-routines -local -inline -inline-global -specialize}} (maximal optimization, while still "safe"), level {{4}} is equivalent to {{-optimize-leaf-routines -local -inline -inline-global -specialize -unsafe}} (maximal optimization, "unsafe") and any higher level is equivalent to {{-optimize-leaf-routines -block -inline -inline-global -specialize -unsafe -disable-interrupts -no-trace -no-lambda-info -clustering -lfa2}} (all possible optimizations, "unsafe"). -; -output-file FILENAME : Specifies the pathname of the generated C file. Default is {{FILENAME.c}}. +; -output-file FILENAME : Specifies the pathname of the generated C file. Default is to use the source filename with the extension replaced by {{.c}}. ; -postlude EXPRESSIONS : Add {{EXPRESSIONS}} after all other toplevel expressions in the compiled file. This option may be given multiple times. Processing of this option takes place after processing of {{-epilogue}}. ; -prelude EXPRESSIONS : Add {{EXPRESSIONS}} before all other toplevel expressions in the compiled file. This option may be given multiple times. Processing of this option takes place before processing of {{-prologue}}. ; -profile : -; -accumulate-profile : Instruments the source code to count procedure calls and execution times. After the program terminates (either via an explicit {{exit}} or implicitly), profiling statistics are written to a file named {{PROFILE.<randomnumber>}}. Each line of the generated file contains a list with the procedure name, the number of calls and the time spent executing it. Use the {{chicken-profile}} program to display the profiling information in a more user-friendly form. Enter {{chicken-profile -help}} at the command line to get a list of available options. The {{-accumulate-profile}} option is similar to {{-profile}}, but the resulting profile information will be appended to any existing {{PROFILE}} file. {{chicken-profile}} will merge and sum up the accumulated timing information, if several entries for the same procedure calls exist. Only profiling information for global procedures will be collected. See the {{-:p}} option under [[#runtime-options|"Runtime options"]] below for statistical profiling support. +; -accumulate-profile : Instruments the source code to count procedure calls and execution times. After the program terminates (either via an explicit {{exit}} or implicitly), profiling statistics are written to a file named {{PROFILE.<randomnumber>}}. Each line of the generated file contains a list with the procedure name, the number of calls and the time spent executing it. Use the {{chicken-profile}} program to display the profiling information in a more user-friendly form. Enter {{chicken-profile -help}} at the command line to get a list of available options. The {{-accumulate-profile}} option is similar to {{-profile}}, but the resulting profile information will be appended to any existing {{PROFILE}} file. {{chicken-profile}} will merge and sum up the accumulated timing information, if several entries for the same procedure calls exist. Only profiling information for global procedures will be collected. See the {{-:p}} option under [[#Runtime options|"Runtime options"]] below for statistical profiling support. ; -profile-name FILENAME : Specifies name of the generated profile information (which defaults to {{PROFILE.<randomnumber>}}. Implies {{-profile}}. ; -prologue FILENAME : Includes the file named {{FILENAME}} at the start of the compiled source file. The include-path is not searched. This option may be given multiple times. -; -r5rs-syntax : Disables the CHICKEN extensions to R5RS syntax. Does not disable [[Non-standard read syntax|non-standard read syntax]]. +; -r5rs-syntax : Disables the CHICKEN extensions to R5RS syntax. Does not disable non-standard read syntax. -; -raw : Disables the generation of any implicit code that uses the Scheme libraries (that is all runtime system files besides {{runtime.c}} and {{chicken.h}}). +; -raw : Disables the generation of any implicit code that uses the Scheme libraries (that is all runtime system files besides {{runtime.c}} and {{chicken.h}}). Use this only when you know what you are doing. ; -require-extension NAME : Loads the extension {{NAME}} before the compilation process commences. This is identical to adding {{(require-extension NAME)}} at the start of the compiled program. If {{-uses NAME}} is also given on the command line, then any occurrences of {{-require-extension NAME}} are replaced with {{(declare (uses NAME))}}. Multiple names may be given and should be separated by commas. @@ -160,9 +148,9 @@ the source text should be read from standard input. ; -static : Link extensions statically, if possible. -; -strict-types : Assume that the type of variables is not changed by assignments. This gives more type-information during specialization, but violating this assumption will result in unsafe and incorrectly behaving code. +; -strict-types : Assume that the type of variables is not changed by assignments. This gives more type-information during specialization, but violating this assumption will result in unsafe and incorrectly behaving code. Use with care. -; -consult-type-file FILENAME : load additional type database from {{FILENAME}}. Type-definitions in {{FILENAME}} will override previous type-definitions. +; -consult-types-file FILENAME : load additional type database from {{FILENAME}}. Type-definitions in {{FILENAME}} will override previous type-definitions. ; -compile-syntax : Makes macros also available at run-time. By default macros are not available at run-time. @@ -172,7 +160,7 @@ the source text should be read from standard input. ; -unsafe : Disable runtime safety checks. -; -uses NAME : Use definitions from the library unit {{NAME}}. This is equivalent to {{-prelude "(declare (uses NAME))"}}. Multiple arguments may be given, separated by {{,}}. +; -uses NAME : Use definitions from the library unit {{NAME}}. This is equivalent to {{-prelude "(declare (uses NAME))"}}. Multiple arguments may be given, separated by {{,}} (comma). ; -no-usual-integrations : Specifies that standard procedures and certain internal procedures may be redefined, and can not be inlined. This is equivalent to declaring {{(not usual-integrations)}}. @@ -195,17 +183,19 @@ to see a list of all supported options and short aliases to basic options. After successful compilation a C source file is generated and can be compiled with a C compiler. Executables generated with CHICKEN (and the -compiler itself) accept a small set of runtime options: +compiler itself) accept a small set of runtime options. These are filtered out +by the startup code and will not be contained in the result of +{{(command-line-arguments)}}. ; {{-:?}} : Shows a list of the available runtime options and exits the program. ; {{-:aNUMBER}} : Specifies the length of the buffer for recording a trace of the last invoked procedures. Defaults to 16. -; {{-:ANUMBER}} : Specifies fixed "temporary stack" size. This is used mostly for {{apply}}. If you supply a zero size (the default), the stack will be dynamically reallocated as needed. +; {{-:ANUMBER}} : Specifies fixed ''temporary stack'' size. This is used mostly for {{apply}}. If you supply a zero size (the default), the temorary stack will be dynamically reallocated as needed. ; {{-:b}} : Enter a read-eval-print-loop when an error is encountered. -; {{-:B}} : Sounds a bell (ASCII 7) on every major garbage collection. +; {{-:B}} : Sounds a bell (by writing ASCII 7 to stdout) on every major garbage collection. ; {{-:c}} : Forces console mode. Currently this is only used in the interpreter ({{csi}}) to force output of the {{#;N>}} prompt even if stdin is not a terminal (for example if running in an {{emacs}} buffer under Windows). @@ -215,7 +205,7 @@ compiler itself) accept a small set of runtime options: ; {{-:g}} : Prints information about garbage-collection. -; {{-:G}} : Force GUI mode (show error messages in dialog box, suitable for platform). +; {{-:G}} : Force GUI mode (show error messages in dialog box if running under MacOS X or Windows). ; {{-:H}} : Before terminating, dump heap usage to stderr. @@ -237,14 +227,12 @@ compiler itself) accept a small set of runtime options: ; {{-:PFREQUENCY}} : Same as {{-:p}} but set the sampling frequency in microseconds (default is 10000 microseconds or every 10 milliseconds). -; {{-:r}} : Writes trace output to stderr. This option has no effect with in files compiled with the {{-no-trace}} options. +; {{-:r}} : Writes trace output to stderr. This option has no effect in files compiled with the {{-no-trace}} options. ; {{-:sNUMBER}} : Specifies stack size. ; {{-:tNUMBER}} : Specifies symbol table size. -; {{-:w}} : Enables garbage collection of unused symbols. By default unused and unbound symbols are not garbage collected. - ; {{-:x}} : Raises uncaught exceptions of separately spawned threads in primordial thread. By default uncaught exceptions in separate threads are not handled, unless the primordial one explicitly joins them. When warnings are enabled (the default) and {{-:x}} is not given, a warning will be shown, though. Runtime argument values should be given as integers, optionally followed @@ -253,117 +241,8 @@ megabytes (suffixed with {{M}} or {{m}}), or gigabytes (suffixed with {{G}} or {{g}}). Runtime options may be combined, like {{-:dc}}, but everything following -an argument is ignored. So {{-:wh64m}} is OK, but {{-:h64mw}} will not -enable GC of unused symbols. - -=== Examples - -==== A simple example (with one source file) - -To compile a Scheme program (assuming a UNIX-like environment) consisting of a single source file, perform the following steps. - -===== Writing your source file - -In this example we will assume your source file is called {{foo.scm}}: - -<enscript highlight=scheme> -;;; foo.scm - -(define (fac n) - (if (zero? n) - 1 - (* n (fac (- n 1))) ) ) - -(write (fac 10)) -(newline) -</enscript> - -===== Compiling your program - -Compile the file {{foo.scm}}: - - % csc foo.scm - -This will produce the {{foo}} executable: - - % ls - foo foo.scm - -===== Running your program - -To run your newly compiled executable use: - - % ./foo - 3628800 - - -==== An example with multiple files - -If multiple bodies of Scheme code are to be combined into a single -executable, then we have to compile each file and link the resulting -object files together with the runtime system. - -Let's consider an example where your program consists of multiple source files. - -===== Writing your source files - -The declarations in these files specify which of the compiled files is the main -module, and which is the library module. An executable can only have -one main module, since a program has only a single entry-point. In this -case {{foo.scm}} is the main module, because it doesn't have a -{{unit}} declaration: - -<enscript highlight=scheme> -;;; foo.scm - -; The declaration marks this source file as dependant on the symbols provided -; by the bar unit: -(declare (uses bar)) - -(write (fac 10)) (newline) -</enscript> - -{{bar.scm}} will be our library: - -<enscript highlight=scheme> -;;; bar.scm - -; The declaration marks this source file as the bar unit. The names of the -; units and your files don't need to match. -(declare (unit bar)) - -(define (fac n) - (if (zero? n) - 1 - (* n (fac (- n 1))) ) ) -</enscript> - -===== Compiling and running your program - -You should compile your two files with the following commands: - - % csc -c bar.scm - % csc -c foo.scm - -That should produce two files, {{bar.o}} and {{foo.o}}. -They contain the code from your source files in compiled form. - -To link your compiled files use the following command: - - % csc foo.o bar.o -o foo - -This should produce the {{foo}} executable, which you can run just as in the previous example. -At this point you can also erase the {{*.o}} files. - -You could avoid one step and link the two files just as {{foo.scm}} is compiled: - - % csc -c bar.scm - % csc foo.scm bar.o -o foo - -Note that if you want to distribute your program, you might want it to -follow the GNU Coding Standards. One relatively easy way to achieve -this is to use Autoconf and Automake, two tools made for this specific -purpose. +an argument is ignored. So {{-:oh64m}} is OK, but {{-:h64mo}} will not +disable stack overflow checks. === Extending the compiler @@ -373,8 +252,7 @@ or compiled code specified using the {{-extend}} option are loaded and evaluated. The parameters {{user-options-pass}}, {{user-read-pass}}, {{user-preprocessor-pass}}, {{user-pass}} and {{user-post-analysis-pass}} can be set to procedures that are called to perform certain compilation -passes instead of the usual processing (for more information about -parameters see [[Supported language]]). +passes in addition to the usual processing. These parameters are provided by the {{(chicken compiler user-pass)}} module. @@ -403,79 +281,7 @@ Note that the macroexpansion/canonicalization phase of the compiler adds certain forms to the source program. These extra expressions are not seen by {{user-preprocessor-pass}}, but are seen by {{user-pass}}. -=== Distributing compiled C files - -It is relatively easy to create distributions of Scheme projects that -have been compiled to C. The runtime system of CHICKEN consists of only -two handcoded C files ({{runtime.c}} and {{chicken.h}}), plus the files -{{chicken-config.h}} and {{buildtag.h}}, which are generated by the -build process. All other modules of the runtime system and the extension -libraries are just compiled Scheme code. The following example shows a -minimal application, which should run without changes on most operating -systems, like Windows, Linux or FreeBSD (note however that static -binaries are not supported on Mac OS X). - -Take the following "Hello World" program: - -<enscript highlight=scheme> -; hello.scm - -(print "Hello, world!") -</enscript> - - % csc -t hello.scm -optimize-level 3 -output-file hello.c - -Compiled to C, we get {{hello.c}}. We need the files {{chicken.h}}, -{{chicken-config.h}}, {{buildtag.h}} and {{runtime.c}}, which contain -the basic runtime system, plus the library files {{build-version.c}}, -{{chicken-syntax.c}}, {{eval.c}}, {{expand.c}}, {{internal.c}}, -{{library.c}} and {{modules.c}}, which contain the same functionality as -the library that is linked into plain CHICKEN-compiled applications: - - % cd /tmp - % echo '(print "Hello World.")' > hello.scm - % csc -t hello.scm - % cp $CHICKEN_BUILD/build-version.c . - % cp $CHICKEN_BUILD/chicken-syntax.c . - % cp $CHICKEN_BUILD/eval.c . - % cp $CHICKEN_BUILD/expand.c . - % cp $CHICKEN_BUILD/internal.c . - % cp $CHICKEN_BUILD/library.c . - % cp $CHICKEN_BUILD/modules.c . - % cp $CHICKEN_BUILD/runtime.c . - % cp $CHICKEN_BUILD/chicken.h . - % cp $CHICKEN_BUILD/chicken-config.h . - % cp $CHICKEN_BUILD/buildtag.h . - % gcc -static -Os -fomit-frame-pointer -DHAVE_CHICKEN_CONFIG_H hello.c \ - build-version.c eval.c expand.c internal.c library.c modules.c runtime.c \ - -o hello -lm - -Once we have all the files together, we can create a tarball: - - % tar cf hello.tar hello.c build-version.c chicken-syntax.c eval.c \ - expand.c internal.c library.c modules.c runtime.c chicken.h \ - chicken-config.h buildtag.h - % gzip hello.tar - -This is naturally rather simplistic. Things like enabling dynamic -loading and selecting supported features of the host system would need -more configuration- and build-time support. All this can be addressed -using more elaborate build-scripts, makefiles or by using -autoconf/automake. - -The {{chicken-config.h}} file may contain incorrect settings for your -deployment target. Especially when the architecture is different. In -that case you will have to adjust the values as needed. - -Note that the size of the application can still be reduced by removing -any of the C files besides {{build-version.c}}, {{library.c}}, and -{{runtime.c}}, and compiling {{hello.scm}} with the {{-explicit-use}} -option. - -For more information, study the CHICKEN source code and/or ask on the CHICKEN -mailing list. - --- -Previous: [[Basic mode of operation]] +Previous: [[Using the interpreter]] -Next: [[Using the interpreter]] +Next: [[Deviations from the standard]] diff --git a/manual/Using the interpreter b/manual/Using the interpreter index 2891f090..d646ca87 100644 --- a/manual/Using the interpreter +++ b/manual/Using the interpreter @@ -6,64 +6,6 @@ CHICKEN provides an interpreter named {{csi}} for evaluating Scheme programs and expressions interactively. -=== Interpreter command line format - -{{csi {FILENAME|OPTION}}} - -where {{FILENAME}} specifies a file with Scheme source-code. If the -extension of the source file is {{.scm}}, it may be omitted. The -runtime options described in [[Using the compiler#Compiler command line format|Compiler command line format]] are also available -for the interpreter. If the environment variable {{CSI_OPTIONS}} -is set to a list of options, then these options are additionally passed -to every direct or indirect invocation of {{csi}}. Please note that -runtime options (like {{-:...}}) can not be passed using this method. -The options recognized by the interpreter are: - -; -- : Ignore everything on the command-line following this marker. Runtime options ({{-:...}}) are still recognized. - -; -i -case-insensitive : Enables the reader to read symbols case insensitive. The default is to read case sensitive (in violation of R5RS). This option registers the {{case-insensitive}} feature identifier. - -; -b -batch : Quit the interpreter after processing all command line options. - -; -e -eval EXPRESSIONS : Evaluate {{EXPRESSIONS}}. This option implies {{-batch}}, {{-no-init}} and {{-quiet}}, so no startup message will be printed and the interpreter exits after processing all {{-eval}} options and/or loading files given on the command-line. - -; -p -print EXPRESSIONS : Evaluate {{EXPRESSIONS}} and print the results of each expression using {{print}}. Implies {{-batch}}, {{-no-init}} and {{-quiet}}. - -; -P -pretty-print EXPRESSIONS : Evaluate {{EXPRESSIONS}} and print the results of each expression using {{pretty-print}}. Implies {{-batch}}, {{-no-init}} and {{-quiet}}. - -; -D -feature SYMBOL : Registers {{SYMBOL}} to be a valid feature identifier for {{cond-expand}} and {{feature?}}. - -; -h -help : Write a summary of the available command line options to standard output and exit. - -; -I -include-path PATHNAME : Specifies an alternative search-path for files included via the {{include}} special form. This option may be given multiple times. If the environment variable {{CHICKEN_INCLUDE_PATH}} is set, it should contain a list of alternative include pathnames separated by {{;}}. - -; -K -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp) or {{suffix}} (as in DSSSL). Any other value is ignored. - -; -n -no-init : Do not load initialization-file. If this option is not given and the file {{$HOME/.csirc}} exists, then it is loaded before the read-eval-print loop commences. - -; -no-parentheses-synonyms : Disables list delimiter synonyms, [..] and {...} for (...). - -; -no-symbol-escape : Disables support for escaped symbols, the |...| form. - -; -w -no-warnings : Disables any warnings that might be issued by the reader or evaluated code. - -; -q -quiet : Do not print a startup message. Also disables generation of call-trace information for interpreted code. - -; -r5rs-syntax : Disables the CHICKEN extensions to R5RS syntax. Does not disable [[Non-standard read syntax|non-standard read syntax]]. - -; -s -script PATHNAME : This is equivalent to {{-batch -quiet -no-init PATHNAME}}. Arguments following {{PATHNAME}} are available by using {{command-line-arguments}} and are not processed as interpreter options. Extra options in the environment variable {{CSI_OPTIONS}} are ignored. - -; -sx PATHNAME : The same as {{-s PATHNAME}} but prints each expression to {{(current-error-port)}} before it is evaluated. - -; -ss PATHNAME : The same as {{-s PATHNAME}} but invokes the procedure {{main}} with the value of {{(command-line-arguments)}} as its single argument. If the main procedure returns an integer result, then the interpreter is terminated, returning the integer as the status code back to the invoking process. Any other result terminates the interpreter with a zero exit status. - -; -setup-mode : When locating extensions, search the current directory first. By default, extensions are located first in the ''extension repository'', where {{chicken-install}} stores compiled extensions and their associated metadata. - -; -R -require-extension NAME : Equivalent to evaluating {{(require-extension NAME)}}. - -; -v -version : Write the banner with version information to standard output and exit. - - === Writing Scheme scripts Since UNIX shells use the {{#!}} notation for starting scripts, @@ -84,7 +26,7 @@ The easiest way is to use the {{-script}} option like this: The parameter {{command-line-arguments}} is set to a list of the parameters that were passed to the Scheme script. Scripts can be compiled -to standalone executables (don't forget to declare used library units). +to standalone executables. CHICKEN supports writing shell scripts in Scheme for other platforms as well, using a slightly different approach. The first example would look like @@ -189,19 +131,7 @@ The toplevel loop understands a number of special commands: ; ,x EXP : Pretty-print macroexpanded expression {{EXP}} (the expression is not evaluated). You can define your own toplevel commands using the {{toplevel-command}} -procedure: - - -=== toplevel-command - -<procedure>(toplevel-command SYMBOL PROC [HELPSTRING])</procedure> - -Defines or redefines a toplevel interpreter command which can be invoked by entering -{{,SYMBOL}}. {{PROC}} will be invoked when the command is entered and may -read any required argument via {{read}} (or {{read-line}}). If the optional -argument {{HELPSTRING}} is given, it will be listed by the {{,?}} command. - -This procedure is provided by the {{(chicken csi)}} module. +procedure (see [[Module (chicken csi)]]). === Getting error information @@ -245,7 +175,8 @@ variable lookup done internally by the interpreter. The {{,e}} command runs the editor given by: -* The parameter {{editor-command}} which should return a string naming +* The parameter {{editor-command}} in the {{(chicken csi)}} module should + return a string naming an external editor and defaults to {{#f}}, which means no editor is currently selected (so the following alternatives are tried). @@ -253,44 +184,26 @@ The {{,e}} command runs the editor given by: * If the environment variable {{EMACS}} is set, the editor chosen is {{emacsclient}}. -* As a truly last resort, {{vi}} is used. +* In a desparate attempt to find an editor, {{vi}} is used. === History access -The interpreter toplevel accepts the special object {{#[INDEX]}} which +The interpreter toplevel accepts the special object {{#INDEX}} which returns the result of entry number {{INDEX}} in the history list. If the expression for that entry resulted in multiple values, the first result (or an unspecified value for no values) is returned. If no {{INDEX}} is given (and if a whitespace or closing paranthesis character follows the {{#}}, then the result of the last expression is -returned. Note that the value returned is implicitly quoted. +returned. Note that the value that {{#INDEX}} stands for is an expression, +not a literal, and so is implicitly quoted, so -=== set-describer! + #;1> 123 + 123 + #;2> '(1 2 #) -<procedure>(set-describer! TAG PROC)</procedure> +will not return the result you expected. -Sets a custom description handler that invokes {{PROC}} when the -{{,d}} command is invoked with a record-type object that has the type -{{TAG}} (a symbol). {{PROC}} is called with two arguments: the object -to be described and an output-port. It should write a possibly useful -textual description of the object to the passed output-port. For -example: - - #;1> (define-record-type point (make-point x y) point? - (x point-x) - (y point-y)) - #;2> (set-describer! 'point - (lambda (pt o) - (with-output-to-port o - (lambda () - (print "a point with x=" (point-x pt) " and y=" (point-y pt)))))) - #;3> ,d (make-point 1 2) - a point with x=1 and y=2 - -This procedure is provided by the {{(chicken csi)}} module. - - -=== Auto-completion and edition +=== Auto-completion and editing On platforms that support it, it is possible to get auto-completion of symbols, history (over different {{csi}} sessions) and a more @@ -304,7 +217,66 @@ instead. It should work on almost any system but is not as feature-rich as readline (e.g. it lacks reverse-i-search and auto-completion). + +=== csi command line format + +{{csi {FILENAME|OPTION}}} + +where {{FILENAME}} specifies a file with Scheme source-code. If the +extension of the source file is {{.scm}}, it may be omitted. The +runtime options described in [[Using the compiler#Compiler command line format|Compiler command line format]] are also available +for the interpreter. If the environment variable {{CSI_OPTIONS}} +is set to a list of options, then these options are additionally passed +to every direct or indirect invocation of {{csi}}. Please note that +runtime options (like {{-:...}}) can not be passed using this method. +The options recognized by the interpreter are: + +; -- : Ignore everything on the command-line following this marker. Runtime options ({{-:...}}) are still recognized. + +; -i -case-insensitive : Enables the reader to read symbols case insensitive. The default is to read case sensitive (in violation of R5RS). This option registers the {{case-insensitive}} feature identifier. + +; -b -batch : Quit the interpreter after processing all command line options. + +; -e -eval EXPRESSIONS : Evaluate {{EXPRESSIONS}}. This option implies {{-batch}}, {{-no-init}} and {{-quiet}}, so no startup message will be printed and the interpreter exits after processing all {{-eval}} options and/or loading files given on the command-line. + +; -p -print EXPRESSIONS : Evaluate {{EXPRESSIONS}} and print the results of each expression using {{print}}. Implies {{-batch}}, {{-no-init}} and {{-quiet}}. + +; -P -pretty-print EXPRESSIONS : Evaluate {{EXPRESSIONS}} and print the results of each expression using {{pretty-print}}. Implies {{-batch}}, {{-no-init}} and {{-quiet}}. + +; -D -feature SYMBOL : Registers {{SYMBOL}} to be a valid feature identifier for {{cond-expand}} and {{feature?}}. + +; -h -help : Write a summary of the available command line options to standard output and exit. + +; -I -include-path PATHNAME : Specifies an alternative search-path for files included via the {{include}} special form. This option may be given multiple times. If the environment variable {{CHICKEN_INCLUDE_PATH}} is set, it should contain a list of alternative include pathnames separated by {{:}} (UNIX) or {{;}} (Windows). + +; -K -keyword-style STYLE : Enables alternative keyword syntax, where {{STYLE}} may be either {{prefix}} (as in Common Lisp) or {{suffix}} (as in DSSSL). Any other value is ignored. + +; -n -no-init : Do not load initialization-file. If this option is not given and the file {{$HOME/.csirc}} exists, then it is loaded before the read-eval-print loop commences. + +; -no-parentheses-synonyms : Disables list delimiter synonyms, [..] and {...} for (...). + +; -no-symbol-escape : Disables support for escaped symbols, the |...| form. + +; -w -no-warnings : Disables any warnings that might be issued by the reader or evaluated code. + +; -q -quiet : Do not print a startup message. Also disables generation of call-trace information for interpreted code. + +; -r5rs-syntax : Disables the CHICKEN extensions to R5RS syntax. Does not disable non-standard read syntax. + +; -s -script PATHNAME : This is equivalent to {{-batch -quiet -no-init PATHNAME}}. Arguments following {{PATHNAME}} are available by using {{command-line-arguments}} and are not processed as interpreter options. Extra options in the environment variable {{CSI_OPTIONS}} are ignored. + +; -sx PATHNAME : The same as {{-s PATHNAME}} but prints each expression to {{(current-error-port)}} before it is evaluated. + +; -ss PATHNAME : The same as {{-s PATHNAME}} but invokes the procedure {{main}} with the value of {{(command-line-arguments)}} as its single argument. If the main procedure returns an integer result, then the interpreter is terminated, returning the integer as the status code back to the invoking process. Any other result terminates the interpreter with a zero exit status. + +; -setup-mode : When locating extensions, search the current directory first. By default, extensions are located first in the ''extension repository'', where {{chicken-install}} stores compiled extensions and their associated metadata. + +; -R -require-extension NAME : Equivalent to evaluating {{(require-extension NAME)}}. + +; -v -version : Write the banner with version information to standard output and exit. + + --- -Previous: [[Using the compiler]] +Previous: [[Getting started]] -Next: [[Supported language]] +Next: [[Using the compiler]] diff --git a/manual/faq b/manual/faq deleted file mode 100644 index a1669ba7..00000000 --- a/manual/faq +++ /dev/null @@ -1,868 +0,0 @@ -[[toc:]] -[[tags:faq manual]] - -== FAQ - -This is the list of Frequently Asked Questions about CHICKEN Scheme. -If you have a question not answered here, feel free to post to the chicken-users mailing list; -if you consider your question general enough, feel free to add it to this list. - -=== General - -==== Why yet another Scheme implementation? - -Since Scheme is a relatively simple language, a large number of implementations exist and -each has its specific advantages and disadvantages. Some are fast, some provide a rich -programming environment. Some are free, others are tailored to specific domains, and so on. The reasons -for the existence of CHICKEN are: - -* CHICKEN is portable because it generates C code that runs on a large number of platforms. - -* CHICKEN is extensible, since its code generation scheme and runtime system/garbage collector fits neatly into a C environment. - -* CHICKEN is free and can be freely distributed, including its source code. - -* CHICKEN offers better performance than nearly all interpreter based implementations, but still provides full Scheme semantics. - -* As far as we know, CHICKEN is the first implementation of Scheme that uses Henry Baker's [[http://home.pipeline.com/~hbaker1/CheneyMTA.html|Cheney on the M.T.A]] concept. - -==== What should I do if I find a bug? - -Fill a ticket at [[http://bugs.call-cc.org|bugs.call-cc.org]] with -some hints about the problem, like version/build of the compiler, -platform, system configuration, code that causes the bug, etc. - - -=== Specific - -==== Why are values defined with {{define-foreign-variable}} or {{define-constant}} or {{define-inline}} not seen outside of the containing source file? - -Accesses to foreign variables are translated directly into C constructs that access the variable, -so the Scheme name given to that variable does only exist during compile-time. -The same goes for constant- and inline-definitions: The name is only there to tell the compiler -that this reference is to be replaced with the actual value. - -==== How does {{cond-expand}} know which features are registered in used units? - -Each unit used via {{(declare (uses ...))}} is registered as a feature and -so a symbol with the unit-name can be tested by {{cond-expand}} during macro-expansion-time. -Features registered using the {{register-feature!}} procedure are only -available during run-time of the compiled file. You can use the {{eval-when}} form -to register features at compile time. - -==== Why are constants defined by {{define-constant}} not honoured in {{case}} constructs? - -{{case}} expands into a cascaded {{if}} expression, where the first item in each arm -is treated as a quoted list. So the {{case}} macro can not infer whether -a symbol is to be treated as a constant-name (defined via {{define-constant}}) or -a literal symbol. - - -==== How can I enable case sensitive reading/writing in user code? - -To enable the {{read}} procedure to read symbols and identifiers case sensitive, you can set the -parameter {{case-sensitivity}} to {{#t}}. - - -==== Why doesn't CHICKEN support the full numeric tower by default? - -The short answer is to use the [[/egg/numbers|numbers]] egg: - -<enscript highlight=scheme> -% chicken-install numbers -% csi -q -#;1> (import numbers) -</enscript> - -The long answer: - -There are a number of reasons for this: - -- For most applications of Scheme fixnums (exact word-sized integers) and flonums (64-bit floating-point -numbers) are more than sufficient; - -- Interfacing to C is simpler; - -- Dispatching of arithmetic operations is more efficient. - - -==== Does CHICKEN support native threads? - -Native threads are not supported for two reasons. One, the runtime -system is not reentrant. Two, concurrency implemented properly would -require mandatory locking of every object that could be potentially -shared between two threads. The garbage-collection algorithm would -then become much more complex and inefficient, since the location of -every object has to be accessed via a thread synchronization -protocol. Such a design would make native threads in CHICKEN -essentially equivalent to Unix processes and shared memory. - -For a different approach to concurrency, please see the -[[/egg/mpi|mpi]] or -[[/egg/concurrent-native-callbacks|concurrent-native-callbacks]] egg. - -[[http://www.stylewarning.com/blog/about|Robert Smith]] has put -[[http://www.stylewarning.com/blog/bounties|a bounty]] on a -release-quality implementation of native threads. - -==== Does CHICKEN support Unicode strings? - -The system does not directly support Unicode, but there is an extension for UTF-8 strings: [[/egg/utf8|utf8]]. - -=== Why are `dynamic-wind' thunks not executed when a thread signals an error? - -Here is what Marc Feeley, the author of [[http://srfi.schemers.org/srfi-18|SRFI-18]] has to -say about this subject: - - >No the default exception handler shouldn't invoke the after - > thunks of the current continuation. That's because the - > exception handler doesn't "continue" at the initial - > continuation of that thread. Here are the relevant words of - > SRFI 18: - - > - > Moreover, in this dynamic environment the exception handler - > is bound to the "initial exception handler" which is a unary - > procedure which causes the (then) current thread to store in - > its end-exception field an "uncaught exception" object whose - > "reason" is the argument of the handler, abandon all mutexes - > it owns, and finally terminate. - > - - >The rationale is that, when an uncaught exception occurs in a - >thread the thread is in bad shape and things have gone - >sufficiently wrong that there is no universally acceptable way to - >continue execution. Executing after thunks could require a - >whole lot of processing that the thread is not in a shape to do. - >So the safe thing is to terminate the thread. If the programmer - >knows how to recover from an exception, then he can capture the - >continuation early on, and install an exception handler which - >invokes the continuation. When the continuation is invoked the - >after thunks will execute. - - -=== Platform specific - -==== How do I generate a DLL under MS Windows (tm) ? - -Use {{csc}} in combination with the {{-dll}} option: - -{{C:\> csc foo.scm -dll}} - -==== How do I generate a GUI application under Windows(tm)? - -Invoke {{csc}} with the {{-gui}} option. In GUI-mode, the runtime -system displays error messages in a message box and does some -rudimentary command-line parsing. - -==== Compiling very large files under Windows with the Microsoft C compiler fails with a message indicating insufficient heap space. - -It seems that the Microsoft C compiler can only handle files up to a certain size, and it doesn't utilize virtual memory as -well as the GNU C compiler, for example. Try closing running applications. If that fails, try to break up the Scheme code -into several library units. - -==== When I run {{csi}} inside an emacs buffer under Windows, nothing happens. - -Invoke {{csi}} with the {{-:c}} runtime option. Under Windows the interpreter thinks it -is not running under control of a terminal and doesn't print the prompt and does not flush the output stream properly. - -==== On Windows, {{csc.exe}} seems to be doing something wrong. - -The Windows development tools include a C# compiler with the same name. Either invoke {{csc.exe}} with a full -pathname, or put the directory where you installed CHICKEN in front of the MS development tool path in the {{PATH}} -environment variable. - -==== On Windows source and/or output filenames with embedded whitespace are not found. - -There is no current workaround. Do not use filenames with embedded whitespace for code. However, command -names with embedded whitespace will work correctly. -=== Customization - - -==== How do I run custom startup code before the runtime-system is invoked? - -When you invoke the C compiler for your translated Scheme source program, add the C compiler option -{{-DC_EMBEDDED}}, or pass {{-embedded}} to the {{csc}} -driver program, so no entry-point function will be generated ({{main()}}). -When your are finished with your startup processing, invoke: - -<enscript highlight=c> -CHICKEN_main(argc, argv, C_toplevel); -</enscript> - -where {{C_toplevel}} is the entry-point into the compiled Scheme code. You -should add the following declarations at the head of your code: - -<enscript highlight=c> -#include "chicken.h" -extern void C_toplevel(C_word,C_word,C_word) C_noret; -</enscript> - -==== How can I add compiled user passes? - -To add a compiled user pass instead of an interpreted one, create a library unit and recompile -the main unit of the compiler (in the file {{chicken.scm}}) with an additional {{uses}} -declaration. Then link all compiler modules and your (compiled) extension to create a new version of -the compiler, like this (assuming all sources are in the -current directory): - -<enscript highlight=scheme> - % cat userpass.scm - ;;;; userpass.scm - My very own compiler pass - - (declare (unit userpass)) - - ;; Perhaps more user passes/extensions are added: - (let ([old (user-pass)]) - (user-pass - (lambda (x) - (let ([x2 (do-something-with x)]) - (if old - (old x2) - x2) ) ) ) ) -</enscript> - - % csc -c -x userpass.scm - % csc chicken.scm -c -o chicken-extended.o -uses userpass - % gcc chicken-extended.o support.o easyffi.o compiler.o optimizer.o batch-driver.o c-platform.o \ - c-backend.o userpass.o `csc -ldflags -libs` -o chicken-extended - -On platforms that support it (Linux ELF, Solaris, Windows + VC++), compiled code can be loaded via {{-extend}} -just like source files (see {{load}} in the User's Manual). - - -=== Macros - -==== Where is {{define-macro}}? - -With CHICKEN 4, the macro-expansion subsystem is now hygienic where old Lisp-style low-level macros -are not available anymore. {{define-syntax}} can define hygienic macros using {{syntax-rules}} -or low-level macros with user-controlled hygienic with ''explicit renaming'' macros. Translating -old-style macros into ER-macros isn't that hard, see [[Macros]] for more information. - -==== Why are low-level macros defined with {{define-syntax}} complaining about unbound variables? - -Macro bodies that are defined and used in a compiled source-file are -evaluated during compilation and so have no access to anything created with {{define}}. Use {{define-for-syntax}} instead. - -==== Why isn't {{load}} properly loading my library of macros? - -During compile-time, macros are only available in the source file in which they are defined. Files included via {{include}} are considered part of the containing file. - -=== Warnings and errors - -==== Why does my program crash when I use callback functions (from Scheme to C and back to Scheme again)? - -There are two reasons why code involving callbacks can crash out of no apparent reason: - -# It is important to use {{foreign-safe-lambda/foreign-safe-lambda*}} for the C code that is to call back into Scheme. If this is not done than sooner or later the available stack space will be exhausted. - -# If the C code uses a large amount of stack storage, or if Scheme-to-C-to-Scheme calls are nested deeply, then the available nursery space on the stack will run low. To avoid this it might be advisable to run the compiled code with a larger nursery setting, i.e. run the code with {{-:s...}} and a larger value than the default (for example {{-:s300k}}), or use the {{-nursery}} compiler option. Note that this can decrease runtime performance on some platforms. - -==== Why does the linker complain about a missing function {{_C_..._toplevel}}? - -This message indicates that your program uses a library-unit, but that the -object-file or library was not supplied to the linker. If you have the unit -{{foo}}, which is contained in {{foo.o}} than you have to supply it to the -linker like this (assuming a GCC environment): - -{{% csc program.scm foo.o -o program}} - -==== Why does the linker complain about a missing function {{_C_toplevel}}? - -This means you have compiled a library unit as an application. When a unit-declaration (as in {{(declare (unit ...))}}) -is given, then this file has a specially named toplevel entry procedure. Just remove the declaration, -or compile this file to an object-module and link it to your application code. - -==== Why does my program crash when I compile a file with {{-unsafe}} or unsafe declarations? - -The compiler option {{-unsafe}} or the declaration {{(declare (unsafe))}} disable -certain safety-checks to improve performance, so code that would normally -trigger an error will work unexpectedly or even crash the running application. -It is advisable to develop and debug a program in safe mode (without unsafe -declarations) and use this feature only if the application works properly. - -==== Why don't toplevel-continuations captured in interpreted code work? - -Consider the following piece of code: - -<enscript highlight=scheme> -(define k (call-with-current-continuation (lambda (k) k))) -(k k) -</enscript> - -When compiled, this will loop endlessly. But when interpreted, {{(k k)}} will return -to the read-eval-print loop! This happens because the continuation captured will eventually read the -next toplevel expression from the standard-input (or an input-file if loading from a file). At the moment -{{k}} was defined, the next expression was {{(k k)}}. But when {{k}} -is invoked, the next expression will be whatever follows after {{(k k)}}. -In other words, invoking a captured continuation will not rewind the file-position of the input source. -A solution is to wrap the whole code into a {{(begin ...)}} expression, so all toplevel -expressions will be loaded together. - -==== Why does {{define-reader-ctor}} not work in my compiled program? - -The following piece of code does not work as expected: - -<enscript highlight=scheme> - (eval-when (compile) - (define-reader-ctor 'integer->char integer->char) ) - (print #,(integer->char 33)) -</enscript> - -The problem is that the compiler reads the complete source-file before doing any processing on it, -so the sharp-comma form is encountered before the reader-ctor is defined. A possible solution is to include -the file containing the sharp-comma form, like this: - -<enscript highlight=scheme> - (eval-when (compile) - (define-reader-ctor 'integer->char integer->char) ) - - (include "other-file") -</enscript> - -<enscript highlight=scheme> - ;;; other-file.scm: - (print #,(integer->char 33)) -</enscript> - -==== Why do built-in units, such as srfi-4 and posix fail to load? - -When you try to {{use}} a built-in unit such as {{posix}}, you may get the following error: - -<enscript highlight=scheme> - #;1> (import posix) - ; loading library posix ... - Error: (load-library) unable to load library - posix - "dlopen(libchicken.dylib, 9): image not found" ;; on a Mac - "libchicken.so: cannot open shared object file: No such file or directory" ;; Linux -</enscript> - -Another symptom is that {{(require 'posix)}} will silently fail. - -This typically happens because the CHICKEN libraries have been installed in a non-standard location, such as your home directory. The workaround is to explicitly tell the dynamic linker where to look for your libraries: - - export DYLD_LIBRARY_PATH=~/scheme/chicken/lib:$DYLD_LIBRARY_PATH ;; Mac - export LD_LIBRARY_PATH=~/scheme/chicken/lib:$LD_LIBRARY_PATH ;; Linux - -==== How can I increase the size of the trace shown when runtime errors are detected? - -When a runtime error is detected, CHICKEN will print the last entries from the trace of functions called -(unless your executable was compiled with the {{-no-trace}} option. -By default, only 16 entries will be shown. -To increase this number pass the {{-:aN}} parameter to your executable. - - -=== Optimizations - -==== How can I obtain smaller executables? - -If you don't need {{eval}} or the stuff in the {{extras}} library unit, -you can just use the {{library}} unit: - -<enscript highlight=scheme> - (declare (uses library)) - (display "Hello, world!\n") -</enscript> - -(Don't forget to compile with the {{-explicit-use}} option) -Compiled with Visual C++ this generates an executable of around 240 kilobytes. -It is theoretically possible to compile something without the library, but -a program would have to implement quite a lot of support code on its own. - -==== How can I obtain faster executables? - -There are a number of declaration specifiers that should be used to speed up -compiled files: declaring {{(standard-bindings)}} is mandatory, since this enables -most optimizations. Even if some standard procedures should be redefined, you can -list untouched bindings in the declaration. -Declaring {{(extended-bindings)}} lets the compiler choose faster versions of certain -internal library functions. This might give another speedup. You can also use the -the {{usual-integrations}} declaration, which is identical to declaring -{{standard-bindings}} and {{extended-bindings}} -(note that {{usual-integrations}} is set by default). -Declaring {{(block)}} tells the compiler that global procedures are not changed -outside the current compilation unit, this gives the compiler some more -opportunities for optimization. -If no floating point arithmetic is required, then declaring {{(number-type fixnum)}} -can give a big performance improvement, because the compiler can now inline -most arithmetic operations. -Declaring {{(unsafe)}} will switch off most safety checks. -If threads are not used, you can declare {{(disable-interrupts)}}. -You should always use maximum optimizations settings for your C compiler. -Good GCC compiler options on Pentium (and compatible) hardware are: -{{-Os -fomit-frame-pointer -fno-strict-aliasing}} -Some programs are very sensitive to the setting of the nursery (the first heap-generation). You -should experiment with different nursery settings (either by compiling with the {{-nursery}} -option or by using the {{-:s...}} runtime option). - -==== Which non-standard procedures are treated specially when the {{extended-bindings}} or {{usual-integrations}} declaration or compiler option is used? - -The following standard bindings are handled specially, depending on optimization options -and compiler settings: - -{{*}} -{{+}} -{{-}} -{{/}} -{{<=}} -{{<}} -{{=}} -{{>=}} -{{>}} -{{abs}} -{{acos}} -{{append}} -{{apply}} -{{asin}} -{{assoc}} -{{assv}} -{{atan}} -{{boolean?}} -{{c...r}} -{{call-with-current-continuation}} -{{call-with-values}} -{{ceiling}} -{{char->integer}} -{{char-alphabetic?}} -{{char-downcase}} -{{char-lower-case?}} -{{char-numeric?}} -{{char-upcae}} -{{char-upper-case?}} -{{char-whitespace?}} -{{char<=?}} -{{char<?}} -{{char=?}} -{{char>=?}} -{{char>?}} -{{char?}} -{{complex?}} -{{cons}} -{{cos}} -{{current-input-port}} -{{current-output-port}} -{{eof-object?}} -{{eq?}} -{{equal?}} -{{eqv?}} -{{even?}} -{{exact->inexact}} -{{exact?}} -{{exp}} -{{floor}} -{{for-each}} -{{gcd}} -{{inexact->exact}} -{{inexact?}} -{{integer->char}} -{{lcm}} -{{length}} -{{list-ref}} -{{list-tail}} -{{list?}} -{{list}} -{{log}} -{{make-vector}} -{{map}} -{{member}} -{{memq}} -{{memv}} -{{make-polar}} -{{make-rectangular}} -{{negative?}} -{{not}} -{{null?}} -{{number->string}} -{{number?}} -{{odd?}} -{{pair?}} -{{positive?}} -{{procedure?}} -{{quotient}} -{{rational?}} -{{read-string}} -{{real?}} -{{remainder}} -{{reverse}} -{{round}} -{{set-car!}} -{{set-cdr!}} -{{sin}} -{{sqrt}} -{{string->number}} -{{string-append}} -{{string-ci=?}} -{{string-length}} -{{string-ref}} -{{string-set!}} -{{string=?}} -{{string?}} -{{string}} -{{substring}} -{{symbol?}} -{{tan}} -{{truncate}} -{{values}} -{{vector-length}} -{{vector-ref}} -{{vector-set!}} -{{vector?}} -{{vector}} -{{write-char}} -{{zero?}} - -The following extended bindings are handled specially: - -{{add1}} -{{arithmetic-shift}} -{{atom?}} -{{bignum?}} -{{bit-set?}} -{{bitwise-and}} -{{bitwise-ior}} -{{bitwise-not}} -{{bitwise-xor}} -{{blob-size}} -{{block-ref}} -{{block-set!}} -{{call/cc}} -{{call-with-input-file}} -{{call-with-output-file}} -{{current-error-port}} -{{current-thread}} -{{error}} -{{f32vector->blob/shared}} -{{f32vector-length}} -{{f32vector-ref}} -{{f64vector->blob/shared}} -{{f64vector-length}} -{{f64vector-ref}} -{{finite?}} -{{fixnum?}} -{{flonum?}} -{{flush-output}} -{{foldl}} -{{foldr}} -{{format}} -{{fp*}} -{{fp+}} -{{fp-}} -{{fp/}} -{{fp<=}} -{{fp<}} -{{fp=}} -{{fp>=}} -{{fp>}} -{{fpabs}} -{{fpacos}} -{{fpasin}} -{{fpatan2}} -{{fpatan}} -{{fpceiling}} -{{fpcos}} -{{fpexpt}} -{{fpexp}} -{{fpfloor}} -{{fpinteger?}} -{{fplog}} -{{fpmax}} -{{fpmin}} -{{fpneg}} -{{fprintf}} -{{fpround}} -{{fpsin}} -{{fpsqrt}} -{{fptan}} -{{fptruncate}} -{{fx*?}} -{{fx*}} -{{fx+?}} -{{fx+}} -{{fx-?}} -{{fx-}} -{{fx/?}} -{{fx/}} -{{fx=}} -{{fx>=}} -{{fx>}} -{{fxand}} -{{fxeven?}} -{{fxior}} -{{fxmax}} -{{fxmin}} -{{fxmod}} -{{fxneg}} -{{fxnot}} -{{fxodd?}} -{{fxrem}} -{{fxshl}} -{{fxshr}} -{{fxxor}} -{{identity}} -{{infinite?}} -{{list->string}} -{{list->vector}} -{{locative->object}} -{{locative-ref}} -{{locative-set!}} -{{locative?}} -{{make-record-instance}} -{{nan?}} -{{number-of-slots}} -{{o}} -{{pointer+}} -{{pointer->object}} -{{pointer-f32-ref}} -{{pointer-f32-set!}} -{{pointer-f64-ref}} -{{pointer-f64-set!}} -{{pointer-s16-ref}} -{{pointer-s16-set!}} -{{pointer-s32-ref}} -{{pointer-s32-set!}} -{{pointer-s8-ref}} -{{pointer-s8-set!}} -{{pointer-u16-ref}} -{{pointer-u16-set!}} -{{pointer-u32-ref}} -{{pointer-u32-set!}} -{{pointer-u8-ref}} -{{pointer-u8-set!}} -{{pointer=?}} -{{print*}} -{{printf}} -{{print}} -{{s16vector->blob/shared}} -{{s16vector-length}} -{{s16vector-ref}} -{{s16vector-set!}} -{{s32vector->blob/shared}} -{{s32vector-length}} -{{s32vector-ref}} -{{s32vector-set!}} -{{s64vector->blob/shared}} -{{s64vector-length}} -{{s64vector-ref}} -{{s64vector-set!}} -{{s8vector->blob/shared}} -{{s8vector-length}} -{{s8vector-ref}} -{{s8vector-set!}} -{{signum}} -{{sprintf}} -{{string-append}} -{{string->list}} -{{sub1}} -{{substring}} -{{substring-ci=?}} -{{substring-index-ci}} -{{substring-index}} -{{substring=?}} -{{u16vector->blob/shared}} -{{u16vector-length}} -{{u16vector-ref}} -{{u16vector-set!}} -{{u32vector->blob/shared}} -{{u32vector-length}} -{{u32vector-ref}} -{{u32vector-set!}} -{{u64vector->blob/shared}} -{{u64vector-length}} -{{u64vector-ref}} -{{u64vector-set!}} -{{u8vector->blob/shared}} -{{u8vector-length}} -{{u8vector-ref}} -{{u8vector-set!}} -{{vector->list}} - -==== What's the difference betweem "block" and "local" mode? - -In {{block}} mode, the compiler assumes that definitions in the current file -are not visible from outside of the current compilation unit, so unused -definitions can be removed and calls can be inlined. In {{local}} mode, -definitions are not hidden, but the compiler assumes that they are -not modified from other compilation units (or code evaluated at runtime), -and thus allows inlining of them. - -==== Can I load compiled code at runtime? - -Yes. You can load compiled at code at runtime with {{load}} just as -well as you can load Scheme source code. Compiled code will, of -course, run faster. - -To do this, pass to {{load}} a path for a shared object. Use a form -such as {{(load "foo.so")}} and run {{csc -shared foo.scm}} to produce -{{foo.so}} from {{foo.scm}} (at which point {{foo.scm}} will no longer -be required). - -If you have compiled code that contains a {{module}} definition, then -executing the code will "register" the module to allow importing the -bindings provided by the module into a running Scheme process. -The information required to use a module is in this case embedded in -the compiled code. Compiling another program that uses this (compiled) -module is more difficult: the used module will not necessarily be loaded -into the compiler, so the registration will not be executed. In this -case the information about what bindings the compiled module exports -must be separated from the actual code that executes at runtime. -To make this possible, compiling a module can be done in such a -manner that an "import library" is created. This is a file that -contains the binding information of the module and we can use it -to compile a file that refers to that module. An example can perhaps -make this clearer: - - ;; my-module.scm - - (module my-module (...) ...) - - ;; use-my-module.scm - - (import my-module) - ... - -Compile the module and generate an import library for the "my-module" module: - - % csc -s my-module.scm -emit-import-library my-module - -Compile the program that uses the module: - - % csc use-my-module.scm - -==== Why is my program which uses regular expressions so slow? - -The regular expression engine has recently been replaced by [[/users/alex shinn|alex shinn]]'s excellent -{{irregex}} library, which is fully implemented in Scheme. Precompiling regular -expressions to internal forms is somewhat slower than with the old PCRE-based -regex engine. It is advisable to use {{irregex}} to precompile regular expressions -outside of time-critical loops and use them where performance matters. - - -=== Garbage collection - -==== Why does a loop that doesn't {{cons}} still trigger garbage collections? - -Under CHICKEN's implementation policy, tail recursion is achieved simply by avoiding -returns from function calls. Since the programs are CPS converted, a continuous -sequence of nested procedure calls is performed. At some stage the stack-space has -to run out and the current procedure and its parameters (including the current -continuation) are stored somewhere in the runtime system. Now a minor garbage collection -occurs and rescues all live -data from the stack (the first heap generation) and moves it into the the second heap -generation. Then the stack is cleared (using -a {{longjmp}}) and execution can continue from the saved state. -With this method arbitrary recursion (in tail- or non-tail position) can happen, -provided the application doesn't run out of heap-space. -(The difference between a tail- and a non-tail call is that the tail-call has no -live data after it invokes its continuation - and so the amount of heap-space needed stays constant) - -==== Why do finalizers not seem to work in simple cases in the interpeter? - -Consider the following interaction in CSI: - - #;1> (define x '(1 2 3)) - #;2> (define (yammer x) (print x " is dead")) - #;3> (set-finalizer! x yammer) - (1 2 3) - #;4> (gc #t) - 157812 - #;5> (define x #f) - #;6> (gc #t) - 157812 - #;7> - -While you might expect objects to be reclaimed and "''(1 2 3) is dead''" printed, it won't happen: -the literal list gets held in the interpreter history, because it is the -result value of the set-finalizer! call. -Running this in a normal program will work fine. - -When testing finalizers from the interpreter, you might want to define a trivial macro such as - - (define-syntax v - (syntax-rules () - ((_ x) (begin (print x) (void))))) - -and wrap calls to {{set-finalizer!}} in it. - -=== Interpreter - -==== Does CSI support history and autocompletion? - -CSI doesn't support it natively but it can be activated with one of the -[[/egg/readline|readline]], [[/egg/linenoise|linenoise]] or -[[/egg/parley|parley]] eggs. Out of these three, the parley egg is -recommended. After installing parley, add the following to your -{{~/.csirc}} or equivalent file: - -<enscript highlight=scheme> -(import parley) -(let ((old (current-input-port))) - (current-input-port (make-parley-port old))) -</enscript> - -Users of *nix-like systems (including Cygwin), may also want to check out [[http://utopia.knoware.nl/~hlub/rlwrap/|rlwrap]]. This program lets you "wrap" another process (e.g. {{rlwrap csi}}) with the readline library, giving you history, autocompletion, and the ability to set the keystroke set. Vi fans can get vi keystrokes by adding "set editing-mode vi" to their {{.inputrc}} file. - -==== Does code loaded with {{load}} run compiled or interpreted? - -If you compile a file with a call to {{load}}, the code will be loaded at -runtime and, if the file loaded is a Scheme source code file -(instead of a shared object), it will be -interpreted (even if the caller program is compiled). - -==== How do I use extended (non-standard) syntax in evaluated code at run-time? - -Normally, only standard Scheme syntax is available to the evaluator. To -use the extensions provided in the CHICKEN compiler and interpreter, -add: - -<enscript highlight=scheme> -(require-library chicken-syntax) -</enscript> - -=== Extensions - -==== Where is "chicken-setup" ? - -{{chicken-setup}} has been rewritten from scratch and its functionality is now -contained in the three tools {{chicken-install}}, {{chicken-uninstall}} and {{chicken-status}}. -See the [[Extensions]] chapter for more information. - -==== How can I install CHICKEN eggs to a non-default location? - -You can just set the {{CHICKEN_INSTALL_REPOSITORY}} and {{CHICKEN_REPOSITORY_PATH}} -environment variables. -They should contain the path where you want eggs to be installed: - - $ export CHICKEN_INSTALL_REPOSITORY=~/eggs/lib/chicken/5 - $ export CHICKEN_REPOSITORY_PATH=~/eggs/lib/chicken/5 - $ chicken-install -init ~/eggs/lib/chicken/5 - $ chicken-install -p ~/eggs/ extensionname - -In order to make programs (including csi) see these eggs, you should set {{CHICKEN_REPOSITORY_PATH}} when you run them. See the [[Extensions#Changing repository location|Extensions/Changing repository location]] section of the manual for more information on that. - -Alternatively, you can call the {{repository-path}} Scheme procedure before loading the eggs, as in: - -<enscript highlight=scheme> -(repository-path "/home/azul/eggs") -(import format-modular) -</enscript> - -Note, however, that using {{repository-path}} as above hard-codes the location of your eggs in your source files. While this might not be an issue in your case, it might be safe to keep this configuration outside of the source code (that is, specifying it as an environment variable) to make it easier to maintain. - -The repository needs to be initialized before use. See the documentation for the {{-init}} option -to {{chicken-install}}, in [[Extensions]]. - -==== Can I install chicken eggs as a non-root user? - -Yes, just install them in a directory you can write to by using {{CHICKEN_INSTALL_REPOSITORY}} (see above). - -==== Why does downloading an extension via {{chicken-install}} fail on Windows Vista? - -Possibly the Windows Firewall is active, which prevents {{chicken-install}} from opening a TCP -connection to the egg repository. Try disabling the firewall temporarily. - ---- -Previous: [[Bugs and limitations]] - -Next: [[Acknowledgements]]Trap