Gauche Reference Manual

version 0.6.5

Shiro Kawai (shiro@acm.org)


1. Introduction

This is a programmers' guide and reference manual of the Gauche Scheme system. Here I tried to describe Gauche's implementation precisely, sometimes referring to background design choices.

The target readers are those who already know Scheme and want to write useful programs in Gauche. For those who are new to Scheme, it'll be easier to start from some kind of tutorial. I'm planning to write one.

This manual only deals with Scheme side of things. Gauche has another face, a C interface. Details of it will be discussed in a separate document to be written. Those who wants to use Gauche as an embedded language, or wants to write an extension, need that volume.

For the Scheme side, I tried to make this manual self-contained for reader's convenience, i.e. as far as you want to look up Gauche's features you don't need to refer to other documents. For example, description of functions defined in the standard documents are included in this manual, instead of saying "see the standard document". However, this document is not a verbatim copy of the standard documents; sometimes I omit detailed discussions in the standard documents for brevity. I put pointers to the original documents, so please consult them if you need to refer to the standards.

If you're reading this document off-line, you may find the most recent version on the web:

http://www.shiro.dreamhost.com/scheme/gauche/.

1.1 Overview of Gauche

Gauche is a script interpreter based on Scheme. Gauche conforms the language standard "Revised^5 Report on the Algorithmic Language Scheme" (@xref{r5rs,[R5RS],R5RS}), and supports various common libraries defined in SRFIs (http://srfi.schemers.org).

The goal of Gauche is to provide a handy tool for programmers and system administrators to handle daily works conveniently and efficiently in the production environment.

There are lots of Scheme implementations available, and each of them has its design emphasis and weeknesses. Gauche is designed with emphasis on the following criteria.

Quick startup
One of the situation Gauche is aiming at is in the production environment, where you write ten-lines throw-away script that may invoked very frequently. This includes CGI scripts as well. Gauche includes a set of most common features in its executable, while splits less common stuffs into libraries which are to be loaded on demand, to make itself start quickly.
Multibyte strings
We can no longer live happily in ASCII-only or 1-byte-per-character world. The practical language implementations are required to handle multibyte (wide) characters. Gauche supports multibyte strings natively, providing robust and consistent support than ad hoc library-level implementation. See section 2.2 Multibyte Strings, for details.
Modular development
Gauche has a simple module system to separate namespaces, which allows the developers to work in parallel without worrying name collision.
Integrated object system
A powerful CLOS-like object system with MetaObject protocol (mostly compatible with STklos and Guile) is provided.
System interface
Although Scheme abstracts lots of details of the machine, sometimes you have to bypass these high-level layers and go down to the basement to make things work. Gauche has built-in support of most of POSIX.1 system calls. Other modules, such as networking module, usually provide both high-level abstract interface and low-level interface close to system calls.
Enhanced I/O
No real application can be written without dealing with I/O. Scheme neatly abstracts I/O as a port, but defines least operations on it. Gauche uses a port object as a unified abstraction, providing utility functions to operate on the underlying I/O system. See section 6.18 Input and Output, for the basic I/O support.

On the other hand, Gauche is not designed for applications such like high-performance number cruncher or very large scale database handling. It is an interpreter, after all.

You can still use Gauche as a "glue" language for such applications, however. For example, you can write a performance-critical part in another language that compiles to native code, and use Gauche to set up.

1.2 Notations

In this manual, each entry is represented like this:

Category: foo arg1 arg2
[spec] Description of foo ...

Category denotes the category of the entry foo. The following category will appear in this manual:
Function A Scheme function.
Special Form A special form (in the R5RS term, "syntax").
Macro A macro.
Module A module
Class A class.
Generic Function A generic function
Method A method
Reader Syntax A lexical syntax that is interpreted by the reader.

For functions, special forms and macros, the entry may followed by one or more arguments. In the argument list, the following notations may appear:

arg ...
Indicates zero or more arguments.
&optional x y z
&optional (x x-default) (y y-default) z
Indicates it may take up to three optional arguments. The second form specifies default values. Note that Gauche doesn't really support Common-Lisp style &optional argument specifier in the lambda list. I use this notation since it is useful to indicate valid pattern of arguments.
&keyword x y z
&keyword (x x-default) (y y-default) z
Indicates it may take keyword arguments x, y and z. Note that Gauche doesn't really support Common-Lisp style &keyword argument specifier in the lambda list. I use this notation since it is useful to indicate valid pattern of arguments.
&rest args
Indicates it may take rest arguements. Note that Gauche doesn't really support Common-Lisp style &rest argument specifier in the lambda list. I use this notation since it is useful to indicate valid pattern of arguments.

The description of the entry follows the entry line. If the specification of the entry comes from some standard or implementation, its origin is noted in the bracket at the beginning of the description. The following origins are noted:

[R5RS]
[R5RS+]
The entry works as specified in "Revised^5 Report of Algorithmic Language Scheme.". If it is marked as "[R5RS+]", the entry has additional functionality.
[SRFI-n]
[SRFI-n+]
The entry works as specified in SRFI-n. If it is marked as "[SRFI-n+]", the entry has additional functionality.
[POSIX]
The API of the entry reflects the API specified in POSIX.

2. Concepts

In this chapter I describe a few Gauche's design concepts that help you to understand how Gauche works.

2.1 Standard conformance

Gauche conforms "Revised^5 Report of Algorithmic Language Scheme," including optional syntax and procedures, except the following features.

Gauche also supports the following SRFIs (Scheme Request for Implementation).

SRFI-0, Feature-based conditional expansion construct.
As an autoloaded macro. See section 10.1 srfi-0 - Feature conditional.
SRFI-1, List library.
Supported by the module srfi-1. See section 10.2 srfi-1 - List library. (Some of SRFI-1 procedures are built-in).
SRFI-2, AND-LET*: an AND with local bindings, a guarded LET* special form.
Supported by the module srfi-2. See section 10.3 srfi-2 - And-let*.
SRFI-4, Homogeneous numeric vector datatypes.
The module gauche.uvector provides a superset of srfi-4 procedures, including arithmetic operations and generic interface on the SRFI-4 vectors. See section 9.24 gauche.uvector - Uniform vectors.
SRFI-6, Basic String Ports.
SRFI-6 procedures are built-in. See section 6.18.4 String ports.
SRFI-8, receive: Binding to multiple values.
Syntax receive is built-in. See section 4.6 Binding constructs.
SRFI-9, Defining record types.
Supported by the module srfi-9. See section 10.5 srfi-9 - Record types.
SRFI-10, Sharp-comma external form.
Built-in. See section 6.18.6.2 Read-time constructor.
SRFI-11, Syntax for receiving multiple values.
Supported by the module srfi-11. See section 10.6 srfi-11 - Let-values.
SRFI-13, String library
Supported by the module srfi-13. See section 10.7 srfi-13 - String library. (Some of SRFI-13 procedures are built-in).
SRFI-14, Character-set library
Character-set object and a few SRFI-14 procedures are built-in. See section 6.9 Character Set. Complete set of SRFI-14 is supported by the module srfi-14. See section 10.8 srfi-14 - Character-set library.
SRFI-17, Generalized set!
Built-in. See section 4.4 Assignments.
SRFI-18, Multithreading support
Some SRFI-18 features are built-in, and the rest is in gauche.threads module. See section 9.22 gauche.threads - Threads.
SRFI-19, Time Data Types and Procedures.
Time data type is Gauche built-in (See section 6.21.8.2 SRFI time). Complete set of SRFI-19 is supported by the module srfi-19. See section 10.9 srfi-19 - Time data types and procedures.
SRFI-22, Running Scheme scripts on Unix
Supported. See section 3.4 Writing Scheme scripts.
SRFI-23, Error reporting mechanism.
Built-in. See section 6.16.1 Signalling errors.
SRFI-25, Multi-dimensional array primitives.
Supported by the module gauche.array, which defines superset of SRFI-25. See section 9.1 gauche.array - Arrays.
SRFI-26, Notation for specializing parameters without currying.
As an autoloaded macro. See section 4.3 Making Procedures.
SRFI-27, Sources of Random Bits.
Supported by the module srfi-27. See section 10.10 srfi-27 - Sources of Random Bits.
SRFI-28, Basic format strings.
Gauche's built-in format procedure is a superset of SRFI-28 format. See section 6.18.7 Output.
SRFI-30, Nested multi-line comments.
Supported by the native reader. See section 4.1 Lexical structure.

2.2 Multibyte Strings

Traditionally, a string is considered as a simple array of bytes. Programmers tend to imagine a string as a simple array of characters (though a character may occupy more than one byte). It's not the case in Gauche.

Gauche supports multibyte string natively, which means characters are represented by variable number of bytes in a string. Gauche retains semantic compatibility of Scheme string, so such details can be hidden, but it'll helpful if you know a few points.

A string object keeps a type tag and a pointer to the storage of the string body. The storage of the body is managed in a sort of "copy-on-write" way--if you take substring, e.g. using directly by substring or using regular expression matcher, or even if you copy a string by copy-string, the underlying storage is shared (the "anchor" of the string is different, so the copied string is not eq? to the original string). The actual string is copied only if you destructively modify it.

Consequently the algorithm like pre-allocating a string by make-string and filling it with string-set! becomes extremely inefficient in Gauche. Don't do it. (It doesn't work with mulitbyte strings anyway). Sequential access of string is much more efficient using string ports (See section 6.18.4 String ports).

String search primitives such as string-scan (See section 6.10.7 String utilities) and regular expression matcher (See section 6.11 Regular expression) can return a matched string directly, without using index access at all.

You can choose internal encoding scheme at the time of compiling Gauche. At runtime, a procedure gauche-character-encoding can be used to query the internal encoding. Currently, the following internal encodings are supported.

euc-jp
EUC-JP encoding of ASCII, JIS X 0201 kana, JIS X 0212 and JIS X 0213:2000 Japanese character set.
sjis
Shift-JIS encoding of JIS X 0201 kana and JIS X 0213:2000 Japanese character set. For source-code compatibility, the character code between 0 and 0x7f is mapped to ASCII.
utf-8
UTF-8 encoding of Unicode.
none
8-bit fixed-length character encoding, with the code between 0 and 0x7f matches ASCII. When converted to Unicode, ISO8859-1 encoding is assumed.

Conversions from other encoding scheme is provided as a special port. See section 9.2 gauche.charconv - Character Code Conversion, for details.

Gauche assumes the Scheme program is written in its internal encoding scheme.

2.3 Case-sensitivity

Historically, most Lisp-family languages are case-insensitive for symbols. Scheme is no exception and R5RS defines symbols are read in case-insensitive way. (Note that symbols are case-sensitive internally even in R5RS Scheme; case-insensitivity is about readers.)

However, nowadays programming is hardly completed in one language. When you have to interact with other languages that distinguishe uppercase and lowercase characters, it is desirable that Scheme distinguishes them as well.

So Gauche has two modes in reading and writing symbols. By default, Gauche reads and writes symbols in case-sensitive manner. This behavior doesn't conform R5RS.

; In case-sensitive mode (default)
(eq? 'a 'A) => #f  ; #t in R5RS
(symbol->string 'ABC) => "ABC"
(symbol->string 'abc) => "abc"
(display (string->symbol "ABC")) => writes ABC
(display (string->symbol "abc")) => writes abc

You can make Gauche case-insensitive by giving -fcase-fold command-line option to the gosh interpreter (See section 3.1 Invoking Gosh). In this mode, the reader folds uppercase characters in symbols to lowercase ones. If a symbol name contains uppercase characters, it is written out using |-escape (See section 6.5 Symbols).

; In case-insensitive mode (with -fcase-fold option)
(eq? 'a 'A) => #t
(symbol->string 'ABC) => "abc"
(symbol->string 'abc) => "abc"
(display (string->symbol "ABC")) => writes |ABC|
(display (string->symbol "abc")) => writes abc

Right now, there's no way to switch these two modes back and forth inside the intepreter; an API will be provided in the later versions.

2.4 Integrated Object System

Gauche has a STklos-style object system, similar to CLOS. If you have used some kind of object oriented (OO) languages, you'll find it easy to understand the basic usage:

;; Defines a class point, that has x and y coordinate
(define-class point ()
  ((x :init-value 0)
   (y :init-value 0))
  )

(define-method move ((p point) dx dy)
  (inc! (slot-ref p 'x) dx)
  (inc! (slot-ref p 'y) dy))

(define-method write-object ((p point) port)
  (format port "[point ~a ~a]"
          (slot-ref p 'x)
          (slot-ref p 'y)))

However, if you are familiar with mainstream OO langauges but new to CLOS-style object system, Gauche's object system may look strange when you look deeper into it. Here I describe several characteristics of Gauche object system quickly. See section 7. Object system, for details.

Everything is an object (if you care)
You have seen this tagline for the other languages. And yes, in Gauche, everything is an object in the sense that you can query its class, and get various meta information of the object at run time. You can also define a new method on any class including built-in classes. Note that, however, in CLOS-like paradigm it doesn't really matter whether everything is an object or not, because of the following characteristics:
Method is dispatched by all of its arguments.
Unlike other object-oriented languages such as C++, Objective-C, Python, Ruby, etc., in which a method always belong to a single class, a Gauche method doesn't belong to a specific class. For example, suppose you define a numeric vector class <num-vector> and a numeric matrix class <num-matrix>. You can define a method product with all possible combinations of those type of arguments:
  (product <num-vector> <num-matrix>)
  (product <num-matrix> <num-vector>)
  (product <num-vector> <num-vector>)
  (product <num-matrix> <num-matrix>)
  (product <number>     <num-vector>)
  (product <number>     <num-matrix>)
  (product <number>     <number>)
Each method belongs to neither <num-vector> class nor <num-matrix> class. Since a method is not owned by a class, you can always define your own method on the existing class (except a few cases that the system prohibits altering pre-defined methods). The above example already shows it; you can make product method work on the built-in class <number>. That is why I said it doesn't make much sense to discuss whether everything is object or not in CLOS-style object system.
Class is also an instance.
By default, a class is also an instance of class <class>, and a generic function is an instance of class <generic>. You can subclass <class> to customize how a class is initialized or how its slots are accessed. You can subclass <generic> to customize how the applicable methods are selected, which order those methods are called, etc. The mechanism is called metaobject protocol. Metaobject protocol allows you to extend the language by the language itself. To find examples, see the files lib/gauche/singleton.scm and lib/gauche/validator.scm included in the distribution. You can also read lib/gauche/object.scm, which actually defines how a class is defined in Gauche. For more details about metaobject protocol, see @xref{mop,[MOP],MOP}.
Class doesn't create namespace
In the mainstream OO language, a class often creates its own namespace. This isn't the case in CLOS-style object system. In Gauche, a namespace is managed by the module system which is orthogonal to the object system.

2.5 Module system

Gauche has a simple module system that allows modularlized development of large software.

A higher level interface is simple enough from the user's point of view. It works like this: When you want to use the features provided by module foo, you just need to say (use foo) in your code. This form is a macro and interpreted at compile time. Usually it loads the files that defines foo's features, and imports the external APIs into the calling module.

The use mechanism is built on top of two independent lower mechanisms, namespace separation and file loading mechanism. Those two lower mechanisms can be used separately, although it is much more convenient when used together.

The use mechanism is not transitive; that is, if a module B uses a module A, and a module C uses the module B, C doesn't see the bindings in A. It is because B and A is not in the is-a relationship. Suppose the module A implements a low-level functionality and the module B implements a high-level abstraction; if C is using B, what C wants to see is just a high-level abstraction, and doesn't concern how B implements such functionality. If C wants to access low-level stuff, C has to use A explicitly.

There is another type of relationship, though. You might want to take an exiting module A, and add some interface to it and provide the resulting module B as an extension of A. In such a case, B is-a A, and it'd be natural that the module that uses B can also see A's bindings. In Gauche, it is called module inheritance and realized by extend form.

The following sections in this manual describes modules in details.

2.6 Compilation

Gauche is a Scheme interpreter, in the sense that it reads a Scheme form at a time and evaluates it. Actually, Gauche compiles every toplevel form into an intermediate form before executing.

Built-in sytanxes and macros are recognized and expanded at the compilation time. Some built-in procedures are expanded in-line as far as the compiler can see the global binding is not altered at the time the form is compiled.

This raises a few problems you should care.

load is done at run time.
load is a procedure in Gauche, therefore evaluated at run time. If the loaded program defines a macro, which is available for the compiler after the toplevel form containing load is evaluated. So, suppose foo.scm defines a macro foo, and you use the macro like this:
;; in ``foo.scm''
(define-syntax foo
  (syntax-rules () (_ arg) (quote arg)))

;; in your program
(begin (load "foo") (foo (1 2 3)))
  => error, bad procedure: `1'

(load "foo")
(foo (1 2 3)) => '(1 2 3)
The (begin (load ...)) form fails, because the compiler doesn't know foo is a special form at the compilation time and compiles (1 2 3) as if it is a normal procedure call. The latter example works, however, since the execution of the toplevel form (load "foo") is done before (foo (1 2 3)) is compiled. To avoid this kind of subtleties, use require or use to load a program fragments. Those are recognized by the compiler.
require is done at compile time
On the other hand, since require and use is recognized by the compiler, the specified file is loaded even if the form is in the conditional expression. If you really need to load a file on certain condition, use load or do dispatch in macro (i.e. at compile time).

3. Programming in Gauche

3.1 Invoking Gosh

Gauche can be used either as an independent Scheme interpreter or as an embedded Scheme library. The interpreter which comes with Gauche distribution is a program named gosh.

Program: gosh [options] [scheme-file arg ...]
Gauche's interpreter. Without scheme-file, gosh works interactively, i.e. it reads a Scheme expression from the standard input, evaluates it, and prints the result, and repeat that until it reads EOF or is terminated.

If gosh is invoked without scheme-file, but the input is not a terminal, it enters read-eval-print loop but not writes out a prompt while waiting input form. This is useful when you pipe Scheme program into gosh. You can force this behavior or suppress this behavior by -b and -i options.

If scheme-file is specified, gosh runs it as a Scheme program and exit. See section 3.4 Writing Scheme scripts, for details.

The following command line options are recognized by gosh. The first command line argument which doesn't begin with `-' is recognized as the script file. If you want to specify a file that begins with a minus sign, use a dummy option `--'.

Command Option: -I path
Prepends path to the load path list. You can specify this option more than once to add multiple paths.

Command Option: -A path
Appends path to the tail of the load path list. You can specify this option more than once to add multiple paths.

Command Option: -q
Makes gosh not to load the default initialization file.

Command Option: -V
Prints the gosh version and exits.

Command Option: -u module
Use module. Before starting execution of scheme-file or entering the read-eval-print loop, the specified module is used, i.e. it is loaded and imported (See section 4.11.2 Defining and selecting modules, for details of use). You can specify this option more than once to use multiple modules.

Command Option: -l file
Load file before starting execution of scheme-file or entering the read-eval-print loop. The file is loaded in the same way as load (See section 6.19.1 Loading Scheme file). You can specify this option more than once to load multiple files.

Command Option: -e scheme-expression
Evaluate scheme-expression before starting execution of scheme-file or entering the read-eval-print loop. Evaluation is done in the interaction-environment (See section 6.17 Eval and repl). You can specify this option more than once to evaluate multiple experssions.

Command Option: -E scheme-expression
Same as -e, except the scheme-experssion is read as if it is surrounded by parenthesis. For example:
% gosh -umath.const -E"print (sin (* pi/180 15))" -Eexit
0.25881904510252074

Command Option: -b
Batch. Does not print prompts in read-eval-print loop even if the input is a terminal.

Command Option: -i
Interactive. Print prompts in read-eval-print loop even if the input is not a terminal.

Command Option: -f compiler-option
This option controls the compiler behavior. For now we have following options available:
no-inline
Prohibits the compiler from inilining primitive Scheme procedures.
no-source-info
Don't keep source information for debugging. Consumes less memory.
load-verbose
Reports whenever a file is loaded.
case-fold
Ignore case for symbols as specified in R5RS. (It is distinguished by default). See section 2.3 Case-sensitivity.

Command Option: --
When gosh sees this option, it stops processing the options and takes next command line argument as a script file. It is useful in case if you have a script file that begins with a minus sign, although it is not generally recommended.

The options -I, -A, -l, -u, -e and -E are processes in the order of appearance. For example, adding a load path by -I affects the -l and -u option after it but not before it.

3.2 Interactive development

When gosh is invoked without any script files, it goes into interactive read-eval-print loop.

To exit the interpreter, type EOF (usually Control-D in Unix termials) or evaluate (exit).

I recommend you to run gosh inside Emacs, for it has rich features useful to interact with internal Scheme process. Put the following line to your `.emacs' file:

(setq scheme-program-name "gosh")

And you can run gosh by M-x run-scheme.

If you want to use multibyte characters in the interaction, make sure your terminal's settings is in sync with gosh's internal character encodings.

Currently gosh has no fancy features such as line-editing or command history. They'll be added in future.

See section 9.6 gauche.interactive - Utilities for interactive session, for some procedures useful in interactive session.

3.3 Debugging

Gauche doesn't have much support for debugging yet. The idea of good debugging interfaces are welcome.

For now, the author uses the classic 'debug print stub' technique when necessary. A special reader syntax #?=expr is defined, which is read as (debug-print expr). The macro debug-print evaluates and returns the result(s), printing messages before and after evaluation of expr.

gosh> #?=(+ 2 3)
#?="(stdin)":1:(+ 2 3)
#?-    5
5
gosh> #?=(begin (print "foo") (values 'a 'b 'c))
#?="(stdin)":2:(begin (print "foo") (values 'a 'b 'c))
foo
#?-    a
#?+    b
#?+    c
a
b
c
gosh> (define (fact n)
        (if (zero? n)
            1
            (* n #?=(fact (- n 1)))))
fact
gosh> (fact 5)
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?-    1
#?-    1
#?-    2
#?-    6
#?-    24
120

You can also use trace/untrace macros in Gauche, written by Shigenobu Kimura: http://homepage.mac.com/skimu/ggc/.

3.4 Writing Scheme scripts

When a Scheme program file is given to gosh, it bounds a global varialbe *argv* to the list of the remaining command-line arguments, then loads the Scheme program. If the first line of scheme-file begins with two character sequence "#!", the entire line is ignored by gosh. This is useful to write a Scheme program that works as an executable script in unix-like systems.

Typical Gauche script has the first line like these

#!/usr/local/bin/gosh
  or,
#!/usr/bin/env gosh
  or,
#!/bin/sh
:; exec gosh -- $0 "$@"

The second and third form uses a "shell trampoline" technique so that the script works as far as gosh is in the PATH. The third form is useful when you want to pass extra arguments to gosh, for typically #!-magic of executable scripts has limitations for the number of arguments to pass the interpreter.

After the file is successfully loaded, gosh calls a procedure named `main' if it is defined in the user module. Main receives a single argument, a list of command line arguments. Its first element is the script name itself.

When main returns, and its value is an integer, gosh uses it for exit code of the program. Otherwise, gosh exits with exit code 70 (EX_SOFTWARE). This behavior is compatible with the SRFI-22.

(Note: this interface has been changed from Gauche release 0.5 in incompatible way. See section 3.4.1 Script compatibility before release 0.5, for details.)

If the main procedure is not defined, gosh exits after loading the script file.

Although you can still write the program main body as toplevel expressions, like shell scripts or Perl scripts, it is much convenient to use this `main' convention, for you can load the script file interactively to debug.

Variable: *argv*
The program arguments passed to the Scheme script is bound to this variable. If gosh is invoked in an interactive mode, this variable always contains ().

STk uses this variable to pass the command line argument as well, but other Scheme implementations use different ways. It is better to define main procedure and uses its argument to receive command line arguments, for it is expected to be more portable.

Variable: *program-name*
This variable is bound to the script file name passed to gosh. If gosh is invoked in the interactive mode, this variable contains the pathname of gosh itself.

STk uses the same variable to access the program/script name. Other Scheme implementations use different ways.

Now I show several simple examples below. First, this script works like cat(1), without any command-line option processing and error handling.

#!/usr/bin/env gosh

(define (main args)   ;entry point
  (if (null? (cdr args))
      (copy-port (current-input-port) (current-output-port))
      (for-each (lambda (file)
                  (call-with-input-file file
                    (lambda (in)
                      (copy-port in (current-output-port)))))
                (cdr args)))
  0)

The following script is a simple grep command.

#!/usr/bin/env gosh

(define (usage)
  (format (current-error-port)
          "Usage: ~a regexp file ...\n" *program-name*)
  (exit 2))

(define (grep rx port)
  (with-input-from-port port
    (lambda ()
      (port-for-each
       (lambda (line)
         (when (rxmatch rx line)
           (format #t "~a:~a: ~a\n"
                   (port-name port)
                   (- (port-current-line port) 1)
                   line)))
       read-line))))

(define (main args)
  (if (null? (cdr args))
      (usage)
      (let ((rx (string->regexp (cadr args))))
        (if (null? (cddr args))
            (grep rx (current-input-port))
            (for-each (lambda (f)
                        (call-with-input-file f
                          (lambda (p) (grep rx p))))
                      (cddr args)))))
  0)

See also section 9.13 gauche.parseopt - Parsing command-line options, for a convenient way to parse command-line options.

3.4.1 Script compatibility before release 0.5

In order to conform final SRFI-22, Gauche release 0.5.1 changes the way main is called. Unfortunately, this makes the Scheme scripts that is written for older Gauche no longer work. I decided to take this change now, in the early stage of Gauche, rather than keeping incomatibility to the standard (srfi).

The incompatible changes are these two points.

3.5 Writing Gauche modules

Gauche's libraries are organized by modules. Although Gauche can load any valid Scheme programs, there is a convention that Gauche library follows. When you write a chunk of Scheme code for Gauche, it is convenient to make it a module, so that it can be shared and/or reused.

Usually a module is contained in a file, but you can make a multi-file module. First I explain the structure of a single-file module. The following template is the convention used in Gauche's libraries.

;; Define the module interface
(define-module foo
  (use xxx)
  (use yyy)
  (export foo1 foo2 foo3)
  )
;; Enter the module
(select-module foo)

... module body ...

;; Make `require' happy
(provide "foo")

This file must be saved as "foo.scm" in some directory in the *load-path*.

The define-module form creates a module foo. It also loads and imports some other modules by `use' macros, and declares which symbols the foo module exports, by `export' syntax. (See section section 4.11.2 Defining and selecting modules, for detailed specification of those syntaxes).

Those use forms or export forms are not required to appeare in the define-module form, but it is a good convention to keep them in there at the head of the file so that it is visually recognizable which modules foo depends and which symbols it exports.

The second form, `select-module', specifies the rest of the file is evaluated in the module foo you just defined. Again, this is just a convention; you can write entire module body inside define-module. However, I think it is error-prone, for the closing parenthesis can be easily forgotten or the automatic indentation mechanism of editor will be confused.

After select-module you can write whatever Scheme expression. It is evaluated in the selected module, foo. Only the bindings of the exported symbols will be directly accessible from outside.

The last provide form is just a cliche. It is needed since the `use' mechanism uses traditional require-provide mechanism (if you don't know about it, it's ok--just put it as a magic spell).

So, that's it. Other programs can use your module by just saying `(use foo)'. If you want to make your module available on your site, you can put it to the site library location, which can be obtained by

(gauche-site-library-directory)

in gosh, or

gauche-config --sitelibdir

from shell.

If you feel like to conserve global module name space, you can organize modules hierarchically. Some Gauche libraries already does so. See section 8. Library modules - Overview, for examples. For example, text.tr module is implemented in "text/tr.scm" file. Note that the pathname separator `/' in the file becomes a period in the module name.

4. Core syntax

4.1 Lexical structure

Gauche extends R5RS Scheme parser in some ways:

Nested block comments (SRFI-30)
A text surrounded by '#|' and '|#' becomes a comment. It can be nested.
Numeric literals
Either integral part or fraction part of inexact real numbers can be omitted if it is zero, i.e. 30., .25, -.4 are read as real numbers. Using '#' as insignificant digits is not supported.
Symbol names
Symbol names are case sensitive by default (See section 2.3 Case-sensitivity). Symbol name can begin with digits, '+' or '-', as long as the entire token doesn't consist valid number syntax. Other weird characters can be included in a symbol name by surrounding it with '|', e.g. '|this is a symbol|'. See section 6.5 Symbols, for details.
Character literal by character code
Character literals can be written using its code, by #\xNN (Gauche internal code) or #\uNN (Unicode). See section 6.8 Characters, for details.
Extended sharp syntax
Many more special tokens begins with '#' is defined. See the table below.

The table below lists sharp-syntaxes.

  • #! [SRFI-22] Specifies interpreter at the beginning of file. Scheme loader ignores the line.
  • #", ##, #$, #%, #&, #' Unused.
  • #( [R5RS] Introduces a vector.
  • #) Unused.
  • #* If followed by a double quote, denotes an incomplete string. See section 6.10 Strings.
  • #+ Unused.
  • #, [SRFI-10] Introduces reader constructor syntax.
  • #-, #. Unused.
  • #/ Introduces a literal regular expression. See section 6.11 Regular expression.
  • #0 ... #9 Reserved for shared structure reference.
  • #:, #; Unused
  • #< Introduces an unreadable object.
  • #=, #> Unused.
  • #? Introduces debug macros. See section 3.3 Debugging.
  • #@ Unused.
  • #a Unused.
  • #b [R5RS] Binary number prefix.
  • #c Unused.
  • #d [R5RS] Decimal number prefix.
  • #e [R5RS] Exact number prefix.
  • #f [R5RS] Boolean false, or introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - Uniform vectors.
  • #g, #h Unused.
  • #i [R5RS] Inxact number prefix.
  • #j, #k, #l, #m, #n Unused.
  • #o [R5RS] Octal number prefix.
  • #p, #q, #r Unused.
  • #s [SRFI-4] introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - Uniform vectors.
  • #t [R5RS] Boolean true.
  • #u [SRFI-4] introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - Uniform vectors.
  • #v, #w Unused.
  • #x [R5RS] Hexadecimal number prefix.
  • #y, #z Unused.
  • #[ Introduces a literal character set. See section 6.9 Character Set.
  • #\ [R5RS] Introduces a literal character. See section 6.8 Characters.
  • #], #^, #_ Unused.
  • #` Introduces an interpolated string. See section 6.10.4 String interpolation.
  • #{ Unused.
  • #| [SRFI-30] Introduces a block comment. Comment ends by matching '|#'.
  • #}, #~ Unused.

    4.2 Literals

    Special Form: quote datum
    [R5RS] Evaluates to datum.
    (quote x) => x
    (quote (1 2 3)) => (1 2 3)
    

    Reader Syntax: 'datum
    [R5RS] Equivalent to (quote datum).
    'x => x
    '(1 2 3) => (1 2 3)
    

    Note: R5RS says it is an error to alter the value of a literal expression. Gauche doesn't check constant-ness of pairs and vectors, so you can alter them using the destructive procedures such as set-car! and vector-set!. Doing so will cause unexpected results. Gauche does check constant-ness of strings, and signals an error if you try to alter a constant string.

    4.3 Making Procedures

    Special Form: lambda formals body ...
    [R5RS] Evaluates to a procedure. The environment in effect when this expression is evaluated is stored in the procedure. When the procedure is called, body is evaluated sequentially in the stored environment extended by the bindings of the formal arguments, and returns the value(s) of the last expression in the body.

    Formals should have one of the following forms:

    • (variable ...) : The procedure takes a fixed number of arguments. The actual arguments are bound to the corresponding variables.
    • variable : The procedure takes any number of argumnets. The actual arguments are collected to form a new list and bound to the variable.
    • (variable_0 ... variable_N-1. variable_N) : The procedure takes at least N arguments. The actual arguments up to N is bound to the corresponding varibles. If more than N arguments are given, the rest arguments are collected to form a new list and bound to variable_N.
    (lambda (a b) (+ a b))
      => procedure that adds two arguments
    
    ((lambda (a b) (+ a b)) 1 2)
      => 3
    

    Note: Some Scheme implementations extend the syntax of formals to have notation of optional arguments or keyword arguments, similar to CommonLisp's. Gauche doesn't have such extensions now.

    Macro: cut expr-or-slot expr-or-slot2 ...
    Macro: cute expr-or-slot expr-or-slot2 ...
    [SRFI-26] Convenience macros to notate a procedure compactly. This form can be used to realize partial application, a.k.a sectioning or projection.

    Each expr-or-slot must be either an expression or a symbol <>, indicating a 'slot'. The last expr-or-slot can be a symbol <...>, indicating a 'rest-slot'. Cut expands into a lambda form that takes as many arguments as the number of slots in the given form, and whose body is an expression

      (expr-or-slot expr-or-slot2 ...)
    

    where each occurrence of <> is replaced to the corresponding argument. In case there is a rest-slot symbol, the resulting procedure is also of variable arity, and all the extra arguments are passed to the call of expr-or-slot. See the fourth example below.

    (cut cons (+ a 1) <>)  == (lambda (x2) (cons (+ a 1) x2))
    (cut list 1 <> 3 <> 5) == (lambda (x2 x4) (list 1 x2 3 x4 5))
    (cut list)             == (lambda () (list))
    (cut list 1 <> 3 <...>)
       == (lambda (x2 . xs) (apply list 1 x2 3 xs))
    (cut <> a b)           == (lambda (f) (f a b))
    
    ;; Usage
    (map (cut * 2 <>) '(1 2 3 4))
    (for-each (cut write <> port) exprs)
    

    Cute is a variation of cut that evaluates expr-or-slots before creating the procedure.

    (cute cons (+ a 1) <>)
       == (let ((xa (+ a 1))) (lambda (x2 (cons xa x2))))
    

    Gauche also has a built-in procedure pa$ for partial application (See section 6.15.1.2 Combinators).

    4.4 Assignments

    Special Form: set! symbol expression
    Special Form: set! (proc arg ...) expression
    [R5RS][SRFI-17] First, expression is evaluated. In the first form, the binding of symbol is modified so that next reference of symbol will return the result of expression. If symbol is not locally bound, the global variable named symbol must already exist, or an error is signalled.

    The second form is a "generalized set!" specified in SRFI-17. It is a syntactic sugar of the following form.

    ((setter proc) arg ... expression)
    

    Note the order of the arguments of the setter method differs from CommonLisp's setf.

    Some examples:

    (define x 3)
    (set! x (list 1 2))  => undefined
    x                    => (1 2)
    
    (set! (car x) 5)     => undefined
    x                    => (5 2)
    

    Macro: set!-values (var ...) expr
    Sets values of multiple variables at once. Expr must yield as many values as var .... Each value is set to the corresponding var.
    (define a 0)
    (define b 1)
    (set!-values (a b) (values 3 4)) => undefined
    a => 3
    b => 4
    (set!-values (a b) (values b a)) => undefined
    a => 4
    b => 3
    

    Function: setter proc
    [SRFI-17] Returns a setter procedure associated to the procedure proc. If no setter is associated to proc, an error is signalled.

    A setter procedure g of a procedure f is such that when used as (g a b ... v), the next evaluation of (f a b ...) returns v.

    To associate a setter procedure to another procedure, you can use the setter of setter, like this:

    (set! (setter f) g)
    

    A procedure's setter can be "locked" to it. System default setters, like set-car! for car, is locked and can't be set by the above way. In order to lock a setter to a user defined procedure, use getter-with-setter below.

    Function: getter-with-setter get set
    [SRFI-17] Takes two procedure get and set. Returns a new procedure which does the same thing as get, and its setter is locked to set.

    The intention of this procedure is, according to the SRFI-17 document, to allow implementations to inline setters efficiently. Gauche hasn't implement such optimization yet.

    A few macros that adopts the same semantics of generalized set! are also provided. They are built on top of set!.

    Macro: push! place item
    Conses item and the value of place, then sets the result to place. place is either a variable or a form (proc arg ...), as the second argument of set!. The result of this form is undefined.
    (define x (list 2))
    (push! x 3) => undefined
    x => (3 2)
    
    (push! (cdr x) 4) => undefined
    x => (3 4 2)
    

    When place is a list, it roughly expands like the following.

    (push! (foo x y) item)
     ==
     (let ((tfoo foo)
           (tx x)
           (ty y))
       ((setter tfoo) tx ty (cons item (tfoo tx ty))))
    

    Note: Common Lisp's push macro takes its argument reverse order. I adopted this order since it is consistent with other destructive operations. Perl's push function takes the same argument order, but it appends item at the end of the array (Perl's unshift is closer to push!). You can use a queue (See section 11.22 util.queue - Queue) if you need a behavior of Perl's push.

    Macro: pop! place
    Retrieves the value of place, sets its cdr back to place and returns its car.
    (define x (list 1 2 3))
    (pop! x) => 1
    x => (2 3)
    
    (define x (vector (list 1 2 3)))
    x => #((1 2 3))
    (pop! (vector-ref x 0)) => 1
    x => #((2 3))
    

    Note: This works the same as Common Lisp's pop. Perl's pop pops value from the end of the sequence; its shift does the same thing as pop!.

    Macro: inc! place &optional delta
    Macro: dec! place &optional delta
    Evaluates the value of place. It should be a number. Adds (inc!) or subtracts (dec!) delta to/from it, and then stores the result to place. The default value of delta is 1.

    This is Common Lisp's incf and decf.

    Macro: update! place proc
    Generalized form of push! etc. Proc must be a procedure which takes one argument and returns one value. The original value of place is passed to the proc, then its result is set to place.
    (define a (cons 2 3))
    (update! (car a) (lambda (v) (* v 3))) => undefined
    a => (6 . 3)
    
    (update! (cdr a) (cut - <> 3))
    a => (6 . 0)
    

    4.5 Conditionals

    Special Form: if test consequent alternative
    Special Form: if test consequent
    [R5RS] Test is evaluated. If it yields a true value, consequent is evaluated. Otherwise, alternative is evaluated. If alternative is not provided, it results undefined value.
    (if (number? 3) 'yes 'no) => yes
    (if (number? #f) 'yes 'no) => no
    
    (let ((x '(1 . 2)))
      (if (pair? x)
          (values (car x) (cdr x))
          (values #f #f)))
      => 1 and 2
    

    Special Form: cond clause1 clause2 ...
    [R5RS] Each clause must be the form
    (test expr ...)
    (test => expr)
    (else expr expr2 ...)
    

    The last form can appear only as the last clause.

    cond evaluates test of each clauses in order, until it yields a true value. Once it yields true, if the clause is the first form, the corresponding exprs are evaluated and the result(s) of last expr is(are) returned; if the clause is the second form, the expr is evaluated and it must yield a procedure that takes one argument. Then the result of test is passed to it, and the result(s) it returns will be returned. If no test yields true, and the last clause is not the third form (else clause), an undefined value is returned.

    If the last clause is else clause and all tests are failed, exprs in the else clause are evaluated, and its last expr's result(s) 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
    

    Special Form: case key clause1 clause2 ...
    [R5RS] Key may be any expression. Each clause should have the form
    ((datum ...) expr expr2 ...)
    

    where each datum is an external representation of some object. All the datums must be distinct. The last clause may be an "else clause," which has the form

    (else expr expr2 ...)
    

    First, key is evaluated and its result is compared against each datum. If the result of evaluating datum is equivalent (using eqv?, See section 6.1 Equivalence), to a datum, then the expressions in the corresponding clause are evaluated sequentially, and the result(s) of the last expression in the clause is(are) returned from 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)) => undefined
    (case (car '(c d))
      ((a e i o u) 'vowel)
      ((w y) 'semivowel)
      (else 'consonant)) => consonant
    

    Special Form: and test ...
    [R5RS] The test expressions are evaluated from left to right, and the value of the first expression that evaluates to a false value 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
    

    Special Form: or test ...
    [R5RS] The test expressions are evaluated from left to right, and the value of the first expression that evaluates to a true value 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)
    

    Special Form: when test body ...
    Special Form: unless test body ...
    Evaluates test. If it yields true value (or false in case of unless), body ... are evaluated sequentially, and the result(s) of the last evaluation is(are) returned. Otherwise, undefined value is returned.

    4.6 Binding constructs

    Special Form: let ((var expr) ...) body ...
    Special Form: let* ((var expr) ...) body ...
    Special Form: letrec ((var expr) ...) body ...
    [R5RS] Creates a local scope where var ... are bound to the value of expr ..., then evaluates body .... vars must be symbols, and there shouldn't be a duplication. The value(s) of the last expression of body ... becomes the value(s) of this form.

    The three forms differ in terms of the scope exprs are evaluated. Let evaluates exprs before (outside of) let form. Let* evaluates exprs in the scope where vars before it are bound. Letrec evaluates exprs in the environment where vars are already bound (to an undefined value, initially). letrec is necessary to define mutually recursive local procedures.

    (define x 'top-x)
    
    (let  ((x 3) (y x)) (cons x y)) => (3 . top-x)
    (let* ((x 3) (y x)) (cons x y)) => (3 . 3)
    
    (let ((cons (lambda (a b) (+ a b)))
          (list (lambda (a b) (cons a (cons b 0)))))
      (list 1 2))  => (1 2 . 0)
    
    (letrec ((cons (lambda (a b) (+ a b)))
             (list (lambda (a b) (cons a (cons b 0)))))
      (list 1 2))  => 3
    

    Macro: let1 var expr body ...
    A convenient macro when you have only one variable. Expanded as follows.
    (let ((var expr)) body ...)
    

    Special Form: receive formals expression body ...
    [SRFI-8] This is the way to receive multiple values. Formals can be a (maybe-improper) list of symbols. Expression is evaluated, and the returned value(s) are bound to formals like the binding of lambda formals, then body ... are evaluated.
    (define (divrem n m)
      (values (quotient n m) (remainder n m)))
    
    (receive (q r) (divrem 13 4) (list q r))
      => (3 1)
    
    (receive all (divrem 13 4) all)
      => (3 1)
    
    (receive (q . rest) (divrem 13 4) (list q rest)
      => (3 (1))
    

    See also call-with-values in section 6.15.4 Multiple values which is the procedural equivalent of receive. You can use define-values (See section 4.10 Definitions) to bind multiple values to the toplevel variables simultaneously. Also let-values and let*-values in SRFI-11 (section 10.6 srfi-11 - Let-values) provides let-like syntax with multiple values.

    4.7 Sequencing

    Special Form: begin form ...
    [R5RS] Evaluates forms sequentially, and returns the last result(s).

    Begin doesn't introduce new "block" like let, that is, you can't place "internal define" at the beginning of forms generally. Semantically begin behaves as if forms are spliced into the surrounding context. For example, topleve expression like the following is the same as two toplevel definitions:

    (begin (define x 1) (define y 2))
    

    Here's a trickier example:

    (let ()
      (begin 
        (define x 2)
        (begin
          (define y 3)
        ))
      (+ x y))
    
      ==
    
    (let ()
      (define x 2)
      (define y 3)
      (+ x y))
    

    Macro: begin0 exp0 exp1 ...
    Evaluates exp0, exp1, ..., then returns the result(s) of exp0. The name is taken from MzScheme. This is called prog1 in CommonLisp.

    Unlike begin, this does creates a "block", for the begin0 form is expanded as follows.

    (receive tmp exp0
      exp1 ...
      (apply values tmp))
    

    4.8 Iteration

    Special Form: do ((variable init [step]) ...) (test expr ...) body ...
    [R5RS]

    Special Form: let name bindings body ...
    [R5RS]

    Macro: dotimes (variable limit [result]) body ...
    Macro: dolist (variable lexpr [result]) body ...
    Imported from Common Lisp. These are equivalent to the following forms, respectively.
    (dotimes (variable limit result) body ...)
    ==>
    (do ((tlimit limit)
         (variable 0 (+ variable 1)))
        ((>= variable tlimit) result)
      body ...)
    
    (dolist (variable lexpr result) body ...)
    ==>
    (begin
      (for-each (lambda (variable) body ...) lexpr)
      (let ((variable '())) result))
    

    4.9 Quasiquotation

    Special Form: quasiquote template
    [R5RS]

    4.10 Definitions

    Special Form: define variable expression
    Special Form: define (variable . formals) body ...
    [R5RS] This form has different meanings in the toplevel (without no local bindings) or inside a local scope.

    On toplevel, it defines a global binding to a symbol variable. In the first form, it globally binds a symbol variable to the value of expression, in the current module.

    (define x (+ 1 2))
    x => 3
    (define y (lambda (a) (* a 2)))
    (y 8) => 16
    

    The second form is a syntactic sugar of defining a procedure. It is equivalent to the following form.

    (define (name . args) body ...)
      == (define name (lambda args body ...))
    

    If the form appears inside a local scope (internal define), this introduce a local binding of the variable.

    Note that begin (See section 4.7 Sequencing) doesn't introduce a new scope. Defines in the begin act as if begin and surrounding parenthesis are not there. Thus these two forms are equivalent.

    (let ((x 0))
      (begin
        (define (foo y) (+ x y)))
      (foo 3))
     ==
    (let ((x 0))
      (define (foo y) (+ x y))
      (foo 3))
    

    Macro: define-values (var ...) expr
    Expr is evaluated, and it should return as many values as vars. Then each value of the results are bound to each variable in var .... See section 10.6 srfi-11 - Let-values.
    (define-values (lo hi) (min&max 3 -1 15 2))
    
    lo => -1
    hi => 15
    

    Special Form: define-constant variable expression
    Special Form: define-constant (variable . formals) body ...
    Like define, but that the compiler assumes the value of variable won't change and generates optimized code.

    An error is signalled when you use set! to change the value of variable. It is allowed to redefine variable, but a warning is printed.

    Special Form: define-in-module module variable expression
    Special Form: define-in-module module (variable . formals) body ...
    This form creates a global binding of variable in module, which must be either a symbol of the module name or a module object. If module is a symbol, the named module must exist.

    Expression is evaluated in the current module.

    The second form is merely a syntactic sugar of:

    (define-in-module module variable (lambda formals body ...))
    

    4.11 Modules

    This section describes the semantics of Gauche modules and its API. See also section 3.5 Writing Gauche modules, for the conventions Gauche is using for its modules.

    4.11.1 Module semantics

    Module is an object that maps symbols onto bindings, and affects the resolution of global variable reference.

    Unlike CommonLisp's packages, which map names to symbols, in Gauche symbols are always eq? if two have the same name. However, Gauche's symbol doesn't have a 'value' slot in it. Given symbol, a module finds its binding that keeps a value. Different modules can associate different bindings to the same symbol, that yield different values.

    ;; Makes two modules A and B, and defines a global variable 'x' in them
    (define-module A (define x 3))
    (define-module B (define x 4))
    
    ;;  #<symbol 'x'> ---[module A]--> #<binding that has 3>
    (with-module A x) => 3
    
    ;;  #<symbol 'x'> ---[module B]--> #<binding that has 4>
    (with-module B x) => 4
    

    A module can export a part or all of its bindings for other module to use. A module can import other modules, and their exported bindings become visible to the module. A module can import any number of modules.

    (define-module A
      (export pi)
      (define pi 3.1416))
    
    (define-module B
      (export e)
      (define e 2.71828))
    
    (define-module C
      (import A B))
    
    (select-module C)
    (* pi e) => 8.539748448
    

    A module can also be inherited, that is, you can extend the existing module by inheriting it and adding new bindings and exports. From the new module, all ancestor's bindings (including non-exported bindings) are visible. (A new module inherits the gauche module by default, which is why the built-in procedures and syntax of gauche are available in the new module). From outside, the new module looks like having all exported bindings of the original module plus the newly defined and exported bindings.

    ;; Module A defines and exports deg->rad.
    ;; A binding of pi is not exported.
    (define-module A
      (export deg->rad)
      (define pi 3.1416)   ;; not exported
      (define (deg->rad deg) (* deg (/ pi 180))))
    
    ;; Module Aprime defines and exports rad->deg.
    ;; The binding of pi is visible from inside Aprime.
    (define-module Aprime
      (extend A)
      (export rad->deg)
      (define (rad->deg rad) (* rad (/ 180 pi))))
    
    ;; Module C imports Aprime.
    (define-module C
      (import Aprime)
      ;; Here, both deg->rad and rad->deg are visible,
      ;; but pi is not visible.
      )
    

    At any moment of the compilation, there is one "current module" available, and the global variable reference is looked for from the module. If there is a visible binding of the variable, the variable reference is compiled to the access of the binding. If the compiler can't find a visible binding, it marks the variable reference with the current module, and delays the resolution of binding at the time the variable is actually used. That is, when the variable is referenced at run time, the binding is again looked for from the marked module (not the current module at the run time) and if found, the variable reference code is replaced for the the code to access the binding. If the variable reference is not found even at run time, an 'undefined variable' error is signalled.

    Once the appropriate binding is found for the global variable, the access to the binding is hard-wired in the compiled code and the global variable resolution will never take place again.

    The definition special form such as define and define-syntax inserts the binding to the current module. Thus it may shadow the binding of imported or inherited modules.

    The resolution of binding of a global variable happens like this. First, the current module is searched. Then, each imported module is taken in the order of import, and searched, including each module's ancestors. Note that import is not transitive; imported module list is not chased recursively. Finally, ancestors of the current module are searched in order.

    4.11.2 Defining and selecting modules

    Special Form: define-module name body ...
    Name must be a symbol If a module named name does not exist, create one. Then evaluates body sequentially in the module.

    Special Form: select-module name
    Makes a module named name as the current module. It is an error if no module named name exists.

    If select-module is used in the Scheme file, its effect is limited inside the file, i.e. even if you load/require a file that uses select-module internallly, the current module of requirer is not affected.

    Special Form: with-module name body ...
    Evaluates body sequentially in the module named name. Returns the last result(s). If no moudle named name, an error is signalled.

    Special Form: current-module
    Evaluates to the current module in the compile context. Note that this is a special form, not a function. Module in Gauche is statically determined at compile time.
    (define-module foo
      (export get-current-module)
      (define (get-current-module) (module-name (current-module))))
    
    (define-module bar
      (import foo)
      (get-current-module)) => foo ; not bar
    

    4.11.3 Using modules

    Special Form: export symbol ...
    Makes bindings of symbols in the current module available to modules that imports the current module.

    Special Form: export-all
    Makes all bindings in the current module available to modules that imports it.

    Special Form: import module-name ...
    Makes all exported bindings in the module named module-name available in the current module. The named modules should exist when the compiler sees this special form.

    Note that imports are not transitive. The modules that module-names are importing are not automatically imported to the current module. This keeps modules' modularity; a library module can import whatever modules it needs without worring about polluting the namespace of the user of the module.

    Macro: use name
    A convenience macro that combines module imports and on-demand file loading. Basically, (use foo) is equivalent to the following two forms:
    (require "foo")
    (import foo)
    

    That is, it loads the library file named "foo" (if not yet loaded) which defines a module named foo in it, and then import the module foo into the current module.

    Although the files and modules are orthogonal concept, it is practically convenient to separate files by modules. Gauche doesn't force you to do so, and you can always use require and import separately. However, all modules provided with Gauche are arranged so that they can be used by use macro.

    If a module is too big to fit in one file, you can split them into several subfiles and one main file. The main file defines the module, and either loads, requires, or autoloads subfiles.

    If name contains periods `.', it is replaced to `/' in the file name.to be required, for example, (use foo.bar.baz) is expanded to:

    (require "foo/bar/baz")
    (import foo.bar.baz)
    

    This is not very Scheme-ish way, but nevertheless convenient. (The alternative design is to use a list of symbols to represent hierarchical file/module configuration, as in Guile.)

    4.11.4 Module inheritance

    The export-import mechanism doesn't work well in some cases, such as:

    You can use module inheritance in these cases.

    Macro: extend module-name ...
    Makes the current module inherit from named modules. The current inheritance information is altered by the inheritance information calculated from given modules.

    A new module inherits from gauche module when created. If you put (extend scheme) in that module, for example, the module resets to inherit directly from scheme module that has only bindings defined in R5RS, hence, after the export form, you can't use 'import' or any other gauche-specific bindings in the module.

    If a named module is not defined yet, extend tries to load it, using the same convention use macro does.

    A module can inherit multiple modules, exactly the same way as a class can inherit from multiple classes. The resolution of order of inheritance needs to be explained a bit.

    Each module has a module precedence list, which lists modules in the order of how they are searched. When the module inherits multiple modules, module precedence lists of inherited modules are merged into a single list, keeping the constraints that: (1) if a module A appears before module B in some module precedence list, A has to appear before B in the resulting module precedence list; and (2) if a module A appears before module B in extend form, A has to appear before B in the resulting module precedence list. If no precedence list can be constructed with these constraints, an error is signalled.

    For example, suppose you wrote a library in modules mylib.base, mylib.util and mylib.system. You can bundle those modules into one module by creating a module mylib, as follows:

    (define-module mylib
      (extend mylib.system mylib.util mylib.base))
    

    The user of your module just says (use mylib) and all exported symbols from three submodules become available.

    4.11.5 Module introspection

    Builtin Class: <module>
    A module class.

    Function: module? obj
    Returns true if obj is a module.

    Function: find-module name
    Returns a module object whose name is a symbol name. If the named module doesn't exist, #f is returned.

    Function: all-modules
    Returns a list of modules currently known to the system.

    Function: module-name module
    Function: module-imports module
    Function: module-exports module
    Function: module-table module
    Accessors of a module object. Returns the name of the module (a symbol), list of imported modules, list of exported symbols, and a hash table that maps symbols to bindings, of the module are returned, respectively.

    If the module exports all symbols, module-exports returns #t.

    It is an error to pass a non-module object.

    Function: module-parents module
    Function: module-precedence-list module
    Returns the information of module inheritance. Module-parents returns the modules module directly inherits from. Module-precedence-list returns the module precedence list of module (See section 4.11.4 Module inheritance).

    4.11.6 Predefined modules

    Several modules are predefined in Gauche.

    Builtin Module: null
    This module corresponds to the null environment referred in R5RS. This module contains only syntactic bindings of R5RS syntax. (With one exception in the current implmenetation: Syntax with-module is in this module, since Gauche needed it for certain internal setup. It'll be removed in future.)

    Builtin Module: scheme
    This module contains all the binding of null module, and the binding of procedures defined in R5RS.

    Builtin Module: gauche
    This module contains all the bindings of scheme module, plus Gauche specific built-in procedures.

    Builtin Module: user
    This module is the default module the user code is compiled. all the bindings of gauche module is imported.

    5. Macros

    Gauche supports both R5RS hygienic macros and traditional macros.

    Macro of Lisp-family language is very different feature from ones of other languages, such as C preprocessor macros. It allows you to extend the original language syntax. You can use macros to change Gauche syntax so that you can run a Scheme program written to other Scheme implementations, and you can even design your own mini-language to solve your problem easily.

    5.1 Hygienic Macros

    R5RS hygienic macro is based on a special pattern language, and guaranteed that no "variable capture" occurs. "Variable catpture" means that if you insert new variable bindings in the expanded form, the new bindings shadows the bindings in the form passed to the macro.

    Special Form: define-syntax name transformer-spec
    [R5RS]

    Special Form: let-syntax ((name transformer-spec) ...) body
    Special Form: letrec-syntax ((name transformer-spec) ...) body
    [R5RS]

    Special Form: syntax-rules literals clause1 clause2 ...
    [R5RS]

    5.2 Traditional Macros

    Special Form: define-macro name procedure
    Special Form: define-macro (name formals) body ...
    Defines name to be a global macro whose transformer is procedure. The second form is a shorthand notation of the following form:
    (define-macro name (lambda formals body ...))
    

    When a form (name arg ...) is seen by the compiler, it calls procedure with arg .... When procedure returns, the compiler inserts the returned form in place of the original form, and compile it again.

    5.3 Macro expansion

    Function: macroexpand form
    Function: macroexpand-1 form
    If form is a list and its first element is a variable globally bound to a macro, macroexpand-1 invokes its macro transformer and returns the expanded form. Otherwise, returns form as is.

    macroexpand repeats macroexpand-1 until the form can't be expanded.

    These procedures can be used to expand globally defined macros.

    Special Form: %macroexpand form
    Special Form: %macroexpand-1 form

    5.4 Macro utilities

    Macro: syntax-error msg arg ...
    Macro: syntax-errorf fmt arg ...
    Signal an error. They are same as error and errorf (See section 6.16.1 Signalling errors), except that the error is signalled at macro-expansion time (i.e. compile time) rather than run time.

    They are useful to tell the user the wrong usage of macro in the comprehensive way, instead of the cryptic error from the macro expander. Because of the purpose, arg ... are first passed to unwrap-syntax described below, to strip off the internal syntactic binding informations.

    (define-syntax my-macro
      (syntax-rules ()
        ((_ a b)   (foo2 a b))
        ((_ a b c) (foo3 a b c))
        ((_ . ?)
         (syntax-error "malformed my-macro" (my-macro . ?)))))
    
    (my-macro 1 2 3 4)
      => error: "malformed my-macro: (mymacro 1 2 3 4)"
    

    Function: unwrap-syntax form
    Removes internal syntactic information from form. In order to implement a hygienic macro, macro expander replaces symbols in the macro form for identifiers, which captures the syntactic environment where they are defined. Although it is necessary information for the compiler, it is rather confusing for users if it appears in the messages. This function replaces occurrences of identifiers in form to the original symbols.

    6. Core library

    6.1 Equivalence

    Scheme has three different general equivalence test predicates. Other than these, some types have their own comarison predicates.

    Function: eq? obj1 obj2
    [R5RS] This is the fastest and finest predicate. Returns #t if obj1 and obj2 are allocated objects of the same types, and denote the same location. Returns #t if both objects are #f, #t, or (). You can think eq? as a pointer comparison. Note that the result is unspecified in Scheme standard when both objects are characters or numbers.
    (eq? #t #t)               => #t
    (eq? #t #f)               => #f
    (eq? 'a 'a)               => #t
    (eq? 'a 'b)               => #f
    (eq? (list 'a) (list 'a)) => #f
    (let ((x (list 'a)))
      (eq? x x))              => #t
    

    Function: eqv? obj1 obj2
    [R5RS] When obj1 and obj2 are both exact or both inexact numbers, eqv? returns #t iff (= obj1 obj2) is true. When obj1 and obj2 are both characters, eqv? returns #t iff (char=? obj1 obj2) is true. Otherwise, eqv? is the same as eq? on Gauche.
    (eqv? #\a #\a)             => #t
    (eqv? #\a #\b)             => #f
    (eqv? 1.0 1.0)             => #t
    (eqv? 1 1)                 => #t
    (eqv? 1 1.0)               => #f
    (eqv? (list 'a) (list 'a)) => #f
    (let ((x (list 'a)))
      (eqv? x x))              => #t
    

    Function: equal? obj1 obj2
    [R5RS+] If obj1 and obj2 are both aggregate types, equal? compares its elements recursively. Otherwise, equal? behaves the same as eqv?.

    If obj1 and obj2 are other than booleans, numbers, characters, pairs, strings and vectors, and the class of both objects are the same, equal? calls the generic function object-equal?. By defining the method, users can extend the behavior of equal? for user-defined classes.

    (equal? (list 1 2) (list 1 2)) => #t
    (equal? "abc" "abc")           => #t
    (equal? 100 100)               => #t
    (equal? 100 100.0)             => #f
    

    Generic Function: object-equal? obj1 obj2
    This generic function is called when equal? is called on the objects it doesn't know about. You can define this method on your class so that equal? can check equivalence. This method is supposed to return #t if obj1 is equal to obj2, #f otherwise. If you want to check equivalence of elements recursively, do not call object-equal? directly; call equal? on each element.
    (define-class <foo> ()
      ((x :init-keyword :x)
       (y :init-keyword :y)))
    
    (define-method object-equal? ((a <foo>) (b <foo>))
      (and (equal? (slot-ref a 'x) (slot-ref b 'x))
           (equal? (slot-ref a 'y) (slot-ref b 'y))))
    
    (equal? (make <foo> :x 1 :y (list 'a 'b))
            (make <foo> :x 1 :y (list 'a 'b)))
      => #t
    
    (equal? (make <foo> :x 1 :y (make <foo> :x 3 :y 4))
            (make <foo> :x 1 :y (make <foo> :x 3 :y 4)))
      => #t
    

    Sometimes you want to test if two aggregate structures are topologically equal, i.e., if one has a shared substructure, the other has a shared substructure in the same way. Equal? can't handle it; module util.isomorph provides a procedure isomorphic? which does the job (See section 11.21 util.isomorph - Determine isomorphism).

    6.2 Numbers

    Gauche supports the following types of numbers

    multi-precision exact integer
    There's no limit of the size of number except the memory of the machine.
    inexact floating-point real number
    Using double-type of underlying C compiler, usually IEEE 64-bit floating point number.
    inexact floating-point complex number
    Real part and imaginary part are represented by inexact floating-point real numbers.

    6.2.1 Number classes

    Builtin Class: <number>
    Builtin Class: <complex>
    Builtin Class: <real>
    Builtin Class: <integer>
    These classes consist a class hierarchy of number objects. <complex> inherits <number>, <real> inherits <complex> and <integer> inherits <real>.

    Note that these classes does not exactly corresponds to the number hierarchy defined in R5RS. Especially, only exact integers are the instances of the <integer> class. That is,

    (integer? 1)        => #t
    (is-a? 1 <integer>) => #t
    (is-a? 1 <real>)    => #t
    
    (integer? 1.0)        => #t
    (is-a? 1.0 <integer>) => #f
    (is-a? 1.0 <real>)    => #t
    
    (class-of (expt 2 100)) => #<class <integer>>
    (class-of (sqrt -3)) => #<class <complex>>
    

    6.2.2 Numerical predicates

    Function: number? obj
    Function: complex? obj
    Function: real? obj
    Function: rational? obj
    Function: integer? obj
    [R5RS] Returns #t if obj is a number, a complex number, a real number, a rational number or an integer, respectively. In Gauche, a set of numbers is the same as a set of complex numbers, and a set of rational numbers is the same as a set of integers.
    (complex? 3+4i)   => #t
    (complex? 3)      => #t
    (real? 3)         => #t
    (real? -2.5+0.0i) => #t
    (real? #e1e10)    => #t
    (integer? 3+0i)   => #t
    (integer? 3.0)    => #t
    

    Function: exact? obj
    Function: inexact? obj
    [R5RS] Returns #t if obj is an exact number and an inexact number, respectively.
    (exact? 1)       => #t
    (exact? 1.0)     => #f
    (inexact? 1)     => #f
    (inexact? 1.0)   => #t
    
    (exact? (modulo 5 3)) => #t
    (inexact? (modulo 5 3.0)) => #f
    

    Function: zero? z
    [R5RS] Returns #t if a number z equals to zero.
    (zero? 1)        => #f
    (zero? 0)        => #t
    (zero? 0.0)      => #t
    (zero? 0.0+0.0i) => #t
    

    Function: positive? x
    Function: negative? x
    [R5RS] Returns #t if a real number x is positive and negative, respectively. It is an error to pass a non-real number.

    Function: odd? n
    Function: even? n
    [R5RS] Returns #t if an integer n is odd and even, respectively. It is an error to pass a non-integral number.
    (odd? 3)     => #t
    (even? 3)    => #f
    (odd? 3.0)   => #t
    

    Function: fixnum? n
    Function: bignum? n
    Returns #t iff n is an exact integer whose internal representation is fixnum and bignum, respectively. Portable Scheme programs don't need to care about the internal representation of integer. These are for certain low-level routines that does particular optimization.

    6.2.3 Numerical comparison

    Function: = z1 z2 z3 ...
    [R5RS] If all the numbers z are equal, returns #t.
    (= 2 2)          => #t
    (= 2 3)          => #f
    (= 2 2.0)        => #t
    (= 2 2.0 2.0+0i) => #t
    

    Function: < x1 x2 x3 ...
    Function: <= x1 x2 x3 ...
    Function: > x1 x2 x3 ...
    Function: >= x1 x2 x3 ...
    [R5RS] Returns #t If all the real numbers x are monotonically increasing, monotonically nondecreasing, monotonically decreasing, or monotonically nonincreasing, respectively.

    Function: max x1 x2 ...
    Function: min x1 x2 ...
    [R5RS] Returns a maximum or minimum number in the given real numbers, respectively.

    Function: min&max x1 x2 ...
    Returns a maximum and minimum number in the given real numbers.

    6.2.4 Arithmetics

    Function: + z ...
    Function: * z ...
    [R5RS] Returns the sum or the product of given numbers, respectively. If no argument is given, (+) yields 0 and (*) yields 1.

    Function: - z1 z2 ...
    Function: / z1 z2 ...
    [R5RS] If only one number z1 is given, returns its negation and reciprocal, respectively.

    If more than one number are given, returns:

    z1 - z2 - z3 ...
    z1 / z2 / z3 ...
    

    respectively.

    (- 3)       => -3
    (- -3.0)    => 3.0
    (- 5+2i)    => -5.0-2.0i
    (/ 3)       => 0.333333333333333
    (/ 5+2i)    => 0.172413793103448-0.0689655172413793i
    
    (- 5 2 1)     => 2
    (- 5 2.0 1)   => 2.0
    (- 5+3i -i)   => 5.0+2.0i
    (/ 6+2i 2)    => 3.0+1.0i
    

    Function: abs z
    [R5RS+] For real number z, returns an absolute value of it. For complex number z, returns the magnitude of the number. The complex part is Gauche extension.
    (abs -1)   => 1
    (abs -1.0) => 1.0
    (abs 1+i)  => 1.4142135623731
    

    Function: quotient n1 n2
    Function: remainder n1 n2
    Function: modulo n1 n2
    [R5RS] Returns the quotient, remainder and modulo of dividing an integer n1 by an integer n2. The result is an exact number only if both n1 and n2 are exact numbers.

    Remainder and modulo differ when either one of the arguments is negative. Remainder R and quotient Q have the following relationship.

      n1 = Q * n2 + R
    

    where abs(Q) = floor(abs(n1)/abs(n2)). Consequently, R's sign is always the same as n1's.

    On the other hand, modulo works as expected for positive n2, regardless of the sign of n1 (e.g. (modulo -1 n2) == n2 - 1). If n2 is negative, it is mapped to the positive case by the following relationship.

      modulo(n1, n2) = -modulo(-n1, -n2)
    

    Consequently, modulo's sign is always the same as n2's.

    (remainder 10 3)    => 1
    (modulo 10 3)       => 1
    
    (remainder -10 3)   => -1
    (modulo -10 3)      => 2
    
    (remainder 10 -3)   => 1
    (modulo 10 -3)      => -2
    
    (remainder -10 -3)  => -1
    (modulo -10 -3)     => -1
    

    Function: quotient&remainder n1 n2
    Calculates the quotient and the remainder of dividing integer n1 by integer n2 simultaneously, and returns them as two values.

    Function: gcd n ...
    Function: lcm n ...
    [R5RS] Returns the greatest common divisor or the least common multiplier of the given integers, respectively

    Function: numerator q
    Function: denominator q
    [R5RS] Returns the numerator and denominator of a rational number q. Since Gauche doesn't support full rational numbers, they actually work only on integers; that is, given integer q, numerator always returns q and denominator always return 1.

    Function: floor x
    Function: ceiling x
    Function: truncate x
    Function: round x
    [R5RS] The argument x must be a real number. Floor and ceiling return a minimum integer that is greater than x and a maximim integer that is less than x, respectively. Truncate returns an integer that truncates x towards zero. Round returns an integer that is closest to x. If fractional part of x is exactly 0.5, round returns the closest even integer.

    Function: clamp x &optional min max
    Returns
     min if x < min
     x   if min <= x <= max
     max if max < x
    

    If min or max is omitted or #f, it is regarded as -infinity or +infinity, respectively. Returns an exact integer only if all the given numbers are exact integers.

    (clamp 3.1 0.0 1.0) => 1.0
    (clamp 0.5 0.0 1.0) => 0.5
    (clamp -0.3 0.0 1.0) => 0.0
    (clamp -5 0)        => 0
    (clamp 3724 #f 256) => 256
    

    Function: exp z
    Function: log z
    Function: sin z
    Function: cos z
    Function: tan z
    Function: asin z
    Function: acos z
    Function: atan z
    [R5RS] Transcedental functions. Work for complex numbers as well.

    Function: atan x y
    [R5RS] For real numbers x and y, returns atan(y/x).

    Function: sinh z
    Function: cosh z
    Function: tanh z
    Function: asinh z
    Function: acosh z
    Function: atanh z
    Hyperbolic trigonometric functions. Work for complex numbers as well.

    Function: sqrt z
    [R5RS] Returns a square root of a complex number z. The branch cut scheme is the same as Common Lisp. For real numbers, it returns a positive root.

    Function: expt z1 z2
    [R5RS] Returns z1^z2 (z1 powered by z2), where z1 and z2 are complex numbers.

    6.2.5 Numerical conversions

    Function: make-rectangular x1 x2
    Function: make-polar x1 x2
    [R5RS] Creates a complex number from two real numbers, x1 and x2. make-rectangular returns x1 + ix2. make-polar returns x1e^(ix2).

    Function: real-part z
    Function: imag-part z
    Function: magnitude z
    Function: angle z
    [R5RS] Decompose a complex number z and returns a real number. real-part and imag-part return z's real and imaginary part, respectively. magnitude and angle return z's magnitude and angle, respectively.

    Function: decode-float x
    Given floating-point number (inexact real number), returns a vector of three exact integers, #(m, e, sign), where
      x = (* sign m (expt 2.0 e))
      sign is either 1, 0 or -1.
    

    The API is taken from ChezScheme.

    (decode-float 3.1415926)
     => #(7074237631354954 -51 1)
    (* 7074237631354954 (expt 2.0 -51))
     => 3.1415926
    

    Function: fmod x y
    Function: modf x
    Function: frexp x
    Function: ldexp x n
    [POSIX] These procedures can be used to compose and decompose floating point numbers. Fmod computes the remainder of dividing x by y, that is, it returns x-n*y where n is the quotient of x/y rounded towards zero to an integer. Modf returns two values; a fractional part of x and an integral part of x. Frexp returns two values, fraction and exponent of x, where x = fraction * 2^exponent, and 0 <= fraction <= 0.5. Ldexp is a reverse operation of frexp; it returns a real number x * 2^n.
    (fmod 32.1 10.0)  => 2.1
    (fmod 1.5 1.4)    => 0.1
    (modf 12.5)       => 0.5 and 12.0
    (frexp 3.14)      => 0.785 and 2
    (ldexp 0.785 2)   => 3.14
    

    Function: exact->inexact z
    Function: inexact->exact z
    [R5RS] Converts an exact number to an inexact number, or vice versa.

    Since Gauche doesn't support general rational numbers, the result of inexact->exact is always a whole number. If the passed number is not an integer, the fraction part is rounded. Note that it is an implementation dependent behavior. If you want to get a closest exact integer of the given inexact real number, it's better to use round explicitly before inexact->exact.

    If you pass an inexact number to exact->inexact or an exact number to inexact->exact, Gauche returns the argument as is, instead of reporting an error. This is also an implementation dependent behavior and you shouldn't count on that.

    Function: number->string z &optional radix use-upper?
    Function: string->number string &optional radix
    [R5RS+] These procedurs convert a number and its string representation in radix radix system. radix must be between 2 and 36 inclusive. If radix is omitted, 10 is assumed.

    Number->string takes a number z and returns a string. If z is not an exact integer, radix must be 10. For the numbers with radix more than 10, lower case alphabet character is used for digits, unless the optional argument use-upper? is true, in that case upper case characters are used. The argument use-upper? is Gauche's extension.

    String->number takes a string string and parses it as a number in radix radix system. If the number looks like non-exact number, only radix 10 is allowed. If the given string can't be a number, #f is returned.

    Generic Function: x->number obj
    Generic Function: x->integer obj
    Generic coercion functions. Returns `natural' interpretation of obj as a number or an exact integer, respectively. The default methods are defined for numbers and strings; a string is interpreted by string->number, and if the string can't be interpreted as a number, 0 is returned. Other obj is simply converted to 0. If obj is naturally interpreted as a number that is not an exact integer, x->integer uses round and inexact->exact to obtain an integer.

    Other class may provide a method to customize the behavior.

    6.2.6 Bitwise operations

    These procedures treat integers as half-open bit vectors. If an integer is positive, it is regarded as if infinite number of zeros are padded to the left. If an integer is negative, it is regarded in 2's complement form, and infinite number of 1's are padded to the left.

    The API is consisntent to SLIB's "logical" module.

    Function: ash n count
    Shifts integer n left with count bits. If count is negative, ash shifts n right with -count bits.
    ; Note: 6  == [...00110], and
    ;       -6 == [...11010]
    (ash 6 2)   => 24  ;[...0011000]
    (ash 6 -2)  => 1   ;[...0000001]
    (ash -6 2)  => -24 ;[...1101000]
    (ash -6 -2) => -2  ;[...1111110]
    

    Function: logand n1 n2 ...
    Function: logior n1 n2 ...
    Function: logxor n1 n2 ...
    Returns bitwise and, bitwise inclusive or and bitwise exclusive or of two or more integers n1, n2 ....

    Function: lognot n
    Returns bitwise not of an integer n.

    Function: logtest n1 n2 ...
    == (not (zero? (logand n1 n2 ...)))

    Function: logbit? index n
    Returns #t if index-th bit of integer n is 1, #f otherwise.

    Function: bit-field n start end
    Extracts (start+1)-th bit to end-th bit (inclusive) from an exact integer n, where start < end.

    Function: copy-bit index n bit
    If bit is true, sets index-th bit of an exact integer n. If bit is false, resets index-th bit of an exact integer n.

    Function: copy-bit-field n start end from

    Function: logcount n

    Function: integer-length n

    6.3 Booleans

    Builtin Class: <boolean>
    A boolean class. Only #t and #f belong to this class.

    Function: not obj
    [R5RS] Returns #t if and only if obj is #t, and returns #f otherwise.

    Function: boolean? obj
    [R5RS] Returns #t if obj is a boolean value.

    6.4 Pairs and Lists

    6.4.1 Pair and null class

    Builtin Class: <list>
    An abstract class respresents lists. A parent class of <null> and <pair>. Inherits <sequence>.

    Note that a cirular list is also an instance of the <list> class, while R5RS procedure list? returns false on the circular lists and dotted lists.

    (use srfi-1)
    (list? (circular-list 1 2)) => #f
    (is-a? (circular-list 1 2) <list>) => #t
    

    Builtin Class: <null>
    A class of empty list. () is the only instance.

    Builtin Class: <pair>
    A class of pairs.

    6.4.2 List predicates

    Function: pair? obj
    [R5RS] Returns #t if obj is a pair, #f otherwise.

    Function: null? obj
    [R5RS] Returns #t if obj is an empty list, #f otherwise.

    Function: list? obj
    [R5RS] Returns #t if obj is a proper list, #f otherwise. This function returns #f if obj is a dotted or circular list.

    See also proper-list?, circular-list? and dotted-list? in section 10.2.2 List predicates.

    6.4.3 List constructors

    Function: cons obj1 obj2
    [R5RS] Constructs a pair of obj1 and obj2 and returns it.
    (cons 'a 'b) => (a . b)
    

    Function: acons obj1 obj2 obj3
    Returns (cons (cons obj1 obj2) obj3). Useful to put an entry at the head of an associative list.
    (acons 'a 'b '((c . d))) => ((a . b) (c . d))
    

    Function: make-list len &optional fill
    [SRFI-1] Makes a proper list of length len. If optional argument fill is provided, each element is initialized by it. Otherwise each element is undefined.
    (make-list 5 #t) => (#t #t #t #t #t)
    

    Function: list obj ...
    [R5RS] Makes a list, whose elements are obj ....
    (list 1 2 3) => (1 2 3)
    (list) => ()
    

    Function: list* obj1 obj2 ...
    Like list, but the last argument becomes cdr of the last pair. SRFI-1 defines the same function with the name cons*.
    (list* 1 2 3) => (1 2 . 3)
    (list* 1) => 1
    

    Function: list-copy list
    [SRFI-1] Shallow copies list. If list is circular, this function diverges.

    6.4.4 List accessors and modifiers

    Function: car pair
    Function: cdr pair
    [R5RS] Returns car and cdr of pair, respectively.

    Function: set-car! pair obj
    Function: set-cdr! pair obj
    [R5RS] Modifies car and cdr of pair, by obj, respectively.

    Note: (setter car) == set-car!, and (setter cdr) == set-cdr!.

    Function: caar pair
    Function: cadr pair
    ...
    Function: cdddar pair
    Function: cddddr pair
    [R5RS] caar == (car (car x)), cadr == (car (cdr x)), and so on.

    The corresponding setters are also defined.

    (let ((x (list 1 2 3 4 5)))
      (set! (caddr x) -1)
      x)
      => (1 2 -1 4 5)
    

    Function: length list
    [R5RS] Returns the length of a proper list list. If list is a dotted list, an error is signalled. If list is a circular list, this function diverges.

    If you want to handle circular lists as well, See length+ in section 10.2.4 List miscellaneous routines.

    Function: list-tail list k
    [R5RS] Returns k-th cdr of list. list can be a proper, dotted or circular list.

    Function: list-ref list k &optional fallback
    [R5RS+] Returns k-th element of list. list can be a proper, dotted or circular list.

    By default, list-ref signals an error if k is negative, or greater than or equal to the length of list. However, if an optional argument fallback is given, it is returned for such case. This is an extension of Gauche.

    Function: last-pair list
    [SRFI-1] Returns the last pair of list. list can be a proper or dotted list.

    6.4.5 Other list procedures

    Function: append list ...
    [R5RS] Returns a list consisting of the elements of the first list followed by the elements of the other lists. 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.

    Function: append! list ...
    [SRFI-1] Returns a list consisting of the elements of the first list followed by the elements of the other lists. The cells in the lists except the last one may be reused to construct the result. The last argument may be any object.

    Function: reverse list
    [R5RS] Returns a newly allocated list consisting of the elements of list in reverse order.

    Function: reverse! list
    [SRFI-1] Returns a list consisting of the elements of list in reverse order. The cells of list may be reused to construct the returned list.

    Function: memq obj list
    Function: memv obj list
    Function: member obj list
    [R5RS] Searches obj in the list. If n-th element of list equals to obj (in the sense of eq? for memq, eqv? for memv, and equal? for member), (list-tail list n) is returned. Otherwise, #f is returned.

    If you use SRFI-1 (See section 10.2 srfi-1 - List library), member is extended to take optional argument for a equality procedure.

    (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
    (memv 101 '(100 101 102))   => (101 102)
    

    Function: assq obj list
    Function: assv obj list
    Function: assoc obj list
    [R5RS] Each element in list must be a pair. These procedures search a pair whose car matches obj (in the sense of eq? for assq, eqv? for assv, and equal? for assoc) from left to right, and return the leftmost matched pair if any. If no pair matches, these return #f.

    If you use SRFI-1 (See section 10.2 srfi-1 - List library), assoc is extended to take optional argument for a equality procedure.

    6.5 Symbols

    Builtin Class: <symbol>
    A class for symbols.

    In Gauche, all symbols are interned, i.e. two symbols with the same print name are always eq?.

    Reader Syntax: |name|
    Denotes a symbol that has weird name, i.e. the name including the characters which is not allowed in the R5RS symbol syntax. If the interpreter is running in case-insensitive mode, this syntax can be used to include uppercase characters in a symbol (See section 2.3 Case-sensitivity).

    The syntax is taken from CommonLisp. Some other Scheme implementation use it as well.

    Function: symbol? obj
    [R5RS] Returns true if and only if obj is a symbol.
    (symbol? 'abc)     => #t
    (symbol? 0)        => #f
    (symbol? 'i)       => #t
    (symbol? '-i)      => #f
    (symbol? '|-i|)    => #t
    

    Function: symbol->string symbol
    [R5RS] Returns the name of symbol in a string. Returned string is immutable.
    (symbol->string 'foo) => foo
    

    Function: string->symbol string
    [R5RS] Returns a symbol whose name is a string string. String may contain weird characters.
    (string->symbol "a") => a
    (string->symbol "A") => A
    (string->symbol "weird symbol name" => |weird symbol name|
    

    Function: gensym &optional prefix

    6.6 Keywords

    Builtin Class: <keyword>
    A keyword is a sort of a special symbol that is automatically quoted. It is extensively used in pass-by-name arguments (keyword arguments), and keyword-value list Unlike CommonLisp, keywords and symbols are distinct types.

    See also let-keywords* macro (section 6.15.1.3 Optional argument parsing) for keyword argument processing.

    Reader syntax: :name
    Read to a keyword whose name is name. (Note that the preceding ':' is not a part of the keyword's name.)

    Function: keyword? obj
    Returns #t iff obj is a keyword.

    Function: make-keyword name
    Returns a keyword whose name is name.

    Function: keyword->string keyword
    Returns the name of the keyword keyword.

    Function: get-keyword key list &optional fallback
    A useful procedure to extract a value from key-value list. A key-value list list must contains even number of elements; the first, third, fifth ... elements are regarded as keys, and the second, fourth, sixth ... elements are the values of the preceding keys.

    This procedure looks for key from the keys, and if it finds one, it returns the corresponding value. If there are more than one matching keys, the leftmost one is taken. If there is no matching key, it returns fallback if provided, or signals an error otherwise.

    It is an error if list is not a proper, even-number element list.

    Actually, `keywords' in the keyword-value list and the key argument need not be a keyword--it can be any Scheme object. Key comparison is done by eq?.

    This procedure is taken from STk.

    Macro: get-keyword* key list &optional fallback
    Like get-keyword, but fallback is evaluated only if list does not have key.

    6.7 Identifiers

    Builtin Class: <identifier>

    Function: identifier? obj

    Function: identifier->symbol identiifer

    6.8 Characters

    Builtin Class: <char>

    Reader Syntax: #\charname
    [R5RS] Denotes a literal character.

    When the reader reads #\, it fetches a sbusequent character. If it is one of ()[]{}" \|;#, this is a character literal of itself. Otherwise, the reader reads subsequent characters until it sees a non word-constituent character. If only one character is read, it is the character. Otherwise, the reader matches the read characters with predefined character names. If it doesn't match any, an error is signalled.

    The following character names are recognized. These haracter names are case insensitive.

    space
    Whitespace (ASCII #x20)
    newline, nl, lf
    Newline (ASCII #x0a)
    return, cr
    Carriage return (ASCII #x0d)
    tab, ht
    Horizontal tab (ASCII #x09)
    page
    Form feed (ASCII #x0c)
    escape, esc
    Escape (ASCII #x1b)
    delete, del
    Delete (ASCII #x7f)
    null
    NUL character (ASCII #x00)
    xN
    A character whose internal encoding is the integer N, when N is a hexadecimal integer. Note that this notation is not portable among different internal encoding schemes except ASCII character range.
    uN
    A character whose UCS character code is the integer N, where N is 4-digit or 8-digit hexadecimal number. If Gauche is compiled with the internal encoding other than UTF-8, the reader uses gauche.charconv module to convert Unicode to the internal character code. Note that the specified character may not be defined in the internal encoding; in which case, either a substitution character is used, or an error is signalled.
    #\newline => #\newline ; newline character
    #\x0a     => #\newline ; ditto
    #\x41     => #\A       ; ASCII letter 'A'
    #\u0041   => #\A       ; ASCII letter 'A', specified by UCS
    #\u3042   => ; Hiragana letter A, specified by UCS
    #\u0002a6b2 => ; JISX0213 Kanji 2-94-86, specified by UCS4
    

    You can denote multibyte characters with this syntax if the program text is written in the same encoding as the internal character encoding.

    Function: char? obj
    [R5RS] Returns #t if obj is a character, #f otherwise.

    Function: char=? char1 char2
    Function: char<? char1 char2
    Function: char<=? char1 char2
    Function: char>? char1 char2
    Function: char>=? char1 char2
    [R5RS] Compares characters. Character comparison is done in internal character encoding.

    Function: char-ci=? char1 char2
    Function: char-ci<? char1 char2
    Function: char-ci<=? char1 char2
    Function: char-ci>? char1 char2
    Function: char-ci>=? char1 char2
    [R5RS] Compares characters in case-insensitive way. In the current version, character cases are not well defined outside the ASCII character range.

    Function: char-alphabetic? char
    Function: char-numeric? char
    Function: char-whitespace? char
    Function: char-upper-case? char
    Function: char-lower-case? char
    [R5RS] Returns true if a character char is an alphabetic character ([A-Za-z]), a numeric character ([0-9]), a whitespace character, an upper case character or a lower case character, respectively. Currently, these procedures works only for ASCII characters. They return #f for all other characters.

    Function: char->integer char
    Function: integer->char n
    [R5RS] char->integer returns an exact integer that represents internal encoding of the character char. integer->char returns a character whose internal encoding is an exact integer n. The following expression is always true for valid charcter char:
    (eq? char (integer->char (char->integer char)))
    

    The result is undefined if you pass n to integer->char that doesn't have a corresponding character.

    Function: char->ucs char
    Function: ucs->char n
    Converts a character char to integer UCS codepoint, and integer UCS codepoint n to a character, respectively.

    If Gauche is compiled with UTF-8 encoding, these procedures are the same as char->integer and integer->char.

    When Gauche's internal encoding differs from UTF-8, these procedures implicitly loads gauche.charconv module to convert internal character code to UCS or vice versa (See section 9.2 gauche.charconv - Character Code Conversion). If char doesn't have corresponding UCS codepoint, char->ucs returns #f. If UCS codepoint n can't be represented in the internal character encoding, ucs->char returns #f, unless the conversion routine provides a substitution character.

    Function: char-upcase char
    Function: char-downcase char
    [R5RS] Returns the upper case and lower case of char, respectively. If char doesn't have such distinction of upper or lower case, char itself is returned.

    In the current version, character cases are not well defined outside the ASCII character range.

    Function: digit->integer char &optional (radix 10)
    If given character char is a valid digit character in radix radix number, the corresponding integer is returned. Otherwise #f is returned.
    (digit->integer #\4) => 4
    (digit->integer #\e 16) => 14
    (digit->integer #\9 8) => #f
    

    Note: CommonLisp has a similar function in rather confusing name, digit-char-p.

    Function: integer->digit integer &optional (radix 10)
    Reverse operation of digit->integer. Returns a character that represents the number integer in the radix radix system. If integer is out of the valid range, #f is returned.
    (integer->digit 13 16) => #\d
    (integer->digit 10) => #f
    

    Note: CommonLisp's digit-char.

    Function: gauche-character-encoding
    Returns a symbol designates the native character encoding, selected at the compile time. The possible return values are those:
    euc-jp
    EUC-JP
    utf-8
    UTF-8
    sjis
    Shift JIS
    none
    No multibyte character support (8-bit fixed-length character).

    Function: supported-character-encodings
    Returns a list of string names of character encoding schemes that are supported in the native multibyte encoding scheme.

    6.9 Character Set

    Builtin Class: <char-set>
    Character set class. Character set object represents a set of characters. Gauche provides built-in support of character set creation and a predicate that tests whether a character is in the set or not.

    Further operations, such as set algebra, is defined in SRFI-14 module (See section 10.8 srfi-14 - Character-set library).

    Reader Syntax: #[char-set-spec]
    You can write a literal character set in this syntax. char-set-spec is a sequence of characters to be included in the set. You can include the following special sequences:
    x-y
    Characters between x and y, inclusive. x must be smaller than y in the internal encoding.
    ^
    If char-set-spec begins with caret, the actual character set is a complement of what the rest of char-set-spec indicates.
    \xNN
    A character whose internal code is a hexadecimal number NN.
    \uNNNN
    A character whose UCS-2 code is a 4-digit hexadecimal number NNNN.
    \UNNNNNNNN
    A character whose UCS-4 code is a 8-digit hexadecimal number NNNNNNNN.
    \s
    Whitespace characters.
    \S
    Complement of whitespace characters.
    \d
    Decimal digit characters.
    \D
    Complement of decimal digit characters.
    \w
    Alphanumeric characters.
    \W
    Complement of alphanumeric characters.
    \\
    A backslash character.
    \-
    A minus character.
    \^
    A caret character.
    [:alnum:] ...
    Character set a la POSIX. The following character set name is recognized: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper and xdigit.
    #[aeiou]     ; a character set consists of vowels
    #[a-zA-Z]    ; alphabet
    #[[:alpha:]] ; alphabet (using POSIX notation)
    #[\x0d\x0a]  ; newline and carriage return
    #[\\\-]      ; backslash and minus
    #[]          ; empty charset
    

    Function: char-set? obj
    [SRFI-14] Returns true if and only if obj is a character set object.

    Function: char-set-contains? char-set char
    [SRFI-14] Returns true if and only if a character set object char-set contains a character char.
    (char-set-contains? #[a-z] #\y) => #t
    (char-set-contains? #[a-z] #\3) => #f
    
    (char-set-contains? #[^ABC] #\A) => #f
    (char-set-contains? #[^ABC] #\D) => #t
    
    

    Function: char-set char ...
    [SRFI-14] Creates a character set that contains char ....
    (char-set #\a #\b #\c)   => #[a-c]
    

    Function: char-set-copy char-set
    [SRFI-14] Copies a character set char-set.

    6.10 Strings

    Builtin Class: <string>
    A string class. In Gauche, a string can be viewed in two ways: a sequence of characters, or a sequence of bytes.

    R5RS string operations are very minimal. Gauche supports some extra built-in operations, and also a rich string library defined in SRFI-13. See section 10.7 srfi-13 - String library, for details about SRFI-13.

    6.10.1 String syntax

    Reader syntax: "..."
    [R5RS+] Denotes a literal string. Inside the double quotes, the following backslash escape sequences are recognized.
    \"
    [R5RS] Double-quote character
    \\
    [R5RS] Backslash character
    \n
    Newline character (ASCII 0x0a).
    \r
    Return character (ASCII 0x0d).
    \f
    Form-feed character (ASCII 0x0c).
    \t
    Tab character (ASCII 0x09)
    \0
    ASCII NUL character (ASCII 0x00).
    \xNN
    A byte represented by two-digit hexadecimal number NN. The byte is interpreted as the internal multibyte encoding.
    \uNNNN
    A character whose UCS2 code is represented by four-digit hexadecimal number NNNN.
    \UNNNNNNNN
    A character whose UCS4 code is represented by eight-digit hexadecimal number NNNNNNNN.

    If Gauche is compiled with internal encoding other than UTF-8, the reader uses gauche.charconv module to interpret \uNNNN and \UNNNNNNNN escape sequence.

    Reader syntax: #*"..."
    Denotes incomplete string. The same escape sequences as the complete string syntax are recognized.

    Note: literal incomplete strings used to be #"...". As of Gauche 0.6.3, the syntax switched to #*"...". The old syntax is still recognized, but eventually will fade away. String interpolation will eventually take #"..." syntax.

    Rationale of the syntax: '#*' is used for bit vector in Common Lisp. Since an incomplete strings is really a byte vector, it has similarity. (Bit vector can be added later, if necessary, and two can coexist).

    6.10.2 String Predicates

    Function: string? obj
    [R5RS] Returns #t if obj is a string, #f otherwise.

    Function: string-immutable? obj
    Returns #t if obj is an immutable string, #f otherwise

    Function: string-incomplete? obj
    Returns #t if obj is an incomplete string, #f otherwise

    6.10.3 String Constructors

    Function: make-string k &optional char
    [R5RS] Returns a string of length k. If optional char is given, the new string is filled with it. Otherwise, the string is filled with a whitespace. The result string is always complete.
    (make-string 5 #\x) => "xxxxx"
    

    Note that the algorithm to allocate a string by make-string and then fills it one character at a time is extremely inefficient in Gauche, and should be avoided. That kind of algorithms unnecessarily assumes underlying string allocation and representation mechanism, which Gauche doesn't follow. You can use an output string port for a string construction (See section 6.18.4 String ports). Even creating a list of characters and using list->string is faster than using make-string and string-set!.

    Function: string char ...
    [R5RS] Returns a string consisted by char ....

    Generic Function: x->string obj
    A generic coercion function. Returns a string representation of obj. The default methods are defined as follows: strings are returned as is, numbers are converted by number->string, symbols are converted by symbol->string, and other objects are converted by display.

    Other class may provide a method to customize the behavior.

    6.10.4 String interpolation

    The term "string interpolation" is used in various scripting languages such as Perl and Python to refer to the feature to embed expressions in a string literal, which are evaluated and then their results are inserted into the string literal at run time.

    Scheme doesn't define such a feature, but Gauche implements it as a reader macro.

    Reader syntax: #`string-literal
    Evaluates to a string. If string-literal contains the character sequence ,expr, where expr is a valid external representation of a Scheme expression, expr is evaluated and its result is inserted in the original place (by using x->string, see section 6.10.3 String Constructors).

    The comma and the following expression must be adjacent (without containing any whitespace characters), or it is not recognized as a special sequence.

    Two adjacent commas are converted to a single comma. You can embed a comma before a non-whitespace character in string-literal by this.

    Other characters in the string-literal are copied as is.

    If you use a variable as expr and need to delimit it from the subsequent string, you can use the symbol escape syntax using `|' character, as shown in the last two examples below.

    #`"This is Gauche, version ,(gauche-version)."
     => "This is Gauche, version 0.6.5."
    
    #`"Date: ,(sys-strftime \"%Y/%m/%d\" (sys-localtime (sys-time)))"
     => "Date: 2002/02/18"
    
    (let ((a "AAA")
          (b "BBB"))
     #`"xxx ,a ,b zzz")
     => "xxx AAA BBB zzz"
    
    #`"123,,456,,789"
     => "123,456,789"
    
    (let ((n 5)) #`"R,|n|RS")
     => "R5RS"
    
    (let ((x "bar")) #`"foo,|x|.")
     => "foobar"
    

    In fact, the reader expands this syntax into a macro call, which is then expanded into a call of string-append as follows:

    #`"This is Gauche, version ,(gauche-version)."
     ==
    (string-append "This is Gauche, version "
                   (x->string (gauche-version))
                   ".")
    

    Rationale of the syntax: Some other scripting languages use `$expr' or '#{...}'. I chose this syntax with respect to the quasiquote (See section 4.9 Quasiquotation). Althogh it may be awkward to delimit variable names by `|', the comma syntax should be easier to read than the other exotic syntax for seasoned Scheme programmers.

    Note that Scheme allows wider range of characters for valid identifier names than usual scripting languages. Consequently, you will almost always need to use `|' delimiters when you interpolate the value of a variable. For example, while you can write "$year/$month/$day $hour:$minutes:$seconds" in Perl, you should write #`",|year|/,|month|/,day ,|hour|:,|minutes|:,seconds". It may be better always to delimit direct variable references in this syntax to avoid confusion.

    6.10.5 String Accessors & Modifiers

    Function: string-length string
    [R5RS] Returns a length of (possibly incomplete) string string.

    Function: string-size string
    Returns a size of (possibly incomplete) string. A size of string is a number of bytes string occupies on memory. The same string may have different sizes if the native encoding scheme differs.

    For incomplete string, its length and its size always match.

    Function: string-ref cstring k &optional fallback
    [R5RS+] Returns k-th character of a complete string cstring. It is an error to pass an incomplete string.

    By default, an error is signalled if k is out of range (negative, or greater than or equal to the length of cstring). However, if an optional argument fallback is given, it is returned in such case. This is Gauche's extension.

    Function: string-byte-ref string k
    Returns k-th byte of a (possibly incomplete) string string. Returned value is an integer in the range between 0 and 255. k must be greater than or equal to zero, and less than (string-size string).

    Function: string-set! string k char
    [R5RS] Substitute string's k-th character by char. k must be greater than or equal to zero, and less than (string-length string). Return value is undefined.

    If string is an incomplete string, integer value of the lower 8 bits of char is used to set string's k-th byte.

    See the notes in make-string about performance consideration.

    Function: string-byte-set! string k byte
    Substitute string's k-th byte by integer byte. byte must be in the range between 0 to 255, inclusive. k must be greater than or equal to zero, and less than (string-size string). If string is a complete string, it is turned to incomplete string by this operation. Return value is undefined.

    6.10.6 String Comparison

    Function: string=? string1 string2
    Function: string-ci=? string1 string2
    [R5RS]

    Function: string<? string1 string2
    Function: string<=? string1 string2
    Function: string>? string1 string2
    Function: string>=? string1 string2
    Function: string-ci<? string1 string2
    Function: string-ci<=? string1 string2
    Function: string-ci>? string1 string2
    Function: string-ci>=? string1 string2
    [R5RS]

    6.10.7 String utilities

    Function: substring string start end
    [R5RS]

    Function: string-append string ...
    [R5RS]

    Function: string->list string &optional start end
    Function: list->string list
    [R5RS+][SRFI-13]

    Function: string-copy string &optional start end
    [R5RS+][SRFI-13]

    Function: string-fill! string char &optional start end
    [R5RS+][SRFI-13] Fills string by char. Optional start and end limits the effective area.
    (string-fill! "orange" #\X)
      => "XXXXXX"
    (string-fill! "orange" #\X 2 4)
      => "orXXge"
    

    Function: string-join strs &optional delim grammer
    [SRFI-13] Concatenate strings in the list strs, with a string delim as `glue'.

    The argument grammer may be one of the following symbol to specify how the strings are concatenated.

    infix
    Use delim between each string. This mode is default. Note that this mode introduce ambiguity when strs is an empty string or a list with a null string.
    (string-join '("apple" "mango" "banana") ", ") 
      => "apple, mango, banana"
    (string-join '() ":")
      => ""
    (string-join '("") ":")
      => ""
    
    strict-infix
    Works like infix, but empty list is not allowed to strs, thus avoiding ambiguity.
    prefix
    Use delim before each string.
    (string-join '("usr" "local" "bin") "/" 'prefix)
      => "/usr/local/bin"
    (string-join '() "/" 'prefix)
      => ""
    (string-join '("") "/" 'prefix)
      => "/"
    
    suffix
    Use delim after each string.
    (string-join '("a" "b" "c") "&" 'suffix)
      => "a&b&c&"
    (string-join '() "&" 'suffix)
      => ""
    (string-join '("") "&" 'suffix)
      => "&"
    

    Function: string-scan string item &optional return
    Scan item (either a string or a character) in string. The return argument specifies what value should be returned when item is found in string. It must be one of the following symbols.
    index
    Returns the index in string if item is found, or #f. This is the default behavior.
    (string-scan "abracadabra" "ada") => 5
    (string-scan "abracadabra" #\c) => 4
    (string-scan "abracadabra" "aba") => #f
    
    before
    Returns a substring of string before item, or #f if item is not found.
    (string-scan "abracadabra" "ada" 'before) => "abrac"
    (string-scan "abracadabra" #\c 'before) => "abra"
    
    after
    Returns a substring of string after item, or #f if item is not found.
    (string-scan "abracadabra" "ada" 'after) => "bra"
    (string-scan "abracadabra" #\c 'after) => "adabra"
    
    before*
    Returns a substring of string before item, and the substring after it. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'before*)
      => "abrac" and "adabra"
    (string-scan "abracadabra" #\c 'before*)
      => "abra" and "cadabra"
    
    after*
    Returns a substring of string up to the end of item, and the rest. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'after*)
      => "abracada" and "bra"
    (string-scan "abracadabra" #\c 'after*)
      => "abrac" and "adabra"
    
    both
    Returns a substring of string before item and after item. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'both)
      => "abrac" and "bra"
    (string-scan "abracadabra" #\c 'both)
      => "abra" and "adabra"
    

    Function: string-split s char

    6.10.8 String Pointers

    Builtin Class: <string-pointer>
    String pointer is an object to access string efficiently in sequential order (either forward or backward).

    Higher level string iterators and accessors are constructed on top of this primitive. See section 10.7 srfi-13 - String library, for details. It is highly recommended to use SRFI-13 functions instead of these string pointer objects, for portability.

    Function: make-string-pointer str &optional (index 0)
    Creates a string pointer that points to the index-th character of string str.

    Function: string-pointer-copy sp
    Copies a string pointer. The resulting string pointer shares the same string as sp, but has distinct pointer.

    Function: string-pointer? obj
    Returns #t iff obj is a string pointer.

    Function: string-pointer-next! sp
    Function: string-pointer-prev! sp

    Function: string-pointer-set! sp index

    Function: string-pointer-substring sp &keyword (after #f)

    Function: string-pointer-index sp
    Function: string-pointer-byte-index sp

    6.10.9 Incomplete strings

    Function: string-complete->incomplete str

    Function: string-incomplete->complete str

    6.11 Regular expression

    Builtin Class: <regexp>
    Regular expression object. You can construct a regexp object from a string by string->regexp at run time. Gauche also has a special syntax to denote regexp literals, which construct regexp object at loading time.

    Gauche's regexp engine is fully aware of multibyte characters.

    Builtin Class: <regmatch>
    Regexp match object. A regexp matcher rxmatch returns this object if match. This object contains all the information about the match, including submatches.

    The advantage of using match object, rather than substrings or list of indices is efficiency. The regmatch object keeps internal state of match, and computes indices and/or substrings only when requested. This is particularly effective for mutibyte strings, for index access is slow on them.

    Reader Syntax: #/regexp-spec/
    Reader Syntax: #/regexp-spec/i
    Denotes literal regular expression object. When read, it becomes an instance of <regexp>.

    If a letter 'i' is given at the end, the created regexp becomes case-folding regexp, i.e. it matches in the case-insensitive way. (The current version only cares ASCII characters for case-folding--- beyond ASCII characters, the match is done in the same way as normal match.)

    The advantage of using this syntax over string->regexp is that the regexp is compiled only once. You can use literal regexp inside loop without worring about regexp compilation overhead. If you want to construct regexp on-the-fly, however, use string->regexp.

    The recognized syntax is a subset of POSIX extended regular expression, with a bit of extension taken from Perl. Specifically, Gauche supports:

    • Repetition by *, + and ?.
    • Grouping by (). No backslash escape is needed.
    • Alternative by |.
    • Character class by []. The syntax recognized by character set literals (See section 6.9 Character Set) are valid.
    • Beginning of the string ^ and end of the string $ assertions.
    • Several special character class abbreviations; \d for digits, \D for non-digits, \w for alfphanumeric characters, \W for non-alphanumeric characters, \s for whitespace characters, and \S for non-whitespace characters. These can be used both inside and outside of [].

    And Gauche does not supports:

    • Collating elements, e.g. [=e=] and [.ll.].
    • Beginning/end of word assertions.
    • Fixed-number repetition, {m,n}.
    • Back reference of submatches.

    Among those unsupported features, the first three will eventually be supported. It is unlikely to support back reference, however. If you use back reference, you're not dealing with regular grammer any more. And if you're dealing with higher class of grammer, there should be appropriate tools rather than regular expressions.

    Function: string->regexp string &keyword case-fold
    Takes string as a regexp specification, and constructs an instance of <regexp> object.

    If a true value is given to the keyword argument case-fold, the created regexp object becomes case-folding regexp. (See the above explanation about case-folding regexp).

    Function: regexp? obj
    Returns true iff obj is a regexp object.

    Function: regexp->string regexp
    Returns a source string describing the regexp regexp. The returned string is immutable.

    Function: rxmatch regexp string
    Regexp is a regular expression object. A string string is matched by regexp. If it matches, the function returns a <regmatch> object. Otherwise it returns #f.

    This is called match, regexp-search or string-match in some other Scheme implementations.

    Generic application: regexp string
    A regular expression object can be applied directly to the string. This works the same as (rxmatch regexp string), but allows shorter notation. See section 6.15.2 Applicable objects, for generic mechanism used to implement this.

    Function: rxmatch-start match &optional (i 0)
    Function: rxmatch-end match &optional (i 0)
    Function: rxmatch-substring match &optional (i 0)
    Match is a match object returned by rxmatch. If i equals to zero, the functions return start, end or the substring of entire match, respectively. With positive integer I, it returns those of I-th submatches. It is an error to pass other values to I.

    It is allowed to pass #f to match for convenience. The functions return #f in such case.

    These functions correspond to scsh's match:start, match:end and match:substring.

    Function: rxmatch-after match &optional (i 0)
    Function: rxmatch-before match &optional (i 0)
    Returns substring of the input string after or before match. If optional argument is given, the i-th submatch is used (0-th submatch is the entire match).
    (define match (rxmatch #/(\d+)\.(\d+)/ "pi=3.14..."))
    
    (rxmatch-after match) => "..."
    (rxmatch-after match 1) => ".14..."
    
    (rxmatch-before match) => "pi="
    (rxmatch-before match 2) => "pi=3."
    

    Generic application: regmatch &optional index
    Generic application: regmatch 'before &optional index
    Generic application: regmatch 'after &optional index
    A regmatch object can be applied directly to the integer index, or a symbol before or after. They works the same as (rxmatch-substring regmatch index), (rxmatch-before regmatch), and (rxmatch-after regmatch), respectively. This allows shorter notation. See section 6.15.2 Applicable objects, for generic mechanism used to implement this.
    (define match (#/(\d+)\.(\d+)/ "pi=3.14..."))
    
    (match)           => "3.14"
    (match 1)         => "3"
    (match 2)         => "14"
    
    (match 'after)    => "..."
    (match 'after 1)  => ".14..."
    
    (match 'before)   => "pi="
    (match 'before 2) => "pi=3."
    

    Seel also section 9.15 gauche.regexp - Regular expression utilities, which defines useful macros and functions to deal with regular expression matching.

    6.12 Vectors

    Builtin Class: <vector>
    A vector is a simple 1-dimensional array of Scheme objects. You can access its element by index in constant time. Once created, a vector can't be resized.

    Class <vector> inherits <sequence> and you can use various generic functions such as map and fold on it. See section 9.3 gauche.collection - Collection framework, and See section 9.18 gauche.sequence - Sequence framework.

    If you keep only a homogeneous numeric type, you may be able to use SRFI-4 homogenous vectors (See section 10.4 srfi-4 - Homogeneous vectors).

    Function: vector? obj
    [R5RS] Returns #t if obj is a vector, #f otherwise.

    Function: make-vector k &optional fill
    [R5RS] Creates and returns a vector with length k. If optional argument fill is given, each element of the vector is initialized by it. Otherwise, the initial value of each element is undefined.

    Function: vector obj ...
    [R5RS] Creates a vector whose elements are obj ....

    Function: vector-length vector
    [R5RS] Returns the length of a vector vector.

    With gauche.collection module, you can also use a method size-of.

    Function: vector-ref vector k &optional fallback
    [R5RS+] Returns k-th element of vector vector.

    By default, vector-ref signals an error if k is negative, or greater than or equal to the length of vector. However, if an optional argument fallback is given, it is returned for such case. This is an extension of Gauche.

    With gauche.sequence module, you can also use a method ref.

    Function: vector-set! vector k obj
    [R5RS] Sets k-th element of the vector vector to obj. It is an error if k is negative or greater than or equal to the length of vector.

    With gauche.sequence module, you can also use a setter method of ref.

    Function: vector->list vector &optional start end
    Function: list->vector list
    [R5RS+] Converts a vector to a list, or vice versa.

    The optional start and end argument of vector->list limits the range of the vector to be retrieved.

    (vector->list '#(1 2 3 4 5))     => (1 2 3 4 5)
    (list->vector '(1 2 3 4 5))      => #(1 2 3 4 5)
    (vector->list '#(1 2 3 4 5) 2 4) => (3 4)
    

    With gauche.collection module, you can use (coerce-to <list> vector) and (coerce-to <vector> list) as well.

    Function: vector-fill! vector fill &optional start end
    [R5RS+] Sets all elements in a vector vector to fill.

    Optional start and end limits the range of effect between start-th index (inclusive) to end-th index (exclusive). Start defaults to zero, and end defaults to the length of vector. These optional arguments are Gauche's extension.

    Function: vector-copy vector &optional start end
    Copies a vector vector. Optional start and end arguments can be used to limit the range of vector to be copied.
    (vector-copy '#(1 2 3 4 5))     => #(1 2 3 4 5)
    (vector-copy '#(1 2 3 4 5) 2 4) => #(3 4)
    

    6.13 Hashtables

    Builtin Class: <hash-table>
    Hash table class.

    Function: make-hash-table &optional type
    Creates a hash table. A symbol type specifies the type of the table. The following types are currently supported.
    eq?
    Keys are compared by eq?
    eqv?
    Keys are compared by eqv?
    equal?
    Keys are compared by equal?
    string=?
    Keys are compared by string=?. Key must be a string.

    If type is omitted, eq? is assumed.

    Function: hash-table? obj
    Returns #t if obj is a hash table.

    Function: hash-table-get hash key &optional default
    Search key from a hash table hash, and returns its value if found. If the key is not found in the table and default is given, it is returned. Otherwise an error is signalled.

    Function: hash-table-put! hash key value
    Puts a key key with a value value to the hash table hash.

    Function: hash-table-exists? hash key
    Returns #t if a hash table hash has a key key.

    Function: hash-table-delete! hash key
    Deletes an entry that has a key key from the hash table hash. Returns #t if the entry has exist, or #f if the entry hasn't exist. The same function is called hash-table-remove! in STk (except that it returns an undefined value); I use `delete' for consistency to SRFI-1, SRFI-13 and other parts of the libraries.

    Function: hash-table-push! hash key value
    Conses value to the existing value for the key key in the hash table hash and makes it the new value for key. If there's no entry for key, an entry is created with the value (list value).

    Works the same as the following code, except that this function only looks up the key once, thus it's more efficient.

    (hash-table-put! hash key
        (cons value (hash-table-get hash key '())))
    

    Function: hash-table-pop! hash key &optional default
    Looks for the value for the key key in the hash table hash. If found and it is a pair, replaces the value for its cdr and returns car of the original value. If no entry for key is in the table, or the value is not a pair, the table is not modified and the procedure returns default if given, or signals an error otherwise.

    During the operation the key is looked for only once, thus runs efficiently.

    Function: hash-table-for-each hash proc
    Function: hash-table-map hash proc
    A procedure proc is called with two arguments, a key and associated value, over all the entries in the hash table hash.

    Function: hash-table-keys hash
    Function: hash-table-values hash
    Returns all the keys or values of hash table hash in a list, respectively.

    6.14 Weak pointers

    A weak pointer is a reference to an object that doesn't prevent the object from being garbage-collected. Gauche provides weak pointers as a weak vector object. A weak vector is like a vector of objects, except each object can be garbage collected if it is not referenced from objects other than weak vectors. If the object is collected, the entry of the weak vector is replaced for #f.

    gosh> (define v (make-weak-vector 1))
    v
    gosh> (weak-vector-ref v 0)
    #f
    gosh> (weak-vector-set! v 0 (cons 1 1))
    #<undef>
    gosh> (weak-vector-ref v 0)
    (1 . 1)
    gosh> (gc)
    #<undef>
    gosh> (gc)
    #<undef>
    gosh> (weak-vector-ref v 0)
    #f
    

    Builtin Class: <weak-vector>
    The weak vector class. Inherits <sequence> and <collection>, so you can use gauche.collection (See section 9.3 gauche.collection - Collection framework) and gauche.sequence (See section 9.18 gauche.sequence - Sequence framework).
    (coerce-to <weak-vector> '(1 2 3 4))
      => a weak vector with four elements
    

    Function: make-weak-vector size
    Creates and returns a weak vector of size size.

    Function: weak-vector-length wvec
    Returns the length of a weak vector wvec.

    Function: weak-vector-ref wvec k &optioal fallback
    Returns k-th element of a weak vector wvec.

    By default, weak-vector-ref signals an error if k is negative, or greater than or equal to the size of wvec. However, if an optional argument fallback is given, it is returned for such case.

    With gauche.sequence module, you can also use a method ref.

    Function: weak-vector-set! wvec k obj
    Sets k-th element of the weak vector wvec to obj. It is an error if k is negative or greater than or equal to the size of wec.

    6.15 Control features

    6.15.1 Procedures

    Builtin Class: <procedure>

    Function: procedure? obj
    [R5RS] Returns #t if obj is a procedure, #f otherwise.

    Function: apply proc arg1 ... args
    [R5RS] Calls a procedure proc with a list of arguments, (arg1 ... . args). The last argument args must be a proper list. Returns (a) value(s) proc returns.
    (apply list 'a 'b '(c d e)) => (a b c d e)
    
    (apply + 1 2 '(3 4 5))      => 15
    

    6.15.1.1 Mapping

    Function: map proc list1 list2 ...
    [R5RS+] Applies proc for each element(s) of given list(s), and returns a list of the results. R5RS doesn't specify the application order of map, but Gauche guarantees proc is always applied in order of the list(s). Gauche's map also terminates as soon as one of the list is exhausted.
    (map car '((a b) (c d) (e f))) => (a c e)
    
    (map cons '(a b c) '(d e f))
      => ((a . d) (b . e) (c . f))
    

    Note that the gauche.collection module (See section 9.3 gauche.collection - Collection framework) extends map to work on any type of collection.

    Function: for-each proc list1 list2 ...
    [R5RS] Applies proc for each element(s) of given list(s) in order. The results of proc are discarded. The return value of for-each is undefined. When more than one list is given, for-each terminates as soon as one of the list is exhausted.

    Note that the gauche.collection module (See section 9.3 gauche.collection - Collection framework) extends for-each to work on any type of collection.

    6.15.1.2 Combinators

    Gauche has some primitive procedures that allows combinatory programming.

    Function: pa$ proc arg ...
    Partial application. Returns a procedure, and when it is called with arguments m ..., it is equivalent to call (proc arg ... m ...).
    (define add3 (pa$ + 3))
    (add3 4) => 7
    
    (map (pa$ * 2) '(1 2 3)) => (2 4 6)
    

    Macros cut and cute defined in SRFI-26 provide a similar abstraction, with a bit more flexible but less compact notation. See section 4.3 Making Procedures.

    Function: apply$ proc
    Function: map$ proc
    Function: for-each$ proc
    Partial application version of apply, map and for-each.
    (define map2* (map$ (pa$ * 2)))
    (map2* '(1 2 3)) => (2 4 6)
    

    There are more 'partial-applied' version of procedures defined in SRFI-1 (See section 10.2 srfi-1 - List library), such as fold$, filter$, member$, etc.

    Function: compose f g h ...
    Combine two or more procedures. Arguments must be procedures. When two procedures are given, (compose f g) is equivalent to
    (lambda args (call-with-values (lambda () (apply g args)) f))
    

    Some examples:

    (define not-zero? (compose not zero?))
    (not-zero? 3) => #t
    (not-zero? 0) => #f
    
    (define dot-product (compose (apply$ +) (map$ *)))
    (dot-product '(1 2 3) '(4 5 6)) => 32
    

    Function: any-pred pred ...
    Returns a procedure which applies given argument(s) to each predicate pred. If any pred returns a non-#f value, the value is returned. If all the preds return #f, #f is returned.
    (define string-or-symbol? (any-pred string? symbol?))
    (string-or-symbol? "abc") => #t
    (string-or-symbol? 'abc)  => #t
    (string-or-symbol? 3)     => #f
    
    (define <> (any-pred < >))
    (<> 3 4) => #t
    (<> 3 3) => #f
    
    ((any-pred (cut memq <> '(a b c))
               (cut memq <> '(1 2 3)))
     'b)  => '(b c)
    

    Function: every-pred pred ...
    Returns a procedure which applies given argument(s) to each predicate pred. If every pred returns a non-#f value, the value returned by the last pred is returned. If any pred returns #f, every-pred returns #f without calling further preds.
    ((every-pred odd? positive?) 3)  => #t
    ((every-pred odd? positive?) 4)  => #f
    ((every-pred odd? positive?) -3) => #f
    
    (define safe-length (every-pred list? length))
    (safe-length '(a b c))  => 3
    (safe-length "aaa")     => #f
    

    6.15.1.3 Optional argument parsing

    To have optional arguments or keyword arguments in Scheme, you have to take variable arguments as a list and decompose them by yourself. The following macros help it.

    Macro: let-optionals* restargs (var-spec ...) body ...
    Macro: let-optionals* restargs (var-spec ... . restvar) body ...
    Given a list of values restargs, binds variables accodring to var-spec, then evaluates body.

    Var-spec can be either a symbol, or a list of two elements and its car is a symbol. The symbol is the bound variable name. The values in restargs are bound to the symbol in order. If there are not as many values in restargs as var-spec, the rest of symbols are bound to the default values, determined as follows: If var-spec is just a symbol, the default value is undefined. If var-spec is a list, the default value is the result of evaluation of the second element of the list. In the latter case the second element is only evaluated when there are not enough arguments. The binding proceeds in the order of var-spec, so the second element may refer to the bindings of previous var-spec.

    In the second form, restvar must be a symbol and bound to the list of values whatever left from restargs after binding to var-spec.

    It is not an error if restarg has more values than var-specs. The extra values are simply ignored in the first form.

    (define (proc x . args)
      (let-optionals* args ((a 'a)
                            (b 'b)
                            (c 'c))
        (list x a b c)))
    
    (proc 0)         => (0 a b c)
    (proc 0 1)       => (0 1 b c)
    (proc 0 1 2)     => (0 1 2 c)
    (proc 0 1 2 3)   => (0 1 2 3)
    
    (define (proc2 . args)
      (let-optionals* args ((a 'a) . b)
        (list a b)))
    
    (proc2)          => (a ())
    (proc2 0)        => (0 ())
    (proc2 0 1)      => (0 (1))
    (proc2 0 1 2)    => (0 (1 2))
    
    (define (proc3 . args)
      (let-optionals* args ((a 0)
                            (b (+ a 1))
                            (c (+ b 1)))
        (list a b c)))
    
    (proc3)          => (0 1 2)
    (proc3 8)        => (8 9 10)
    (proc3 8 2)      => (8 2 3)
    (proc3 8 2 -1)   => (8 2 -1)
    

    Macro: get-optional restargs default
    This is a short version of let-optionals* where you have only one optional argument. Given the optional argument list restargs, this macro returns the value of optional argument if one is given, or the result of default otherwise. Default is not evaluated unless restargs is an empty list.
    (define (proc x . maybe-opt)
      (let ((option (get-optional maybe-opt #f)))
        (list x option)))
    
    (proc 0)         => (0 #f)
    (proc 0 1)       => (0 1)
    

    Macro: let-keywords* restarg (var-spec ...) body ...
    This macro is for keyword arguments. Var-spec can be one of the following forms:
    (symbol expr)
    If the restrag contains keyword which has the same name as symbol, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.
    (symbol keyword expr)
    If the restrag contains keyword keyword, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.

    The default value expr is only evaluated when the keyword is not given to the restarg. The binding is done in the order of var-spec, so the expr can refer to the variables bound by preceding var-spec.

    If a keyword that doesn't listed in var-spec appears in restarg, it is simply ignored.

    (define (proc x . options)
      (let-keywords* options ((a 'a)
                              (b :beta 'b)
                              (c 'c))
        (list x a b c)))
    
    (proc 0)         => (0 a b c)
    (proc 0 :a 1)    => (0 1 b c)
    (proc 0 :beta 1) => (0 a 1 c)
    (proc 0 :beta 1 :c 3) => (0 a 1 3)
    

    6.15.1.4 Procedure arity

    Interface to query procedure's arity. The API is taken from MzScheme (PLT Scheme).

    Function: arity proc
    Given procedure proc, returns an integer, an arity-at-least object, or a list of integer(s) and arity-at-least objects.

    An integer result indicates proc takes exactly that number of arguments. An arity-at-least indicats proc takes at least (arity-at-least-value arity-at-least) arguments. The list indicates there are multiple procedures with different arities.

    Since one can add methods to an existing procedure or generic function at any moment in Gauche, the value returned by arity only indicates the current state of the procedure. It will change if new method is added to the procedure/generic-function.

    (arity cons) => 2
    (arity list) => #<arity-at-least 0>
    (arity make) => (#<arity-at-least 1>)
    

    Function: arity-at-least? obj
    Returns true if obj is an arity-at-least object.

    Function: arity-at-least-value arity-at-least
    Returns the number of required arguments the arity-at-least object indicates.

    Function: procedure-arity-includes? proc k
    If a procedure proc can take k arguments, returns #t. Otherwise returns #f.

    6.15.2 Applicable objects

    Gauche has a special hook to make an arbitrary object applicable.

    Generic Function: object-apply object arg ...
    If an object that is neither a procedure nor a generic function is applied to some arguments, the object and the arguments are passed to a generic function object-apply.

    This can be explained better by examples.

    For example, suppose you try to evaluate the following expression:

    ("abcde" 2)
    

    The operator evaluates to a string, which is neither a procedure nor a generic fuction. So Gauche interpretes the expression as if it were like this:

    (object-apply "abcde" 2)
    

    Gauche doesn't define a method of object-apply that takes <string> and <integer> by default, so this signals an error. However, if you define such a method:

    (define-method object-apply ((s <string>) (i <integer>))
      (string-ref s i))
    

    Then the first expression works as if a string is applied on the integer:

    ("abcde" 2) => #\c
    

    This mechanism works on almost all occasions where a procedure is allowed.

    (apply "abcde" '(1))   => (#\b)
    (map "abcde" '(3 2 1)) => (#\d #\c #\b)
    

    Among Gauche built-in objects, <regexp> object and <regmatch> object have object-apply defined. See section 6.11 Regular expression.

    Generic Function: (setter object-apply) object arg ... value
    If a form of applying an applicable object appears in the first position of set! form, this method is called, that is:
    (set! (object arg ...) value)
     => ((setter object-apply) object arg ... value)
    

    6.15.3 Continuation

    Function: call-with-current-continuation proc
    Function: call/cc proc
    [R5RS] Encapsulates the current continuation to a procedure ("continuation procedure"), and calls proc with it. When proc returns, its value becomes call/cc's value. When the continuation procedure is invoked with zero or more arguments somewhere, the further calculation is abandoned and call/cc returns with the arguments given to the continuation procedure.

    First class continuation is one of the most distinct feature of Scheme, but this margin is too small to contain explanation. Please consult to the appropriate documents.

    Gauche supports full continuation, with a few limitations in rare cases. Normally a continuation has an unlimited extent. However, if a continuation is created during "callback" from C code--- that is, you call some C-implemented function that calls Scheme code again--the continuation's extent is limited until the Scheme evaluation returns to the C code. If you try to invoke the continuation from out of its extent, Gauche detects it and signals an error. This is a fundamental limitation and not likely to be addressed.

    Note that it is still allowed to invoke a continuation from such callbacks. Also, the typical higher-order functions such as map, for-each or apply are not using callbacks, and not affected by this limitation

    Fortunately, there are not much cases that you need to create an unlimited extent continuation in such callbacks. So far, the following code is executed in such callbacks. Besides them, typical callback functions from external C libraries, like GUI toolkit, obeys the same limitation.

    (define *oob-cont* #f)
    
    (call/cc (lambda (valid-cont)
               (sort '(1 2 3 4 5 6)
                     (lambda (a b)
                       (call/cc (lambda (oob-cont)
                                  (set! *oob-cont* oob-cont)))
                       (valid-cont 'ok)))))
     => ok  ;callback can call a continuation
    
    (*oob-cont* 'not-ok)
     => ;error -- *oob-cont* is out of its extent.
    

    Function: dynamic-wind before thunk after
    [R5RS] Before, thunk and after are all procedures with no arguments. In normal situation, dynamic-wind calls before, then thunk, then after, then returns whatever value(s) thunk returned.

    If a control flow goes out from thunk by invoking a continuation captured outside of the dynamic scope of dynamic-wind (for example, an error is signalled in thunk), after is called.

    If a control flow goes into thunk by invoking a continuation captured inside thunk from outside of the dynamic scope of dynamic-wind, before is called.

    (letrec ((paths '())
             (c #f)
             (add (lambda (s) (push! paths s))))
      (dynamic-wind
       (lambda () (add 'connect))
       (lambda ()
         (add (call/cc (lambda (c0) (set! c c0) 'talk1))))
       (lambda () (add 'disconnect)))
      (if (< (length paths) 4)
          (c 'talk2)
          (reverse paths)))
     => (connect talk1 disconnect connect talk2 disconnect)
    

    6.15.4 Multiple values

    Function: values obj ...
    [R5RS] Returns obj ... as multiple values. Caller can capture multiple values by a built-in syntax receive (section 4.6 Binding constructs), or the R5Rs procedure call-with-values described below. See also section 10.6 srfi-11 - Let-values.
    (values 1 2) => 1 and 2
    

    Function: call-with-values producer consumer
    [R5RS] Call a procedure producer with no argument. Then applies a procedure consumer on the value(s) producer returned. Returns the value(s) consumer returns.
    (call-with-values (lambda () (values 1 2)) cons)
      => (1 . 2)
    

    6.15.5 Delayed Evaludation

    Special Form: delay expression
    [R5RS]

    Function: force promise
    [R5RS]

    6.16 Exceptions

    In Gauche, error singnaling mechanism is implemented in multiple layers. The lower layer provides very simple mechanism with which the user can implement various semantics. The higher layer provides a way to handle common patterns like error handling in a simple way.

    6.16.1 Signalling errors

    Function: error string arg ...
    [SRFI-23] Signals an error. Internally the action is realized by those two steps.
    1. An error exception is created, with the message prefixed by string and followed by args.
    2. The error exception is thrown, which may be handled by the current active error handler, if any.

    If no error handler is active, the default error handler is used, which prints the error message to the current error port and some debug information. Then, if Gauche is running interactively, the control moves to the toplevel; if Gauche is running as a script, it exits with the exit status EX_SOFTWARE (70).

    Function: errorf fmt-string arg ...
    Similar to an error, but the error message is formatted by format, i.e. it is equivalent to:
    (define (errorf fmt . args)
      (error (apply format #f fmt args)))
    

    6.16.2 Handling errors

    Function: with-error-handler handler thunk
    Makes handler the active error handler and executes thunk. If thunk returns normally, the result(s) will be returned. If an error is signalled during execution of thunk, handler is called with one argument, an exception object representing the error, with the continuation of with-error-handler. That is, with-error-handler returns whatever value(s) handler returns.

    If handler signals an error, it will be handled by the handler installed when with-error-handler called.

    The dynamic environment where handler is executed is the same as the error occurs. If dynamic-wind is used in thunk, its after method is called after handler has returned, and before with-error-handler returns.

    The behavior of with-error-handler can be described in the form of Scheme code shown below, using the low-level mechanism (See section 6.16.4 Low-level exception mechanism). Note that the actual function is built in VM, using lighter mechanisms (similar to "one-shot continuation", @xref{onecont, [1CC], 1CC}).

    ;; conceptual implementation of with-error-handler
    (define (with-error-handler handler thunk)
      (call/cc
        (lambda (cont)
          (let* ((prev-handler (current-exception-handler))
            (with-exception-handler
              (lambda (exn)
                (if (error? exn)
                    (with-exception-handler
                      (lambda (err) (prev-handler err))
                      (lambda () (call-with-values (handler exn) cont)))
                    (prev-handler exn)))
              thunk))))))
    

    6.16.3 Exception object

    Class: <exception>
    Represents An exception. The complete exception class hierarchy is under construction. Right now, only the following information is available.

    Instance Variable: <exception> message
    For an error exception, this is the error message.

    6.16.4 Low-level exception mechanism

    This layer provides SRFI-18 compatible simple exception mechanism. You can override the behavior of higher-level constructs such as with-error-handler by using with-exception-handler.

    Note that it is a double-edged sword. You'll get a freedom to construct your own exception handling semantics, but the Gauche system won't save if something goes wrong. Use these primitives when you want to customize the system's higher-level semantics or you are porting from other SRFI-18 code.

    Function: current-exception-handler
    [SRFI-18] Returns the current exception handler.

    Function: raise exception
    [SRFI-18] Invokes the current exception handler with one argument, exception. exception can be any Scheme object; it doesn't need to be an instance of <exception> class. Combined with with-exception-handler you can give your own semantics to the exception. raise returns whatever the handler returns.

    Function: with-exception-handler handler thunk
    [SRFI-18] A procedure handler must take one argument. This procedure sets handler to the current exception handler and calls thunk.

    Generally, if you want to handle non-continuable exception such as errors using this low-level mechanism, you have to transfer the control from the handler explicitly (See the explanation of with-error-handler above). raise detects if the handler returns on the non-continuable exceptions and reports an error using the default error handler mechanism, but it is just a safety net.

    Note also that handler is called in the same dynamic environment of raise. So if you raise an exception inside handler, it is captured by handler again. It is the programmer's responsibility to propagate the exception handling to the "outer" exception handlers.

    The behavior of those procedures can be explained in the following conceptual Scheme code.

    ;; Conceptual implementation of low-level exception mechanism.
    ;; Suppose %xh is a list of exception handlers
    
    (define (current-exception-handler) (car %xh))
    
    (define (raise exn)
      (receive r ((car %xh) exn)
        (when (uncontinuable-exception? exn)
          (set! %xh (cdr %xh))
          (raise (make-error "returned from uncontinuable exception")))
        (apply values r)))
    
    (define (with-exception-handler handler thunk)
      (let ((prev %xh))
        (dynamic-wind
          (lambda () (set! %xh (cons handler)))
          thunk
          (lambda () (set! %xh prev)))))
    

    6.17 Eval and repl

    Function: eval expr env
    [R5RS] Evaluate expr. env must be a value returned by the following procedures below. Right now it is just a <module> object, but it is possible that the Gauche adopts a first-class environment object in future.

    Function: null-environment version
    Function: scheme-report-environment version
    Function: interaction-environment
    [R5RS] Returns an environment specifier which can be used as the second argument of eval. Right now an environment specifier is just a module. (null-environment 5) returns a null module, which contains just the syntactic bindings specified in R5RS, (scheme-report-environment 5) returns a scheme module, which contains syntactic and procedure bindings in R5RS, and (interaction-environment) returns a user module that contains all the Gauche built-ins plus whatever the user defined. It is possible that the Gauche adopts a first-class environment object in future, so do not rely on the fact that the environment specifier is just a module.

    An error is signaled if a value other than 5 is passed as version argument.

    There's one difference from R5RS in null-environment and scheme-report-environment; they contain with-module special form. It is necessary to define R5RS procedure using Gauche built-ins for now. It'll be removed as soon as I find a better way.

    Function: read-eval-print-loop &optional reader evaluator printer prompter
    This exports Gosh's default read-eval-print loop to applications. Each argument can be #f, which indicates it to use Gauche's default procedure(s), or a procedure that satisfies the following conditions.
    reader
    A procedure that takes no arguments. It is supposed to read an expression and returns it.
    evaluator
    A procedure that takes two arguments, an expression and an environment specifier. It is supposed to evaluate the expression and returns zero or more value(s).
    printer
    A procedure that takes zero or more arguments. It is supposed to print out these values. The result of this procedure is discarded.
    prompter
    A procedure that takes no arguments. It is supposed to print out the prompt. The result of this procedure is discarded.

    Given those procedures, read-eval-print-loop runs as follows:

    1. Prints the prompt by calling prompter.
    2. Reads an expression by calling reader. If it returns EOF, exits the loop and returns from read-eval-print-loop.
    3. Evaluates an expression by calling evaluator
    4. Prints the result by calling printer, then repeats from 1.

    When an error is signaled from one of those procedures, it is captured and reported by the default escape handler, then the loop restarts from 1.

    It is OK to capture a continuation within those procedures and re-invoke them afterwards.

    6.18 Input and Output

    6.18.1 Ports

    Builtin Class: <port>
    A port class. A port is Scheme's way of abstraction of I/O channel. Gauche extends a port in number of ways so that it can be used in wide range of applications.

    Standard Scheme (R5RS) essentially defines a port as an entity that you can fetch a character at a time and look one character ahead from an input port, and put a character at a time to an output port. Other R5RS I/O routines can be built on top of them.

    Besides this basics, Gauche's port can handle the following opertaions.

    Byte I/O
    You can read/write one byte at a time, instead of a character. (Remember, Gauche handles multibyte characters, so a character may be consisted from more than one bytes). Most ports allow you to mix byte I/O and character I/O, if needed.
    Block I/O
    You can read/write a specified number of byte sequences. This can be an efficient way of moving block of data, if the port's underlying implementation supports block I/O operation (for example, if the underyling port is a unix buffered stream, this operation uses fread or fwrite).
    Conversion
    Some ports can be used to convert a data stream from one format to another; one of such applications is character code conversion ports, provided by gauche.charconv module (See section 9.2 gauche.charconv - Character Code Conversion, for details). You can define a procedural ports, in both Scheme and C, to implement other functionality.

    6.18.2 Common port operations

    Function: port? obj
    Function: input-port? obj
    Function: output-port? obj
    [R5RS] Returns true if obj is a port, an input port and an output port, respectively. Port? is not listed in the R5RS standard procedures, but mentioned in the "Disjointness of Types" section.

    Function: port-closed? port
    Returns true if obj is a port and it is already closed. A closed port can't be reopened.

    Function: current-input-port
    Function: current-output-port
    [R5RS] Returns the current input port and the current output port, respectively.

    Function: current-error-port
    Returns the current output port.

    Function: standard-input-port
    Function: standard-output-port
    Function: standard-error-port
    Returns ports that are bound initially to current input, output and error port, respectively.

    Function: with-input-from-port port thunk
    Function: with-output-to-port port thunk
    Function: with-error-to-port port thunk
    Calls thunk. During evaluation of thunk, the current input port, current output port and current error port are set to port, respectively.

    Function: close-input-port port
    Function: close-output-port port
    [R5RS] Closes input and output port, respectively

    Function: port-type port
    Returns the type of port in one of the symbols file, string or proc.

    Function: port-name port
    Returns the name of port. If the port is associated to a file, it is the name of the file. Otherwise, it is some description of the port.

    Function: port-buffering port
    Function: (setter port-buffering) port buffering-mode
    If port is type of file port (i.e. (port-type port) returns file), these procedures gets and sets the port's buffering mode. For input ports, the port buffering mode may be either one of :full, :modest or :none. For output ports, port-buffering, it may be one of :full, :line or :none. See section 6.18.3 File ports, for explanation of those modes.

    If port-buffering is applied to ports other than file ports, it returns #f. If the setter of port-buffering is applied to ports other than file ports, it signals an error.

    Function: port-current-line port
    Returns the current line count of port. This information is only available on file-based port, and as long as you're doing sequential character I/O on it. Otherwise, this returns -1.

    Function: port-file-number port
    Returns an integer file descriptor, if the port is associated to the system file I/O. Returns #f otherwise.

    Function: copy-port src dst &keyword (unit 0)
    Copies data from an input port src to an output port dst, until eof is read from src.

    The keyword argument unit may be zero, a positive exact integer, a symbol byte or a symbol char, to specify the unit of copying. If it is an integer, a buffer of the size (in case of zero, a system default size) is used to copy, using block I/O. Generally it is the fastest if you copy between normal files. If unit is a symbol byte, the copying is done byte by byte, using C-verson of read-byte and write-byte. If unit is a symbol char, the copying is done character by character, using C-version of read-char and write-char.

    6.18.3 File ports

    Function: open-input-file filename &keyword if-does-not-exist buffering element-type
    Function: open-output-file filename &keyword if-does-not-exist if-exists buffering element-type
    [R5RS+] Opens a file filename for input or output, and returns an input or output port associated with it, respectively.

    The keyword arguments specify precise behavior on the exceptional case.

    :if-exists
    This keyword argument can be specified only for open-output-file, and specifies the action when the filename already exists. One of the following value can be given.
    :supersede
    The existing file is truncated. This is the default behavior.
    :append
    The output data will be appended to the existing file.
    :error
    An error is signalled.
    #f
    No action is taken, and the function returns #f.
    :if-does-not-exist
    This keyword argument specifies the action when filename does not exist.
    :error
    An error is signalled. This is the default behavior of open-input-file.
    :create
    A file is created. This is the default behavior of open-output-file. The check of file existence and creation is done atomically; you can exclusively create the file by specifying :error or #f to if-exists, along this option. You can't specify this value for open-input-file.
    #f
    No action is taken, and the function returns #f.
    :buffering
    This argument specifies the buffering mode. The following values are allowed. The port's buffering mode can be get/set by port-buffering. (See section 6.18.2 Common port operations).
    :full
    Buffer the data as much as possible. This is the default mode.
    :none
    No buffering is done. Every time the data is written (to an output port) or read (from an input port), the underlying system call is used. Process's standard error port is opened in this mode by default.
    :line
    This is valid only for output ports. The written data is buffered, but the buffer is flushed whenever a newline character is written. This is suitable for interactive output port. Process's standard output port is opened in this mode by default. (Note that this differs from the line buffering mode of C stdio, which flushes the buffer as well when input is requested from the same file descriptor.)
    :modest
    This is valid only for input ports. This is almost the same as the mode :full, except that read-block may return less data than requested if the requested amount of data is not immediately available. (In the :full mode, read-block waits the entire data to be read). This is suitable for the port connected to a pipe or network.
    :element-type
    This argument specifies the type of the file.
    :character
    The file is opened in "character" (or "text") mode.
    :binary
    The file is opened in "binary" mode.
    In the current version, this argument is ignored and all files are opened in binary mode. It doesn't make difference in the Unix platforms.

    By combination of if-exists and if-does-not-exist flags, you can implement various actions:

    (open-output-file "foo" :if-exists :error)
     => ;opens "foo" exclusively, or error
    
    (open-output-file "foo" :if-exists #f)
     => ;opens "foo" exclusively, or returns #f
    
    (open-output-file "foo" :if-exists :append
                            :if-does-not-exist :error)
     => ;opens "foo" for append only if it already exists
    

    To check the existence of a file without opening it, use sys-access or file-exists? (See section 6.21.3.4 File stats).

    Note: gauche.charconv module extends these procedures to take encoding keyword argument so that they can read or write in different character encoding scheme. See section 9.2 gauche.charconv - Character Code Conversion.

    Note for portability: Some Scheme implementations (e.g. STk) allows you to specify a command to filename and reads from, or writes to, the subprocess standard input/output. Some other scripting languages (e.g. Perl) have similar features. In Gauche, open-input-file and open-output-file strictly operates on files (what the underlying OS thinks as files). However, you can use "process ports" to invoke other command in a subprocess and to communiate it. See section 9.14.2 Process ports, for details.

    Function: call-with-input-file string proc &keyword if-exists buffering element-type
    Function: call-with-output-file string proc &keyword if-does-not-exist if-exists buffering element-type
    [R5RS] Opens a file specified by string for input/output, and call proc with one argument, the file port. When proc returns, or an error is signalled from proc that is not captured within proc, the file is closed.

    The keyword arguments if-exists, element-type and if-does-not-exist have the same meanings of open-input-file and open-output-file's. Note that if you specify #f to if-exists and/or if-does-not-exist, proc may receive #f instead of a port object when the file is not opened.

    Returns the value(s) proc returned.

    Function: with-input-from-file string thunk &keyword if-exists buffering element-type
    Function: with-output-to-file string thunk &keyword if-does-not-exist if-exists buffering element-type
    [R5RS] Opens a file specified by string for input or output and makes the opened port as the current input or output port, then calls thunk. The file is closed when thunk returns or an error is signalled from thunk that is not captured within thunk.

    The keyword arguments have the same meanings of open-input-file and open-output-file's, except that #f is not allowed to if-exists and if-does-not-exist; i.e. an error is always signalled if the file can't be opened.

    Returns the value(s) thunk returned.

    Notes on semantics of closing file ports: R5RS states, in the description of call-with-input-file et al., that "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 read or write operation."

    Gauche's implementation slightly misses this criteria; the mere fact that an uncaptured error is thrown in proc does not prove the port will never be used. Nevertheless, it is very diffcult to think the situation that you can do meaningful operation on the port after such an error is signalled; you'd have no idea what kind of state the port is in. In practical programs, you should capture error explicitly inside proc if you still want to do some meaningful operation with the port.

    Note that if a continuation captured outside call-with-input-file et al. is invoked inside proc, the port is not closed. It is possible that the control returns later into the proc, if a continuation is captured in it (e.g. coroutines). The low-level exceptions (See section 6.16.4 Low-level exception mechanism) also doesn't ensure closing the port.

    Function: open-input-fd-port fd &keyword buffering name owner?
    Function: open-output-fd-port fd &keyword buffering name owner?
    Creates and returns an input or output port on top of the given file descriptor. Buffering specifies the buffering mode as described in open-input-file entry above; the default is :full. Name is used for the created port's name and returned by port-name. A boolean flag owner? specfies whether fd should be closed when the port is closed.

    6.18.4 String ports

    String ports are the ports that you can read from or write to memory.

    Function: open-input-string string
    [SRFI-6] Creates an input string port that has the content string. This is a more efficient way to access a string in order rather than using string-ref with incremental index.
    (define p (open-input-string "foo x"))
    (read p) => foo
    (read-char p) => #\space
    (read-char p) => #\x
    (read-char p) => #<eof>
    (read-char p) => #<eof>
    

    Function: open-output-string
    [SRFI-6] Creates an output string port. Anything written to the port is accumulated in the buffer, and can be obtained as a string by get-output-string. This is a far more efficient way to construct a string sequentially than pre-allocate a string and fill it with string-set!.

    Function: get-output-string port
    [SRFI-6] Takes an output string port port and returns a string that has been accumulated to port so far. If a byte data has been written to the port, this function re-scans the buffer to see if it can consist a complete string; if not, an incomplete string is returned.

    Function: call-with-input-string string proc
    Function: call-with-output-string proc
    Function: with-input-from-string string thunk
    Function: with-output-to-string thunk
    These utility functions are trivially defined as follows. The interface is parallel to the file port version.
    (define (call-with-output-string proc)
      (let ((out (open-output-string)))
        (proc out)
        (get-output-string out)))
    
    (define (call-with-input-string str proc)
      (let ((in (open-input-string str)))
        (proc in)))
    
    (define (with-output-to-string thunk)
      (let ((out (open-output-string)))
        (with-output-to-port out thunk)
        (get-output-string out)))
    
    (define (with-input-from-string str thunk)
      (with-input-from-port (open-input-string str) thunk))
    

    Function: call-with-string-io str proc
    Function: with-string-io str thunk
    (define (call-with-string-io str proc)
      (let ((out (open-output-string))
            (in  (open-input-string str)))
        (proc in out)
        (get-output-string out)))
    
    (define (with-string-io str thunk)
      (with-output-to-string
        (lambda ()
          (with-input-from-string str
            thunk))))
    

    Function: write-to-string obj &optional writer
    Function: read-from-string string &optional start end
    These convenience functions cover commin idioms using string ports.
    (write-to-string obj writer)
      ==
      (with-output-to-string (lambda () (writer obj)))
    
    (read-from-string string)
      ==
      (with-input-from-string string read)
    

    The default value of writer is the procedure write. The default values of start and end is 0 and the length of string.

    Portability note: Common Lisp has these functions, with different optional arguments. STk has read-from-string without optional argument.

    6.18.5 Procedural ports

    The underlying mechanism of procedural ports is very flexible, but I don't have Scheme interface yet, except the following ones:

    Function: open-input-buffered-port filler buffer-size
    Function: open-output-buffered-port flusher buffer-size
    These procedures are deprecated and will be replaced by more general procedural APIs.

    These are the Scheme interface to the "buffered port".

    open-input-buffered-port creates and returns an input port, with associated buffer of size buffer-size. The data is read from the buffer. When the port is read and the buffer is empty, a procedure filler is called with one argument, the size of required data. filler must return a string (either complete or incomplete) of the specified size. It is permitted for filler to return a string shorter than the size, if not enough data is available. The behavior is undefined if filler returns larger string than specified. Note that the size of string matters, not the length of string. If filler finds that it reached EOF of its data source, it can return EOF. Retuning zero size string has the same effect as EOF. Initially, the buffer is empty, so filler is always called at the first attempt of reading from the port.

    open-output-buffered-port creates and returns an output port, with associated buffer of size buffer-size. The data output to the port is accumulated in the buffer. When the buffer gets full, or flush is called on the port, a procedure flusher is called with an incomplete string to be flushed. flusher must return a number of bytes flushed, which must be the same as the size of the passed string. The string may shorter than buffer-size. When the port is closed, flusher is called with any data remaining in the buffer, then it is called again with #f to indicate the port is closed.

    6.18.6 Input

    For the input-related procedures, the optional iport argument must be an input port, and when omitted, the current input port is assumed.

    6.18.6.1 Reading data

    Function: read &optional iport
    [R5RS]

    Function: read-char &optional iport
    [R5RS]

    Function: peek-char &optional iport
    [R5RS]

    Function: read-byte &optional iport
    Reads one byte from an input port iport, and returns an integer in the range between 0 and 255. If iport has already reached EOF, an eof object is returned.

    Function: read-line &optional iport
    Reads one line (a sequence of characters terminated by newline or EOF) and returns a string. The terminating newline is not included. This function recognizes popular line terminators (LF only, CRLF, and CR only). If iport has already reached EOF, an eof object is returned.

    Function: read-block nbytes &optional iport
    Reads nbytes bytes from iport, and returns an incomplete string consisted by those bytes. The size of returned string may shorter than nbytes when iport doesn't have enough bytes to fill. If iport has already reached EOF, an eof object is returned.

    If iport is a file port, the behavior of read-block differs by the buffering mode of the port (See section 6.18.3 File ports, for the detail explanation of buffering modes).

    • If the buffering mode is :full, read-block waits until nbytes data is read, except it reads EOF.
    • If the buffering mode is :modest or :none, read-block returns shorter string than nbytes even if it doesn't reach EOF, but the entire data is not available immediately.

    Read-block returns newly allocated string every time. If you want to avoid allocation and read the data into a pre-allocated fixed-length buffer, you can use read-block! in gauche.uvector module (See section 9.24.4 Uvector block I/O). It uses a uniform vector as the buffer.

    If you want to write a chunk of bytes to a port, you can use either display if the data is in string, or write-block in gauche.uvector (See section 9.24.4 Uvector block I/O) if the data is in uniform vector.

    Function: eof-object? obj
    [R5RS] Returns true if obj is an EOF object.

    Function: char-ready? port
    [R5RS] If a character is ready to be read from port, returns #t.

    For now, this procedure actually checks only if next byte is immediately available from port. If the next byte is a part of a multibyte character, the attempt to read the whole character may block, even if char-ready? returns #t on the port. (It is unlikely to happen in usual situation, but theoretically it can. If you concern, use read-block to read the input as a byte sequence, then use input string port to read characters.)

    6.18.6.2 Read-time constructor

    Read-time constructor, defined in SRFI-10, provides an easy way to create an external representation of user-defined structures.

    Reader Syntax: #,(tag arg ...)
    [SRFI-10]

    Function: define-read-ctor tag procedure
    [SRFI-10]

    6.18.6.3 Input utility functions

    Function: port->string port
    Function: port->list reader port
    Function: port->string-list port
    Function: port->sexp-list port
    Generally useful input procedures. The API is taken from scsh and STk.

    port->string reads port until EOF and returns the accumulated data as a string.

    port->list applies reader on port repeatedly, until reader returns an EOF, then returns the list of objects reader returned.

    (port->string-list port) == (port->list read-line port) , and (port->sexp-list port) == (port->list read port) .

    Function: port-fold fn knil reader
    Function: port-fold-right fn knil reader
    Function: port-for-each fn reader
    Function: port-map fn reader
    Convenient iterators over the input read by reader. Basically, reader is called repeatedly without arguments and fn is called for each item it returns, until reader returns EOF. Actually reader can be any thunk; it doesn't need to be related to input port.

    Suppose reader returns a series of items {X0, X1, ..., Xn}. port-fold returns the following:

    (fn Xn (fn Xn-1 ... (fn X0 knil)))
    

    while port-fold-right returns the following:

    (fn X0 (fn X1 ... (fn Xn knil)))
    

    That is, (port-fold cons '() read) returns a reverse list of all the inputs, while (port-fold-right cons '() read) returns the same thing as (port->list read port).

    On the other hand, port-for-each and port-map applies fn to each item. The former discards the results fn returns, while the latter returns a list of results.

    6.18.7 Output

    For the following procedures, the optional port argument must be an output port, and when omitted, the current output port is assumed.

    Function: write obj &optional port
    [R5RS]

    Function: display obj &optional port
    [R5RS]

    Function: print expr ...
    Displays exprs (using display) to the current output port, then writes a newline.

    Method: write-object (obj <object>) port
    You can customize how the object is printed out by this method.

    Function: newline &optional port
    [R5RS] Writes a newline character to port

    Function: flush &optional port
    Function: flush-all-ports
    Output the buffered data in port, or all ports, respectively.

    The function "flush" is called in variety of ways on the various Scheme implementations: force-output (Scsh, SCM), flush-output (Gambit), or flush-output-port (Bigloo). The name flush is taken from STk and STklos.

    Function: write-char char &optional port
    [R5RS] Write a single character char to the output port port.

    Function: write-byte byte &optional port
    Write a byte byte to the port. byte must be an exact integer in range between 0 and 255.

    Function: write* obj &optional port

    Function: format port string arg ...
    Function: format string arg ...
    [SRFI-28+] Format arg ... according to string. This function is a subset of CommonLisp's format function, with a bit of extension. It is also a superset of SRFi-28, Basic format strings (@xref{srfi-28,[SRFI-28],SRFI-28}).

    port specifies the destination; if it is an output port, the formatted result is written to it; if it is #t, the result is written to the current output port; if it is #f, the formatted result is returned as a string. Port can be omitted, as SRFI-28 format; it has the same effects as giving #f to the port.

    string is a string that contains format directives. A format directive is a character sequence begins with tilda, `~', and ends with some specific characters. A format directive takes the corresponding arg and formats it. The rest of string is copied to the output as is.

    (format #f "the answer is ~s" 42)
      => "the answer is 42"
    

    The format directive can take one or more parameters, separated by comma characters. A parameter may be an integer or a character; if it is a character, it should be preceded by a quote character. Parameter can be omitted, in such case the system default value is used. The interpretation of the parameters depends on the format directive.

    Furthermore, a format directive can take two additional flags: atmark `@' and colon `:'. One or both of them may modify the behavior of the format directive. Those flags must be placed immediately before the directive character.

    If a character `v' or `V' is in the place of the parameter, the value of the parameter is taken from the format's argument. The argument must be either an integer, a character, or #f (indicating that the parameter is effectively omitted).

    Some examples:

    ~10,2s
    A format directive ~s, with two parameters, 10 and 2.
    ~12,,,'*A
    A format directive ~a, with 12 for the first parameter and a character `*' for the fourth parameter. The second and third parameters are omitted.
    ~10@d
    A format directive ~d, with 10 for the first parameter and `@' flag.
    ~v,vx
    A format directive ~x, whose first and second parameter will be taken from the arguments.

    The following is a complete list of the supported format directives. Either upper case or lower case character can be used for the format directive; usually they have no distinction, except noted.

    ~mincol,colinc,minpad,padchar,maxcolA
    Ascii output. The corresponding argument is printed by display. If an integer mincol is given, it specifies the minimum number of characters to be output; if the formatted result is shorter than mincol, a whitespace is padded to the right (i.e. the result is left justified). The colinc, minpad and padchar parameters control, if given, further padding. A character padchar replaces the padding character for the whitespace. If an integer minpad is given and greater than 0, at least minpad padding character is used, regardless of the resulting width. If an integer colinc is given, the padding character is added (after minpad) in chunk of colinc characters, until the entire width exceeds mincol. If atmark-flag is given, the format result is right justified, i.e. padding is added to the left. The maxcol parameter, if given, limits the maximum number of characters to be written. If the length of formatted string exceeds maxcol, only maxcol characters are written. If colon-flag is given as well and the length of formatted string exceeds maxcol, maxcol - 4 characters are written and a string " ..." is attached after it.
    (format #f "|~a|" "oops")
      => "|oops|"
    (format #f "|~10a|" "oops")
      => "|oops      |"
    (format #f "|~10@a|" "oops")
      => "|      oops|"
    (format #f "|~10,,,'*@a|" "oops")
      => "|******oops|"
    
    (format #f "|~,,,,10a|" '(abc def ghi jkl)
      => "|(abc def gh|" 
    (format #f "|~,,,,10:a|" '(abc def ghi jkl)
      => "|(abc de ...|" 
    
    ~mincol,colinc,minpad,padchar,maxcolS
    S-expression output. The corresponding argument is printed by write. The semantics of parameters and flags are the same as ~A directive.
    (format #f "|~s|" "oops")
      => "|\"oops\"|"
    (format #f "|~10s|" "oops")
      => "|\"oops\"    |"
    (format #f "|~10@s|" "oops")
      => "|    \"oops\"|"
    (format #f "|~10,,,'*@s|" "oops")
      => "|****\"oops\"|"
    
    ~mincol,padchar,commachar,intervalD
    Decimal output. The argument is formatted as an decimal integer. If the argument is not an integer, all parameters are ignored (after processing `v' parameters) and it is formatted by ~A directive. If an integer parameter mincol is given, it specifies minimum width of the formatted result; if the result is shorter than it, padchar is padded on the left (i.e. the result is right justified). The default of padchar is a whitespace.
    (format #f "|~d|" 12345)
      => "|12345|"
    (format #f "|~10d|" 12345)
      => "|     12345|"
    (format #f "|~10,'0d|" 12345)
      => "|0000012345|"
    
    If atmark-flag is given, the sign `+' is printed for the positive argument. If colon-flag is given, every interval-th digit of the result is grouped and commachar is inserted between them. The default of commachar is `,', and the default of interval is 3.
    (format #f "|~:d|" 12345)
      => "|12,345|"
    (format #f "|~,,'_,4:d|" -12345678)
      => "|-1234_5678|"
    
    ~mincol,padchar,commachar,intervalB
    Binary output. The argument is formatted as a binary integer. The semantics of parameters and flags are the same as the ~D directive.
    ~mincol,padchar,commachar,intervalO
    Octal output. The argument is formatted as an octal integer. The semantics of parameters and flags are the same as the ~D directive.
    ~mincol,padchar,commachar,intervalX
    ~mincol,padchar,commachar,intervalx
    Hexadecimal output. The argument is formatted as a hexadecimal integer. If `X' is used, upper case alphabets are used for the digits larger than 10. If `x' is used, lower case alphabets are used. The semantics of parameters and flags are the same as the ~D directive.
    (format #f "~8,'0x" 259847592)
      => "0f7cf5a8"
    (format #f "~8,'0X" 259847592)
      => "0F7CF5A8"
    
    ~count*
    Moves the argument counter count times forward, effectively skips next count arguments. The default value of count is 1, hence skip the next argument. If a colon-flag is given, moves the argument counter backwards, e.g. ~:* makes the next directive to process last argument again. If an atmark-flag is given, count specifies absolute position of the arguments, starting from 0.

    6.19 Loading Programs

    6.19.1 Loading Scheme file

    Function: load file &keyword paths (error-if-not-found #t)
    [R5RS+] Loads file, that is, read Scheme expressions in file and evaluates them. An extension ".scm" may be omitted from file.

    If file doesn't begin with "/" or "./" or "../", it is searched from the system file search list, stored in a variable *load-path*. Or you can explicitly specify the search path by passing a list of directory names to the keyword argument paths.

    On success, load returns #t. If the specified file is not found, an error is signalled unless the keyword argument error-if-not-found is #f, in which case load returns #f.

    The current module is preserved; even select-module is called in file, the module in which load is called is restored afterwards.

    If you want to load a library file, it's better to use `use' (See section 4.11.2 Defining and selecting modules), or `require' described below. See section 2.6 Compilation, for difference between load and require.

    Variable: *load-path*
    Keeps a list of directories that are searched by load and require.

    If you want to add other directories to the search path, do not modify this variable directly; use add-load-path, described below, instead.

    Special Form: add-load-path path &optional (afterp #f)
    Adds a path path to the library load path list. If a true value is given to afterp, path is added after the existing paths; otherwise, path is added before the existing paths.

    Use this form instead of changing *load-path* directly. This form is a special form and recognized by the compiler; if you change *load-path*, it is in effect at run time, and that may be too late for "use" or "require".

    Furthermore, add-load-path looks for the architecture dependent directories under the specified path and if it exists, sets up the internal path list for dynamic loading correctly. Suppose you have your Scheme module in /home/yours/lib, and that requires a dyncamic loadable library. You can put the library under /home/yours/lib/ARCH/, where ARCH is the value (gauche-architecture) returns (See section 6.21.2 Environment Inquiry). Then you can have compiled libraries for multiple platforms and Gauche can still find the right library.

    Function: load-from-port port
    Reads Scheme expressions from an input port port and evaluates them, until EOF is read.

    Function: current-load-port
    Function: current-load-history
    Function: current-load-next
    These procedures allows you to query the current context of loading. They returns the following values when called inside a file being loaded:
    current-load-port
    Returns the port object from which the file is being read.
    current-load-history
    Returns a list of pairs of a port and a line number (integer), representing the nesting of loads. Suppose you load `foo.scm', and from its line 7 it loads `bar.scm', and from its line 18 it loads `baz.scm'. If you call current-load-history in the file `baz.scm', you'll get
    ((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))
    
    current-load-next
    Returns a list of remaining directories to be searched at the time this file is found. Suppose the *load-path* is ("." "../lib" "/home/gauche/lib" "/share/gauche/lib") and you load `foo.scm', which happens to be in `../lib/'. Then, inside `foo.scm', current-load-next returns:
    ("/home/gauche/lib" "/share/gauche/lib")
    

    When called outside of load, these procedures returns #f, () and (), respectively.

    6.19.2 Load dynamic library

    Function: dynamic-load file &keyword init-function export-symbols
    Loads and links a dynamic loadable library (shared library) file. File shouldn't contain the suffix (".so" on most systems); dynamic-load adds it, for it may differ among platforms.

    The keyword argument init-function specifies the initialization function name of the library in a string. By default, if the file basename (without extension) is "foo", the initialization function name is "Scm_Init_foo".

    The keyword argument export-symbols tells whether the dynamic loader that the external symbols in file should be appended to the symbol table of the running process. (Note: I'm talking about C function and variable names, not Scheme symbols). By default, the symbols in file are not visible from other dynamically loaded libraries. If you want to allow other dynamically loaded libraries to call C function in your library, you should give #t to this argument. It sets RTLD_GLOBAL flag for dlopen().

    Usually a dynamic loadable library is provided with wrapping Scheme module, so the user doesn't have to call this function directly.

    There's no way to unload the loaded libraries.

    6.19.3 Require and provide

    Special Form: require feature
    If feature is not loaded, load it. Feature must be a string, and it is taken as a file name (without suffix) to be loaded. This loading takes place at compile time. The loaded file must provide feature; if not, a warning is issued.

    If you load SLIB module, require is extended. See section 11.15 slib - SLIB interface for details.

    Function: provide feature
    Adds feature to the system's provided feature list, so that the subsequent require won't load the same file again. Usually this procedure should be called at the end of the Scheme file that is to be required. The reason that it should be at the end of file is that if an error is raised during loading, you may want to fix the error and require it again.

    Function: provided? feature
    Returns #t if feature is already provided.

    6.19.4 Autoload

    Macro: autoload file/module item ...
    Sets up item ... to be autoloaded. That is, when an item is referenced for the first time, file/module is loaded before the item is evaluated. This delays the loading of file/module until it is needed.

    You can specify either a string file name or a symbol module name to file/module. If it is a string, the named file is loaded. If it is a symbol, the named module is loaded (using the same rule as of use), then the binding of item in the file/module is imported to the module used the autoload (See section 4.11.2 Defining and selecting modules, for details of use).

    Item can be either a variable name (symbol), or a form (:macro symbol). If it is a variable, the named file/module is loaded when the variable is about to be evaluated. If it is the latter form, the named file/module is loaded when a form (symbol arg ...) is about to be compiled, which enables autoloading macros.

    file/module must define symbol in it, or an error is signalled when file/module is autoloaded.

    The following is an example of autoloading procedures.

    (autoload "foo" foo0 foo1)
    (autoload "bar" bar0 bar1)
    
    (define (foobar x)
      (if (list? x)
          (map bar0 x)
          (foo0)))
    
    (foobar '(1 2)) ; "bar" is loaded at this moment
    
    (foobar #f)     ; "foo" is loaded at this moment
    

    Note that if you set to autoload macro, the file/module is loaded immediately when such form that uses the macro is compiled, regardless of the piece of the code is executed or not.

    6.20 Comparison and sorting

    Function: compare obj1 obj2

    Generic Function: object-compare obj1 obj2

    Function: sort list &optional cmfpn
    Function: sort! list &optional cmfpn
    Sorts elements in list in ascending order and returns the sorted list. sort! destructively reuses the cons cells of the original list. The sorting order is specified by cmpfn, which is a procedure takes two elements of list, and returns #t if the first argument strictly precedes the second.
    (sort '(("Chopin" "Frederic") 
            ("Liszt" "Franz")
            ("Alkan" "Charles-Valentin"))
          (lambda (x y) (string<? (car x) (car y))))
      => (("Alkan" "Charles-Valentin")
                 ("Chopin" "Frederic")
                 ("Liszt" "Franz"))
    

    Some builtin objects have natural comparison order, and it is used if cmpfn is omitted.

    6.21 System interface

    Gauche supports most of POSIX.1 functions and other system functions popular among Unix variants as built-in procedures.

    Lots of Scheme implementations provide some sort of system interface under various APIs. Some are just called by different names (e.g, delete-file or remove-file or unlink to delete a file), some do more abstraction introducing new Scheme objects. Instead of just picking one of such interfaces, I decided to implement Gauche's system interface API in two layers; the lower level layer, described in this section, follows the operating system's API as close as possible. On top of that, the higher-level APIs are provided, with considering compatibility to the existing systems.

    The low level system interface has the name sys-name and usually correspond to the system call name. I tried to keep the interface similar whenever reasonable.

    If you are familiar with system programming in C, see also section B. C to Scheme mapping, which shows correspondence between C standard library functions and Gauche procedures.

    6.21.1 Program termination

    Function: exit &optional (code 0)
    [POSIX] Terminates the current process with the exit code code. Code must be zero or positive exact integer. This procedure first invokes the after thunks of the current dynamic handlers (See section 6.15.3 Continuation), then flushes opened file buffers, finally calls exit(2).

    Function: sys-exit &optional (code 0)
    [POSIX] Terminates the current process with the exit code code. Code must be zero or positive exact integer. This procedure calls _exit(2) directly. No cleanup is done. Unflushed file output is discarded.

    Function: sys-abort
    [POSIX] Calls POSIX abort(). This usually terminates the running process and dumps core. No cleanup is done.

    6.21.2 Environment Inquiry

    Function: sys-getenv name
    [POSIX] Returns the value of the environment variable name as a string, or #f if the environment variable is not defined.

    Function: sys-putenv name value
    Add environment variable name with value to the current process's environment. If the system doesn't support putenv(3), this function signals an error.

    Function: gauche-version
    Function: gauche-architecture
    Function: gauche-library-directory
    Function: gauche-architecture-directory
    Function: gauche-site-library-directory
    Function: gauche-site-architecture-directory
    These functions returns a string that tells information about Gauche interpreter itself.

    6.21.3 Filesystems

    System calls that deal with filesystems. See also section 11.6 file.util - Filesystem utilities, which defines high-level APIs on top of the procedures described here.

    6.21.3.1 Directories

    See also section 11.6.1 Directory utilities for high-level API.

    Function: sys-readdir path
    path must be a string that denotes valid pathname of an existing directory. This function returns a list of strings of the directory entries. The returned list is not sorted. An error is signalled if path doesn't exists or is not a directory.

    Function: sys-glob pattern
    An interface to glob(3) function. pattern is a file pattern like sh(1): a character `?' matches any single character, `*' matches zero or more characters, `[abc]' matches either `a', `b' or `c'. If no pathname matches pattern, an empty list is returned.

    If the undelying platform doesn't have glob(), this function signals an error of "feature not supported".

    Note: it is known that on some systems glob() implementation has a security issue. Gauche will eventually implment glob() functionality in itself.

    See section 6.21.3.4 File stats, to check if a path is actually a directory.

    6.21.3.2 Directory manipulation

    Function: sys-remove filenmae
    [POSIX] If filename is a file it is removed. On some systems this may also work on an empty directory, but portable scripts shouldn't depend on it.

    Function: sys-rename old new
    [POSIX] Renames a file old to new. The new name can be in different directory from the old name, but both paths must be on the same device.

    Function: sys-tmpnam
    [POSIX] Creates a file name which is supposedly unique, and returns it. This is in POSIX, but its use is discouraged because of potential security risk. Use sys-mkstemp below if possible.

    Function: sys-mkstemp template
    Creates and opens a file that has unique name, and returns two values; opened port and the created filename. The file is created exclusively, avoiding race conditions. tmpname is used as the prefix of the file. Unlinke Unix's mkstemp, you don't need padding characters. The file is opened for writing, and its permission is set to 600.

    Function: sys-link existing new
    [POSIX] Creates a hard link named new to the existing file existing.

    Function: sys-unlink pathname
    [POSIX] Removes pathname. It can't be a directory. Returns #t if it is successfully removed, or #f if pathname doesn't exist. An error is signalled otherwise.

    Function: sys-symlink existing new
    Creates a symbolic link named new to the pathname existing. On systems that doesn't support symbolic links, this function is unbound.

    Function: sys-readlink path
    If a file specified by path is a symbolic link, its content is returned. If path doesn't exist or is not a symbolic link, an error is signalled. On systems that don't support symbolic links, this function is unbound.

    Function: sys-mkdir pathname mode
    [POSIX] Makes a directory pathname with mode mode. The parent directory of pathname must exist and be writable by the process. To create intermediate directories at once, use make-directory* in file.util (section 11.6.1 Directory utilities).

    Function: sys-rmdir pathname
    [POSIX] Removes a directory pathname. The directory must be empty. To remove a directory with its contents, use remove-directory* in file.util (section 11.6.1 Directory utilities).

    Function: sys-umask mode
    [POSIX] Sets umask setting to mode. Returns previous umask setting. See man umask for more details.

    6.21.3.3 Pathnames

    See also section 11.6.2 Pathname utilities, for high-level APIs.

    Function: sys-normalize-pathname pathname &keyword absolute expand canonicalize
    Converts pathname according to the way specified by keyword arguments. More than one keyword argument can be specified.
    absolute
    If this keyword arugment is given and true, and pathname is not an absolute pathname, it is converted to an absolute pathname by appending the current working directory in front of pathname.
    expand
    If this keyword argument is given and true, and pathname begins with `~', it is expanded as follows:
    • If pathname is consisted entirely by "~", or begins with "~/", then the character "~" is replaced for the pathname of the current user's home directory.
    • Otherwise, characters following `~' until either `/' or the end of pathname are taken as a user name, and the user's home directory is replaced in place of it. If there's no such user, an error is signalled.
    canonicalize
    Tries to remove pathname components "." and "..". The pathname interpretation is done purely in textural level, i.e. it doesn't access filesystem to see the conversion reflects the real files. It may be a problem if there's a symbolic links to other directory in the path.

    Function: sys-basename pathname
    Function: sys-dirname pathname
    sys-basename returns a basename, that is the last component of pathname. sys-dirname returns the components of pathname but the last one. If pathname has a trailing `/', it is simply ignored.
    (sys-basename "foo/bar/bar.z") => "bar.z"
    (sys-basename "coo.scm") => "coo.scm"
    (sys-basename "x/y/") => "y"
    (sys-dirname "foo/bar/bar.z") => "foo/bar"
    (sys-dirname "coo.scm") => "."
    (sys-dirname "x/y/") => "x"
    

    These functions doesn't check if pathname really exists.

    Some boundary cases:

    (sys-basename "") => ""
    (sys-dirname "") => "."
    
    (sys-basename "/") => ""
    (sys-dirname "/") => "/"
    

    Note: The above behavior is the same as Perl's basename and dirname. On some implementations, the command basename may return "/" for the argument "/", and "." for the argument ".".

    6.21.3.4 File stats

    See also section 11.6.3 File attibute utilities, for high-level APIs.

    Function: file-exists? path
    Function: file-is-regular? path
    Function: file-is-directory? path
    Returns true if path exists, is a regular file, or is a directory, respectively. The latter two returns false if path doesn't exist at all.

    These functions are built on top of primitive system interfaces described below; I provide these for convenience and compatibility (STk has the same functions).

    Builtin Class: <sys-stat>
    An object that represents struct stat, attributes of an entry in the filesystem. It has the following read-only slots.

    Instance Variable: <sys-stat> type
    A symbol represents the type of the file.
  • regular a regular file
  • directory a directory
  • character a character device
  • block a block device
  • fifo a fifo
  • symlink a symbolic link
  • socket a socket If the file type is none of the above, #f is returned. Note: Some operating systems don't have the socket file type and returns fifo for socket files. Portable programs should check both possibilities to see if the given file is a socket.
  • Instance Variable: <sys-stat> perm
    An exact integer for permission bits of struct stat. It is the same as lower 9-bits of "mode" slot; provided for the convenience.
    Instance Variable: <sys-stat> mode
    Instance Variable: <sys-stat> ino
    Instance Variable: <sys-stat> dev
    Instance Variable: <sys-stat> rdev
    Instance Variable: <sys-stat> nlink
    Instance Variable: <sys-stat> uid
    Instance Variable: <sys-stat> gid
    Instance Variable: <sys-stat> size
    An exact integer for those information of struct stat.
    Instance Variable: <sys-stat> atime
    Instance Variable: <sys-stat> mtime
    Instance Variable: <sys-stat> ctime
    A number of seconds since Unix Epoch for those information of struct stat.
    Function: sys-stat path
    Function: sys-fstat port-or-fd
    [POSIX] Returns a <sys-stat> object of path, or the underlying file of port-or-fd, which may be a port or a positive exact integer file descriptor, respectively. If path is a symbolic link, a stat of the file the link points to is returned from sys-stat. If port-or-fd is not associated to a file, sys-fstat returns #f.
    Function: sys-lstat path
    Like sys-stat, but it returns a stat of a symbolic link if path is a symbolic link.
    gosh> (describe (sys-stat "gauche.h"))
    #<<sys-stat> 0x815af70> is an instance of class <sys-stat>
    slots:
      type      : regular
      perm      : 420
      mode      : 33188
      ino       : 845140
      dev       : 774
      rdev      : 0
      nlink     : 1
      uid       : 400
      gid       : 100
      size      : 79549
      atime     : 1020155914
      mtime     : 1020152005
      ctime     : 1020152005
    
    Function: sys-stat->mode stat
    Function: sys-stat->ino stat
    Function: sys-stat->dev stat
    Function: sys-stat->rdev stat
    Function: sys-stat->nlink stat
    Function: sys-stat->size stat
    Function: sys-stat->uid stat
    Function: sys-stat->gid stat
    Function: sys-stat->atime stat
    Function: sys-stat->mtime stat
    Function: sys-stat->ctime stat
    Function: sys-stat->file-type stat
    Deprecated. Use slot-ref to access information of <sys-stat> object.
    Function: sys-access pathname amode
    [POSIX] An interface to access(2). Returns a boolean value of indicating whether access of pathname is allowed in amode. amode can be a combinations (logical or) of following predefined flags.
    R_OK
    Checks whether pathname is readable by the current user.
    W_OK
    Checks whether pathname is writable by the current user.
    X_OK
    Checks whether pathname is executable (or searchable in case pathname is a directory) by the current user.
    F_OK
    Checks whether pathname exists or not, regardless of the access permissions of pathname. (But you need to have access permissions of the directories containing pathname).
    Function: sys-chmod path mode
    Change the mode of the file named path to mode. mode must be a small positive integer whose lower 9 bits specifies POSIX style permission.
    Function: sys-chown path owner-id group-id
    Change the owner and/or group of the file named path to owner-id and group-id respectively. owner-id and group-id must be an exact integer. If either of them is -1, the corresponding ownership is not changed.
    Function: sys-utime path &optional atime mtime
    Change the file's access time and modification time to atime and mtime, respectively. If atime and mtime is omitted, they are set to the current time. See also touch-file (See section 11.6.4 File operations).

    6.21.3.5 Other file operations

    Function: sys-chdir dir
    [POSIX] An interface to chdir(2). See also current-directory (See section 11.6.1 Directory utilities).

    Function: sys-pipe &keyword (buffering :line)
    [POSIX] Creates a pipe, and returns two ports. The first returned port is an input port and the second is an output port. The data put to the output port can be read from the input port.

    Buffering can be :full, :line or :none, and specifies the buffering mode of the ports opened on the pipe. See section 6.18.3 File ports, for details of the buffering mode. The default mode is sufficient for typical cases.

    (receive (in out) (sys-pipe)
      (display "abc\n" out)
      (flush out)
      (read-line in)) => "abc"
    

    Note: the returned value is changed from version 0.3.15, in which sys-pipe returned a list of two ports.

    Function: sys-mkfifo path mode
    [POSIX] creates a fifo (named pipe) with a name path and mode mode. Mode must be a positive exact integer to represent the file mode.

    Function: sys-isatty port-or-fd
    [POSIX] port-or-fd may be a port or an integer file descriptor. Returns #t if the port is connected to the console, #f otherwise.

    Function: sys-ttyname port-or-fd
    [POSIX] port-or-fd may be a port or an integer file descriptor. Returns the name of the terminal connected to the port, or #f if the port is not connected to a terminal.

    6.21.4 Unix groups and users

    6.21.4.1 Unix Group

    Builtin Class: <sys-group>
    Unix group information. Has following slots.

    Instance Variable: <sys-group> name
    Group name.

    Instance Variable: <sys-group> gid
    Group id.

    Instance Variable: <sys-group> passwd
    Group password.

    Instance Variable: <sys-group> mem
    List of user names who are in this group.

    Function: sys-getgrgid gid
    Function: sys-getgrnam name
    [POSIX] Returns <sys-group> object from an integer group id gid or a group name name, respectively. If the specified group doesn't exist, #f is returned.

    Function: sys-gid->group->name gid
    Function: sys-group-name->gid name
    Convenience function to convert between group id and group name.

    6.21.4.2 Unix users

    Builtin Class: <sys-passwd>
    Unix user information. Has following slots.

    Instance Variable: <sys-group> name
    User name.

    Instance Variable: <sys-group> uid
    User ID.

    Instance Variable: <sys-group> gid
    User's primary group id.

    Instance Variable: <sys-group> passwd
    User's (encrypted) password. If the system uses the shadow password file, you just get obscure string like "x".

    Instance Variable: <sys-group> gecos
    Gecos field.

    Instance Variable: <sys-group> dir
    User's home directory.

    Instance Variable: <sys-group> shell
    User's login shell.

    Instance Variable: <sys-group> class
    User's class (only available on some systems).

    Function: sys-getpwuid uid
    Function: sys-getpwnam name
    [POSIX] Returns <sys-passwd> object from an integer user id uid or a user name name, respectively. If the specified user doesn't exist, #f is returned.

    Function: sys-uid->user-name uid
    Function: sys-user-name->uid
    Convenience functions to convert between user id and user name.

    6.21.4.3 Password encryption

    Function: sys-crypt key salt
    This is the interface to crypt(3). Key and salt must be a string, and an encrypted string is returned. On systems where crypt(3) is not available, call to this function signals an error.

    6.21.5 Locale

    Function: sys-setlocate category locale
    [POSIX] Sets the locale of the category category to the locale locale. category must be an exact integer; the following pre-defined variables are available. locale must be a string locale name. Returns the locale name on success, or #f if the system couldn't change the locale.

    Variable: LC_ALL
    Variable: LC_COLLATE
    Variable: LC_CTYPE
    Variable: LC_MONETARY
    Variable: LC_NUMERIC
    Variable: LC_TIME
    Predefined variables for possible category value of sys-setlocale.

    Function: sys-localeconv
    [POSIX] Returns an assoc list of various information for formatting numbers in the current locale.

    An example session. It may differ on your system settings.

    (sys-localeconv)
     =>
       ((decimal_point . ".") (thousands_sep . "")
        (grouping . "") (int_curr_symbol . "")
        (currency_symbol . "") (mon_decimal_point . "")
        (mon_thousands_sep . "") (mon_grouping . "")
        (positive_sign . "") (negative_sign . "")
        (int_frac_digits . 127) (frac_digits . 127)
        (p_cs_precedes . #t) (p_sep_by_space . #t)
        (n_cs_precedes . #t) (n_sep_by_space . #t)
        (p_sign_posn . 127) (n_sign_posn . 127))
    
    (sys-setlocale LC_ALL "fr_FR")
     => "fr_FR"
    
    (sys-localeconv)
     =>
      ((decimal_point . ",") (thousands_sep . "")
       (grouping . "") (int_curr_symbol . "FRF ")
       (currency_symbol . "F") (mon_decimal_point . ",")
       (mon_thousands_sep . " ") (mon_grouping . "\x03\x03")
       (positive_sign . "") (negative_sign . "-")
       (int_frac_digits . 2) (frac_digits . 2)
       (p_cs_precedes . #f) (p_sep_by_space . #t)
       (n_cs_precedes . #f) (n_sep_by_space . #t)
       (p_sign_posn . 1) (n_sign_posn . 1))
    

    6.21.6 Signal

    Gauche can send out operating system's signals to the other processes (including itself) and can handle the incoming signals.

    In multithread environment, all threads share the signal handlers, and each thread has its own signal mask. See section 6.21.6.5 Signals and threads, for details.

    6.21.6.1 Signals and signal sets

    Signals are referred by its signal number (a small integer) defined on the underlying operating system. Variables are pre-defined to the system's signal number. System's signal numbers may be architecture dependent, so you should use those variables rather than using literal integers.

    Variable: SIGABRT
    Variable: SIGALRM
    Variable: SIGCHLD
    Variable: SIGCONT
    Variable: SIGFPE
    Variable: SIGHUP
    Variable: SIGILL
    Variable: SIGINT
    Variable: SIGKILL
    Variable: SIGPIPE
    Variable: SIGQUIT
    Variable: SIGSEGV
    Variable: SIGSTOP
    Variable: SIGTERM
    Variable: SIGTSTP
    Variable: SIGTTIN
    Variable: SIGTTOU
    Variable: SIGUSR1
    Variable: SIGUSR2
    These variables are bound to the signal numbers of POSIX signals.

    Variable: SIGTRAP
    Variable: SIGIOT
    Variable: SIGBUS
    Variable: SIGSTKFLT
    Variable: SIGURG
    Variable: SIGXCPU
    Variable: SIGXFSZ
    Variable: SIGVTALRM
    Variable: SIGPROF
    Variable: SIGWINCH
    Variable: SIGPOLL
    Variable: SIGIO
    Variable: SIGPWR
    These variables are bound to the signal numbers of system-dependent signals. Not all of them may be defined on some systems.

    Besides each signal numbers, you can refer to a set of signals using a <sys-sigset> object. It can be used to manipulate the signal mask, and to install a signal handler to a set of signals at once.

    Class: <sys-sigset>
    A set of signals. An empty sigset can be created by
    (make <sys-sigset>)
    

    Function: sys-sigset-add! sigset signal ...
    Function: sys-sigset-delete! sigset signal ...
    Sigset must be a <sys-sigset> object. Those procedures adds and removes the specified signals from sigset respectively, and returns the result. sigset itself is also modified.

    signal may be either a signal number, another <sys-sigset> object, or #t for all available signals.

    Function: sys-sigset-fill! sigset
    Function: sys-sigset-empty! sigset
    Fills sigset by all available signals, or empties sigset.

    Function: sys-signal-name signal
    Returns the human-readable name of the signal.

    6.21.6.2 Sending signals

    To send a signal, you can use sys-kill which works like kill(2).

    Function: sys-kill pid sig
    [POSIX] Sends a signal sig to the specified process(es). Sig must be a positive exact integer. pid is an exact integer and specifies the target process(es):
    • If pid is positive, it is the target process id.
    • If pid is zero, the signal is sent to every process in the process group of the current process.
    • If pid is less than -1, the signal is sent to every process in the process group -pid.

    There's no Scheme equivalence for raise(), but you can use (sys-kill (sys-getpid) sig).

    6.21.6.3 Handling signals

    You can register signal handling procedures in Scheme. (In multithread environment, signal handlers are shared by all threads; see section 6.21.6.5 Signals and threads for details).

    When a signal is delivered to the Scheme process, it is queued in VM, and processed in a 'safe point' where the state of VM is consistent. (Note that this makes handling of some signals such as SIGILL useless, for the process can't continue sensible execution after queuing the signal).

    When you're using the gosh interpreter, the default behavior for each signal is as in the following table.

    SIGABRT, SIGILL, SIGKILL, SIGCONT, SIGSTOP, SIGSEGV, SIGBUS
    Cannot be handled in Scheme. Gosh follows the system's default behavior.
    SIGCHLD, SIGTSTP, SIGTTIN, SIGTTOU, SIGWINCH
    No signal handles are installed for these signals by gosh, so the process follows the system's default behavior. Scheme programs can install its own signal handler if necessary.
    SIGHUP, SIGQUIT, SIGTERM
    Gosh installs a signal handler for these signals that exits from the application with code 0.
    SIGPWR, SIGXCPU, SIGUSR1, SIGUSR2
    On Linux platforms with thread support, these signals are used by the system and not available for Scheme. On other systems, these signals behaves the same as described below.
    other signals
    Gosh installs the default signal handler, which signals an "unhandled signal" error. Scheme programs can override it by its own signal handler.

    If you're using Gauche embedded in some other application, it may redefine the default behavior.

    Use the following procedures to get/set signal handlers from Scheme.

    Function: set-signal-handler! signals handler
    Signals may be a single signal number or a <sys-sigset> object, and handler should be either #t, #f or a procedure that takes one argument. If handler is a procedure, it will be called when the process receives one of specified signal(s), with the received signal number as an argument. It is safe to do anything in handler, including throwing an error or invoking continuation captured elsewhere. (However, continuations captured inside handler will be invalid once you return from handler).

    If handler is #t, the operating system's default behavior is set to the specified signal(s). If handler is #f, the specified signals(s) will be ignored.

    Note that signal handler setting is shared among threads in multithread enviornment. The handler is called from the thread which is received the signal. See section 6.21.6.5 Signals and threads for details.

    Function: get-signal-handler signum
    Returns the handler setting of a signal signum.

    Function: get-signal-handlers
    Returns an associative list of all signal handler settings. Car of each element of returned list is a <sys-sigset> object, and cdr of it is the handler (a procedure or a boolean value) of the signals in the set.

    Macro: with-signal-handlers (handler-clause ...) thunk
    A convenience macro to install signal handlers temporarily during execution of thunk. (Note: though this is convenient, this has certain dangerous properties described below. Use with caution.)

    Each Handler-clause may be one of the following forms.

    (signals expr ...)
    Signals must be an expression that will yield either a signal, a list of signals, or a <sys-sigset> object. Installs a signal handler for signals that evaluates expr ... when one of the signals in signals is delivered.
    (signals => proc)
    Proc must be a procedure that takes one argument. This form installs proc as the signal handler for signals.

    When the control exits from thunk, the signal handler setting before with-signal-handlers are recovered.

    CAVEAT: If you're setting more than one signal handlers, they are installed in serial. If a signal is delivered before all the handlers are installed, the signal handler state may be left inconsistent. Also note that the handler setting is a global state; you can't set "thread local" handler by with-signal-handlers, although the form may mislead such misunderstanding.

    6.21.6.4 Masking and waiting signals

    A Scheme program can set a signal mask, which is a set of signals to be blocked from delivery. If a signal is delivered which is completely blocked in the process, the signal becomes "pending". The pending signal may be delivered once the signal mask is changed not to block the specified signal. (However, it depends on the operating system whether the pending signals are queued or not.)

    In multithread environment, each thread has its own signal mask.

    Function: sys-sigmask how mask
    Modifies the current thread's signal mask, and returns the previous signal mask. Mask should be a <sys-sigset> object. How argument should be one of the following integer constants:
    SIG_SETMASK
    Sets mask as the thread's signal mask.
    SIG_BLOCK
    Adds signals in mask to the thread's signal mask.
    SIG_UNBLOCK
    Removes signals in mask from the thread's signal mask.

    Function: sys-sigsuspend mask
    Atomically sets thread's signal mask to mask and suspends the calling thread. When a signal that is not blocked and has a signal handler installed is delivered, the associated handler is called, then sys-sigsuspend returns.

    6.21.6.5 Signals and threads

    The semantics of signals looks a bit compilated in the multithread environment. Nevertheless, it is pretty comprehensible once you remember a small number of rules. Besides, Gauche sets up the default behavior easy to use, while allowing programmers to do tricky stuff.

    If you don't want to be bothered by the details, just remember one thing, with one sidenote. By default, signals are handled by the primordial (main) thread. However, if the main thread is suspended on mutex or condition variable, the signal may not be handled at all, so be careful.

    Now, if you are curious about the details, here are the rules:

    Now, these rules have several implications.

    If there are more than one thread that don't block a particular signal, you can't know which thread receives the signal. Such a situation is much less useful in Gauche than C programs because of the fact that the signal handling can be delayed indefinitely if the receiver thread is waiting on mutex or condition variable. So, it is recommended to make sure, for each signal, there is only one thread that can receive it.

    In Gauche, all threads created by make-thread (See section 9.22.1 Thread procedures) blocks all the signals by default (except the reserved ones). This lets all the signals to be directed to the primordial (main) thread.

    Another strategy is to create a thread dedicated for handling signals. To do so, you have to block the signals in the primordial thread, then create the signal-handling thread, and within that thread you unblock all the signals. Such a thread can just loop on sys-pause.

    (thread-start!
      (make-thread
        (lambda ()
          (sys-sigmask SIG_SETMASK (make <sys-sigset>)) ;;empty mask
          (let loop () (sys-pause) (loop)))))
    

    Complicated application may want to control per-thread signal handling precisely. You can do so, just make sure that at any moment only the designated thread unblocks the desired signal.

    6.21.7 System Inquiry

    Function: sys-uname
    [POSIX] Returns a list of five elements, (sysname nodename release version machine).

    Function: sys-gethostname
    Returns the host name. If the system doesn't have gethostname(), the second element of the list returned by sys-uname is used.

    Function: sys-getdomainname
    Returns the domain name. If the system doesn't have getdomainname(), "localdomain" is returned.

    Function: sys-getcwd
    [POSIX] Returns the current working directory by a string. If the current working directory couldn't be obtained from the system, an error is signalled. See also sys-chdir (See section 6.21.3.5 Other file operations), current-directory (See section 11.6.1 Directory utilities).

    Function: sys-getgid
    Function: sys-getegid
    [POSIX] Returns integer value of real and effective group id of the current process, respectively.

    Function: sys-setgid gid
    [POSIX] Sets the effective group id of the current process.

    Function: sys-getuid
    Function: sys-geteuid
    [POSIX] Returns integer value of real and effective user id of the current process, respectively.

    Function: sys-setuid uid
    [POSIX] Sets the effective user id of the current process.

    Function: sys-getgroups
    [POSIX] Returns a list of integer ids of supplementary groups.

    Function: sys-getlogin
    [POSIX] Returns a string of the name of the user logged in on the controlling terminal of the current process. If the system can't determine the information, #f is returned.

    Function: sys-getpgrp
    [POSIX] Returns a process group id of the current process.

    Function: sys-getpgid pid
    Returns a process group id of the process specified by pid. If pid is zero, the current process is used.

    Note that getpgid() call is not in POSIX. If the system doesn't have getpgid(), sys-getpgid still works if pid is zero (it just calls sys-getpgrp), but signals an error if pid is not zero.

    Function: sys-setpgid pid pgid
    [POSIX] Sets the process group id of the process pid to pgid. If pid is zero, the process ID of the current process is used. If pgid is zero, the process ID of the process specified by pid is used. (Hence sys-setpgid(0, 0) sets the process group id of the current process to the current process id).

    Function: sys-setsid
    [POSIX] Creates a new session if the calling process is not a process group leader.

    Function: sys-getpid
    Function: sys-getppid
    [POSIX] Returns the current process id and the parent process id, respectively.

    Function: sys-times
    [POSIX]

    Function: sys-ctermid
    [POSIX] Returns the name of the controlling terminal of the process. This may be just a "/dev/tty". See also sys-ttyname.

    6.21.8 Time

    Gauche has two representations of time, one is compatible to POSIX API, and the other is compatible to SRFI-18, SRFI-19 and SRFI-21. Most procedures accept both representations; if not, the representation the procedure accepts is indicated as either 'POSIX time' or 'SRFI time'.

    POSIX time is represented by a real number which is a number of seconds since Unix Epoch (Jan 1, 1970, 0:00:00GMT). Procedure sys-time, which corresponds to POSIX time(2), returns this time representation.

    SRFI-compatible time is represented by an object of <time> class, which keeps seconds and nanoseconds, as well as the type of the time (UTC, TAI, duration, process time, etc). Current-time returns this representation.

    6.21.8.1 POSIX time

    Function: sys-time
    [POSIX] Returns the current time in POSIX time (the time since Epoch (00:00:00 UTC, January 1, 1970), measured in seconds). It may be a non-integral number, depending on the architecture.

    Note that POSIX's definition of "seconds since the Epoch" doesn't take leap seconds into acount.

    Function: sys-gettimeofday
    Returns two values. The first value is a number of seconds, and the second value is a fraction in a number of microseconds, since 1970/1/1 0:00:00 UTC. If the system doesn't have gettimeofday call, this function calls time(); in that case, microseconds portion is always zero.

    Builtin Class: <sys-tm>
    Represents struct tm, a calendar date. It has the following slots.
    Instance Variable: <sys-tm> sec
    Seconds. 0-61.
    Instance Variable: <sys-tm> min
    Minutes. 0-59.
    Instance Variable: <sys-tm> hour
    Hours. 0-23.
    Instance Variable: <sys-tm> mday
    Day of the month, counting from 1. 1-31.
    Instance Variable: <sys-tm> mon
    Month, counting from 0. 0-11.
    Instance Variable: <sys-tm> year
    Years since 1900, e.g. 102 for the year 2002.
    Instance Variable: <sys-tm> wday
    Day of the week. Sunday = 0 .. Saturday = 6.
    Instance Variable: <sys-tm> yday
    Day of tye year. January 1 = 0 .. December 31 = 364 or 365.
    Instance Variable: <sys-tm> isdst
    A flag that indicates if the daylight saving time is in effect. Positive if DST is in effect, zero if not, or negative if unknown.

    Function: sys-gmtime time
    Function: sys-localtime time
    [POSIX] Converts time to <sys-tm> object, represented in GMT or local timezone, respectively. Time can be either POSIX-time or SRFI-time.

    Function: sys-ctime time
    [POSIX] Converts time to it string representation, using POSIX ctime(). Time can be either POSIX-time or SRFI-time.

    Function: sys-difftime time1 time0
    [POSIX] Returns the difference of two times in the real number of seconds. Time0 and tiem1 can be either POSIX-time or SRFI-time.

    Function: sys-asctime tm
    [POSIX] Converts <sys-tm> object tm to a string representation.

    Function: sys-strftime format tm
    [POSIX] Converts <sys-tm> object tm to a string representation, according to a format string format.

    Function: sys-mktime tm
    [POSIX] Converts <sys-tm> object tm, expressed as local time, to the POSIX-time (number of seconds since Epoch).

    Function: sys-tm->alist tm
    (Deprecated function)

    6.21.8.2 SRFI time

    Builtin Class: <time>
    The <time> object also represents a point of time.

    Instance Variable: <time> type
    Indicates time type. time-utc is the default, and that represents the number of seconds since Unix Epoch. SRFI-19 (See section 10.9 srfi-19 - Time data types and procedures) adds more types.
    Instance Variable: <time> second
    Second part of the time.
    Instance Variable: <time> nanosecond
    Nanosecond part of the time.

    Function: current-time
    [SRFI-18][SRFI-21] Returns the <time> object representing the current time in time-utc. See section 10.9 srfi-19 - Time data types and procedures, for it redefines current-time to allow optional argument to specify time type.

    Function: time? obj
    [SRFI-18][SRFI-19][SRFI-21] Returns #t if obj is a time object.

    Function: time->seconds time
    Function: seconds->time seconds
    [SRFI-18][SRFI-21] Converts between time object and the number of seconds (POSIX-time). Time argument of time->seconds has to be a <time> object.

    6.21.9 Unix process management

    6.21.9.1 Fork and exec

    Function: sys-system command
    [POSIX] Runs command in a subprocess. command is usually passed to sh, so the shell metacharacters are interpreted.

    This function returns an integer value system() returned. Since POSIX doesn't define what system() returns, you can't interpret the returned value in a portable way.

    Function: sys-fork
    [POSIX] Fork the current process. Returns 0 if you're in the child process, and a child process' pid if you're in the parent process. All the opened file descriptors are shared between the parent and the child. See fork(2) of your system for details.

    If the forked process runs some Scheme code and exits instead of calling sys-exec, the forked process should call sys-exit to terminate itself. Normal exit call tries to flush the file buffers, and on some OS it messes up the parent's file buffers.

    Function: sys-exec command args &optional iomap
    [POSIX+] Execute command with args, a list of arguments. The current process image is replaced by command, so this function never returns.

    All elements of args must be strings. The first element of args is used as argv[0], i.e. the program name.

    The optional iomap argument, when provided, specifies how the open file descriptors are treated. It must be the following format:

    ((to-fd . from-port-or-fd) ...)
    

    To-fd must be an integer, and from-port-or-fd must be an integer file descriptor or a port. Each element of the list makes the file descriptor of from-port-or-fd of the current process be mapped to the file descriptr to-fd in the executed process.

    If iomap is provided, any file descriptors other than specified in the iomap list will be closed before exec(). Otherwise, all file descriptors in the current process remain open.

    (sys-exec "ls" '("ls" "-l")) => ;; ls is executed.
    
    (sys-exec "ls" '("ls" "-l") '((1 . 2) (1 . 1)))
       => ;; ls is executed, with its stderr and stdout are mapped to the
                  current process's stdout.
    

    When it encounters an error, most of the time it raises an error condition. Once the file descriptors are permuted, however, it would be impractical to handle errors in reasonable way (you don't even know stderr is still available!), so Gauche simply exits on the error.

    See also section 9.14 gauche.process - High Level Process Interface, which provides more convenient process handling on top of above primitives.

    6.21.9.2 Wait

    Function: sys-wait
    [POSIX] Calls system's wait(2). The process suspends its execution until one of the child terminates. Returns two exact integer values, the first one is the child's process id, and the second is a status code. The status code can be interpreted by the following functions.

    Function: sys-waitpid pid &keyword nohang untraced
    [POSIX] This is an interface to waitpid(3), an extended version of wait.

    pid is an exact integer specifying which child(ren) it's waiting. If it is a positive integer, it waits fot that specific child. If it is zero, it waits for any member of this process group. If it is -1, it waits for any child process. If it is less than -1, it waits for any child process whose process group id is equal to the absolute value of pid.

    The calling process suspends until one of those child process is terminated, unless true is specified to the keyword argument nohang.

    If true is specified to the keyword argument untraced, the status of stopped child process can be also returned.

    The return values are two exact integers, the first one is the child process id, and the second is a status code. If nohang is true and no child process status is available, the first value is zero.

    Function: sys-wait-exited? status
    Function: sys-wait-exit-status status
    [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-exited? returns #t if the child process is terminated normally. sys-wait-exit-status returns the exit code the child process passed to exit(2), or the return value of main().

    Function: sys-wait-signaled? status
    Function: sys-wait-termsig status
    [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-signaled? returns #t if the child process is termintaed by an uncaught signal. sys-wait-termsig returns the signal number that terminted the child.

    Function: sys-wait-stopped? status
    Function: sys-wait-stopsig status
    [POSIX] The argument is an exit status returned as a second value from sys-waitpid. sys-wait-stopped? returns #t if the child process is stopped. This status can be caught only by sys-waitpid with true untraced argument. sys-wait-stopsig returns the signum number that stopped the child.

    6.21.10 I/O multiplexing

    The interface functions for select(2). The higher level interface is provided on top of these primitives; see section 9.17 gauche.selector - Simple dispatcher.

    Builtin Class: <sys-fdset>
    Represents fd_set, a set of file descriptors. You can make an empty file descriptor set by make method:
    (make <sys-fdset>)
    

    Function: sys-fdset-ref fdset port-or-fd
    Function: sys-fdset-set! fdset port-or-fd flag
    Gets and sets specific file descritor bit of fdset. port-or-fd may be a port or an integer file descriptor. If port-or-fd is a port that doesn't have associated file descriptor, sys-fdset-ref returns #f, and sys-fdset-set! doesn't modify fdset. flag must be a boolean value.

    You can use generic setter of sys-fdset-ref as this:

    (set! (sys-fdset-ref fdset port-or-fd) flag)
      == (sys-fdset-set! fdset port-or-fd flag)
    

    Function: sys-fdset-max-fd fdset
    Returns the maximum file descriptor number in fdset.

    Function: sys-select readfds writefds exceptfds &optional timeout
    Function: sys-select! readfds writefds exceptfds &optional timeout
    Waits for a set of file descriptors to change status. readfds, writefds, and exceptfds are <fdset> objects to represent a set of file descriptors to watch. File descriptors in readfds are watched to see if characters are ready to be read. File descriptors in writefds are watched if writing to them is ok. File descriptors in exceptfds are watched for exceptions. You can pass #f to one or more of those arguments if you don't care about watching the condition.

    timeout specifies maximum time sys-select waits for the condition change. It can be a real number, for number of microseconds, or a list of two integers, the first is the number of seconds and the second is the number of microseconds. If you pass #f, sys-select waits indefinitely.

    sys-select returns four values. The first value is a number of descriptors it detected status change. It may be zero if timeout expired. The second, third and fourth values are <fdset> object that contains a set of descriptors that changed status for reading, writing, and exception, respectively. If you passed #f to one or more of readfds, writefds and exceptfds, the corresponding return value is #f.

    sys-select! variant works the same as sys-select, except it modifies the passed <fdset> arguments. sys-select creates new <fdset> objects and doesn't modify its arguments.

    6.21.11 Miscellaneous system calls

    Function: sys-pause
    [POSIX] Suspends the process until it receives a signal whose action is to either execute a signal-catching function or to terminate the process. This function only returns when the signal-catching function returns. The returned value is undefined.

    Note that just calling pause() doesn't suffice the above semantics in Scheme-level. Internally this procedure calls sigsuspend() with the current signal mask.

    Function: sys-alarm seconds
    [POSIX] Arranges a SIGALRM signal to be delivered after seconds. The previous settings of the alarm clock is cancelled. Passing zero to seconds doesn't schedule new alarm. Returns the number of seconds remaining until previously scheduled alarm was due to be delivered (or zero if no alarm is active).

    Function: sys-sleep seconds
    [POSIX] Suspends the process until the specified number of seconds elapses, or the process receives a signal. Returns zero if it sleeps well, or the number of unslept seconds if it is woke up by a signal.

    To be porable across POSIX implementation, keep seconds less than 65536.

    Function: sys-nanosleep nanoseconds
    [POSIX] Suspends the process until the specified number of nanoseconds elapses, or the process receives a signal. The argument nanoseconds can be a <time> object (See section 6.21.8.2 SRFI time), or a real number. Returns #f if nanoseconds elapsed, or a <time> object that indicates the remaining time if sys-nanosleep is interrupted by a signal.
    ;wait for 0.5 sec
    (sys-nanosleep 500000000)
    
    ;wait for 1.3 sec
    (sys-nanosleep (make <time> :second 1 :nanosecond 300000000)
    

    Function: sys-random
    Function: sys-srandom seed
    A pseudo random number generator. sys-random returns a random number between 0 and a positive integer rand_max, inclusive. This is a straightforward interface to random(3). If the underlying system doesn't have random(3), lrand48(3) is used.

    sys-srandom sets the seed of the random number generator. It uses either srandom(3) or srand48(3), depending on the system.

    The intension of these functions are to provide an off-the-stock handy random number generator (RNG) for applications that doens't sensitive to the quality and/or speed of RNG. For serious statistics analysis, use Mersenne Twister RNG in math.mt-random module (See section 11.8 math.mt-random - Mersenne Twister Random number generator).

    Variable: RAND_MAX
    Bound to a positive integer that sys-random may return.

    7. Object system

    7.1 General Inquiry

    Function: class-of obj
    Returns a class metaobject of obj.

    Function: is-a? obj class
    Returns true if obj is an instance of class or an instance of descendants of class.

    7.2 Defining class

    A class is a first-class object in Gauche and you can create it on the fly at run-time using procedure calls. However, for convenience, a macro is defined to create a class and bind it globally.

    Macro: define-class name supers (slot-spec ...) option ...
    Creates a class object according to the arguments, and globally bind it to a variable name. This macro should be used at toplevel.

    Supers is a list of direct superclasses from which this class inherits. You can use multiple inheritance. See section 7.2.1 Multiple inheritance below, for the rule that determines precedence of inheritance chain.

    Slot-spec is a specification of a "slot", sometimes known as a "field" or an "instance variable" (but you can specify "class variable" in slot-spec as well). The simplest form of slot-spec is just a symbol, which names the slot. Or you can give a list, whose first element is a symbol and whose rest is an interleaved list of keywords and values. The list form not only defines a name of the slot but specifies behavior of the slot. See section 7.2.2 Slot specification, for details.

    Finally, option ... is an interleaved list of keywords and values, specifies how class object should be created. This macro recognizes one keyword, :metaclass, whose corresponding value is used for metaclass (class that instantiates another class). Other options are passed to the make method to create the class object. See section 7.6.3 Class instantiation, for the usage of metaclass.

    7.2.1 Multiple inheritance

    7.2.2 Slot specification

    7.3 Defining methods

    Macro: define-generic name

    Macro: define-method name specs body

    7.4 Creating Instance

    Generic Function: make class arg ...

    Method: make (class <class>) arg ...

    Method: make (class <method>) arg ...
    Method: make (class <generic>) arg ...

    Method: initialize (class <class>) initargs

    7.5 Accessing Instance

    Function: slot-ref obj slot

    Function: slot-set! obj slot

    Function: slot-bound? obj slot

    Function: slot-exists? slot

    Generic Function: slot-unbound

    Method: slot-unbound (class <class>) obj slot

    Generic Function: slot-missing

    Method: slot-missing (class <class>) obj slot &optional value

    Function: class-slot-ref class slot-name
    Function: class-slot-set! class slot-name obj

    7.6 Metaobject procotol

    7.6.1 System metaclasses

    Class: <top>

    Class: <class>

    Class: <generic>

    Class: <method>

    Class: <object>

    7.6.2 Class introspection

    7.6.2.1 Class metaobject

    Function: class-name class

    Function: class-precedence-list class

    Function: class-direct-supers class

    Function: class-direct-slots class

    Function: class-slots

    7.6.2.2 Slot definition

    Class: <slot-accessor>

    Function: class-slot-definition class slot-name

    Function: class-slot-accessor class slot-name

    Function: slot-definition-name slot-def
    Function: slot-definition-allocation slot

    Function: slot-definition-getter slot
    Function: slot-defininion-setter slot
    Function: slot-definition-accessor slot

    Function: slot-definition-options slot-def
    Function: slot-definition-option slot-def key &optional default

    7.6.3 Class instantiation

    Method: make (class <class>) &rest initargs

    7.6.4 Customizing slot access

    Generic Function: compute-slots

    Generic Function: compute-get-n-set

    Function: slot-ref-using-accessor obj slot-accessor
    Function: slot-set-using-accessor obj slot-accessor value

    7.6.5 Method instantiation

    Method: make (class <method>) &rest initargs

    7.6.6 Customizing method application

    Generic Function: apply-generic gf args

    Generic Function: sort-applicable-methods gf methods args

    Generic Function: method-more-specific? method1 method2 classes

    Generic Function: apply-methods gf methods args

    Generic Function: apply-method gf method build-next args

    8. Library modules - Overview

    In the following chapters, the library modules bundled with the Gauche distribution are explained. Those modules should generally be loaded and imported (usually using use - See section 4.11.3 Using modules, for details), unless otherwise noted.

    section 9. Library modules - Gauche extensions describes gauche.* modules, which are more or less considered the core features of Gauche but separated since less frequently used. (Some modules are rather ad-hoc, but here for historically reasons). The modules in this category include system APIs (e.g. gauche.fcntl, gauche.termios), networking (gauche.net), thread APIs (gauche.threads), and some high-level routines that are built on top of Gauche low-level core APIs (e.g. gauche.process, gauche.regexp).

    section 10. Library modules - SRFIs describes the modules that provides SRFI functionalities. Note that some of SRFI features are built in Gauche core and not listed here. See section 2.1 Standard conformance, for entire list of supported SRFIs.

    section 11. Library modules - Utilities describes the modules provides miscellaneous utility functions--including dbm-style database interface, filesystem utilities, network protocol utilities, and more.

    The following table summarizes naming categories of the modules, including external ones and planned ones.

    data.*
    Generic data structures (planned).
    dbm.*
    DBM interface
    gauche.*
    Stuffs more or less considered as Gauche core features.
    gl.*
    OpenGL binding and related libraries (external package).
    gtk.*
    GTk+ binding and related libraries (external package).
    file.*
    Manipulating files and directories.
    lang.*
    Language-related libraries, artificial and/or natural (planned).
    math.*
    Mathematics.
    compat.*
    Compatibility libraries
    rfc.*
    Implementations of net protocols defined in RFC's.
    srfi-*
    SRFI implementations.
    text.*
    Libraries dealing with text data.
    util.*
    Generic implementations of various algorithms.
    www.*
    Implementations of various protocols and formats mainly used in WWW.

    9. Library modules - Gauche extensions

    9.1 gauche.array - Arrays

    Module: gauche.array
    This module provides multi-dimensional array data type and operations. The primitive API follows SRFI-25. This module also defines several useful operations. This module also implements an external representation of arrays, using SRFI-10 mechanism.

    Each element of an N-dimensional array can be accessed by N integer indices, [ i_0 i_1 ... i_N-1 ]. An array has associated shape that knows lower-bound s_k and upper-bound e_k of index of each dimension, where s_k <= e_k, and the index i_k must satisfy s_k <= i_k < e_k. (Note: it is allowed to have s_k == e_k, but such array can't store any data. It is also allowed to have zero-dimensional array, that can store a single data.). The shape itself is a [ D x 2 ] array, where D is the dimension of the array which the shape represents.

    You can pass index to array access primitives in a few ways; each index can be passed as individual argument, or can be 'packed' in a vector or one-dimensional array. In the latter case, such a vector or an array is called an "index object". Using vector is efficient in Gauche when you iterate over the elements by changing the vector elements, for it won't involve memory allocation.

    Arrays can be compared by the equal? procedure. Equal? returns #t if two arrays have the same shape and their corresponding elements are the same in the sense of equal?.

    Internally, an array consists of a backing storage and a mapping procedure. A backing storage is an object of aggregate type that can be accessed by an integer index. A mapping procedure takes multi-dimensional indices (or index object) and returns a scalar index into the backing storage.

    Class: <array>

    Reader syntax: #,(<array> shape obj ...)
    An array is written out in this format. shape is a list of even number of integers, and each 2n-th integer and 2n+1-th integer specifies the inclusive lower-bound and exclusive upper-bound of n-th dimension, respectively. The following obj ... are the values in the array listed in row-major order.

    When read back, this syntax is read as an array with the same shape and content, so it is equal? to the original array.

    ; an array such that:
    ;   8 3 4
    ;   1 5 9
    ;   6 7 2
    #,(<array> (0 3 0 3) 8 3 4 1 5 9 6 7 2)
    
    ; a 4x4 identity matrix
    #,(<array> (0 4 0 4) 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)
    

    Function: array? obj
    [SRFI-25] Returns #t if obj is an array, #f otherwise.

    Function: make-array shape &optional init
    [SRFI-25] Creates an array of shape shape. Shape must be a [ D x 2 ] array, and for each k (0 <= k < D), the [ k 0 ] element must be less than or equal to the [ k 1] element. If init is given, all the elements are initialized by it. Otherwise, the initial value of the elements are undefined.
    (make-array (shape 0 2 0 2 0 2) 5)
     => #,(<array> (0 2 0 2 0 2) 5 5 5 5 5 5 5 5)
    

    Function: shape bound ...
    [SRFI-25] Takes even number of exact integer arguments, and returns a two-dimensional array that is suitable for representing the shape of an array.
    (shape 0 2 1 3 3 5)
     => #,(<array> (0 3 0 2) 0 1 3 2 3 5)
    
    (shape)
     => #,(<array> (0 0 0 2))
    

    Function: array shape init ...
    [SRFI-25] Creates an array of shape shape, initializing its elements by init ....
    (array (shape 0 2 1 3) 'a 'b 'c 'd)
     => #,(<array> (0 2 1 3) a b c d)
    

    Function: array-rank array
    [SRFI-25] Returns the number of dimensions of an array array.
    (array-rank (make-array (shape 0 2 0 2 0 2))) => 3
    (array-rank (make-array (shape))) => 0
    

    Function: array-shape array
    Returns a shape array of array.

    Function: array-start array dim
    Function: array-end array dim
    Function: array-length array dim
    [SRFI-25+] Array-start returns the inclusive lower bound of index of dim-th dimension of an array array. Array-end returns the exclusive upper bound. And array-length returns the difference between two. Array-start and array-end are defined in SRFI-25.
    (define a (make-array (shape 1 5 0 2)))
    
    (array-start a 0)  => 1
    (array-end a 0)    => 5
    (array-length a 0) => 4
    (array-start a 1)  => 0
    (array-end a 1)    => 2
    (array-length a 1) => 2
    

    Function: array-size array
    Returns the total number of elements in the array array.
    (array-size (make-array (shape 5 9 1 3))) => 8
    (array-size (make-array (shape))) => 1
    (array-size (make-array (shape 0 0 0 2))) => 0
    

    Function: array-ref array k ...
    Function: array-ref array index
    [SRFI-25] Gets the element of array array. In the first form, the element is specified by indices k .... In the second form, the element is specified by an index object index, which must be a vector or an one-dimensional array.

    Function: array-set! array k ... value
    Function: array-set! array index value
    [SRFI-25] Sets the element of array array to value. In the first form, the element is specified by indices k .... In the second form, the element is specified by an index object index, which must be a vector or an one-dimensional array.

    Function: share-array array shape proc
    [SRFI-25] Creates and returns a new array of shape shape, that shares the backing storage with the given array array. The procedure proc maps the indices of the new array to the indices to the original array, i.e. proc must be a n-ary procedure that returns m values, where n is the dimension of the new array and m is the one of the original array. Furthermore, proc must be an affine function; each mapping has to be a linear combination of input arguments plus optional constant. (Share-array optimizes the mapping function based on the affinity assumption, so proc won't be called every time the new array is accessed).

    Function: array-for-each-index array proc &optional index

    Function: shape-for-each shape proc &optional index

    Function: tabulate-array shape proc &optional index

    Function: array-retabulate! array shape proc &optional index
    Function: array-retabulate! array proc &optional index

    Function: array-map! array shape proc array0 array1 ...
    Function: array-map! array proc array0 array1 ...

    Function: array-map shape proc array0 array1 ...
    Function: array-map proc array0 array1 ...

    Function: array->vector array
    Function: array->list array

    9.2 gauche.charconv - Character Code Conversion

    Module: gauche.charconv
    This module defines a set of functions that converts character encoding schemes (CES) of the given data stream. This module also overloads Gauche's file stream creating functions (such as open-input-file and call-with-output-file) so that they accept :encoding keyword argument.

    As of release 0.5.6, Gauche natively supports conversions between typical Japanese character encodings: ISO2022JP, ISO2022JP-3, EUC-JP (EUC-JISX0213), Shift_JISX0213, UTF-8 (Unicode 3.2). Conversions between other encodings are handled by iconv(3). See section 9.2.1 Supported character encoding schemes, for details.

    9.2.1 Supported character encoding schemes

    A CES is represented by its name as a string. Case is ignored. There may be several aliases defined for a single encoding.

    You can check whether the specific conversion is supported on your system or not, by the following function.

    Function: ces-conversion-supported? from-ces to-ces
    Returns #t if conversion from the character encoding scheme (CES) from-ces to to-ces is supported in this system.

    Conversion between common japanese CESes (EUC_JP, Shift JIS, UTF-8 and ISO2022-JP) of the character set JIS X 0201 and JIS X 0213 is handled by Gauche's built-in algorithm (see below for details). When other CES name is given, Gauche uses iconv(3) if it is linked.

    When Gauche's conversion routine encounters a character that can't be mapped, it replaces the character for "geta mark" (U+3013) if it's a multibyte character in the input encoding, or for '?' if it's a singlebyte character in the input encoding. If that happens in iconv, handling of such character depends on iconv implementation (glibc implementation returns an error).

    If the conversion routine encounters an input sequence that is illegal in the input CES, an error is signalled.

    Details of Gauche's native conversion algorithm: Between EUC_JP, Shift JIS and ISO2022JP, Gauche uses arithmetic conversion whenever possible. This even maps the undefined codepoint properly. Between Unicode (UTF-8) and EUC_JP, Gauche uses lookup tables. Between Unicode and Shift JIS or ISO2022JP, Gauche converts the input CES to EUC_JP, then convert it to the output CES. If the same CES is specified for input and output, Gauche's conversion routine just copies input characters to output characters, without checking the validity of the encodings.

    EUC_JP, EUCJP, EUCJ, EUC_JISX0213
    Covers ASCII, JIS X 0201 kana, JIS X 0212 and JIS X 0213 character sets. JIS X 0212 character set is supported merely because it uses the code region JIS X 0213 doesn't use, and JIS X 0212 characters are not converted properly to Shift JIS and UTF-8. Use JIS X 0213.
    SJIFT_JIS, SHIFTJIS, SJIS
    Covers Shift_JISX0213, except that 0x5c and 0x7e is mapped to ASCII character set (REVERSE SOLIDUS and TILDE), instead of JIS X 0201 Roman (YEN SIGN and OVERLINE).
    UTF-8, UTF8
    Unicode 3.2. Note that some JIS X 0213 characters are mapped to Extension B (U+20000 and up). Some JIS X 0213 characters are mapped to two unicode characters (one base character plus a combining character).
    ISO2022JP, CSISO2022JP, ISO2022JP-1, ISO2022JP-2, ISO2022JP-3
    These encodings differ a bit (except ISO2022JP and CSISO2022JP, which are synonyms), but Gauche handles them same. If one of these CES is specified as input, Gauche recognizes escape sequences of any of CES. ISO2022JP-2 defines several non-Japanese escape sequences, and they are recognized by Gauche, but mapped to substitution character ('?' or geta mark). For output, Gauche assumes ISO2022JP first, and uses ISO2022JP-1 escape sequence to put JIS X 0212 character, or uses ISO2022JP-3 escape sequence to put JIS X 0213 plane 2 character. Thus, if the string contains only JIS X 0208 characters, the output is compatible to ISO2022JP. Precisely speaking, JIS X 0213 specifies some characters in JIS X 0208 codepoint that shouldn't be mixed with JIS X 0208 characters; Gauche output those characters as JIS X 0208 for compatibility. (This is the same policy as Emacs-Mule's iso2022jp-3-compatible mode).

    9.2.2 Autodetecting the encoding scheme

    There are cases that you don't know the CES of the input, but you know it is one of several possible encodings. The charconv module has a mechanism to guess the input encoding. There can be multiple algorithms, and each algorithm has the name. Right now, there's only one algorithm implemented:

    "*JP"
    To guess the character encoding from japanese text, among either ISO2022-JP(-1,2,3), EUCJP, SHIFT_JIS or UTF-8.

    This name can be used in place of CES name for some conversion functions.

    Function: ces-guess-from-string string scheme
    Guesses the CES of string by the character guessing scheme scheme (e.g. "*JP"). Returns CES name that can be used by other charconv functions. It may return #f if the guessing scheme finds no possible encoding in string. Note that if there may be more than one possible encoding in string, the guessing scheme returns one of them, usually in favor of the native CES.

    9.2.3 Conversion ports

    Function: open-input-conversion-port source from-code &keyword to-code buffer-size owner?
    Takes an input port source, which feeds characters encoded in from-code, and returns another input port, from which you can read characters encoded in to-code.

    If to-code is omitted, the native CES is assumed.

    buffer-size is used to allocate internal buffer size for conversion. The default size is about 1 kilobytes and it's suitable for typical cases.

    If you don't know the source's CES, you can specify CES guessing scheme, such as "*JP", in place of from-code. The conversion port tries to guess the encoding, by prefetching the data from source up to the buffer size. It signals an error if the code guessing routine finds no appropriate CES. If the guessing routine finds ambiguous input, however, it silently assume one of possible CES's, in favor of the native CES. Hence it is possible that the guessing is wrong if the buffer size is too small. The default size is usually enough for most text documents, but it may fail if the large text contains mostly ASCII characters and multibyte characters appear only at the very end of the document. To be sure for the worst case, you have to specify the buffer size large enough to hold entire text.

    By default, open-input-conversion-port leaves source open. If you specify true value to owner?, the function closes source after it reads EOF from the port.

    For example, the following code copies a file `unknown.txt' to a file `eucjp.txt', converting unknown japanese CES to EUC-JP.

    (call-with-output-file "eucjp.txt"
      (lambda (out)
        (copy-port (open-input-conversion-port
                     (open-input-file "unknown.txt")
                     "*jp"             ;guess code
                     :to-code "eucjp"
                     :owner? #t)       ;close unknown.txt afterwards
                   out)))
    

    Function: open-output-conversion-port sink to-code &keyword from-code buffer-size owner?
    Creates and returns an output port that converts given characters from from-code to to-code and feed to an output port sink. If from-code is omitted, the native CES is assumed. You can't specify a character guessing scheme (such as "*JP") to neither from-code nor to-code.

    buffer-size specifies the size of internal conversion buffer. The characters put to the returned port may stay in the buffer, until the port is explicity flushed (by flush) or the port is closed.

    By default, the returned port doesn't closes sink when itself is closed. If a keyword argument owner? is provided and true, however, it closes sink when it is closed.

    Function: ces-convert string from-code &optional to-code
    Convert string's character encoding from from-code to to-code, and returns the converted string. The returned string may be a byte-string if to-code is different from the native CES.

    from-code can be a name of character guessing scheme (e.g. "*JP"). when to-code is omitted, the native CES is assumed.

    9.2.4 Extended port procedures

    Function: open-input-file filename &keyword encoding conversion-buffer-size ...
    Function: call-with-input-file filename proc &keyword encoding conversion-buffer-size ...
    Function: with-input-from-file filename thunk &keyword encoding conversion-buffer-size ...
    Function: open-output-file filename &keyword encoding conversion-buffer-size ...
    Function: call-with-output-file filename proc &keyword encoding conversion-buffer-size ...
    Function: with-output-to-file filename thunk &keyword encoding conversion-buffer-size ...
    These Gauche built-in procedures are extended to accept two extra keyword arguments, encoding and conversion-buffer-size. (See section 6.18.3 File ports, for their default behavior).

    You can give a CES of the file filename to encoding, and the port automatically converts the file CES to the Gauche's native CES. You can use a CES guessing algorithm name for input file port.

    The keyword argument conversion-buffer-size has the same meaning as buffer-size of open-input-conversion-port.

    9.3 gauche.collection - Collection framework

    Module: gauche.collection
    This module provides a set of generic functions (GFs) that iterate over various collections. The Scheme standard [R5RS] has some iterative primitives such as map and for-each, and SRFI-1 (See section 10.2 srfi-1 - List library adds a rich set of such functions, but they work only on lists.

    Using the method dispatch of the object system, this module efficiently extends those functions for other collection classes such as vectors and hash tables. It also provides a simple way for user-defined class to adapt those opertaions. So far, the following operations are defined.

    Mapping
    fold, map, map-to, for-each
    Selection and searching
    find, filter, filter-to, remove, remove-to, partition, partition-to
    Conversion
    coerce-to
    Miscellaneous
    size-of, lazy-size-of
    Fundamental iterator creator
    call-with-iterator, call-with-builder, with-iterator, with-builder, call-with-iterators.

    Those operations work on collections and its subclass, sequences. A collection is a certain form of a set of objects that you can traverse all the object in it in a certain way. A sequence is a collection that all its elements are ordered, so that you can retrieve its element by index.

    The following Gauche built-in objects are treated as collections and/or sequences.

    <list>
    A sequence.
    <vector>
    A sequence.
    <string>
    A sequence (of characters)
    <hash-table>
    A collection. Each element is a pair of a key and a value.
    <s8vector>, <u8vector>, ... <f64vector>
    A sequence (methods defined in srfi-4 module, See section 10.4 srfi-4 - Homogeneous vectors).

    See section 9.18 gauche.sequence - Sequence framework, for it adds more sequence specific methods.

    The methods that needs to return a set of objects, i.e. map, filter, remove and partition. returns a list (or lists). The corresponding "-to" variant (map-to, filter-to, remove-to and partition-to. takes a collection class argument and returns the collection of the class.

    9.3.1 Mapping over collection

    Generic function: fold proc knil coll coll2 ...
    This is a natural extension of fold in SRFI-1 (See section 10.2.5 List fold, unfold & map).

    For each element Ei in the collection coll, proc is called as (proc Ei Ri-1), where Ri-1 is the result of (i-1)-th invocation of proc for i > 0, and R0 is knil. Returns the last invocation of proc.

    (fold + 0 '#(1 2 3 4)) => 10
    (fold cons '() "abc")  => (#\c #\b #\a)
    

    If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

    You can fold more than one collection, although it doesn't make much sense unless all of the collections are sequences. Suppose E(k, i) for i-th element of k-th collection. proc is called as

    (proc E(0,i) E(1,i) ... E(K-1,i) Ri-1)
    

    Different types of collections can be mixed together.

    (fold acons '() "abc" '#(1 2 3))
      => ((#\c 3) (#\b 2) (#\a 1))
    
    ;; calculates dot product of two vectors
    (fold (lambda (a b r) (+ (* a b) r)) 0
          '#(3 5 7) '#(2 4 6))
      => 68
    

    When more than one collection is given, fold terminates as soon as at least one of the collections exhausted.

    Generic function: map proc coll coll2 ...
    This extends the built-in map (See section 6.15.1 Procedures). Apply proc for each element in the collection coll, and returns a list of the results.

    If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

    If more than one collection is passed, proc is called with elements for each collection. In such case, map terminates as soon as at least one of the collection is exhausted. Note that passing more than one collection doesn't make much sense unless all the collections are sequences.

    (map (lambda (x) (* x 2)) '#(1 2 3))
      => #(2 4 6)
    
    (map char-upcase "abc")
      => (#\A #\B #\C)
    
    (map + '#(1 2 3) '#(4 5 6))
      => (5 7 9)
    

    map always returns a list. If you want to get the result in a different type of collection, use map-to described below. If you wonder why (map char-upcase "abc") doesn't return "ABC", read the discussion in the bottom of this subsection.

    Generic function: map-to class proc coll coll2 ...
    This works the same as map, except the result is returned in a collection of class class. Class must be a collection class and have a builder interface (See section 9.3.4 Fundamental iterator creators).
    (map-to <vector> + '#(1 2 3) '#(4 5 6))
      => #(5 7 9)
    
    (map-to <string> char-upcase "def")
      => "DEF"
    
    (map-to <vector> char=? "bed" "pet")
      => #(#f #t #f)
    

    Generic function: for-each proc coll coll2 ...
    Extension of built-in for-each (See section 6.15.1 Procedures). Applies proc for each elements in the collection(s). The result of proc is discarded. The return value of for-each is undefined.

    If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

    If more than one collection is passed, proc is called with elements for each collection. In such case, for-each terminates as soon as one of the collection is exhausted. Note that passing more than one collection doesn't make much sense unless all the collections are sequences.

    Generic Function: fold$ proc
    Generic Function: fold$ proc knil
    Generic Function: map$ proc
    Generic Function: for-each$ proc
    Partial-application version of fold, map and for-each.

    Discussion: It is debatable what type of collection map should return when it operates on the collections other than lists. It may seem more "natural" if (map * '#(1 2) '#(3 4)) returns a vector, and (map char-upcase "abc") returns a string.

    Although such interface seems work for simple cases, it'll become problematic for more general cases. What type of collection should be returned if a string and a vector are passed? Furthermore, some collection may only have iterator interface but no builder interface, so that the result can't be coerced to the argument type (suppose you're mapping over database records, for example). And Scheme programmers are used to think map returns a list, and the result of map are applied to the procedures that takes list everywhere.

    So I decided to add another method, map-to, to specify the return type explicitly The idea of passing the return type is taken from CommonLisp's map function, but taking a class metaobject, map-to is much flexible to extend using method dispatch. This protocol ("-to" variant takes a class metaobject for the result collection) is used thoughout the collection framework.

    9.3.2 Selection and searching in collection

    Generic function: find pred coll
    Applies pred for each element of a collection coll until pred returns a true value. Returns the element on which pred returned a true value, or #f if no element satisfies pred.

    If coll is a sequence, it is guaranteed that pred is applied in order. Otherwise the order of application is undefined. Returns a list of elements of collection coll that satisfies the predicate pred. If the collection is a sequence, the order is preserved in the result.

    (filter char-upper-case? "Hello, World")
      => (#\H #\W)
    (filter even? '#(1 2 3 4)) => (2 4)
    

    Generic function: filter-to class pred coll
    Same as filter, but the result is returned as a collection of class class.
    (filter-to <vector> even? '#(1 2 3 4)) => #(2 4)
    (filter-to <string> char-upper-case? "Hello, World") 
      => "HW"
    

    Generic function: remove pred coll
    Returns a list of elements of collection coll that does not satisfy the predicate pred. If the collection is a sequence, the order is preserved in the result.
    (remove char-upper-case? "Hello, World")
      => (#\e #\l #\l #\o #\, #\space #\o #\r #\l #\d)
    (remove even? '#(1 2 3 4)) => (1 3)
    

    Generic function: remove-to class pred coll
    Same as remove, but the result is returned as a collection of class class.
    (remove-to <vector> even? '#(1 2 3 4)) => #(1 3)
    (remove-to <string> char-upper-case? "Hello, World") 
      => "ello, orld"
    

    Generic function: partition pred coll
    Does filter and remove the same time. Returns two lists, the first consists of elements of the collection coll that satisfies the predicate pred, and the second consists of elements that doesn't.
    (partition char-upper-case? "PuPu")
      => (#\P #\P) and (#\u #\u)
    (partition even? '#(1 2 3 4))
      => (2 4) and (1 3)
    

    Generic function: partition-to class pred coll
    Same as partition, except the results are returned in the collections of class class.
    (partition-to <string> char-upper-case? "PuPu")
      => "PP" and "uu"
    (partition-to <vector> even? '#(1 2 3 4))
      => #(2 4) and #(1 3)
    

    9.3.3 Miscellaneous operations on collection

    Generic function: size-of coll
    Returns the number of elements in the collection. Default method iterates over the collection to calculate the size, which is not very efficient and may diverge if the collection is infinite. Some collection classes overload the method for faster calculation.

    Generic function: lazy-size-of coll
    Returns either the size of the collection, or a promise to calculate it. The intent of this method is to avoid size calculation if it is expensive. In some cases, the caller wants to have size just for optimization, and it is not desirable to spend time to calculate the size. Such caller uses this method and just discards the information if it is a promise.

    Generic function: coerce-to class coll
    Convert a collection coll to another collection which is an instance of class. If coll is a sequence and class is a sequence class, the order is preserved.
    (coerce-to <vector> '(1 2 3 4))
      => #(1 2 3 4)
    
    (coerce-to <string> '#(#\a #\b #\c))
      => "abc"
    

    9.3.4 Fundamental iterator creators

    These are fundamental methods on which all the rest of iterative method are built. The method interface is not intended to be called from general code, but suitable for building other iterator construct. The reason why I chose this interface as fundamental methods are explained at the bottom of this subsection.

    Generic function: call-with-iterator collection proc &keyword start
    A fundamental iterator creator. This creates two procedures from collection, both take no argument, and then call proc with those two procedures. The first procedure is terminate predicate, which returns #t if the iteration is exhausted, or #f if there are still elements to be visited. The second procedure is an incrementer, which returns one element from the collection and sets the internal pointer to the next element. The behavior is undefined if you call the incrementer after the terminate predicate returns #t.

    If the collection is actually a sequence, the incrementer is guaranteed to return elements in order, from 0-th element to the last element. If a keyword argument start is given, however, the iteration begins from start-th element and ends at the last element. If the collection is not a sequence, the iteration order is arbtrary, and start argument has no effect.

    An implementation of call-with-iterator method may limit the extent of the iterator inside the dynamic scope of the method. For example, it allocates some resource (e.g. connect to a database) before calling proc, and deallocates it (e.g. disconnect from a database) after proc returns.

    This method returns the value(s) proc returns.

    (call-with-iterator '(1 2 3 4 5)
      (lambda (end? next)
        (do ((odd-nums 0))
            ((end?) odd-nums)
          (when (odd? (next)) (inc! odd-nums)))))
     => 3
    

    See also with-iterator macro below, for it is easier to use.

    Macro: with-iterator (collection end? next args ...) body ...
    A convenience macro to call call-with-iterator.
    (with-iterator (coll end? next args ...) body ...)
     ==
    (call-with-iterator coll
      (lambda (end? next) body ...)
       args ...)
    

    Function: call-with-iterators collections proc
    A helper function to write n-ary iterator method. This function applies call-with-iterator for each collections, and makes two lists, the first consists of terminate predicates and the second of incrementers. Then proc is called with those two lists. Returns whatever proc returns.

    Generic function: call-with-builder collection-class proc &keyword size
    A fundamental builder creator. Builder is a way to construct a collection incrementally. Not all collection classes provide this method.

    Collection-class is a class of the collection to be built. This method creates two procedures, adder and getter, then calls proc with those procedures. Adder procedure takes one argument and adds it to the collection being built. Getter takes no argument and returns a built collection object. The effect is undefined if adder is called after getter is called.

    A keyword argument size may be specified if the size of the result collection is known. Certain collections may be built much more efficiently if the size is known; other collections may just ignore it. The behavior is undefined if more than size elements are added, or the collection is retrieved before size elements are accumulated.

    If the collection class is actually a sequence class, adder is guaranteed to add elements in order. Otherwise, the order of elements are insignificant.

    Some collection class may take more keyword arguments to initialize the collection.

    This method returns the value(s) proc returned.

    (call-with-builder <list>
      (lambda (add! get)
        (add! 'a) (add! 'b) (add! 'c) (get)))
     => (a b c)
    
    (call-with-builder <vector>
      (lambda (add! get)
        (add! 'a) (add! 'b) (add! 'c) (get)))
     => #(a b c)
    

    See also with-builder macro below, for it is much easier to use.

    Macro: with-builder (collection add! get args ...) body ...
    A convenience macro to call call-with-builder.
    (with-builder (coll add! get args ...) body ...)
     ==
    (call-with-builder coll
      (lambda (add! get) body ...)
      args ...)
    

    Discussion: Other iterator methods are built on top of call-with-iterator and call-with-builder. By implementing those methods, you can easily adapt your own collection class to all of those iterative operations. Optionally you can overload some of higher-level methods for efficiency.

    It is debatable that which set of operations should be primitives. I chose call-with-iterator style for efficiency of the applications I see most. The following is a discussion of other possible primitive iterators.

    fold
    It is possible to make fold a primitive method, and build other iterator method on top of it. Collection-specific iterating states can be kept in the stack of fold, thus it runs efficiently. The method to optimize a procedure that uses fold as a basic iterator construct. However, it is rather cumbersome to derive generator-style interface from it. It is also tricky to iterate irregulary over more than one collections.
    CPS
    Passes iteratee the continuation procedure that continues the iteration. The iteratee just returns when it want to terminate the iteration. It has resource management problem described in Oleg Kiselyov's article (@xref{oleg2,,OLEG2}).
    Iterator object
    Like C++ iterator or Common Lisp generator. Easy to write loop. The problem is that every call of checking termination or getting next element must be dispatched.
    Series
    Common Lisp's series can be very efficient if the compiler can statically analyze the usage of series. Unfortunately it is not the case in Gauche. Even if it could, the extension mechanism doesn't blend well with Gauche's object system.
    Macros
    Iterator can be implemented as macros, and that will be very efficient; e.g. Scheme48's iterator macro. It uses macros to extend, however, and that doesn't blend well with Gauche's object system.

    The current implementation is close to the iterator object approach, but using closures instead of iterator objects so that avoiding dispatching in the inner loop. Also it allows the iterator implementator to take care of the resource problem.

    9.3.5 Implementing collections

    The minimum requirements of the collection class implementation is as follow:

    This makes iterator methods such as map, for-each, find and filter to work.

    In order to make the constructive methods (e.g. map-to to create your collection), you have to implement call-with-builder method as well. Note that call-with-builder method must work a sort of class method, dispatched by class, rather than normal method dispatched by instance. In Gauche, you can implement it by using a metaclass. Then the minimal code will look like this:

    (define-class <your-collection-meta> (<class>) ())
    
    (define-class <your-collection> (<collection>)
     (...) ;; slots
     :metaclass <your-collection-meta>)
    
    (define-method call-with-iterator
        ((coll <your-collection>) proc . options)
      ...
      )
    
    (define-method call-with-builder
         ((coll <your-collection-meta>) proc . options)
      ...
      )
    

    Optionally, you can overload other generic functions to optimize performance.

    9.4 gauche.config - Configuration parameters

    Module: gauche.config
    This module provides a simple wrapper to obtain configuration parameters via gauche-config program.

    The gauche-config program is a simple shell script that records various parameters given at the configuration time of Gauche.

    Function: gauche-config option
    Calls gauche-config with the option option, and returns the string of the parameter value. It is an error to give the option gauche-config doesn't understand.

    See the manpage of gauche-config, or run gauche-config without any argument from the shell, to find out the valid options.

    (gauche-config "--cc")
      => "gcc"
    (gauche-config "-L")
      => "-L/usr/lib/gauche/0.6.5/i686-pc-linux-gnu"
    (gauche-config "-l")
      => "-ldl -lcrypt -lm -lpthread"
    

    9.5 gauche.fcntl - Low-level file operations

    Module: gauche.fcntl
    Provides an interface to fcntl(2), including advisory file locking.

    Function: sys-fcntl port-or-fd operation &optional arg
    Performs certain operation on the file specfied by port-or-fd, which should be a port object or an integer that specifies a system file descriptor. If it is a port, it must be associated to the opened file.

    The operation is specified by an integer operation. Several variables are defined for valid operation.

    F_GETFD
    Returns flags associated to the file descriptor of port-or-fd. The optional argument arg is not used. The return value is an integer whose definition is system specific, except one flag, FD_CLOEXEC, which indicates the file descriptor should be closed on exec.
    F_SETFD
    Sets the file descriptor flags given as arg to port-or-fd. For example, the portable way of setting FL_CLOEXEC flag is as follows:
    (sys-fcntl port F_SETFD
              (logior FD_CLOEXEC
                      (sys-fcntl port F_GETFD)))
    
    F_GETFL
    Returns flags associated to the open files specified by port-or-fd. The flags includes the following information:
    • File access mode. When masked by O_ACCMODE, it's either one of O_RDONLY, O_WRONLY or O_RDWR.
    • File creation options. O_CREAT, O_EXCL and/or O_TRUNC.
    • Whether appending is allowed or not, by O_APPEND
    • Whether I/O is blocking or non-blocking, by O_NONBLOCK.
    • Whether it grabs terminal control, by O_NOCTTY.
    The system may define system-specific flags.
    F_SETFL
    Sets flags to the open files specified by port-or-fd. Among the flags listed above, only O_NONBLOCK and O_APPEND can be changed. Note that F_GETFD/F_SETFD concern flags associated to the file descriptor itself, while F_GETFL/F_SETFL concern flags associated to the opened file itself. This makes difference when more than one file descriptor points to the same opened file.
    F_DUPFD
    Creates new file descriptor that points to the same file referred by port-or-fd. An integer must be provided as arg, and that specifies the minimum value of file descriptor to be assigned.
    F_GETLK
    The third argument must be provided and be an instance of <sys-flock> object described below. It searches the lock information specified by arg, and modifies arg accordingly.
    F_SETLK
    F_SETLKW
    The third argument must be provided and be an instance of <sys-flock> object described below. Sets the advisory file lock according to arg. If the lock is successfully obtained, #t is returned. If the other process has the lock conflicting the request, F_SETLK returns #f, while F_SETLKW waits until the lock is available.

    Other value for operation causes an error.

    Builtin Class: <sys-flock>
    A structure represents POSIX advisory record locking. Advisory record locking means the system may not prevents the process from operating on files that it doesn't have an appropriate lock. All the processes are expected to use fcntl to check locks before it operates on the files that may be shared.

    The following slots are defined.

    Instance Variable: <sys-flock> type
    An integer represents lock type. Following variables are predefined for the valid values:
    F_RDLCK
    Read locking
    F_WRLCK
    Write locking
    F_UNLCK
    To remove a lock by F_SETLK, or to indicate the record is not locked by F_GETLK.

    Instance Variable: <sys-flock> whence
    Indicates from where start is measured.

    Instance Variable: <sys-flock> start
    The offset of beginning of the locked region.

    Instance Variable: <sys-flock> len
    The number of bytes to lock. Zero means "until EOF".

    Instance Variable: <sys-flock> pid
    An integer process id that holding the lock; used only by F_GETLK.

    9.6 gauche.interactive - Utilities for interactive session

    Module: gauche.interactive
    Provides useful utilities for the interactive session.

    This module is automatically loaded when you run gosh interactively.

    Macro: apropos pattern &optional module
    Show a list of defined variables whose name matches pattern. If you give a module or a module name module, only the variables defined in that module are listed. Without module, the variables "visible" from the current module are listed.

    pattern may be a symbol or a regexp object. If it is a symbol, the variables whose name contains the substring that matches the symbol's name are listed. If it is a regexp object, the variables whose name matches the regexp are listed.

    Some examples:

    ;; List variables that contains "string" in their name
    (apropos 'string)
    
    ;; Search in srfi-14 module
    (apropos 'char 'srfi-14)
    

    Generic Function: describe obj
    Generic Function: d obj
    Prints the detail information about a Scheme object obj. The default method shows obj's class, and if it has any slots, the list of slot names and their values. You can specialize this method for customized display.

    Function: info symbol
    Displays a page of Gauche's info file that contains definition of the function or syntax specified by symbol. If an environment variable INFOPATH is defined, this function searches for the info file from the directories in it. Otherwise, this function guesses info file location from the gosh's library directory. If the info file can't be found, an error is signalled. If the info file is found, but symbol is not in its index, an error is signalled as well. So this function doesn't work if you haven't installed info file.

    If the current output port is a tty, the info page is displayed by a paging software. If an environment variable PAGER is defined, it is used as a paging software. Otherwise, this function looks for less and more in this order from the directories in PATH. If none of them is found, or the output port is not a tty, this function just displays the page.

    The first invocation of this function in a session takes some time to parse the info file.

    9.7 gauche.listener - Listener

    Module: gauche.listener
    This module provides a convenient way to enable multiple read-eval-print loop (repl) concurrently.

    An obvious way to run multiple repls is to use threads; creating as many threads as sessions and calling read-eval-print-loop (See section 6.17 Eval and repl) from each thread. Nevertheless, sometimes single threaded implementation is preferred. For instance, you're using a library which is not MT-safe, or your application already uses select/poll-based dispatching mechanism.

    To implement repl in the single-threaded selection-base application, usually you register a handler that is called when data is available in the listening port. The handler reads the data and add them into a buffer. Then it examines if the data in the buffer consists a complete expression, and if so, it reads the expression from the buffer, evaluates it, then prints the result to the reporting port. The <listener> class in this module provides this handler mechanism, so all you need to do is to register the handler to your dispatching mechanism.

    Note: it may also be desirable to buffer the output sometimes, but the current version doesn't implement it.

    Class: <listener>
    An object that maintains the state of a repl session. It has many external slots to customize its behavior. Those slot values can be set at construction time by using the keyword of the same name as the slot, or can be set by slot-set! afterwards. However, most of them should be set before calling listener-read-hander.

    Instance Variable: <listener> input-port
    Specifies the input port from which the listener get the input. The default value is the current input port when the object is constructed.

    Instance Variable: <listener> output-port
    Specifies the output port to which the listener output will go. The default value is the current output port when the object is constructed.

    Instance Variable: <listener> error-port
    Specifies the output port to which the listener's error messages will go. The default value is the current error port when the object is constructed.

    Instance Variable: <listener> reader
    A procedure with no arguments. It should read a Scheme expression from the current input port when called. The default value is system's read procedure.

    Instance Variable: <listener> evaluator
    A procedure that takes two arguments, a Scheme expression and an environment specifier. It should evaluate the expression in the given environment and returns zero or more value(s). The default value is system's eval procedure.

    Instance Variable: <listener> printer
    A procedure that takes zero or more argument(s) and prints them out to the current output port. The default value is a procedure that prints each value by write, followed by a newline.

    Instance Variable: <listener> prompter
    A procedure with no arguments. It should prints a prompt to the current output port. The output is flushed by the listener object so this procedure doesn't need to care about it. The default procedure prints "listener> ".

    Instance Variable: <listener> environment
    An environment specifier where the expressions will be evaluated. The default value is the value returned by (interaction-environment).

    Instance Variable: <listener> finalizer
    A thunk that will be called when EOF is read from input-port. It can be #f if no such procedure is needed. The default value is #f.

    Instance Variable: <listener> error-handler
    A procedure that takes one argument, an error exception. It is called when an error occurs during read-eval-print stage, with the same dynamic environment as the error is signalled. The default value is a procedure that simply prints the error exception by report-error.

    Method: listener-read-handler (listener <listener>)
    Returns a thunk that is to be called when a data is available from input-port of the listener.

    The returned thunk (read handler) does the following steps. Note that the first prompt is not printed by this procedure. See listener-show-prompt below.

    1. Reads available data from input-port and appends it to the listener's internal buffer.
    2. Scans the buffer to see if it has a complete S-expression. If not, returns.
    3. Reads the S-expression from the buffer. The read data is removed from the buffer.
    4. Evaluates the S-expression, then prints the result to output-port.
    5. Prints the prompt by prompter procedure to output-port, then flush output-port.
    6. Repeats from 2.

    Method: listener-show-prompt (listener <listener>)
    Shows a prompt to the listener's output port, by using listener's prompter procedure. Usually you want to use this procedure to print the first prompt, for instance, when the client is connected to the listener socket.

    Function: complete-sexp? str
    Returns #t if str contains a complete S-expression. This utility procedure is exported as well, since it might be useful for other purposes.

    Note that this procedure only checks syntax of the expressions, and doesn't rule out erroneous expressions (such as containing invalid character name, unregistered SRFI-10 tag, etc.). This procedure may raise an error if the input contains '#<' character sequence.

    The following code snippet opens a server socket, and opens a Scheme interactive session when a client is connected. (Note: this code is just for demonstration. Do not run this program on the machine accessible from outside network!)

    (use gauche.net)
    (use gauche.selector)
    (use gauche.listener)
    
    (define (scheme-server port)
      (let ((selector (make <selector>))
            (server   (make-server-socket 'inet port :reuse-addr? #t))
            (cid      0))
    
        (define (accept-handler sock flag)
          (let* ((client (socket-accept server))
                 (id     cid)
                 (input  (socket-input-port client :buffering :none))
                 (output (socket-output-port client))
                 (finalize (lambda ()
                             (selector-delete! selector input #f #f)
                             (socket-close client)
                             (format #t "client #~a disconnected\n" id)))
                 (listener (make <listener>
                             :input-port input
                             :output-port output
                             :error-port output
                             :prompter (lambda () (format #t "client[~a]> " id))
                             :finalizer finalize))
                 (handler (listener-read-handler listener))
                 )
            (format #t "client #~a from ~a\n" cid (socket-address client))
            (inc! cid)
            (listener-show-prompt listener)
            (selector-add! selector input (lambda _ (handler)) '(r))))
    
        (selector-add! selector
                       (socket-fd server)
                       accept-handler
                       '(r))
        (format #t "scheme server started on port ~s\n" port)
        (do () (#f) (selector-select selector))))
    

    9.8 gauche.logger - User-level logging

    Module: gauche.logger
    Provides a simple interface to log the program's activity. The information can be written to the specified file, or to the system logger using syslog(3). When a file is used, syslog-like prefix string is added to each message, which is configurable. It also takes care of locking of the file.

    Class: <log-drain>
    Represents the destination of log messages. There's one implicit global <log-drain> instance, which is used by default. However, you can create as many instances by make method as you want, in case if you want to log to more than one destination.

    Instance Variable: <log-drain> path
    Path of the log file. It can be also #t, which means the current error port, or #f, which makes log-format to return the formatted message but not write to any log files, or a symbol syslog, which means the messages are sent to the system logger.

    By default, this slot is #f.

    Instance Variable: <log-drain> prefix
    Specifies the prefix string that is attached to the beginning of every message. If the message spans to several lines, the prefix is attached to each line. The value of this slot can also be a procedure that takes <log-drain> object and returns a string to be used as the prefix. The procedure is called every time prefix is needed.

    When the path slot is a symbol syslog, the value of this slot is ignored. System logger will attach an appropriate prefix.

    When the value of the prefix slot is a string, the following character sequences have special meanings and replaced by log-format for appropriate information when written out.

    ~T
    Current time, in the format of "Mmm DD hh:mm:ss" where "Mmm" is an abbreviated month, "DD" is the day of month, "hh", "mm" and "ss" are hours (in 24 hour basis), minutes and seconds, respectively. This format is compatible with system logs.
    ~Y
    Current 4-digit year.
    ~P
    The program name. The default value is the basename of *program-name* (See section 3.4 Writing Scheme scripts), but you can change it by the program-name slot described below.
    ~$
    The process id of this program.
    ~U
    The name of the effective user of the process.
    ~H
    The hostname the process is running.

    The default value of this slot is "~T ~P[~$]: ". For example, if a string "this is a log message.\nline 2\nline 3" is given as the message, it produces something like the following log entry.

    Sep  1 17:30:23 myprogram[441]: this is a log message
    Sep  1 17:30:23 myprogram[441]: line 2
    Sep  1 17:30:23 myprogram[441]: line 3
    

    Instance Variable: <log-drain> program-name
    Specifies the program name written by ~P directive of the prefix slot.

    Instance Variable: <log-drain> syslog-option
    Instance Variable: <log-drain> syslog-facility
    Instance Variable: <log-drain> syslog-priority
    The value of these slots are used when the destination of the drain is the system logger. See section 9.19 gauche.syslog - Syslog, for the detailed information about these values. The default values of these slots are LOG_PID, LOG_USER and LOG_INFO, respectively.

    Function: log-open path &keyword prefix program-name
    Sets the destination of the default log message to the path path. It can be a string or a boolean, as described above. You can also set prefix and program name by corresponding keyword arguments.

    Despite its name, this function doesn't open the specified file immediately. The file is opened and closed every time log-format is called.

    Method: log-format (format <string>) arg ...
    Method: log-format (drain <log-drain>) (format <string>) arg ...
    Formats a log message by format and arg ..., by using format (See section 6.18.7 Output). In the first form, the output goes to the default destination. In the second form, the output goes to the specfied drain.

    The file is opened and closed every time. You can safely move the log file while your program that touches the log file is running. Also log-format acquires a write lock of the log file by sys-fcntl (See section 9.5 gauche.fcntl - Low-level file operations).

    If the first form of log-format is called before log-open is called, log-format does nothing. It is useful to embed debug stubs in your code; once your code is past the debugging stage, you just comment out log-open and the code runs without logging.

    9.9 gauche.mop.singleton - Singleton

    Module: gauche.mop.singleton
    Provides a metaclass to define a singleton class.

    Class: <singleton-meta>
    Creates a singleton class. A singleton class is a class that is guaranteed to create only one instance. The first invocation of make creates the single instance, and further attempt of creation returns the same instance.
    (define-class single () () :metaclass <singleton-meta>)
    
    (define a (make single))
    (define b (make single))
    
    (eq? a b) => #t
    

    The slots of the instance are initialized at the first invocation of make. Initargs of make are effective only in the fist invocation, and ignored in the subsequent invocation.

    Method: instance-of (class <singleton-meta>) &rest initargs
    This method just calls make with the passed arguments. It is more obvious in the program that you're dealing with singleton.

    Class: <singleton-mixin>
    An instance of <singleton-meta>. Instead of specifying <singleton-meta> as the :metaclass argument of define-class, you can inherit this class to give your class the property of singleton.

    9.10 gauche.mop.validator - Slot with validator

    Module: gauche.mop.validator
    Provides a metaclass that adds :validator slot option.

    Class: <validator-meta>
    This metaclass adds a feature that the class can validate a value before being set to the slot. For example, if you want to guarantee that a certain slot always holds a string value, you can make a procedure be called before the slot is modified, either by slot-ref or by a setter method. In the procedure you can either rejects a value except string, or coerce the value to a string.

    The validator procedure can be set per each slot by using :validator slot option. The procedure takes two values, the instance and the value to be set. Whatever the procedure returns is set to the actual slot value. See the following example:

    (define-class <v> ()
      ((a :accessor a-of
          :validator (lambda (obj value) (x->string value)))
       (b :accessor b-of
          :validator (lambda (obj value)
                       (if (integer? value)
                           value
                           (error "integer required for slot b")))))
      :metaclass <validator-meta>)
    
    (define v (make <v>))
    (slot-set! v 'a 'foo)
    (slot-ref v 'a) => "foo"
    
    (set! (a-of v) 1234)
    (a-of v) => "1234"
    
    (slot-set! v 'b 55)
    (slot-ref v 'b) => 55
    
    (slot-set! v 'b 3.4) => error
    (set! (b-of v) 3.4)  => error
    

    You can specify default slot value (:init-value etc.) with :validator. In that case, the initialization method of the instance calls the validator with the specified default value, if :init-keyword is not given.

    (define-class <v> ()
      ((a :initform 'foo :init-keyword :a
          :validator (lambda (obj value) (x->string value)))))
    
    (slot-ref (make <v>) 'a)        => "foo"
    (slot-ref (make <v> :a 555) 'a) => "555"
    

    It looks similar to the virtual slot, but note that a slot with validator has an actual storage in the instance, while a virtual slot doesn't.

    It is also a good example of customizing how the slots are accessed using the metaobject protocol. This feature is implemented by only a dozen lines of code.

    9.11 gauche.net - Networking

    Module: gauche.net
    Provides a set of functions necessary for network communications based on BSD socket interface.

    The API is provided in two different levels. Lower level routines reflect traditional BSD socket interface, such as bind(2). Higher level routines provides more convenient way to create typical connection-oriented server/client sockets.

    This module also provides APIs to obtain various information about hostnames, service ports, and protocols.

    9.11.1 Socket address

    Builtin Class: <sockaddr>
    An abstract base class of socket addresses. Each socket address family is implemented as a subclass of this class.

    Although socket addresses are built-in classes, you can use make method to create an instance of a specific socket address family.

    Generic Function: sockaddr-family addr
    Returns a symbol that indicates the family of the socket address addr.

    Generic Function: sockaddr-name addr
    Returns a string which represents the content of the socket address addr.

    Builtin Class: <sockaddr-in>
    AF_INET family socket address. To create an instance of this class, use make method as follows:
    (make <sockaddr-in> :host host :port port)
    

    host can be a string, or one of the keywords :any, :broadcast, :none or :loopback. If it is a string, it is either a host name or a dotted IP notation. Gauche uses gethostbyname(3) to obtain the actual IP address from host parameter. If it is a keyword :any, or :broadcast, the address uses INADDR_ANY, or INADDR_BROADCAST respectively. The keyword :loopback is a synonym to the IPv4 loopback address "127.0.0.1".

    port must be a positive integer indicating the port number.

    Method: sockaddr-family (addr <sockaddr-in>)
    Returns a symbol inet.

    Method: sockaddr-name (addr <sockaddr-in>)
    Returns a string in the form "a.b.c.d:port", where "a.b.c.d" is dotted decimal notion of the IP address and port is the port number.

    Builtin Class: <sockaddr-un>
    AF_UNIX family socket address. To create an instance of this class, use make method as follows:
    (make <sockaddr-un> :path path)
    

    path must be a string specifying pathname of the socket.

    Method: sockaddr-family (addr <sockaddr-un>)
    Returns a symbol unix.

    Method: sockaddr-name (addr <sockaddr-un>)
    Returns a pathname of the socket address.

    9.11.2 High-level network functions

    Builtin Class: <socket>
    Abstracts a socket, a communication endpoint.

    For a connection-oriented socket, you can access the communication channel by two ports associated to the socket, one for input and another for output. socket-input-port and socket-output-port returns those ports, respectively.

    The following two functions are convenient ways to create a connection-oriented socket. Those functions are to provide an easy methods for typical cases, but have less control. If you need more than these functions provide, use low-level interface.

    Function: make-client-socket &optional address-spec ...
    Creates and returns a client socket, connected to the address specified by address-spec ....
    (make-client-socket 'unix path)
    The client socket is connected to the unix domain server socket of addreess path.
    (make-client-socket 'inet host port)
    The client socket is connected to the inet domain server socket with hostname host and port port. TCP protocol is assumed. host can be either a dotted decimal notation of IPv4 address, or a hostname. port must be an exact integer.
    (make-client-socket host port)
    This works the same as above. This form is for compatibility with STk.

    This function raises an error if it cannot create a socket, or cannot connect to the specified address.

    (make-client-socket 'inet "www.w3.com" 80)
      => ;a socket connected to www.w3.com, port 80
    (make-client-socket "127.0.0.1" 23)
      => ;a socket connected to localhost, port 23
    (make-client-socket 'unix "/tmp/.sock"
      => ;a socket connected to a unix domain socket "/tmp/.sock"
    

    Function: make-server-socket &optional address-spec ...
    Creates and returns a server socket, listening the address specified by address-spec.
    (make-server-socket 'unix path)
    The socket is bound to a unix domain socket with a name path.
    (make-server-socket 'inet port [:reuse-addr? flag])
    The socket is bound to an inet domain TCP socket, listening port port, which must be a non-negative exact integer. If port is zero, the system assigns one of available port numbers. If a keyword argument reuse-addr? is given and true, SO_REUSEADDR option is set to the socket before bound to the port. This allows the process to bind the server socket immediately after other process releases the port.
    (make-server-socket port [:reuse-addr? flag])
    This is a synonym to the above form. This form is backward-compatible with STk's make-server-socket.
    (make-server-socket 'inet 8080)
      => #<socket (listen "0.0.0.0:8080")>
    (make-server-socket 8080)
      => #<socket (listen "0.0.0.0:8080")>
    (make-server-socket 'inet 0)
      => #<socket (listen "0.0.0.0:35628")>
    (make-server-socket 'unix "/tmp/.sock")
      => #<socket (listen "/tmp/.sock")>
    

    Several accessors are available on the returned socket object.

    Function: socket-address socket
    Returns a socket address associated with socket. If no address has been associated to the socket, #f is returned.

    Function: socket-input-port socket &keyword (buffering :modest)
    Function: socket-output-port socket &keyword (buffering :line)
    Returns an input and output port associated with socket, respectively.

    The keyword argument buffering specifies the buffering mode of the port. See section 6.18.3 File ports, for explanation of the buffering mode.

    Function: socket-close socket
    Closes socket. All the ports associated to socket are closed as well. If the socket is connected, it is shut down before closing.

    Function: call-with-client-socket socket proc
    socket must be a connected client socket. proc is called with two arguments, an input port that reads from the socket and an output port that writes to the socket. The socket is closed after proc returns or proc raises an error.

    This is an example of usage of high-level socket functions, a very simple http client.

    #!/usr/bin/env gosh
    (use gauche.regexp)
    (use gauche.net)
    
    (define (usage)
      (display "Usage: swget url\n" (current-error-port))
      (exit 1))
    
    ;; Returns three values: host, port, and path.
    (define (parse-url url)
      (rxmatch-let (rxmatch #/^http:\/\/([-A-Za-z\d.]+)(:(\d+))?(\/.*)?/ url)
          (#f host #f port path)
        (values host port path)))
    
    (define (get url)
      (receive (host port path) (parse-url url)
        (call-with-client-socket
            (make-client-socket 'inet host (string->number (or port "80")))
          (lambda (in out)
            (format out "GET ~a HTTP/1.0\r\n" path)
            (format out "host: ~a\r\n\r\n" host)
            (flush out)
            (copy-port in (current-output-port))))))
    
    (define (main args)
      (if (= (length args) 2)
          (get (cadr args))
          (usage))
      0)
    

    9.11.3 Low-level socket interface

    These functions provide APIs similar to the system calls. Those who are familiar to programming with socket APIs will find these functions useful since you can have more detailed control over the sockets.

    Function: make-socket domain type &optional protocol
    Returns a socket with specified parameters.

    Variable: PF_UNIX
    Variable: PF_INET
    These variables are bound to PF_UNIX and PF_INET.

    Variable: AF_UNIX
    Variable: AF_INET
    These variables are bound to AF_UNIX and AF_INET.

    Variable: SOCK_STREAM
    Variable: SOCK_DGRAM
    Variable: SOCK_RAW
    These variables are bound to SOCK_STREAM, SOCK_DGRAM and SOCK_RAW.

    Function: socket-fd socket
    Returns an integer system file descriptor of the underlying socket.

    Function: socket-status socket
    Returns a internal status of socket, by one of the following symbols.
  • none The socket is just created.
  • bound The socket is bound to an address by socket-bind
  • listening The socket is listening a connection by socket-listen
  • connected The socket is connected by socket-connect or socket-accept.
  • shutdown The socket is shutdown by socket-shutdown
  • closed The socket is closed by socket-close.
  • Function: socket-bind socket address
    Binds socket to the local network address address. It is usually used to associate specific address to the server port. If binding failed, an error is signalled (most likely the address is already in use). For the inet domain address, you can pass address with port=0; the system assigns the port number and sets the actual address to the address slot of socket.
    Function: socket-listen socket backlog
    Listens socket. The socket must be already bound to some address. backlog specifies maximum number of connection requests to be queued.
    Function: socket-accept socket
    Accepts a connection request coming to socket. Returns a new socket that is connected to the remote entity. The original socket keeps waiting for further connections. If there's no connection requests, this call waits for one to come. You can use sys-select to check if there's a pending connection request.
    Function: socket-connect socket address
    Connects socket to the remote address address. This is the way for a client socket to connect to the remote entity.
    Function: socket-shutdown socket how
    Shuts down connection of socket. If how is 0, the receive channel of socket is disallowed. If how is 1, the send channel of socket is disallowed. If how is 2, both receive and send channels are disallowed. It is an error to call this function on a non-connected socket. If you shut down the send channel of the socket, the remote peer sees EOF from its receive channel. This is useful if the remote peer expects EOF before sending something back to you. Other than this kind of special cases, you don't usually need to call socket-shutdown explicitly; socket-close calls it anyway.
    Further control over sockets and protocol layers is possible by getsockopt/setsockopt interface, as described below.
    Function: socket-setsockopt socket level option value
    Function: socket-getsockopt socket level option rsize
    These are the interface to setsockopt() and getsockopt() calls. The interface is a bit clumsy, in order to allow full access to those low-level calls. socket must be a non-closed socket object. level and option is an exact integer to specify the level of protocol stack and the option you want to deal with. There are several variables pre-bound to system constants listed below. To set the socket option, you can pass either an exact integer or a string to value. If it is an integer, the value is passed to setsockopt(2) as C int value. If it is a string, the byte sequence is passed as is. The required type of value depends on the option, and Gauche can't know if the value you passed is expected by setsockopt(2); it is your responsibility to pass the correct values. To get the socket option, you need to tell the maximum length of expected result by rsize parameter, for Gauche doesn't know the amount of data each option returns. socket-getsockopt returns the option value as a byte string. If you know the option value is an integer, you can pass 0 to rsize; in that case socket-getsockopt returns the value as an exact integer. Note about the name: I tempted to name these function socket-{set|get}opt or socket-{set|get}-option, but I rather took the naming consistency. Hence duplicated "sock"s.
    The following predefined variables are provided. Note that some of them are not available on all platforms. See manpages socket(7), tcp(7) or ip(7) of your system to find out exact specification of those values. For "level" argument:
    Variable: SOL_SOCKET
    Variable: SOL_TCP
    Variable: SOL_IP
    These variables are bound to SOL_SOCKET, SOL_TCP and SOL_IP, respectively.
    For "option" argument:
    Variable: SO_KEEPALIVE
    Expects integer value. If it is not zero, enables sending of keep-alive messages on connection-oriented sockets.
    Variable: SO_OOBINLINE
    Expects integer value. If it is not zero, out-of-band data is directly placed into the receive data stream. Otherwise out-of-band data is only passed when the MSG_OOB flag is set during receiving.
    Variable: SO_REUSEADDR
    Expects integer value. If it is not zero, socket-bind allows to reuse local addresses, unless an active listening socket bound to the address.
    Variable: SO_TYPE
    Gets the socket type as an integer (like sock_stream). Can be only used with socket-getsockopt.
    Variable: SO_BROADCAST
    Expects integer value. If it is not zero, datagram sockets are allowed to send/receive broadcast packets.
    Variable: SO_PRIORITY
    Expects integer value, specifying the protocol-defined priority for all packets to be sent on this socket.
    Variable: SO_ERROR
    Gets and clears the pending socket error as an integer. Can be only used with socket-getsockopt.

    9.11.4 Netdb interface

    Builtin Class: <sys-hostent>
    A class of objects for network hosts. Corresponding to struct hostent. The following slots are available read-only.

    Instance Variable: <sys-hostent> name
    The formal name of the host (string).
    Instance Variable: <sys-hostent> aliases
    A list of alias names of the host (list of strings).
    Instance Variable: <sys-hostent> addresses
    A list of addresses (list of strings). Only ipv4 address is supported currently. Each address is represented by dotted decimal notation.

    Function: sys-gethostbyname name
    Looks up a host named name. If found, returns a <sys-hostent> object. Otherwise, returns #f.
    (let ((host (sys-gethostbyname "www.w3c.org")))
      (list (slot-ref host 'name)
            (slot-ref host 'aliases)
            (slot-ref host 'addresses)))
      => ("www.w3.org" ("www.w3c.org") ("18.29.1.34" "18.29.1.35"))
    

    Function: sys-gethostbyaddr addr proto
    Looks up a host that has an address addr of protocol proto. addr is a natural string representation of the address; for ipv4, it is a dotted decimal notation. proto is a protocol number; only AF_INET is supported currently. If the host is found, returns a <sys-hostent> object. Otherwise, returns #f.
    (let ((host (sys-gethostbyaddr "127.0.0.1" AF_INET)))
      (list (slot-ref host 'name)
            (slot-ref host 'aliases)
            (slot-ref host 'addresses))
      => ("localhost" ("localhost.localdomain") ("127.0.0.1"))
    

    Builtin Class: <sys-servent>
    An entry of the network service database. Corresponding to struct servent. The following slots are available read-only.

    Instance Variable: <sys-servent> name
    The formal name of the service (string).
    Instance Variable: <sys-servent> aliases
    A list of alias names of the service (list of strings).
    Instance Variable: <sys-servent> port
    A port number registered for this service (exact integer).
    Instance Variable: <sys-servent> proto
    A protocol name for this service (string).

    Function: sys-getservbyname name proto
    Looks up the network service database with a service name name and a protocol proto. Both name and proto must be a string. If a service is found, an instance of <sys-servent> is returned. Otherwise, #f is returned.
    (let ((serv (sys-getservbyname "http" "tcp")))
      (list (slot-ref serv 'name)
            (slot-ref serv 'aliases)
            (slot-ref serv 'port)
            (slot-ref serv 'proto)))
      => ("http" () 80 "tcp")
    

    Function: sys-getservbyport port proto
    Looks up the network service database with a service port port and a protocol proto. port must be an exact integer, and proto must be a string. If a service is found, an instance of <sys-servent> is returned. Otherwise, #f is returned.
    (let ((serv (sys-getservbyport 6000 "tcp")))
      (list (slot-ref serv 'name)
            (slot-ref serv 'aliases)
            (slot-ref serv 'port)
            (slot-ref serv 'proto)))
      => ("x-server" () 6000 "tcp")
    

    Builtin Class: <sys-protoent>
    An entry of the protocol database. Corresponds to struct protoent in C. The following slots are available read-only.

    Instance Variable: <sys-servent> name
    The formal name of the protocol (string).
    Instance Variable: <sys-servent> aliases
    A list of alias names of the protocol (list of strings).
    Instance Variable: <sys-servent> proto
    A protocol number (exact integer).

    Function: sys-getprotobyname name
    Looks up the network protocol database with a name name, which must be a string. If a protocol is found, an instance of <sys-protoent> is returned. Otherwise, #f is returned.
    (let ((proto (sys-getprotobyname "icmp")))
      (list (slot-ref proto 'name)
            (slot-ref proto 'aliases)
            (slot-ref proto 'proto)))
      => ("icmp" ("ICMP") 1)
    

    Function: sys-getprotobynumber number
    Looks up the network protoice database with a protocol number number, which must be an exact integer. If a protocol is found, an instance of <sys-protoent> is returned. Otherwise, #f is returned.
    (let ((proto (sys-getprotobynumber 17)))
      (list (slot-ref proto 'name)
            (slot-ref proto 'aliases)
            (slot-ref proto 'proto)))
      => ("udp" ("UDP") 17)
    

    9.12 gauche.parameter - Parameters

    Module: gauche.parameter
    A "parameter" is basically a stateful procedure that takes zero or one argument. If no argument is given, the parameter returns the current value it is keeping. If single argument is given, it will be the current value of the parameter. Optionally you can give a "filter procedure" that checks the new value before setting it as the parameter value. With the macro parameterize, you can change the parameter's value within certain dynamic scope.

    This feature is built in some Scheme implementations, such as ChezScheme, Chicken or MzScheme. This module emulates them.

    Function: make-parameter value &optional filter
    Creates a parameter whose initial value is value. If an optional argument filter is given, it must be a procedure that takes one argument and returns one value; whenever the parameter's value is about to change, the procedure is called with the given value, and the value the procedure returns will be the parameter's value. The filter procedure can raise an error or reject to change the parameter's value.

    Macro: parameterize ((param value) ...) body ...
    Evaluages body ..., with change parameter param's value to the given value within the dynamic scope of body .... Returns the value(s) of the result of the last body.

    Some examples:

    (define a (make-parameter 1))
    (a) => 1
    (a 2)
    (a) => 2
    (parameterize ((a 3))
      (a)) => 3
    (a) => 2
    

    9.13 gauche.parseopt - Parsing command-line options

    Module: gauche.parseopt
    This module defines a convenient way to parse command-line options. The interface is hinted by Perl, and conveniently handles long-format options with mutiple option arguments.

    Note that you can also use the standard getopt interface by SLIB, if you prefer.

    Macro: parse-options args (option-clause ...)
    args is an expression that contains a list of command-line arguments. This macro scans the command-line options (an argument that begins with `-') and processes it as specified in option-clauses, then returns the remaining arguments.

    Unlike typical getopt or getopt_long implementation in C, parse-options does not permute the given command-line arguments. It stops parsing when it encounters a non-option argument (argument without starting with a minus sign).

    If the parser encounters an argument with only two minus signs `--', it stops argument parsing and returns a list of arguments after `--'.

    Each option-clause is consisted by a pair of option-spec and its action.

    option-spec is a string that specifies the name of the option and how the option takes the arguments. An alphanumeric characters, underscore, plus and minus sign is allowed for option's names, except that minus sign can't be the first character, i.e. the valid option name matches a regexp #/[\w_+][-\w_+]*/. If the option takes argument(s), it can be specified by attaching equal character and the type of the argument after the name. The option can take more than one arguments.

    "name"
    Specifies option name, that doesn't take any argument.
    "name=s"
    Option name takes one argument, and it is passed as a string.
    "name=i"
    Option name takes one argument, and it is passed as an exact integer. If the given argument is not valid string for an exact integer, an error is signalled.
    "name=f"
    Option name takes one argument, and it is passed as a real number. If the given argument is not valid string for a real number, an error is signalled.
    "name=ss"
    Option name takes two arguments, both string.
    "name=iii"
    Option name takes three integer arguments.
    "name=sf"
    Option name takes two arguments, the first is a string and the second is a number.

    In the command line, the option may appear with preceding single or double minus signs. The option's argument may be comibined by the option itself with an equal sign. For example, all the following command line arguments match an option spec "prefix=s".

    -prefix /home/shiro
    -prefix=/home/shiro
    --prefix /home/shiro
    --prefix=/home/shiro
    

    If a given command-line option matches one of option-spec, then the associated action is evaluated. An action can be one of the following forms.

    bind-spec body ...
    bind-spec is a proper or dotted list of variables like lambda-list. The option's arguments are bound to bind-spec, then then body ... is evaluated.
    => proc
    If a command-line option matches option-spec, calls a procedure proc with a list of the option's arguments.

    Examples:

    (parse-options '("-file" "foo")
      (("file=s" (file)
         (format #t "file is ~s\n" file))))
     => ;``file is "foo"'' is printed
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" (xscale yscale)
         (format #t "scale is ~sx~s\n" xscale yscale))))
     => ;``scale is 1.5x2.2'' is printed
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" scales
         (format #t "scale is ~s\n" scales))))
     => ;``scale is (1.5 2.2)'' is printed
    
    (define (scales x y)
      (format #t "scale is ~sx~s\n" x y))
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" => scales)))
     => ;``scale is 1.5x2.2'' is printed
    

    If a symbol else is at the position of option-spec, the clause is selected when no other option clause matches a given command-line option. Three "arguments" are associated to the clause; the unmatched option, the rest of arguments, and a procedure that represents the option parser.

    (parse-options args
      (("file=s" => process-file)
       (else (option . _)  (error "unrecognized option:" option))))
    

    Unlike other clause, the else clause returns to the caller of parse-options, without looping further. In order to continue looping, you have to call the third argument of the else clause with the remaining arguments. This can be used to implement your own sub-parser. The following example just skips unrecognized option, with printing a warning, and continues parsing:

    (parse-options args
      (("file=s" => process-file)
       (else (option args continue)
         (format #t "warning: ignoring unrecognized option: ~a" option)
         (continue args))))
    

    Macro: make-option-parser (option-clause ...)
    This is a lower-level interface. option-clauses are the same as parse-options. This macro returns a procedure that can be used later to parse the command line options.

    The returned procedure takes one required argument and one optional argument. The required argument is a list of strings, for given command-line arguments. The optional argument may be a procedure that takes more than three arguments, and if given, the procedure is used as if it is the body of else option clause.

    9.14 gauche.process - High Level Process Interface

    Module: gauche.process
    This module provides a higher-level API of Unix process control, implemented on top of low-level system calls such as sys-fork and sys-exec. The interface is mostly compatible with STk's process library. This module also provides "process ports", a convenient way to send/receive information to/from subprocesses.

    To use this module, say (use gauche.process).

    9.14.1 Process object

    Class: <process>
    An object to keep the status of a child process. You can create the process object by run-process procedure described below.

    Function: run-process command arg ...
    Run command with arg in a subprocess, and returns a <process> object. command is searched from the command search path.

    Command line arguments args can include the following keyword arguments which specify special handling of the child process:

    :input file
    :output file
    :error file
    These arguments controls the subprocess' standard i/o. file may be either a string or a keyword :pipe. If it is a string, the process' standard input, output, or error goes to the named file. If it is :pipe, the process' corresponding standard i/o is connected to a pipe, and the other side of the pipe is available for the calling process.
    :wait flag
    If flag is true, run-process waits until the subprocess terminates. Othewise the subprocess runs asynchronously and run-process returns immediately, which is the default behavior. Note that if the subprocess is running asynchronously, it is the caller's responsibility to call process-wait at certain timing to correct its exit status.
    :fork flag
    If flag is true, run-process forks to run the subprocess, which is the default behavior. If flag is false, run-process directly calls sys-exec, so it never returns.

    Function: process? obj
    == (is-a? obj <process>)

    Method: process-pid (process <process>)
    Returns the process ID of the subprocess process.

    Method: process-command (process <process>)
    Returns the command invoked in the subprocess process.

    Method: process-input (process <process>)
    Method: process-output (process <process>)
    Method: process-error (process <process>)
    If the process' standard input, output or error is connected to a pipe, returns another end of the pipe, i.e. process-input returns an output port that can feed data to process' stdin, process-output an input port that can read data from process' stdout, and process-error an input port that can read data from process' stderr. If the corresponding i/o is not connected to the pipe, the function returns #f.
    (let* ((process (run-process "date" :output :pipe))
           (line (read-line (process-output process))))
      (process-wait process)
      line)
     => "Fri Jun 22 22:22:22 HST 2001"
    

    Function: process-alive? process
    Returns true if process is alive. Note that Gauche can't know the subprocess' status until it is explicitly checked by process-wait.

    Function: process-list
    Returns a list of active processes. The process remains active until its exit status is explicitly collected by process-wait.

    Function: process-wait process
    Obtains exit status of the subprocess process. This suspends execution until process exits.

    Function: process-send-signal process signal
    Sends a signal signal to the subprocess process. signal must be an exact integer for signal number. See section 6.21.6 Signal, for predefined variables of signals.

    Function: process-kill process
    Function: process-stop process
    Function: process-continue process
    Sends SIGKILL, SIGSTOP and SIGCONT to process, respectively.

    9.14.2 Process ports

    Function: open-input-process-port command
    Runs command via /bin/sh asynchronously. An input port is returned, which is connected to the stdout of command. The stdin and stderr of command is redirected from/to /dev/null. If you need to get an error output, you can use shell's redirection.
    (define port (open-input-process-port "ls -l Makefile"))
    (read-line port)
     => "-rw-r--r--   1 shiro    users        1013 Jun 22 21:09 Makefile"
    
    (open-input-process-port "command 2>&1")
     => ;the port reads both stdout and stderr
    
    (open-input-process-port "command 2>&1 1>/dev/null")
     => ;the port reads stderr
    

    Metacharacters are interpreted by shell. You have to be careful if you pass the string provided from the outside world, for it may make a security flaw.

    The exit status of subprocess is not automatically collected. It is the caller's responsibility to issue process-wait, or the subprocess remains in a zombie state. If it bothers you, you can use one of the following functions.

    Function: call-with-input-process command proc
    Runs command via /bin/sh and pipes its stdout to an input port, then call proc with the port as an argument. When proc returns, it collects its exit status, then returns the result proc returned. The cleanup is done even if proc raises an error.
    (call-with-input-process "ls -l *"
      (lambda (p) (read-line p)))
    

    Function: with-input-from-process command thunk
    Runs command via /bin/sh, and calls thunk with its current input port connected to the command's stdout. The command is terminated and its exit status is collected when thunk returns, or it raises an error.
    (with-input-from-process "ls -l *" read-line)
    

    Function: open-output-process-port command
    Runs command via /bin/sh, and returns an output port which is connected to the stdin of the command. The stdout and stderr of the command is redirected to /dev/null.

    The exit status of the subprocess is not automatically collected. The caller should call process-wait on the subprocess at appropriate time.

    Function: call-with-output-process command proc
    Runs command via /bin/sh, and calls proc with an output port which is conected to the stdin of the command. The exit status of the command is collected after proc returns, or it raises an error.
    (call-with-output-process "/usr/sbin/sendmail"
      (lambda (out) (display mail-body out)))
    

    Function: with-output-to-process command thunk
    Same as call-with-output-process, except that the output port which is connected to the stdin of the command is set to the current output port while executing thunk.

    Function: call-with-process-io command proc
    Runs command via /bin/sh, and calls proc with two arguments; the first argument is an input port which is connected to the command's stdout, and the second is an output port connected to the command's stdin. The error output from the command is redirected to /dev/null.

    The exit status of the command is collected when proc returns or raises an error.

    Function: process-output->string command
    Function: process-output->string-list command
    Runs command and collects its output (to stdout) to return them. process-output->string concatenates all the output from command to one string, replacing any sequence of whitespace characters to single space. The action is similar to "command substitution" in shell scripts. process-output->string-list collects the output from command line-by-line and returns the list of them. Newline characters are stripped.

    Internally, command is run by call-with-input-process.

    (process-output->string "uname -smp")
      => "Linux i686 unknown"
    
    (process-output->string "ls")
      => "a.out foo.c foo.c~ foo.o"
    
    (process-output->string-list "ls")
      => ("a.out" "foo.c" "foo.c~" "foo.o")
    

    9.15 gauche.regexp - Regular expression utilities

    Module: gauche.regexp
    This module defines some macros and utilities useful in regexp match. See section 6.11 Regular expression for builtin regexp features.

    As of release 0.4.11, this module is set to be autoloaded in gosh, so you don't usually need to say (use gauche.regexp).

    The interface of some of the macros is borrowed from scsh (if-match, let-match and match-cond), but I changed the name of macros since scsh's match-cond can be confusing (e.g. Bigloo has match-lambda and match-case in pattern match library, that sounds too similar).

    In the following macros, match-expr is an expression which produces a match object or #f. Typically it is a call of rxmatch, but it can be any expression.

    Macro: rxmatch-let match-expr (var ...) form ...

    Evaluates match-expr, and if matched, binds var ... to the matched strings, then evaluates forms. The first var receives the entire match, and subsequent variables receive submatches. If the number of submatches are smaller than the number of variables to receive them, the rest of variables will get #f.

    It is possible to put #f in variable position, which says you don't care that match.

    (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                          "Jan  1 23:59:58, 2001")
       (time hh mm ss)
      (list time hh mm ss))
     => ("23:59:58" "23" "59" "58")
    
    (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                          "Jan  1 23:59:58, 2001")
       (#f hh mm)
      (list hh mm))
     => ("23" "59")
    

    This macro corresponds to scsh's let-match.

    Macro: rxmatch-if match-expr (var ...) then-form else-form
    Evaluates match-expr, and if matched, binds var ... to the matched strings and evaluate then-form. Otherwise evaluates else-form. The rule of binding vars is the same as rxmatch-let.
    (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11:22:33")
        (time)
      (format #f "time is ~a" time)
      "unknown time")
     => "time is 11:22"
    
    (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11-22-33")
        (time)
      (format #f "time is ~a" time)
      "unknown time")
     => "unknown time"
    

    This macro corresponds to scsh's if-match.

    Macro: rxmatch-cond clause ...
    Evaluate condition in clauses one by one. If a condition of a clause satisfies, rest portion of the clause is evaluated and becomes the result of rxmatch-cond. Clause may be one of the following pattern.
    (match-expr (var ...) form ...)
    Evaluate match-expr, which may return a regexp match object or #f. If it returns a match object, the matches are bound to vars, like rxmatch-let, and forms are evaluated.
    (test expr form ...)
    Evaluates expr. If it yields true, evaluates forms.
    (test expr => proc)
    Evaluates expr and if it is true, calls proc with the result of expr as the only argument.
    (else form ...)
    If this clause exists, it must be the last clause. If other clauses fail, forms are evaluated.

    If no else clause exists, and no other clause matched the string-expr, an undefined value is returned.

    ;; parses several possible date format
    (define (parse-date str)
      (rxmatch-cond
        ((rxmatch #/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ str)
            (#f mm dd yyyy)
          (map string->number (list yyyy mm dd)))
        ((rxmatch #/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ str)
            (#f yyyy mm dd)
          (map string->number (list yyyy mm dd)))
        ((rxmatch #/^\d+\/\d+\/\d+$/ str)
            (#f)
         (error "ambiguous: ~s" str))
        (else (error "bogus: ~s" str))))
    
    (parse-date "2001/2/3") => (2001 2 3)
    (parse-date "12/25/1999") => (1999 12 25)
    

    This macro corresponds to scsh's match-cond.

    Macro: rxmatch-case string-expr clause ...
    String-expr is evaluated, and clauses are interpreted one by one. A clause may be one of the following pattern.
    (re (var ...) form ...)
    Re must be either a literal string describing a regexp, or a regexp object. If it matches with the result of string-expr, the match result is bound to vars and forms are evaluated, and rxmatch-case returns the result of the last form. If re doesn't match the result of string-expr, string-expr yields non-string value, the interpretation proceeds to the next clause.
    (test proc form ...)
    A procedure proc is applied on the result of string-expr. If it yields true value, forms are evaluated, and rxmatch-case returns the result of the last form. If proc yieds #f, the interpretation proceeds to the next clause.
    (test proc => proc2)
    A procedure proc is applied on the result of string-expr. If it yields true value, proc2 is applied on the result, and its result is returned as the result of rxmatch-case. If proc yieds #f, the interpretation proceeds to the next clause.
    (else form ...)
    This form must appear at the end of clauses, if any. If other clauses fail, forms are evaluated, and the result of the last form becomes the result of rxmatch-case.

    If no else clause exists, and no other clause matched the string-expr, an undefined value is returned.

    The parse-date example above becomes simpler if you use rxmatch-case

    (define (parse-date2 str)
      (rxmatch-case str
        (test (lambda (s) (not (string? s))) #f)
        (#/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ (#f mm dd yyyy)
         (map string->number (list yyyy mm dd)))
        (#/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ (#f yyyy mm dd)
         (map string->number (list yyyy mm dd)))
        (#/^\d+\/\d+\/\d+$/                (#f)
         (error "ambiguous: ~s" str))
        (else (error "bogus: ~s" str))))
    

    Function: regexp-replace regexp string substitution
    Function: regexp-replace-all regexp string substitution
    Replaces the part of string that matched to regexp for substitution. regexp-replace just replaces the first match of regexp, while regexp-replace-all repeats the replacing throughout entire string.

    substitution may be a string or a procedure. If it is a string, it can contain a digit sequence preceded by a backslash (e.g. \2) that refers the submatch. \0 refers to the entire match. Note that you need two backslashes to include backslash character in the literal string; if you want to include a backslash character itself in the substitution, you need four backslashes.

    (regexp-replace #/def|DEF/ "abcdefghi" "...")
      => "abc...ghi"
    (regexp-replace #/def|DEF/ "abcdefghi" "|\\0|")
      => "abc|def|ghi"
    (regexp-replace #/def|DEF/ "abcdefghi" "|\\\\0|")
      => "abc|\\0|ghi"
    (regexp-replace #/c(.*)g/ "abcdefghi" "|\\1|")
      => "ab|def|hi"
    

    If substitution is a procedure, for every match in string it is called with one argument, regexp-match object. The returned value from the procedure is inserted to the output string using display.

    (regexp-replace #/c(.*)g/ "abcdefghi" 
                    (lambda (m)
                      (list->string
                       (reverse
                        (string->list (rxmatch-substring m 1))))))
     => "abfedhi"
    

    9.16 gauche.reload - Reloading modules

    Module: gauche.reload
    In the development cycle, you often have to reload modules frequently. This module supports it.

    Note that some part of semantics of the program depends on the order of loading modules, so reloading arbitrary modules may change the program behavior unexpectedly. This module is for developers who knows what they are doing.

    Redefinition rules: Reloading a module resets all the binding in the module by default. Sometimes it is not desirable, however. For example, you might have a large list of objects that takes time to rebuild. You can specify rules for the reloading procedure to determine which binding to keep.

    The rule is described in the following syntax.

      <module-rules> : (<module-rule> ...)
      <module-rule>  : (<module-pattern> <rule> ...)
      <module-pattern> : a symbol module name, or a symbol containing glob pattern
      <rule>         : procedure | symbol | regexp
                     | (and <rule> ...)
                     | (or  <rule> ...)
                     | (not <rule>)
    

    <module-rules> is the global rule to determine per-module rules. <module-pattern> is either a symbol module name or a symbol that contains glob pattern (e.g. mylib.*). If <rule> is a procedure, it is used as a predicate and the bindings whose value satisfies the predicate are kept from redefinition. If <rule> is a symbol, the binding of the variable whose name is the symbol is kept. If <rule> is a regexp, the bindings of the variable whose name matches the regexp are kept.

    Note that the mechanism to prevent redefinition is kind of ad-hoc hack and semantically unclean. It's just for your convenience. Take a look at the code if you want to know the exact behavior.

    Function: reload module-name &optional rule ...
    Reloads the specified module. You can optionally specify redefinition rules by rule ..., where each rule is the term <rule> defined above.

    Function: reload-modified-modules &optional module-rules
    Reloads module(s) that have been modified since they are loaded last time. If optional module-rules is given, it is used to determine the redefinition rules for reloaded modules. If module-rules is omitted, the current rules are used. The default of current rules is empty. You can set the current rules by module-reload-rules.

    Function: module-reload-rules &optional module-rules
    This is a parameter (See section 9.12 gauche.parameter - Parameters) that keeps the default module rules for reload-modified-modules. If called without arguments, returns the current module rules. If called with module-rules, sets the argument to the current module rules.

    Function: reload-verbose &optional flag
    This is a parameter to control verbosity of the reloading procedures. If called without arguments, returns the current verbosity flag. If called with flag, it is set to the current verbosity flag.

    9.17 gauche.selector - Simple dispatcher

    Module: gauche.selector
    This module provides a simple interface to dispatch I/O events to registered handlers, based on sys-select (See section 6.21.10 I/O multiplexing).

    Class: <selector>
    A dispatcher instance that keeps watching I/O ports with associated handlers. A new instance can be created by make method.

    Method: selector-add! (self <selector>) port-or-fd proc flags
    Add a handler proc to the selector. proc is called when port-or-fd, which should be a port object or an integer that specifies a system file descriptor, meets a certain condition specified by flags. flags must be a list of one or more of the following symbols.
    r
    Calls proc when data is available at port-or-fd to read.
    w
    Calls proc when port-or-fd is ready to be written.
    x
    Calls proc when an exceptional condition occurs on port-or-fd.

    proc is called with two arguments. The first one is port-or-fd itself, and the second one is a symbol r, w or x, indicating the condition.

    If a handler is already associated with port-or-fd under the same condition, the previous handler is replaced by proc.

    Method: selector-delete! (self <selector>) port-or-fd proc flags
    Deletes the handler entries that matches port-or-fd, proc and flags. One or more of the arguments may be #f, meaning "don't care". For example,
    (selector-delete! selector the-port #f #f)
    

    deletes all the handlers associated to the-port, and

    (selector-delete! selector #f #f '(w))
    

    delets all the handlers waiting for writable condition.

    Method: selector-select (self <selector>) &optional (timeout #f)
    Dispatcher body. Waits for the conditions registered in self, and when it occurs, calls the associated handler.

    If the timeout argument is omitted or false, this method waits indefinitely. Alternatively you can give a timeout value, that can be a real number in microseconds, or a list of two integers that represents seconds and microseconds.

    Returns the number of handlers called. Zero means the selector has been timed out.

    It is safe to modify self inside handler. The change will be effective from the next call of selector-select

    This is a simple example of "echo" server:

    (use gauche.net)
    (use gauche.selector)
    
    (define (echo-server port)
      (let ((selector (make <selector>))
            (server   (make-server-socket 'inet port :reuse-addr? #t)))
    
        (define (accept-handler sock flag)
          (let* ((client (socket-accept server))
                 (output (socket-output-port client)))
            (selector-add! selector
                           (socket-input-port client :buffered? #f)
                           (lambda (input flag)
                             (echo client input output))
                           '(r))))
    
        (define (echo client input output)
          (let ((str (read-block 4096 input)))
            (if (eof-object? str)
                (begin (selector-delete! selector input #f #f)
                       (socket-close client))
                (begin (display str output)
                       (flush output)))))
    
        (selector-add! selector
                       (socket-fd server)
                       accept-handler
                       '(r))
        (do () (#f) (selector-select selector))))
    

    9.18 gauche.sequence - Sequence framework

    Module: gauche.sequence
    Provides a generic opertaions on sequences. A sequence is a collection in which elements can be accessed by integer index, starting with zero.

    This module inherits gauche.collection (See section 9.3 gauche.collection - Collection framework), All the collection generic operations can be applied to a sequence as well.

    Among Gauche builtin class, lists, vectors and strings are sequences and the specialized methods are defined for them. Other extension types, such as SRFI-4 uniform vector, have the methods as well.

    9.18.1 Fundamental sequence accessors

    Generic function: ref (seq <sequence>) index &optional fallback
    Returns index-th element of the sequence seq. This method enables uniform access for any sequence types.

    When index is less than zero, or greater than or equal to the size of the sequence, fallback is returned if provided, or an error is signalled if not.

    (ref '(a b c) 1)  => b
    (ref '#(a b c) 1) => b
    (ref "abc" 1)     => #\b
    

    Generic function: (setter ref) (seq <sequence>) index value
    Sets value to the index-th element of the sequence seq. This is the uniform sequence modifier.
    (let ((x (list 'a 'b 'c)))
      (set! (ref x 1) 'z)
      x) => (a z c)
    
    (let ((x (vector 'a 'b 'c)))
      (set! (ref x 1) 'z)
      x) => #(a z c)
    
    (let ((x (string #\a #\b #\c)))
      (set! (ref x 1) #\z)
      x) => "azc"
    

    Generic function: referencer (seq <sequence>)

    Generic function: modifier (seq <sequence>)

    9.18.2 Slicing sequence

    Generic function: subseq (seq <sequence>) &optional start end
    Retrieve a subsequence of the sequence seq, from start-th element (inclusive) to end-th element (exclusive). If end is omitted, up to the end of sequence is taken. The type of the returned sequence is the same as seq.
    (subseq '(a b c d e) 1 4)   => (b c d)
    (subseq '#(a b c d e) 1 4)  => #(b c d)
    (subseq "abcde" 1 4)        => "bcd"
    
    (subseq '(a b c d e) 3)     => (d e)
    

    Generic function: (setter subseq) (seq <sequence>) start end value-seq
    Generic function: (setter subseq) (seq <sequence>) start value-seq
    Sets the elements of value-seq from the start-th element (inclusive) to the end-th element (exclusive) of the sequence seq. Value-seq can be any sequence, but its size must be larger than (end - start).

    In the second form, end is figured out by the length of value-seq.

    (define s '#(a b c d e))
    (set! (subseq s 1 4) '(4 5 6))
    s => #(a 4 5 6 e)
    (set! (subseq s 0)   "ab")
    s => #(#\a #\b 5 6 e)
    

    9.18.3 Implementing sequence

    9.19 gauche.syslog - Syslog

    Module: gauche.syslog
    This module provides syslog(3) system logger interface.

    For the common applications, you might find gauche.logger module easier to use (See section 9.8 gauche.logger - User-level logging). This module is for those who need direct access to the syslog API.

    The procedures are only defined if the undelying system supports them.

    Function: sys-openlog ident option facility
    [POSIX] Opens a connection to the system logger. A string argument ident is used for the prefix of the log, and usually is the program name. Option is an integer flag to control the behavior of logging, and facility is an integer that specify the type of the program.

    The flag for option can be composed by logior-ing one or more of the following integer constants: LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY, LOG_PERROR and LOG_PID. (Some of the constants may not be defined if the underlying system doesn't support them).

    The facility argument can be one of the following integer constants: LOG_AUTH, LOG_AUTHPRIV, LOG_CRON, LOG_DAEMON, LOG_FTP, LOG_KERN, LOG_LOCAL0 through LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NEWS, LOG_SYSLOG, LOG_USER and LOG_UUCP. (Some of the constants may not be defined if the underlying system doesn't support them).

    See your system's manpage of openlog(3) for detail description about these constants.

    Function: sys-syslog priority message
    [POSIX] Log the string message. Unlike syslog(3), this procedure doesn't do formatting--you can use format (See section 6.18.7 Output) to create a formatted message, or use higher-level routine log-format (See section 9.8 gauche.logger - User-level logging).

    An integer argument priority can be composed by logior-ing one of the facility constants described above and the level constants: LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG.

    Function: sys-closelog
    [POSIX] Closes the connection to the logging system.

    Function: sys-setlogmask mask
    [POSIX] Sets the process's log priority mask that determines which calls to sys-syslog may be logged. An priority mask can be composed by logior-ing bitmasks corresponding to the level argument of sys-syslog. You can use sys-logmask below to obtain a bitmask from the level.

    Function: sys-logmask level
    [POSIX] Returns an integer bitmask for sys-setlogmask from the log level level.

    9.20 gauche.termios - Termios

    Module: gauche.termios
    This module defines POSIX termios interface, which controls terminal attributes. This module also provides pseudo tty interface, if the system provides it.

    Builtin Class: <sys-termios>
    POSIX termios(7) structure.

    Instance Variable: <sys-termios> iflag
    Instance Variable: <sys-termios> oflag
    Instance Variable: <sys-termios> cflag
    Instance Variable: <sys-termios> lflag

    Throughout this section, argument port-or-fd refers to either a port object or a small integer representing system's file descriptor. If port is not associated to the system terminal, an error is signalled. (You can check if port has an associated terminal by sys-isatty?. See section 6.21.3.5 Other file operations).

    Function: sys-tcgetattr port-or-fd
    Returns terminal parameters in a <sys-termios> object, associated to port-or-fd.

    Function: sys-tcsetattr port-or-fd when termios
    Sets terminal parameters associated to port-or-fd by termios, which must be an instance of <sys-termios>.

    An integer argument when specifies when the changes take effect. Three variables are pre-defined for the argument:

    TCSANOW
    The change is reflected immediately.
    TCSADRAIN
    The change is reflected after all pending output is flushed.
    TCSAFLUSH
    The change is reflected after all pending output is flushed, and all pending input is discarded.

    Function: sys-tcsendbreak port-or-fd duration
    Transmits a zero stream for the specified duration to the terminal associated to port-or-fd. The unit of duration depends on the system; see man tcsendbreak(3) of your system for details.

    Function: sys-tcdrain port-or-fd
    Waits until all output written to port-or-fd is transmitted.

    Function: sys-tcflush port-or-fd queue
    Discards data in the buffer of port-or-fd, specified by queue, which may be one of the following values.
    TCIFLUSH
    Discards data received but not read.
    TCOFLUSH
    Discards data written but not transmitted.
    TCIOFLUSH
    Do both TCIFLUSH and TCOFLUSH action.

    Function: sys-tcflow port-or-fd action
    Controls data flow of port-or-fd by action, which may be one of the following values:
    TCOOFF
    Suspends output transmission.
    TCOON
    Restarts output transmission.
    TCIOFF
    Transmits a STOP character to make the terminal device stop transmitting data to the system.
    TCION
    Transmits a START character to make the terminal device resume transmitting data to the system.

    Function: sys-tcgetpgrp port-or-fd
    Returns process group ID of the terminal associated to port-or-fd.

    Function: sys-tcsetpgrp port-or-fd pgrp
    Sets process group ID of the terminal associated to port-or-fd to pgrp.

    Function: sys-cfgetispeed termios
    Function: sys-cfsetispeed termios speed
    Function: sys-cfgetospeed termios
    Function: sys-cfsetospeed termios speed
    Gets/sets input/output speed (baud rate) parameter stored in termios object. Speed is represented by the following predefined numbers: B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400. Some system may support higher baud rate, such as B57600, B115200 or B230400. You can use symbol-bound? to check these options are defined. B0 is used to terminate the connection.

    Function: sys-openpty &optional term
    Openes a pair of pseudo ttys, one for master and the other for slave, then returns two integers which are their file descriptors. An optional argument term must be, if passed, a <sys-termios> object; it sets the slave pty's parameters.

    You can use open-input-fd-port and/or open-output-fd-port to create a port around the returned file descriptor (See section 6.18.3 File ports). To obtain pseudo tty's name, use sys-ttyname (See section 6.21.3.5 Other file operations).

    This function is available only if the system supports openpty(3).

    Function: sys-forkpty &optional term
    Openes a pair of pseudo ttys, one for master and the other for slave, sets the slave pty suitable for login terminal, then fork(2).

    Returns two integers; the first value is a child pid for the parent process, and 0 for the child process. The second value is a file descriptor of the master pty.

    An optional argument term must be, if passed, a <sys-termios> object; it sets the slave pty's parameters.

    This function is available only if the system supports forkpty(3).

    The following example shows how to get a password from the user without echoing:

    (use gauche.termios)
    
    (define (get-password prompt)
      (let* ((port (current-input-port))
             (attr (sys-tcgetattr port))
             (lflag (slot-ref attr 'lflag)))
        ;; Show prompt
        (display prompt)
        (flush)
        ;; Turn off echo during reading.
        (dynamic-wind
         (lambda ()
           (slot-set! attr 'lflag (logand lflag (lognot ECHO)))
           (sys-tcsetattr port TCSAFLUSH attr))
         (lambda ()
           (read-line port))
         (lambda ()
           (slot-set! attr 'lflag lflag)
           (sys-tcsetattr port TCSANOW attr)))))
    

    9.21 gauche.test - Unit Testing

    Module: gauche.test
    Defines a set of functions to write test scripts. A test script will look like this:
    (use gauche.test)
    (test-start "my feature")
    (load "my-feature")  ; load your program
    (import my-feature)  ; if your program defines a module.
    
    (test-section "feature group 1")
    (test "feature 1-1" EXPECT (lambda () TEST-BODY))
    (test "feature 1-2" EXPECT (lambda () TEST-BODY))
     ...
    
    (test-section "feature group 2")
    (define test-data ...)
    (test "feature 2-1" EXPECT (lambda () TEST-BODY))
     ...
    
    (test-end)
    

    With this convention, you can run test both interactively or in batch. To run a test interactively, just load the file and it reports a result of each test, as well as the summary of failed test at the end. To run a test in batch, it is convenient to redirect the stdout to some file If stdout is redirected to other than tty, all the verbose logs will go there, and only a small amount of messages go to stderr.

    It is recommended to have a "test" target always in Makefile of your module/program, so that the user of your program can run a test easily. The rule may look like this:

    test :
            gosh my-feature-test.scm > test.log
    

    Function: test name expected thunk &optional =
    Calls thunk, and compares its result with expected. The comparison predicate is equal? by default, but you can specify your own predicate by the argument =. Name is a name of the test, for logging purpose.

    Function: test-start module-name
    Initializes internal state and prints a log header. This should be called before any tests. Module-name is used only for logging purpose.

    Function: test-section section-name
    Marks beginning of the group of tests. This is just for logging.

    Function: test-end
    Prints out list of failed tests.

    9.22 gauche.threads - Threads

    If enabled at compilation time, Gauche can use threads built on top of POSIX threads (pthreads).

    Module: gauche.threads
    Provides thread API. You can 'use' this module regardless whether the thread support is compiled in or not; if threads are not supported, many thread-related procedures simply signals a "not supported" error.

    To check if threads are available in the running Gauche program, use the following procedure.

    Function: gauche-thread-type
    Returns a symbol that indicates the supported thread type. In the current version, the return value may be pthread when threads on top of POSIX threads are available, or none when threads are not available.

    Scheme-level thread API conforms SRFI-18, "Multithreading support" (@xref{srfi-18,,[SRFI-18]}), wrapped around Gauche's object interface.

    9.22.1 Thread procedures

    Builtin Class: <thread>
    A thread. Each thread has an associated thunk which is evaluated by a POSIX thread. When thunk returns normally, the result is stored in the internal 'result' slot, and can be retrieved by thread-join!. When thunk terminates abnormally, either by raising an exception or terminated by thread-terminate!, the exception condition is stored in ther internal 'result exception' slot, and will be passed to the thread calling thread-join! on the terminated thread.

    Each thread has its own dynamic environment and dynamic handler stack. When a thread is created, its dynamic environment is initialized by the creator's dynamic environment. The thread's dynamic handler stack is initially empty.

    Access to the resouces shared by multiple threads must be protected explicitly by synchronization primitives. See section 9.22.2 Synchronization primitives.

    Access to ports are serialized by Gauche. If multiple threads attempt to write to a port, their output may be interleaved but no output will be lost, and the state of the port is kept consistent. If multiple threads attempt to read from a port, a single read primitive (e.g. read, read-char or read-line) works atomically.

    Signal handlers are shared by all threads, but each thread has its own signal mask. See section 6.21.6.5 Signals and threads, for details.

    A thread object has the following external slots.

    Instance Variable: <thread> name
    A name can be associated to a thread. This is just for the convenience of the application. The primordial thread has the name "root".

    Instance Variable: <thread> specific
    A thread-local slot for use of the application.

    Function: current-thread
    [SRFI-18], [SRFI-21] Returns the current thread.

    Function: thread? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a thread, #f otherwise.

    Function: make-thread thunk &optional name
    [SRFI-18], [SRFI-21] Creates and returns a new thread. To run the thread, you need to call thread-start!.

    You can provide the name of the thread by the optional argument name.

    Internally, this procedure just allocates and initializes a Scheme thread object; the POSIX thread is not created until thread-start! is called.

    Function: thread-name thread
    [SRFI-18], [SRFI-21] Returns the value of name slot of thread.

    Function: thread-specific thread
    Function: thread-specific-set! thread value
    [SRFI-18], [SRFI-21] Gets/sets the value of the thread's specific slot.

    Function: thread-start! thread
    [SRFI-18], [SRFI-21] Starts the thread. It is an error if thread is already started. Returns thread.

    Function: thread-yield!
    [SRFI-18], [SRFI-21] Suspends the execution of the calling thread and yields CPU to other waiting runnable threads, if any.

    Function: thread-sleep! timeout
    [SRFI-18], [SRFI-21] Suspends the calling thread for the period specified by timeout, which must be either a <time> object (See section 6.21.8.2 SRFI time) that specifies absolute point of time, or a real number that specifies relative point of time from the time this procedure is called in number of seconds.

    After the specified time passes, thread-sleep! returns with unspecified value.

    If timeout points a past time, thread-sleep! returns immediately.

    Function: thread-terminate! thread
    [SRFI-18], [SRFI-21] Terminates the specified thread thread. The thread is terminated and an instance of <terminated-thread-exception> is stored in the result exception field of thread.

    If thread is the same as the calling thread, this procedure won't return. Otherwise, this procedure returns unspecified value.

    This procedure should be used with care, since thread won't have a chance to call cleanup procedures (such as 'after' thunks of dynamic-wind) If thread is in the critical section, it leaves some state inconsistent. However, once a thread is terminated, any mutex that the thread has kept becomes 'abandoned' state, and an attempt to lock such a mutex by other thread raises an 'abandoned mutex exception', so that you will know the situation. See section 9.22.2 Synchronization primitives.

    Function: thread-join! thread &optional timeout timeout-val
    [SRFI-18], [SRFI-21] Waits termination of thread, or until the timeout is reached if timeout is given.

    Timeout must be either a <time> object (See section 6.21.8.2 SRFI time) that specifies absolute point of time, or a real number that specifies relative point of time from the time this procedure is called in number of seconds, or #f that indicates no timeout (default).

    If thread terminates normally, thread-join! returns a value which is stored in the result field of thread. If thread terminates abnormally, thread-join! raises an exception which is stored in the result exception field of thread.

    If the timeout is reached, thread-join! returns timeout-val if given, or raises <join-timeout-exception>.

    9.22.2 Synchronization primitives

    Builtin Class: <mutex>
    A primitive synchronization device. It can take one of four states: locked/owned, locked/not-owned, unlocked/abandoned and unlocked/not-abandoned. A mutex can be locked (by mutex-lock!) only if it is in unlocked state. An 'owned' mutex keeps a thread that owns it. Typically an owner thread is the one that locked the mutex, but you can make a thread other than the locking thread own a mutex. A mutex becomes unlocked either by mutex-unlock! or the owner thread terminates. In the former case, a mutex becomes unlocked/not-abandoned state. In the latter case, a mutex becomes unlocked/abandoned state.

    A mutex has the following external slots.

    Instance Variable: <mutex> name
    The name of the mutex.

    Instance Variable: <mutex> state
    The state of the mutex. This is a read-only slot. See the descrption of mutex-state below.

    Instance Variable: <mutex> specific
    A slot an application can keep arbitrary data. For example, an application can implement a 'recursive' mutex using the specific field.

    Function: mutex? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a mutex, #f otherwise.

    Function: make-mutex &optional name
    [SRFI-18], [SRFI-21] Creates and returns a new mutex object. When created, the mutex is in unlocked/not-abandoned state. Optionally, you can give a name to the mutex.

    Function: mutex-name mutex
    [SRFI-18], [SRFI-21] Returns the name of the mutex.

    Function: mutex-specific mutex
    Function: mutex-specific-set! mutex value
    [SRFI-18], [SRFI-21] Gets/sets the specific value of the mutex.

    Function: mutex-state mutex
    [SRFI-18], [SRFI-21] Returns the state of mutex, which may be one of the followings:
    a thread
    The mutex is locked/owned, and the owner is the returned thread.
    symbol not-owned
    The mutex is locked/not-owned.
    symbol abandoned
    The mutex is unlocked/abandoned.
    symbol not-abandoned
    The mutex is unlocked/not-abandoned.

    Function: mutex-lock! mutex &optional timeout thread
    [SRFI-18], [SRFI-21] Locks mutex. If mutex is in unlocked/not-abandoned state, this procedure changes its state to locked state exclusively. By default, mutex becomes locked/owned state, owned by the calling thread. You can give other owner thread as thread argument. If thread argument is given and #f, the mutex becomes locked/not-owned state.

    If mutex is in unlocked/abandoned state, that is, some other thread has been terminated without unlocking it, this procedure signals 'abandoned mutex exception' (See section 9.22.3 Thread exceptions) after changing the state of mutex.

    If mutex is in locked state and timeout is omitted or #f, this procedure blocks until mutex becomes unlocked. If timeout is specified, mutex-lock! returns when the specified time reaches in case it couldn't obtain a lock. You can give timeout an absolute point of time (by <time> object, See section 6.21.8.2 SRFI time), or a relative time (by a real number).

    Mutex-lock! returns #t if mutex is successfully locked, or #f if timeout reached.

    Note that mutex itself doesn't implements a 'recursive lock' feature; that is, if a thread that has locked mutex tries to lock mutex again, the thread blocks. It is not difficult, however, to implement a recursive lock semantics on top of this mutex. The following example is taken from SRFI-18 document:

    (define (mutex-lock-recursively! mutex)
      (if (eq? (mutex-state mutex) (current-thread))
          (let ((n (mutex-specific mutex)))
            (mutex-specific-set! mutex (+ n 1)))
          (begin
            (mutex-lock! mutex)
            (mutex-specific-set! mutex 0))))
    
    (define (mutex-unlock-recursively! mutex)
      (let ((n (mutex-specific mutex)))
        (if (= n 0)
            (mutex-unlock! mutex)
            (mutex-specific-set! mutex (- n 1)))))
    

    Function: mutex-unlock! mutex &optional condition-variable timeout
    [SRFI-18], [SRFI-21] Unlocks mutex. The state of mutex becomes unlocked/not-abandoned. It is allowed to unlock a mutex that is not owned by the calling thread.

    If optional condition-variable is given, mutex-unlock! serves the "condition variable wait" operation (e.g. pthread_cond_wait in POSIX threads). The current thread atomically wait on condition-variable and unlocks mutex. The thread will be unblocked when other thread signals on condition-variable (see condition-variable-signal! and condition-variable-broadcast! below), or timeout reaches if it is supplied. The timeout argument can be either a <time> object to represent an absolute time point (See section 6.21.8.2 SRFI time), a real number to represent a relative time in seconds, or #f which means never. The calling thread may be unblocked prematurely, so it should reacquire the lock of mutex and checks the condition, as in the follwing example (it is taken from SRFI-18 document):

    (let loop ()
      (mutex-lock! m)
      (if (condition-is-true?)
          (begin
            (do-something-when-condition-is-true)
            (mutex-unlock! m))
          (begin
            (mutex-unlock! m cv)
            (loop))))
    

    Builtin Class: <condition-variable>
    A condition variable keeps a set of threads that are waiting for a certain condition to be true. When a thread modifies the state of the concerned condition, it can call condition-variable-signal! or condition-variable-broadcast!, which unblock one or more waiting threads so that they can check if the condition is satisfied.

    A condition variable object has the following slots.

    Instance Variable: <mutex> name
    The name of the condition variable.

    Instance Variable: <mutex> specific
    A slot an application can keep arbitrary data.

    Function: condition-variable? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a condition variable, #f otherwise.

    Function: make-condition-variable &optional name
    [SRFI-18], [SRFI-21] Returns a new condition variable. You can give its name by optional name argument.

    Function: condition-variable-name cv
    [SRFI-18], [SRFI-21] Returns the name of the condition variable.

    Function: condition-variable-specific cv
    Function: condition-variable-specific-set! cv value
    [SRFI-18], [SRFI-21] Gets/sets the specific value of the condition variable.

    Function: condition-variable-signal! cv
    [SRFI-18], [SRFI-21] If there are threads waiting on cv, causes the scheduler to select one of them and to make it runnable.

    Function: condition-variable-broadcast! cv
    [SRFI-18], [SRFI-21] Unblocks all the threads waiting on cv.

    9.22.3 Thread exceptions

    Some types of exceptions may be thrown from thread-related procedures. These exceptions can be handled by Gauche's exception mechanism (See section 6.16 Exceptions).

    Builtin Class: <thread-exception>
    A base class of thread-related exceptions. Inherits <exception> class. It has one slot.

    Instance Variable: <thread-exception> thread
    A thread that threw this exception.

    Builtin Class: <join-timeout-exception>
    An exception thrown by thread-join! when a timeout reaches before the waited thread returns. Inherits <thread-exception>.

    Builtin Class: <abandoned-mutex-exception>
    An exception thrown by mutex-lock! when a mutex to be locked is in unlocked/abandoned state. Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <abandoned-mutex-exception> mutex
    A mutex that caused this exception.

    Builtin Class: <terminated-thread-exception>
    An exception thrown by thread-join! when the waited thread is terminated abnormally (by thread-terminate!). Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <terminated-thread-exception> terminator
    A thread that terminated the thread that causes this exception.

    Builtin Class: <uncaught-exception>
    An exception thrown by thread-join! when the waited thread is terminated by an uncaught exception. Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <uncaught-exception> reason
    An exception that caused the termination of the thread.

    Function: join-timeout-exception? obj
    Function: abandoned-mutex-exception? obj
    Function: terminated-thread-exception? obj
    Function: uncaught-exception? obj
    [SRFI-18], [SRFI-21] These procedures checks if obj is a certain type of exception. Provided for the compatibility to SRFI-18.

    Function: uncaught-exception-reason exc
    [SRFI-18], [SRFI-21] Returns the value of reason slot of <uncaught-exception> object. Provided for the compatibility to SRFI-18.

    9.23 gauche.time - Measure timings

    Module: gauche.time
    Provides two simple ways to measure execution time of Scheme code. A macro time, which is convenient for interactive use, and <time-counter> objects which are useful to be embedded in the program.

    Macro: time expr expr2 ...
    Evaluates expr expr2 ... sequentially, as begin, and returns the result(s) of the last expression. Before returning the value(s), the macro reports the elapsed (real) time and CPU times in the user space and the kernel space to the current error port, much like the bourne shell's time command.

    The current version uses sys-gettimeofday (See section 6.21.8.1 POSIX time) to calculate the elapsed time, and sys-times (See section 6.21.7 System Inquiry) to calculate user and system CPU times. So the resolution of these numbers depends on these underlying system calls. Usually the CPU time has 10ms resolution, while the elapsed time might have higher resolution. On the systems that doesn't have gettimeofday(2) support, however, the elapsed time resolution can be as bad as a second.

    gosh> (time (length (sort (call-with-input-file "/usr/share/dict/words" port->string-list))))
    ;(time (length (sort (call-with-input-file "/usr/share/dict/words" port- ...
    ; real   0.357
    ; user   0.350
    ; sys    0.000
    45427
    

    Class: <time-counter>
    An abstract class of time counters. Time counter is a kind of timer whose value is incremented as the time passes. The counting can be started and stopped any number of times. The value of the counter can be read when the timer is stopping. You can have multiple time counters. It is useful, for example, to measure the time in two parts inside a loop independently.

    The concrete subclass determines which time it is counting. You have to instantiate one of those subclasses described below to use the time counter.

    Class: <real-time-counter>
    Class: <user-time-counter>
    Class: <system-time-counter>
    Class: <process-time-counter>
    Classes for time counters that count real (elapsed) time, user-space CPU time, kernel-space CPU time, and total CPU time (user + system), respectively.

    Method: time-counter-start! (counter <time-counter>)
    Method: time-counter-stop! (counter <time-counter>)
    Starts and stops the counter. The time during the counter is running is accumulated to the counter value when the counter is stopped.

    Start/stop pairs can be nested, but only the outermost pair takes the effect. That is, if you call time-counter-start! on the counter that is already started, it doesn't have any effect except that to stop such a counter you have to call time-counter-stop! one more time. It is useful when you want to measure the time spent in the larger block that may already contain timer start/stop pairs.

    Calling time-counter-stop! on the already stopped counter has no effect.

    Method: time-counter-reset! (counter <time-counter>)
    Resets the value of counter. If counter is already running, it is forced to stop before being reset.

    Method: time-counter-value (counter <time-counter>)
    Returns the current value of the counter as the number of seconds, in a real number. The resolution depends on the source of the counter.

    Macro: with-time-counter counter expr ...
    A convenience macro to run the counter while expr ... are evaluated. Returns the result(s) of the last expression. It is defined as follows.
    (define-syntax with-time-counter
      (syntax-rules ()
        ((_ counter . exprs)
         (dynamic-wind
          (lambda () (time-counter-start! counter))
          (lambda () . exprs)
          (lambda () (time-counter-stop! counter))))
        ))
    

    The following example measures approximate times spend in process-A and process-B inside a loop.

    (let ((ta (make <real-time-counter>))
          (tb (make <real-time-counter>)))
      (dotimes (i 100000)
        (with-time-counter ta
          (process-A))
        (with-time-counter tb
          (process-B)))
      (format #t "Time spent in process-A: ~s\n" (time-counter-value ta))
      (format #t "Time spent in process-B: ~s\n" (time-counter-value tb))
      )
    

    9.24 gauche.uvector - Uniform vectors

    Module: gauche.uvector
    Provides vectors whose elements are of the same numeric type, as defined in SRFI-4 (@xref{srfi-4,,SRFI-4}).

    Gauche's implementation is a superset of SRFI-4 in a few ways:

    • Some routines takes optional parameters: TAGvector->list takes optional start and end indices, and TAGvector-ref takes optional fallback value.
    • Additional functions: copy procedures (TAGvector-copy and TAGvector-copy!), conversion procedures (TAGvector->vector and vector->TAGvector), and some arithmetic functions (TAGvector-add, etc.)
    • Implements the collection framework (See section 9.3 gauche.collection - Collection framework) and the sequence framework (See section 9.18 gauche.sequence - Sequence framework). So the methods like map, for-each, ref or subseq can be used on the SRFI-4 vector types.

    There are some advantages of using SRFI-4 vectors over normal (heterogeneous) vectors. It may be more compact than the normal vectors. Some operations (especially Gauche's extension of vector arithmetic operations) can bypass type check and conversion of individual elements, thus be more efficient. And it is much easier and efficient to communicate with external libraries that require homogeneous array of numbers; for example, OpenGL binding of Gauche uses SRFI-4 vectors extensively.

    The following ten types of vectors are defined.
    s8vector
    Elements are exact integers in the range between -2^7 and 2^7-1
    u8vector
    Elements are exact integers in the range between 0 and 2^8-1
    s16vector
    Elements are exact integers in the range between -2^15 and 2^15-1
    u16vector
    Elements are exact integers in the range between 0 and 2^16-1
    s32vector
    Elements are exact integers in the range between -2^31 and 2^31-1
    u32vector
    Elements are exact integers in the range between 0 and 2^32-1
    s64vector
    Elements are exact integers in the range between -2^63 and 2^63-1
    u64vector
    Elements are exact integers in the range between 0 and 2^64-1
    f32vector
    Elements are inexact real numbers representable in the float of C compiler that compiles Gauche. Usually it is a single precision IEEE floating point number.
    f64vector
    Elements are inexact real numbers representable in the double of C compiler that compiles Gauche. Usually it is a double precision IEEE floating point number.

    When you try to store a number out of the range of the vector type, an error is signalled by default. However, some procedures take an optional argument clamp that specifies alternative behavior in such a case. Clamp argument may take one of the following values.

    #f
    Default behavior (signals an error).
    high
    Clamps high bound; i.e. if the value to be stored is beyond the higher bound of the range, the maximum value is stored instead.
    low
    Clamps low bound; i.e. if the value to be stored is below the lower bound of the range, the minimum value is stored instead.
    both
    Clamps both sides; does both high and low.
    (list->u8vector '(-1))         => error
    (list->u8vector '(-1) 'low)    => #u8(0)
    (list->u8vector '(-1) 'high)   => error
    (list->u8vector '(3000) 'high) => #u8(255)
    (list->u8vector '(-100 20 300) 'both) => #u8(0 20 255)
    

    In the following description, TAG can be replaced for any of s8, u8, s16, u16, s32, u32, s64, u64, f32, f64.

    9.24.1 Uvector basic operations

    Builtin Class: <TAGvector>
    A class for TAGvector. It inherits <sequence>.

    Reader Syntax: #TAG(n ...)
    Denotes a literal homogeneous vector.
    #s8(3 -2 4)
    #u32(4154 88357 2 323)
    #f32(3.14 0.554525 -3.342)
    

    Function: TAGvector? obj
    [SRFI-4] Returns #t if obj is a TAGvector, #f otherwise.

    Function: TAGvector x ...
    [SRFI-4] Constructs TAGvector whose elements are numbers x .... The numbers must be exact integer for exact integer vectors, and in the valid range of the vector.
    (s8vector 1 2 3) => #s8(1 2 3)
    

    Function: make-TAGvector len &optional fill
    [SRFI-4] Constructs a TAGvector of length len. The elements are initialized by a number fill. For exact integer vectors, fill must be an exact integer and in the valid range. If fill is omitted, the content of the vector is undefined.
    (make-u8vector 4 0) => #u8(0 0 0 0)
    

    Function: TAGvector-length vec
    [SRFI-4] Returns the length of the TAGvector vec.

    Note that the generic function size-of can be used to obtain the length of vec as well, if you import gauche.collection (See section 9.3 gauche.collection - Collection framework).

    (s16vector-length '#s16(111 222 333)) => 3
    
    (use gauche.collection)
    (size-of '#s16(111 222 333)) => 3
    

    Function: TAGvector-ref vec k &optional fallback
    [SRFI-4+] Returns the k-th element of TAGvector vec.

    If the index k is out of the valid range, an error is signalled unless an optional argument fallback is given; in that case, fallback is returned.

    Note that the generic function ref can be used as well, if you import gauche.collection.

    (u16vector-ref '#u16(111 222 333) 1) => 222
    
    (use gauche.collection)
    (ref '#u16(111 222 333) 1) => 222
    

    Function: TAGvector-set! vec k n &optional clamp
    [SRFI-4+] Sets a number n to the k-th element of TAGvector vec. Optional clamp argument specifies the behavior when n is out of valid range. Default is to signal an error.

    Note that the setter of the generic function ref can be used as well, if you import gauche.collection.

    (let ((v (s32vector -439 852 8933)))
      (s32vector-set! v 1 4)
      v)
     => #s32vector(-439 4 8933)
    
    (use gauche.collection)
    (let ((v (s32vector -439 852 8933)))
      (set! (ref v 1) 4)
      v)
     => #s32vector(-439 4 8933)
    

    Function: TAGvector-copy vec &optional start end
    Copies the srfi-4 vector vec. If start and/or end are given, they limit the range of vec to be copied.
    (u8vector-copy '#u8(1 2 3 4))     => #u8(1 2 3 4)
    (u8vector-copy '#u8(1 2 3 4) 2)   => #u8(3 4)
    (u8vector-copy '#u8(1 2 3 4) 1 3) => #u8(2 3)
    

    Function: TAGvector-copy! dstvec srcvec

    Using collection and sequence framework, you can perform various operations on the homogeneous vectors.

    (use gauche.collection)
    (use gauche.sequence)
    
    (fold + 0 '#s32(1 2 3 4)) => 10
    
    (map-to <f32vector> * '#f32(3.2 1.1 4.3) '#f32(-4.3 2.2 9.4))
      => #f32(-13.760001 2.420000 40.420002)
    
    (subseq #u32(1 4 3 4 5) 2 4) => #u32(3 4)
    

    9.24.2 Uvector conversion operations

    Function: TAGvector->list vec &optional start end
    [SRFI-4+] Converts TAGvector vec to a list. If start and/or end are given, they limit the range of vec to be extracted.

    Note that the generic function coerce-to can be used as well, if you import gauche.collection.

    (u32vector->list '#u32(9 2 5)) => (9 2 5)
    
    (use gauche.collection)
    (coerce-to <list> '#u32(9 2 5)) => (9 2 5)
    

    Function: TAGvector->vector vec &optional start end
    Converts TAGvector vec to a vector. If start and/or end are given, they limit the range of vec to be copied.

    Note that the generic function coerce-to can be used as well, if you import gauche.collection.

    (f32vector->vector '#f32(9.3 2.2 5.5))   => #(9.3 2.2 5.5)
    (f32vector->vector '#f32(9.3 2.2 5.5) 2) => #(5.5)
    
    (use gauche.collection)
    (coerce-to <vector> '#f32(9.3 2.2 5.5)) => #(9.3 2.2 5.5)
    

    Function: list->TAGvector list &optional clamp
    [SRFI-4+] Converts a list list to a TAGvector. Optional argument clamp specifies the behavior when the element of list is out of the valid range.

    Note that the generic function coerce-to can be used as well, if you import gauche.collection.

    (list->s64vector '(9 2 5)) => #s64(9 2 5)
    
    (use gauche.collection)
    (coerce-to <s64vector> '(9 2 5)) => #s64(9 2 5)
    

    Function: vector->TAGvector vec &optional start end clamp
    Converts a vector vec to a TAGvector. If start and/or end are given, they limit the range of vec to be copied. Optional argument clamp specifies the behavior when the element of vec is out of the valid range.

    Note that the generic function coerce-to can be used as well, if you import gauche.collection.

    (vector->f64vector '#(3.1 5.4 3.2)) => #f64(3.1 5.4 3.2)
    
    (use gauche.collection)
    (coerce-to <f64vector> '#(3.1 5.4 3.2)) => #f64(3.1 5.4 3.2)
    

    Function: string->s8vector string &optional start end
    Function: string->u8vector string &optional start end
    Returns an s8vector or u8vector whose byte sequence is the same as the internal representation of the given string. Optional range arguments start and end specifies the character position inside string to be converted.

    These procedures are useful when you want to access byte sequence of the string randomly.

    (string->u8vector "abc") => #u8(97 98 99)
    
    

    Function: s8vector->string vec &optional start end
    Function: u8vector->string vec &optional start end
    Converts a byte sequence in s8vector or u8vector to a string that has the same byte sequence. Optional range arguments start and end specifies the byte position in vec to be converted.

    Note that these procedure may result an incomplete string if vec contains a byte sequence invalid as the internal encoding of the string.

    Function: string->s32vector string &optional start end
    Function: string->u32vector string &optional start end
    Returns an s32vector or u32vector whose elements are the internal codes of the characters in the string. Optional range arguments start and end specifies the character position inside string to be converted.

    These procedures are useful when you want to access the characters in the string randomly.

    Function: s32vector->string vec &optional start end
    Function: u32vector->string vec &optional start end
    Without start and end, these procedures work like this:
    (lambda (vec) (map-to <string> integer->char vec)))
    

    Optional range arguments start and end limits the range of conversion between them.

    Function: uvector-alias uvector-class vec &optional start end
    This procedure creates an uvector of class uvector-class that shares the storage of the given uniform vector vec. If optional start and end arugments are given, only the specified range of vec is used for the new vector. Since the storage is shared, modification of the original vector can be seen from the new vector, or vice versa.

    The class uvector-class must be either one of the uniform vector class, but is not necessary match the class of the source vector vec. In such case, the new vector looks at the same region of vec's memory, but interpretes it differently. For example, the following code determines whether Gauche is running on big-endian or little-endian machine:

    (let ((u8v (uvector-alias <u8vector> #u32(1))))
      (if (zero? (u8vector-ref u8v 0))
          'big-endian 
          'little-endian))
    

    If the uvector-class is other than s8vector or u8vector, the region the new vector points has to meet the alignment requirement. You can assume the beginning of the source vector is aligned suitable for any uniform vectors. So, for example, if you're creating u32vector from u8vector, the start and end must be multiple of 4 (or, if they're omitted, the length of the original u8vector must be multiple of 4). An error is signalled when the given parameters doesn't satisfy alignment constraint.

    9.24.3 Uvector numeric operations

    Function: TAGvector-add vec val &optional clamp
    Function: TAGvector-add! vec val &optional clamp
    Function: TAGvector-sub vec val &optional clamp
    Function: TAGvector-sub! vec val &optional clamp
    Function: TAGvector-mul vec val &optional clamp
    Function: TAGvector-mul! vec val &optional clamp
    Element-wise arithmetic. Vec must be a TAGvector, and val must be either a TAGvector, a vector, or a list of the same length as vec, or a number (an exact integer for integer vectors, and a real number for f32- and f64-vectors).

    If val is a TAGvector, its elements are added to, subtracted from, or multiplied by the corresponding elements of vec, respectively, and the results are gathered to a TAGvector and returned. The destructive version (those have bang `!' in the name) reuses vec to store the result. If the result of calculation goes out of the range of TAGvector's element, the behavior is specified by clamp optional argument. (For f32vector and f64vector, clamp argument is ignored and the result may contain infinity).

    If val is a number, it is added to, subtracted from, or multiplied by each element of vec, respectively.

    (s8vector-add '#s8(1 2 3 4) '#s8(5 6 7 8)) => #s8(6 8 10 12)
    (u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2)) => error
    (u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2) 'both) => #u8(0 0 1 2)
    
    (f32vector-mul '#f32(3.0 2.0 1.0) 1.5) => #f32(4.5 3.0 1.5)
    

    Function: TAGvector-div vec val
    Function: TAGvector-div! vec val
    Element-wise division of flonum vectors. These are only defined for f32vector and f64vector. val must be a TAGvector, a vector or a list of the same length as vec, or a real number.
    (f32vector-div '#f32(1.0 2.0 3.0) 2.0) => #f32(0.5 1.0 1.5)
    

    Function: TAGvector-and vec val
    Function: TAGvector-and! vec val
    Function: TAGvector-ior vec val
    Function: TAGvector-ior! vec val
    Function: TAGvector-xor vec val
    Function: TAGvector-xor! vec val
    Element-wise logical (bitwise) operation. These procedures are only defined for integral vectors. val must be a TAGvector, a vector or a list of the same length as vec, or an exact integer. Bitwise and, inclusive or or exclusive or is calculated between each element in vec and the corresponding element of val (when val is a non-scalar value), or val itself (when val is an integer). The result is returned in a TAGvector. The destructive version reuses vec to store the result.

    Function: TAGvector-dot vec0 vec1
    Calculates the dot product of two TAGvectors. The length of vec0 and vec1 must be the same.

    Function: TAGvector-range-check vec min max
    Vec must be a TAGvector, and each of min and max must be either a TAGvector, a vector or a list of the same length as vec, or a number, or #f.

    For each element in vec, this procedure checks if the value is between minval and maxval inclusive, where minval and maxval are the corresponding values of min and max (when min and/or max is/are non-scalar value) or min and max themselves (when min and/or max is/are a number). When min is #f, negative infinity is assumed. When max is #f, positive infinity is assumed.

    If all the elements in vec are within the range, #f is returned. Otherwise, the index of the leftmost element of vec that is out of range is returned.

    (u8vector-range-check '#u8(3 1 0 2) 0 3)  => #f
    (u8vector-range-check '#u8(3 1 0 2) 1 3)  => 2
    
    (u8vector-range-check '#u8(4 32 64 98) 0 '#u8(10 40 70 90))
      => 3
    
    ;; Range check in a program
    (cond
     ((u8vector-range-check u8v 1 31)
      => (lambda (i)
          (errorf "~sth vector element is out of range: ~s"
                  i (u8vector-ref u8v i))))
     (else (do-something u8v)))
    

    Function: TAGvector-clamp vec min max
    Function: TAGvector-clamp! vec min max
    Vec must be a TAGvector, and each of min and max must be either a TAGvector, a vector or a list of the same length as vec, or a number, or #f.

    Like TAGvector-range-check, these procedures check if each element of vec are within the range between minval and maxval inclusive, which are defived from min and max. If the value is less than minval, it is replaced by minval. If the value is grater than maxval, it is replaced by maxval.

    TAGvector-clamp creates a copy of vec and do clamp operation on it, while TAGvector-clamp! modifies vec. Both return the clamped vector.

    (s8vector-clamp '#s8(8 14 -3 -22 0) -10 10) => #s8(8 10 -3 -10 0)
    

    9.24.4 Uvector block I/O

    A uniform vector can be seen as an abstraction of a chunk of memory. So you might want to use it for binary I/O. Yes, you can do it.

    Function: read-block! vec &optional iport start end
    Reads a chunk of data from the given input port iport, and stores it to the uniform vector vec. You can give any uniform vector. If optional start and end arguments are given, they specify the index range in vec that is to be filled, and the rest of the vector remains untouched. Otherwise, entire vector is used. If iport is omitted, the current input port is used.

    If the input reached EOF before the required region of vec is filled, the rest of the vector is untouched.

    If iport is already reached EOF when read-block! is called, an EOF object is returned. Otherwise, the procedure returns the number of elements read (not bytes).

    If the iport is a buffered port with `modest' or `none' buffering mode (See section 6.18.3 File ports), read-block! may return before all the elements in vec is filled, even if iport hasn't reached EOF. The ports connected to a pipe or a network socket behave so by default. If you know there will be enough data arriving and want to make sure vec is filled, change the buffering mode of iport to `full'.

    The data is read as a byte stream, so if you give uniform vectors other than s8vector or u8vector, your result may affected by the endianness of the platform. Suppose the input stream has a byte sequence #x01, #x02, #x03, #x04. If you read it into u32vector, the first element you'll get may be #x01020304 if you're using big-endian architecture, or #x04030201 if you're using little-endian architecture.

    Function: write-block vec &optional oport start end
    Writes out the content of the uniform vector vec 'as is' to the output port oport. If oport is omitted, the current output port is used. If optional start and end arguments are given, they specify the index range in vec to be written out. This procedure returns an unspecified value.

    If you write out a uniform vector except s8vector and u8vector, the care should be taken about the endianness, as in read-block!. The number #x01020304 in your u32vector may be written out as the byte sequence #x01, #x02, #x03, #x04 or #x04, #x03, #x02, #x01, depending on your architecture.

    9.25 gauche.version - Comparing version numbers

    Module: gauche.version
    This module provides a convenient procedure to compare version numbers or revision numbers, such as "0.5.1", "3.2-3" or "8.2pl1". Usually each release of software component has a version number, and you can define order between them. For example, version "1.2.3" is newer than "1.2" and older than "2.1". You can compare those version numbers like this:
    (version<? "2.2.3" "2.2.11")     => #t
    (version<? "2.3.1" "2.3")        => #f
    (version<? "2.3.1-1" "2.3.1-10") => #t
    (version<? "13a" "5b")           => #f
    

    There are no standard way to name versions, so I chose one convention. This won't work for all possible variations, but I think it covers typical cases.

    Strictly speaking, you can only define partial order between version numbers, for there can be branches. This module uses simple measure and just assumes the version numbers can be fully ordered.

    The version number here is defined by the following syntax.

     <version> : <principal-release>
               | <version> <post-subrelease>
               | <version> <pre-subrelease>
     <principal-release> : <relnum>
     <post-subrelease>   : [.-] <relnum>
     <pre-subrelease>    : _ <relnum>
     <relnum>            : [0-9A-Za-z]+
    

    Typically <relnum> is composed by numeric part and extension part. For example, "23a" is composed by an integer 23 and extension "a". If <relnum> doesn't begins with digits, we assume its numeric part is -1.

    Then, the order of <relnum> is defined as follows:

    1. If relnum A and relnum B have different numeric part, we ignore the extension and order them numerically, e.g. "3b" < "4a".
    2. If relnum A and relnum B have the same numeric part, we compare extension by alphabetically, e.g. "4c" < "4d" and "5" < "5a".

    Given the order of <relnum>, the order of version numbers are defined as follows:

    1. Decompose each version number into a list of <principal-release> and subsequence subrelease components. We call each element of the list "release components".
    2. If the first release component of both lists are the same, remove it from both. Repeat this until the head of the lists differ.
    3. Now we have the following cases.
      1. Both lists are empty: versions are the same.
      2. One list (A) is empty and the other list (B) has post-subrelease at head: A is prior to B
      3. One list (A) is empty and the other list (B) has pre-subrelease at head: B is prior to A
      4. List A's head is post-subrelease and list B's head is pre-subrelease: B is prior to A
      5. Both lists have post-subrelease or pre-subrelease at head: compare their relnums.

    Here are some examples:

    "1" < "1.0" < "1.1" < "1.1.1" < "1.1.2" < "1.2" < "1.11"
    "1.2.3" < "1.2.3-1" < "1.2.4"
    "1.2.3" < "1.2.3a" < "1.2.3b"
    "1.2_rc0" < "1.2_rc1" < "1.2" < "1.2-pl1" < "1.2-pl2"
    "1.1-patch112" < "1.2_alpha"
    

    The reason of having <pre-subrelease> is to allow "release candidate" or "pre-release" version.

    Function: version=? ver1 ver2
    Function: version<? ver1 ver2
    Function: version<=? ver1 ver2
    Function: version>? ver1 ver2
    Function: version>=? ver1 ver2
    Returns a boolean value depending on the order of two version number string ver1 and ver2. If the arguments contain invalid strings as the defined version number, an error is signalled.

    Function: version-compare ver1 ver2
    Compares two version number strings ver1 and ver2, and returns either -1, 0, or 1, depending whether ver1 is prior to ver2, ver1 is the same as ver2, or ver1 is after ver2, respectively.

    Function: relnum-compare rel1 rel2
    This is lower-level procedure of version-compare. Compares two release numbers (relnums) rel1 and rel2, and returns either -1, 0, or 1 depending whether rel1 is prior to rel2, rel1 is the same as rel2, or rel1 is after rel2, respectively.

    10. Library modules - SRFIs

    This chapter lists modules that provides SRFI functionalities. Note that some of SRFI features are built in Gauche core and not listed here. See section 2.1 Standard conformance, for entire list of supported SRFIs.

    10.1 srfi-0 - Feature conditional

    Module: srfi-0
    Provides SRFI-0 cond-expand macro form. Now this module is autoloaded when cond-expand is used, so you don't need to say (use srfi-0) explicitly; it is required to write a portable Scheme program.

    Macro: cond-expand (feature-requirement command-or-definition ...) ...
    [SRFI-0] This macro expands to command-or-definition ... if Gauche supports feature-requirement. In a way, it can be used to absorb the different feature sets supported by different Scheme implementations.

    feature-requiremnt must be in the following syntax:

    feature-requirement
      : feature-identifier
      | (and feature-requirement ...)
      | (or  feature-requirement ...)
      | (not feature-requirement)
    

    feature-identifier is a symbol that indicates a feature. If such a feature is supported in Gauche, it satisfies the feature-requirement. You can do boolean combination of feature-requirements to compose more complex conditions.

    The macro tests each feature-requirement in order, and if one is satisfied, the macro itself expands to the corresponding command-or-definition ....

    The last clause may begin with a symbol else instead of feature-requirement. If no condition is fulfilled before it, then the macro expands to the command-or-definitions of the else clause. If there's no else clause and no condition is fulfilled, an error is signalled.

    Currently, Gauche recognizes srfi names (e.g. srfi-1) that it supports (See section 2.1 Standard conformance, for the list of supported SRFIs), and a symbol gauche as feature-identifier.

    Suppose you are writing a program that requires srfi-13 (string library). In Gauche, the standard way to use srfi-13 is like this:

    (use srfi-13)
    
    ;; ... your program ...
    

    However, the 'use' macro is Gauche specific and won't work on other Scheme implementations. You can write instead:

    (cond-expand
      (srfi-13
        ;; ... your program ...
      ))
    

    If the implementation supports srfi-13, the form expands to your program. Note that Gauche issues (use srfi-13) for you in this case.

    The above form signals an error if the implementation doesn't support srfi-13. However, you might want to run your program on such implentations as well, by providing alternative library definitions.

    (cond-expand
     (srfi-13
       ;; ... your program ...
     )
     (else
       (load "my-srfi-13-implementation")
       ;; ... your program ...
     ))
    

    10.2 srfi-1 - List library

    Module: srfi-1
    SRFI-1 is a rich collection of list manipulation library (@xref{srfi-1,[SRFI-1],SRFI-1}). It is available by saying (use srfi-1). The implementation is based on Olin Shivers's reference implementation. I splitted it into number of subfiles that will be autoloaded on demand.

    10.2.1 List constructors

    Function: xcons cd ca
    [SRFI-1] Equivalent to (cons ca cd). Useful to pass to higher-order procedures.

    Function: cons* elt1 elt2 ...
    [SRFI-1] Like list, but the last argument provides the tail of the constructed list. This is just a synonym of Gauche built-in procedure list*.
    (cons* 1 2 3 4) => (1 2 3 . 4)
    (cons* 1) => 1
    

    Function: list-tabulate n init-proc
    [SRFI-1] Constructs an n-element list, in which each element is generated by (init-proc i).
    (list-tabulate 4 values) => (0 1 2 3)
    

    Function: circular-list elt1 elt2 ...
    [SRFI-1] Constructs a circular list of the elements.
    (circular-list 'z 'q) => (z q z q z q ...)
    

    Function: iota count &optional (start 0) (step 1)
    [SRFI-1] Returns a list of numbers, starting from start, increasing by step.
    (iota 5) => (0 1 2 3 4)
    (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)
    

    10.2.2 List predicates

    Function: proper-list? x
    [SRFI-1] Returns #t if x is a proper list.

    Function: circular-list? x
    [SRFI-1] Returns #t if x is a circular list.

    Function: dotted-list? x
    [SRFI-1] Returns #t if x is a finite, non-nil-terminated list. This includes non-pair, non-() values (e.g. symbols, numbers), which are considered to be dotted lists of length 0.

    Function: null-list? list
    [SRFI-1] Returns #t if list is the empty list (), and #f if list is a non-null, proper or circular list. This procedure signals an error if list is not a proper or circular list.

    Function: not-pair? x
    [SRFI-1] (lambda (x) (not (pair? x))).

    SRFI-1 says: Provided as a procedure as it can be useful as the termination condition for list-processing procedures that wish to handle all finite lists, both proper and dotted.

    Function: list= elt= list ...
    [SRFI-1] Determines list equality by comparing every n-th element of given lists by the procedure elt=.

    It is an error to apply list= to anything except proper lists.

    The equality procedure must be consistent with eq?, i.e.

    (eq? x y) => (elt= x y).
    

    10.2.3 List selectors

    Function: first pair
    Function: second pair
    Function: third pair
    Function: fourth pair
    Function: fifth pair
    Function: sixth pair
    Function: seventh pair
    Function: eighth pair
    Function: ninth pair
    Function: tenth pair
    [SRFI-1] Returns n-th element of the (maybe improper) list.

    Function: car+cdr pair
    [SRFI-1] Returns two values, (car pair) and (cdr pair).

    Function: take x i
    Function: drop x i
    [SRFI-1] take returns the first i elements of list x. drop returns all but the first i elements of list x.
    (take '(a b c d e)  2) => (a b)
    (drop '(a b c d e)  2) => (c d e)
    

    x may be any value:

    (take '(1 2 3 . d) 2) => (1 2)
    (drop '(1 2 3 . d) 2) => (3 . d)
    (drop '(1 2 3 . d) 3) => d
    

    drop is exactly equivalent to performing i cdr operations on x. The returned value shares a common tail with x. On the other hand, take always allocates a new list for result if the argument is a list of non-zero length.

    Function: take-right flist i
    Function: drop-right flist i
    [SRFI-1] take-right returns the last i elements of flist. drop-right returns all but the last i elements of flist.
    (take-right '(a b c d e) 2) => (d e)
    (drop-right '(a b c d e) 2) => (a b c)
    

    flist may be any finite list.

    (take-right '(1 2 3 . d) 2) => (2 3 . d)
    (drop-right '(1 2 3 . d) 2) => (1)
    (take-right '(1 2 3 . d) 0) => d
    (drop-right '(1 2 3 . d) 0) => (1 2 3)
    

    take-right's return value always shares a common tail with flist. drop-right always allocates a new list if the argument is a list of non-zero length.

    Function: take! x i
    Function: drop-right! x i
    [SRFI-1] Linear update variants of take and drop-right. Those procedures may destructively modifies x.

    If x is circular, take! may return a list shorter than expected.

    Function: split-at x i
    Function: split-at! x i
    [SRFI-1] split-at splits the list x at index i, returning a list of the first i elements, and the remaining tail.
    (split-at '(a b c d e) 2) => (a b) (c d e)
    

    split-at! is the linear-update variant. It may destructively modifes x to produce the result.

    Function: last pair
    [SRFI-1] Returns the last element of the non-empty, finite list pair. It is equivalent to (car (last-pair pair)). Note that last-pair is Gauche built-in procedure.

    10.2.4 List miscellaneous routines

    Function: length+ x
    [SRFI-1] If x is a proper list, returns its length. Otherwise, returns #f.

    Function: concatenate list-of-lists
    Function: concatenate! list-of-lists!
    [SRFI-1] Equivalent to (apply append list-of-lists) and (apply append! list-of-lists), respectively.

    Function: append-reverse rev-head tail
    Function: append-reverse! rev-head tail
    [SRFI-1] append-reverse returns (append (reverse rev-head) tail). append-reverse! is the linear-update variant.

    Function: zip clist1 clist2 ...
    [SRFI-1] Equivalent to (map list clist1 clist2 ...). If zip is passed n lists, it returns a list as long as the shortest of these lists, each element of which is an n-element list comprised of the corresponding elements from the parameter lists.
    (zip '(one two three) 
         '(1 2 3)
         '(odd even odd even odd even odd even))
         => ((one 1 odd) (two 2 even) (three 3 odd))
    
    (zip '(1 2 3)) => ((1) (2) (3))
    

    At least one of the argument lists must be finite:

    (zip '(3 1 4 1) (circular-list #f #t)) 
         => ((3 #f) (1 #t) (4 #f) (1 #t))
    

    Function: unzip1 list
    Function: unzip2 list
    Function: unzip3 list
    Function: unzip4 list
    Function: unzip5 list
    [SRFI-1] unzip1 takes a list of lists, where every list must contain at least one element, and returns a list containing the initial element of each such list. unzip2 takes a list of lists, where every list must contain at least two elements, and returns two values: a list of the first elements, and a list of the second elements. unzip3 does the same for the first three elements of the lists, and so on.
    (unzip2 '((1 one) (2 two) (3 three))) =>
       (1 2 3) and
       (one two three)
    

    Function: count pred clist1 clist2 ...
    [SRFI-1] A procedure pred is applied to the n-th element of given lists, from n is zero to the length of the the shortest finite list in the given lists, and the count of times pred returned true is returned.
    (count even? '(3 1 4 1 5 9 2 5 6)) => 3
    (count < '(1 2 4 8) '(2 4 6 8 10 12 14 16)) => 3
    

    At least one of the argument lists must be finite:

    (count < '(3 1 4 1) (circular-list 1 10)) => 2
    

    Function: count$ pred
    Partial application version of count
    ((count$ pred) arg ...) === (count pred arg ...)
    

    10.2.5 List fold, unfold & map

    Function: fold kons knil clist1 clist2 ...
    [SRFI-1] The fundamental list iterator. When it is given a single list clist1 = (e1 e2 ... en), then this procedure returns
    (kons en ... (kons e2 (kons e1 knil)) ... ) 
    

    If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

    Examples:

    (fold + 0 '(3 1 4 1 5 9)) => 23 ;sum up the elements
    (fold cons '() '(a b c d e)) => (e d c b a) ;reverse
    (fold cons* '() '(a b c) '(1 2 3 4 5))
        => (c 3 b 2 a 1) ;n-ary case
    

    Function: fold-right kons knil clist1 clist2 ...
    [SRFI-1] The fundamental list recursion operator. When it is given a single list clist1 = (e1 e2 ... en), then this procedure returns
    (kons e1 (kons e2 ... (kons en knil)))
    

    If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

    Examples:

    (fold-right cons '() '(a b c d e))
       => (a b c d e) ;copy list
    (fold-right cons* '() '(a b c) '(1 2 3 4 5))
       => (a 1 b 2 c 3) ;n-ary case
    

    Function: pair-fold kons knil clist1 clist2 ...
    Function: pair-fold-right kons knil clist1 clist2 ...
    [SRFI-1] Like fold and fold-right, but the procedure kons gets each cdr of the given clists, instead of car.

    Function: reduce f ridentity list
    Function: reduce-right f ridentity list
    [SRFI-1] Variant of fold and fold-right. F must be a binary operator, and ridentity is the value such that for any value x that is valid as f's input,
     (f x ridentity) == ridentity
    

    These functions effectively do the same thing as fold or fold-right, respectively, but omit application of f when list contains exactly one element, using the nature of ridentity.

    Function: unfold p f g seed &optional tail-gen
    [SRFI-1] Fundamental recursive list constructor. Defined by the following recursin.
    (unfold p f g seed tail-gen) ==
       (if (p seed)
           (tail-gen seed)
           (cons (f seed)
                 (unfold p f g (g seed))))
    

    That is, p determines where to stop, g is used to generate successive seed value from the current seed value, and f is used to map each seed value to a list element.

    Function: unfold-right p f g seed &optional tail
    [SRFI-1] Fundamental iterative list constructor. Defined by the following recursin.
    (unfold-right p f g seed tail) ==
      (let lp ((seed seed) (lis tail))
        (if (p seed)
            lis
            (lp (g seed) (cons (f seed) lis))))
    

    Function: append-map f clist1 clist2 ...
    Function: append-map! f clist1 clist2 ...
    [SRFI-1] Equivalent to
      (apply append (map f clist1 clist2 ...))
      (apply append! (map f clist1 clist2 ...))
    

    At least one of the list arguments must be finite.

    Function: map! f list1 clist2 ...
    [SRFI-1] The procedure f is applied to each element of list1 and corresponding elements of clists, and the result is collected to a list. Celss in list1 is reused to construct the result list.

    Function: map-in-order f clist1 clist2 ...
    [SRFI-1] A variant of map, but it guarantees to apply f on each elements of arguments in a left-to-right order. Since Gauche's map implementation follows the same order, this function is just a synonym of map.

    Function: pair-for-each f clist1 clist2 ...
    [SRFI-1] Like for-each, but the procedure f is applied on each cdr of clists.

    Function: filter-map f clist1 clist2 ...
    [SRFI-1] Like map, but only true values are saved. At least one of the list arguments must be finite.
    (filter-map (lambda (x) (and (number? x) (* x x)))
                '(a 1 b 3 c 7))
      => (1 9 49)
    

    Function: fold$ kons &optional knil
    Function: fold-right$ kons &optional knil
    Function: reduce$ f &optional ridentity
    Function: reduce-right$ f &optional ridentity
    Partial application versions of fold, fold-right, reduce, and reduce-right.

    10.2.6 List filtering & partitioning

    Function: filter pred list
    Function: filter! pred list
    [SRFI-1] A procedure pred is applied on each element of list, and a list of elements that pred returned true on it is returned.
    (filter odd? '(3 1 4 5 9 2 6)) => (3 1 5 9)
    

    filter! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: remove pred list
    Function: remove! pred list
    [SRFI-1] A procedure pred is applied on each element of list, and a list of elements that pred returned false on it is returned.
    (remove odd? '(3 1 4 5 9 2 6)) => (4 2 6)
    

    remove! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: partition pred list
    Function: partition! pred list
    [SRFI-1] filter and remove simultaneously, i.e. returns two lists, the first is the result of filtering elements of list by pred, and the second is the result of removing elements of list by pred.
    (partition odd? '(3 1 4 5 9 2 6))
      => (3 1 5 9) (4 2 6)
    

    partition! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: filter$ pred
    Function: remove$ pred
    Function: partition$ pred
    Partial application versions of filter, remove and partition.

    10.2.7 List searching

    Function: find pred clist
    [SRFI-1] Applies pred for each element of clist, from left to right, and returns the first element that pred returns true on.

    Function: find-tail pred clist
    [SRFI-1] Applies pred for each element of clist, from left to right, and when pred returns a true value, returns the pair whose car is the element.

    Function: take-while pred clist
    Function: take-while! pred list
    [SRFI-1] Returns the longest initial prefix of clist whose elements all satisfy pred.

    Function: drop-while pred clist
    [SRFI-1] Drops the longest initial prefix of clist whose elements all satisfy pred, and returns the rest.

    Function: span pred clist
    Function: span! pred list
    Function: break pred clist
    Function: break! pred list
    [SRFI-1] span is equivalent to (values (take-while pred clist) (drop-while pred clist)). break inverts the sense of pred.

    Function: any pred clist1 clist2 ...
    [SRFI-1] Applies pred across each element of clists, and returns true if any application of pred returns true. The returned value is the true value pred returned.

    Function: every pred clist1 clist2 ...
    [SRFI-1] Applies pred across each element of clists, and returns true if every application of pred returns true. If all applications returns a true value until one of the lists is exhausted, every returns the value the last pred returned.

    Function: list-index pred clist1 clist2 ...
    [SRFI-1] Returns the index of the leftmost element that satisfies pred.

    Function: member$ item
    Function: find$ pred
    Function: find-tail$ pred
    Function: any$ pred
    Function: every$ pred
    Partial application version of member, find, find-tail, any and every.

    10.2.8 List deletion

    Function: delete x list &optional elt=
    Function: delete! x list &optional elt=
    [SRFI-1] Equivalent to
      (remove (lambda (y) (elt= x y)) list)
      (remove! (lambda (y) (elt= x y)) list)
    

    The comparison procedure, elt=, defaults to equal?.

    Function: delete$ x
    Partial application version of delete.

    Function: delete-duplicates list &optional elt=
    Function: delete-duplicates! list &optional elt=
    [SRFI-1] Removes duplicate elements from list. If there are multiple equal elements in list, the result list only contains the first or leftmost of these elements in the result. The order of these surviving elements is the same as in the original list. The comparison procedure, elt=, defaults to equal?.

    10.2.9 Association lists

    Function: alist-cons key datum alist
    [SRFI-1] Returns (cons (cons obj1 obj2) obj3). This is an alias of the Gauche builtin procedure acons.

    Function: alist-copy alist
    [SRFI-1] Returns a fresh copy of alist.

    Function: alist-delete key alist &optional =
    Function: alist-delete! key alist &optional =
    [SRFI-1]

    Function: assoc$ item
    Partial application version of assoc.

    10.2.10 Lists as sets

    These procedures use lists as a set.

    Function: lset<= elt= list1 ...
    [SRFI-1]

    Function: lset= elt= list1 list2 ...
    [SRFI-1]

    Function: lset-adjoin elt= list elt ...
    [SRFI-1]

    Function: lset-union elt= list1 ...
    [SRFI-1]

    Function: lset-intersection elt= list1 list2 ...
    [SRFI-1]

    Function: lset-difference elt= list1 list2 ...
    [SRFI-1]

    Function: lset-xor elt= list1 ...
    [SRFI-1]

    Function: lset-diff+intersection elt= list1 list2 ...
    [SRFI-1]

    Function: lset-union! elt= list ...
    Function: lset-intersection! elt= list1 list2 ...
    Function: lset-difference! elt= list1 list2 ...
    Function: lset-xor! elt= list1 ...
    Function: lset-diff+intersection! elt= list1 list2 ...
    [SRFI-1] Linear update variant of the corresponding procedures. The cells in the first list argument may be reused to construct the result.

    10.3 srfi-2 - And-let*

    Module: srfi-2
    Provides SRFI-2 and-let* macro.

    Macro: and-let* (binding ...) body ...
    [SRFI-2] In short, it works like let*, but returns #f immediately whenever the expression in bindings evaluates to #f.

    Each binding should be one of the following form:

    (variable expression)
    The expression is evaluated; if it yields true value, the value is bound to variable, then proceed to the next binding. If no more bindings, evaluates body .... If expression yieds #f, stops evaluation and returns #f from and-let*.
    (expression)
    In this form, variable is omitted. Expression is evaluated and the result is used just to determine whether we continue or stop further evaluation.

    Let's see some examples. The following code searches key from an assoc-list alist and returns its value if found.

    (and-let* ((entry (assoc key alist))) (cdr entry))
    

    If arg is a string representation of an exact integer, returns its value; otherwise, returns 0:

    (or (and-let* ((num (string->number arg))
                   ((exact? num))
                   ((integer? num)))
          num)
        0)
    

    The following is a hypothetical code that searches a certain server port number from a few possibilities (environment variable, configuration file, ...)

    (or (and-let* ((val (sys-getenv "SERVER_PORT")))
          (string->number val))
        (and-let* ((portfile (expand-path "~/.server_port"))
                   ((file-exists? portfile))
                   (val (call-with-input-string portfile port->string)))
          (string->number val))
        8080) ; default
    

    10.4 srfi-4 - Homogeneous vectors

    Module: srfi-4
    SRFI-4 is now implemented in gauche.uvector module See section 9.24 gauche.uvector - Uniform vectors. This module simply inherits gauche.uvector for backward-compatibility.

    10.5 srfi-9 - Record types

    Module: srfi-9
    Contains a macro to use record types. A record type is implemented on top of Gauche's object system.

    The SRFI-9 record type is not as powerful as the object system, but it will be useful if you want your program to be portable.

    Macro: define-record-type name (constructor init-tag ...) predicate (field accessor [modifier]) ...
    Creates a record type and binds it to name. In Gauche, a record type is just a subclass of <record>.

    constructor is bound to a procedure that creates an instance of the record type, which takes as many arguments as init-tag .... Each init-tag corresponds to one of the field name, and the fields of the created record instance is initialized accordingly. Not all of fields need to appear in init-tag; uninitialized fields remain unbound.

    predicate is bound to a procedure that takes one argument, and returns #t if the argument is an instance of the defined record type, #f otherwise.

    Followings are field specifications. The record has fields field ..., and each field can be accessed by a method accessor. If modifier is given to the field, it is bound to a method that sets the value to the field.

    Example:

    (define-record-type pare
      (kons x y) pare?
      (x kar set-kar!)
      (y kdr))
     => #<class pare>
    
    (pare? (kons 2 3)) => #t
    (pare? (cons 2 3)) => #f
    
    (kar (kons 2 3)) => 2
    (kdr (kons 2 3)) => 3
    
    (let ((x (kons 2 3)))
      (set-kar! x -1)
      (kar x)) => -1
    

    Conceptually, the above example is expanded into the following sequence of forms.

    (define-class pare (<record>) (x y))
    (define (kons x y)
      (let ((obj (make pare)))
        (slot-set! obj 'x x) 
        (slot-set! obj 'y y)
        obj))
    (define (pare? obj) (is-a? obj pare))
    (define-method kar ((obj pare))
      (slot-ref obj 'x))
    (define-method set-kar! ((obj pare) value)
      (slot-set! obj 'x value))
    (define-method kdr ((obj pare))
      (slot-ref obj 'y))
    

    10.6 srfi-11 - Let-values

    Module: srfi-11
    Defines two macros, let-values and let*-values. They are convenient to use with multiple values (@xref{srfi-11,,[SRFI-11]}).

    Macro: let-values ((vars expr) ...) body ...
    [SRFI-11] vars are a list of variables. expr is evaluated, and its first return value is bound to the first variable in vars, its second return value to the second variable, and so on, then body is evaluated. The scope of exprs are the outside of let-values form, like let.
    (let-values (((a b) (values 1 2))
                 ((c d) (values 3 4)))
      (list a b c d)) => (1 2 3 4)
    
    (let ((a 1) (b 2) (c 3) (d 4))
      (let-values (((a b) (values c d))
                   ((c d) (values a b)))
        (list a b c d))) => (3 4 1 2)
    

    vars can be a dotted list or a single symbol, like the lambda parameters.

    (let-values (((x . y) (values 1 2 3 4)))
      y) => (2 3 4)
    
    (let-values ((x (values 1 2 3 4)))
      x) => (1 2 3 4)
    

    If the number of values returned by expr doesn't match what vars expects, an error is signalled.

    Macro: let*-values ((vars expr) ...) body ...
    [SRFI-11] Same as let-values, but each expr's scope includes the preceding vars.
    (let ((a 1) (b 2) (c 3) (d 4))
      (let*-values (((a b) (values c d))
                    ((c d) (values a b)))
        (list a b c d))) => (3 4 3 4)
    

    10.7 srfi-13 - String library

    Module: srfi-13
    Defines a large set of string-related functions. In Gauche, those functions are splitted to number of files and the form (use srfi-13) merely sets up autoloading of those files. So it is not likely to slow down the script startup.

    See SRFI-13 (@xref{srfi-13, [SRFI-13], SRFI-13}) for the detailed specification and discussion of design issues. This manual serves as a reference of function API. Some SRFI-13 functions are Gauche built-in and not listed here.

    Note: SRFI-13 documents suggests the name of the module that implements these functions to be "string-lib" and "string-lib-internals". Gauche uses the name "srfi-13" for consistency.

    10.7.1 General conventions

    There are a few common factors in string library API, which I don't repeat in each function description

    argument convention
    The following argument names imply their types.
    s, s1, s2
    Those arguments must be strings.
    char/char-set/pred
    This argument can be a character, a character-set object, or a predicate that takes a single character and returns a boolean value. "Applying char/char-set/pred to a character" means, if char/char-set/pred is a character, it is compared to the given character; if char/char-set/pred is a character set, it is checked if the character set contains the given character; if char/char-set/pred is a procedure, it is applied to the given character. "A character satisfies char/char-set/pred" means such application to the character yields true value.
    start, end
    Lots of SRFI-13 functions takes these two optional arguments, which limit the area of input string from start-th character (inclusive) to end-th character (exclusive), where the operation is performed. When specified, the condition 0 <= start <= end <= length of the string must be satisfied. Default value of start and end is 0 and the length of the string, respectively.
    `shared' variant
    Some functions have variants with "/shared" attached to its name. SRFI-13 defines those functions to allow to share the part of input string, for better performance. Gauche doesn't have a concept of shared string, and these functions are mere synonyms of their non-shared variants. However, Gauche internally shares the storage of strings, so generally you don't need to worry about the overhead of copying substrings.
    `right' variant
    Most functions works from left to right of the input string. Some functions have variants with "-right" to its name, that works from right to left.

    10.7.2 String predicates

    Function: string-null? s
    [SRFI-13] Returns #t if s is an empty string, "".

    Function: string-every char/char-set/pred s &optional start end
    [SRFI-13] Sees if every character in s satisfies char/char-set/pred. If so, string-every returns the value that is returned at the last application of char/char-set/pred. If any of the application returns #f, string-every returns #f immediately.

    Function: string-any char/char-set/pred s &optional start end
    [SRFI-13] Sees if any character in s satisfies char/char-set/pred. If so, string-any returns the value that is returned by the application. If no character satisfies char/char-set/pred, #f is returned.

    10.7.3 String Constructors

    Function: string-tabulate proc len
    [SRFI-13] proc must be a procedure that takes an integer argument and returns a character. string-tabulate creates a string, whose i-th character is calculated by (proc i).
    (string-tabulate
      (lambda (i) (integer->char (+ i #x30))) 10)
     => "0123456789"
    

    Function: reverse-list->string char-list
    [SRFI-13] == (list->string (reverse char-list)).

    10.7.4 String selection

    Function: substring/shared s start &optional end
    [SRFI-13] In Gauche, this is the same as substring, except that the end argument is optional.
    (substring/shared "abcde" 2) => "cde"
    

    Function: string-copy! target tstart s &optional start end
    [SRFI-13] Copies a string s into a string target from the position tstart. Optional start and end arguments limits the range of s. If the copied string run over the end of target, an error is signalled.
    (define s (string-copy "abcde"))
    (string-copy! s 2 "ZZ")
    s => "abZZe"
    

    Function: string-take s nchars
    Function: string-drop s nchars
    Function: string-take-right s nchars
    Function: string-drop-right s nchars
    [SRFI-13] Returns the first nchars-character string of s (string-take) or the string without first nchars (string-drop). The *-right variation counts from the end of string. It is guaranteed that the returned string is always a copy of s, even no character is dropped.
    (string-take "abcde" 2) => "ab"
    (string-drop "abcde" 2) => "cde"
    
    (string-take-right "abcde" 2) => "cde"
    (string-drop-right "abcde" 2) => "ab"
    

    Function: string-pad s len &optional char start end
    Function: string-pad-right s len &optional char start end
    [SRFI-13]

    Function: string-trim s &optional char/char-set/pred start end
    Function: string-trim-right s &optional char/char-set/pred start end
    Function: string-trim-both s &optional char/char-set/pred start end
    [SRFI-13]

    10.7.5 String comparison

    Function: string-compare s1 s2 proc< proc= proc> &optional start1 end1 start2 end2
    Function: string-compare-ci s1 s2 proc< proc= proc> &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string= s1 s2 &optional start1 end1 start2 end2
    Function: string<> s1 s2 &optional start1 end1 start2 end2
    Function: string< s1 s2 &optional start1 end1 start2 end2
    Function: string<= s1 s2 &optional start1 end1 start2 end2
    Function: string> s1 s2 &optional start1 end1 start2 end2
    Function: string>= s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-ci= s1 s2 &optional start1 end1 start2 end2
    Function: string-ci<> s1 s2 &optional start1 end1 start2 end2
    Function: string-ci< s1 s2 &optional start1 end1 start2 end2
    Function: string-ci<= s1 s2 &optional start1 end1 start2 end2
    Function: string-ci> s1 s2 &optional start1 end1 start2 end2
    Function: string-ci>= s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-hash s &optional bound start end
    Function: string-hash-ci s &optional bound start end
    [SRFI-13]

    10.7.6 String Prefixes & Suffixes

    Function: string-prefix-length s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-length s1 s2 &optional start1 end1 start2 end2
    Function: string-prefix-length-ci s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-length-ci s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-prefix? s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix? s1 s2 &optional start1 end1 start2 end2
    Function: string-prefix-ci? s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-ci? s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    10.7.7 String searching

    Function: string-index s char/char-set/pred &optional start end
    Function: string-index-right s char/char-set/pred &optional start end
    [SRFI-13] Looks for the first element in a string s that matches char/char-set/pred, and returns its index. If char/char-set/pred is not found in s, returns #f. Optional start and end limit the range of s to search.
    (string-index "Aloha oe" #\a) => 4
    (string-index "Aloha oe" #[Aa]) => 0
    (string-index "Aloha oe" #[\s]) => 5
    (string-index "Aloha oe" char-lower-case?) => 1
    (string-index "Aloha oe" #\o 3) => 6
    

    See also the Gauche built-in procedure string-scan (section 6.10.7 String utilities), if you need speed over portability.

    Function: string-skip s char/char-set/pred &optional start end
    Function: string-skip-right s char/char-set/pred &optional start end
    [SRFI-13] Looks for the first element that does not match char/char-set/pred and returns its index. If such element is not found, returns #f. Optional start and end limit the range of s to search.

    Function: string-count s char/char-set/pred &optional start end
    [SRFI-13] Counts the number of elements in s that matches char/char-set/pred. Optional start and end limit the range of s to search.

    Function: string-contains s1 s2 &optional start1 end1 start2 end2
    Function: string-contains-ci s1 s2 &optional start1 end1 start2 end2
    [SRFI-13] Looks for a string s2 inside another string s1. If found, returns an index in s1 from where the maching string begins. Returns #f otherwise. Optional start1, end1, start2 and end2 limits the range of s1 and s2.

    See also the Gauche built-in procedure string-scan (section 6.10.7 String utilities), if you need speed over portability.

    10.7.8 String case mapping

    Function: string-titlecase s &optional start end
    Function: string-titlecase! s &optional start end
    [SRFI-13]

    Function: string-upcase s &optional start end
    Function: string-upcase! s &optional start end
    [SRFI-13]

    Function: string-downcase s &optional start end
    Function: string-downcase! s &optional start end
    [SRFI-13]

    10.7.9 String reverse & append

    Function: string-reverse s &optional start end
    Function: string-reverse! s &optional start end
    [SRFI-13] Returns a string in which the character posisions are reversed from s. string-reverse! modifies s.
    (string-reverse "mahalo") => "olaham"
    (string-reverse "mahalo" 3) => "ola"
    (string-reverse "mahalo" 1 4) => "aha"
    
    (let ((s (string-copy "mahalo")))
      (string-reverse! s 1 5)
      s)
      => "mlahao"
    

    Function: string-concatenate string-list
    [SRFI-13] Concatenates list of strings.
    (string-concatenate '("humuhumu" "nukunuku" "apua" "`a"))
      => "humuhumunukunukuapua`a"
    

    Function: string-concatenate/shared string-list
    Function: string-append/shared s ...
    [SRFI-13] "Shared" version of string-concatenate and string-append. In Gauche, these are just synonyms of them.

    Function: string-concatenate-reverse string-list
    Function: string-concatenate-reverse/shared string-list
    [SRFI-13] Reverses string-list before concatenation. "Shared" version works the same in Gauche.

    10.7.10 String mapping

    Function: string-map proc s &optional start end
    Function: string-map! proc s &optional start end
    [SRFI-13] string-map applies proc on every character of s, and collects the results into a string and returns it. On the other hand, string-map! modifies s.
    (string-map char-upcase "wikiwiki") => "WIKIWIKI"
    (string-map char-upcase "wikiwiki" 4) => "WIKI"
    
    (let ((s (string-copy "wikiwiki")))
      (string-map! char-upcase s 4)
      s)
      => "wikiWIKI"
    

    Function: string-fold kons knil s &optional start end
    Function: string-fold-right kons knil s &optional start end
    [SRFI-13]

    Function: string-unfold p f g seed &optional base make-final
    [SRFI-13]

    Function: string-unfold-right p f g seed &optional base make-final
    [SRFI-13]

    Function: string-for-each proc s &optional start end
    [SRFI-13]

    Function: string-for-each-index proc s &optional start end
    [SRFI-13]

    10.7.11 String rotation

    Function: xsubstring s from &optional to start end
    [SRFI-13]

    Function: string-xcopy! target tstart s sfrom &optional sto start end
    [SRFI-13]

    10.7.12 Other string operations

    Function: string-replace s1 s2 start1 end2 &optional start2 end2
    [SRFI-13]

    Function: string-tokenize s &optional token-set start end
    [SRFI-13]

    10.7.13 String filtering

    Function: string-filter s char/char-set/pred &optional start end
    Function: string-delete s char/char-set/pred &optional start end
    [SRFI-13]

    10.7.14 Low-level string procedures

    Function: string-parse-start+end proc s args
    Function: string-parse-final-start+end proc s args
    [SRFI-13]

    Macro: let-string-start+end (start end [rest]) proc-exp s-exp args-exp body ...
    [SRFI-13]

    Function: check-substring-spec proc s start end
    Function: substring-spec-ok? s start end
    [SRFI-13]

    Function: make-kmp-restart-vector s &optional c= start end
    [SRFI-13]

    Function: kmp-step pat rv c i c= p-start
    [SRFI-13]

    Function: string-kmp-partial-search pat rv s i &optional c= p-start s-start s-end
    [SRFI-13]

    10.8 srfi-14 - Character-set library

    Module: srfi-14
    Implements the character set library defined in SRFI-14 (@xref{srfi-14,,SRFI-14}). Note that several basic character-set operations are Gauche's build-in functions. See section 6.9 Character Set.

    10.8.1 Character-set constructors

    Function: list->char-set char-list &optional base-cs
    Function: list->char-set! char-list base-cs
    [SRFI-14] Constructs a character set from a list of characters char-list. If base-cs is given, it must be a character set, and the characters in it are added to the result character set. List->char-set! is allowed, but not required, to reuse base-cs to store the result.

    Function: string->char-set s &optional base-cs
    Function: string->char-set! s base-cs
    [SRFI-14] Like list->char-set and list->char-set!, but take a list of characters from a string s.

    Function: char-set-filter pred char-set &optional base-cs
    Function: char-set-filter! pred char-set base-cs
    [SRFI-14] Returns a character set containing every character c in char-set such that (pred c) returns true. If a character set base-cs is given, its content is added to the result. The linear update version char-set-filter! is allowed, but not required, to modify base-cs to store the result.

    Function: ucs-range->char-set lower upper &optional error? base-cs
    Function: ucs-range->char-set! lower upper error? base-cs
    [SRFI-14]

    Function: integer-range->char-set lower upper &optional error? base-cs
    Function: integer-range->char-set! lower upper error? base-cs

    Function: ->char-set x
    [SRFI-14]

    10.8.2 Character-set comparison

    Function: char-set= char-set1 ...
    [SRFI-14]

    Function: char-set<= char-set1 ...
    [SRFI-14]

    Function: char-set-hash char-set &optional bound
    [SRFI-14]

    10.8.3 Character-set iteration

    Function: char-set-cursor char-set
    [SRFI-14]

    Function: char-set-ref char-set cursor
    [SRFI-14]

    Function: char-set-cursor-next char-set cursor
    [SRFI-14]

    Function: end-of-char-set? ccursor
    [SRFI-14]

    Function: char-set-fold kons knil char-set
    [SRFI-14]

    Function: char-set-unfold pred fun gen seed &optional base-char-set
    Function: char-set-unfold! pred fun gen seed base-char-set
    [SRFI-14]

    Function: char-set-for-each proc char-set
    [SRFI-14]

    Function: char-set-map proc char-set
    [SRFI-14]

    10.8.4 Character-set query

    Function: char-set-size char-set
    [SRFI-14]

    Function: char-set-count pred char-set
    [SRFI-14]

    Function: char-set->list char-set
    [SRFI-14]

    Function: char-set->string char-set
    [SRFI-14]

    Function: char-set-every pred char-set
    [SRFI-14]

    Function: char-set-any pred char-set
    [SRFI-14]

    10.8.5 Character-set algebra

    Function: char-set-adjoin char-set char1 ...
    Function: char-set-adjoin! char-set char1 ...
    [SRFI-14]

    Function: char-set-delete char-set char1 ...
    Function: char-set-delete! char-set char1 ...
    [SRFI-14]

    Function: char-set-complement char-set
    Function: char-set-complement! char-set
    [SRFI-14]

    Function: char-set-union char-set ...
    Function: char-set-union! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-intersection char-set ...
    Function: char-set-intersection! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-difference char-set1 char-set2 ...
    Function: char-set-difference! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-xor char-set ...
    Function: char-set-xor! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-diff+intersection char-set1 char-set2 ...
    Function: char-set-diff+intersection! char-set1 char-set2 char-set3 ...
    [SRFI-14]

    10.8.6 Predefined character-set

    Variable: char-set:letter
    [SRFI-14]

    Variable: char-set:blank
    [SRFI-14]

    Variable: char-set:iso-control
    [SRFI-14]

    Variable: char-set:digit
    Variable: char-set:hex-digit
    [SRFI-14]

    Variable: char-set:graphic
    [SRFI-14]

    Variable: char-set:lower-case
    Variable: char-set:upper-case
    Variable: char-set:title-case
    [SRFI-14]

    Variable: char-set:printing
    [SRFI-14]

    Variable: char-set:punctuation
    [SRFI-14]

    Variable: char-set:whitespace
    [SRFI-14]

    Variable: char-set:symbol
    [SRFI-14]

    Variable: char-set:ascii
    [SRFI-14]

    Variable: char-set:empty
    [SRFI-14]

    Variable: char-set:full
    [SRFI-14]

    10.9 srfi-19 - Time data types and procedures

    This SRFI defines various representations of time and date, and conversion methods among them.

    On Gauche, time object is supported natively by <time> class (See section 6.21.8.2 SRFI time). Date object is supported by <date> class described below.

    10.9.1 Time types

    Time type is represented by a symbol. This module defines the following constant variables that is bound to its name, for convenience.

    Constant: time-utc
    [SRFI-19] UTC time. Gauche's built-in current-time always returns this type (See section 6.21.8.2 SRFI time).

    Constant: time-tai
    [SRFI-19] International Atomic Time. This time is a bit larger than UTC, due to the leap seconds.

    Constant: time-monotonic
    [SRFI-19] Implementation-dependent monotonically increasing time. In Gauche, this is the same as time-tai.

    Constant: time-duration
    [SRFI-19] Duration between two absolute time points.

    Constant: time-process
    [SRFI-19] CPU time in current process. Gauche calculates this from user time and system time returned by POSIX times(3).

    Constant: time-thread
    [SRFI-19] CPU time in current thread. In the current implementation, this is the same as time-process.

    10.9.2 Time queries

    Function: current-time &optional time-type
    [SRFI-19] Extends Gauche built-in current-time (See section 6.21.8.2 SRFI time) to take optional time-type argument to specify the desired time type. time-type must be one of the types described in section 10.9.1 Time types.

    Function: current-date &optional tz-offset
    [SRFI-19] Returns the current date as an instance of <date> class (See section 10.9.4 Date). If tz-offset is given, it must be an offset from UTC in number of seconds. If tz-offset is not given, returns the date in local time zone.

    Function: current-julian-day
    [SRFI-19] Returns the current julian day, a point in time as a real number of days since -4714-11-24T12:00:00Z (November 24, -4714 at noon, UTC).

    Function: current-modified-julian-day
    [SRFI-19] Returns the current modified julian day, a point in time as a real number of days since 1858-11-17T00:00:00Z (November 17, 1858 at midnight, UTC).

    Function: time-resolution
    [SRFI-19]

    10.9.3 Time procedures

    Function: make-time type seconds nanoseconds
    [SRFI-19] Returns an instance of <time> class with specified initial values. Equivalent to (make <time> :type type :second seconds :nanosecond nanoseconds).

    Function: time-type time
    Function: time-second time
    Function: time-nanosecond time
    Function: set-time-type! time type
    Function: set-time-second! time second
    Function: set-time-nanosecond! time nanosecond
    [SRFI-19] Getter and setter of <time> object slots.

    Function: copy-time time
    [SRFI-19] Returns a new instance of <time> whose content is the same as given time

    Function: time=? time0 time1
    Function: time<? time0 time1
    Function: time<=? time0 time1
    Function: time>? time0 time1
    Function: time>=? time0 time1
    [SRFI-19] Compares two times. Types of both times must match.

    Function: time-difference time0 time1
    Function: time-difference! time0 time1
    [SRFI-19] Returns the difference of two times, in time-duration time. Types of both times must match. Time-difference! modifies time0 to store the result.

    Function: add-duration time0 time-duration
    Function: add-duration! time0 time-duration
    Function: subtract-duration time0 time-duration
    Function: subtract-duration! time0 time-duration
    [SRFI-19] Adds or subtracts time-duration to or from time0. Type of returned time is the same as time0. Type of time-duration must be time-duration. add-duration! and subtract-duration! reuse time0 to store the result.

    10.9.4 Date

    Class: <date>

    Function: make-date nanosecond second minute hour day month year zone-offset
    [SRFI-19]

    Function: date?
    [SRFI-19]

    Function: date-nanosecond date
    Function: date-second date
    Function: date-minute date
    Function: date-hour date
    Function: date-day date
    Function: date-month date
    Function: date-year date
    Function: date-zone-offset date
    [SRFI-19]

    Function: date-year-day date
    Function: date-week-day date
    Function: date-week-number date day-of-week-starting-week
    [SRFI-19]

    Function: date->julian-day date
    Function: date->modified-julian-day date
    Function: date->time-monotonic date
    Function: date->time-tai date
    Function: date->time-utc date
    [SRFI-19] Conversions from date to various date/time types.

    Function: julian-day->date jd &optional tz-offset
    Function: julian-day->time-monotonic jd
    Function: julian-day->time-tai jd
    Function: julian-day->time-utc jd
    [SRFI-19] Conversions from julian-day to various date/time types.

    Function: modified-julian-day->date jd &optional tz-offset
    Function: modified-julian-day->time-monotonic jd
    Function: modified-julian-day->time-tai jd
    Function: modified-julian-day->time-utc jd
    [SRFI-19] Conversions from modified julian-day to various date/time types.

    Function: time-monotonic->date time &optional tz-offset
    Function: time-monotonic->julian-day time
    Function: time-monotonic->modified-julian-day time
    Function: time-monotonic->time-tai time
    Function: time-monotonic->time-tai! time
    Function: time-monotonic->time-utc time
    Function: time-monotonic->time-utc! time
    [SRFI-19] Conversions from time-monotonic to various date/time types.

    Function: time-tai->date time &optional tz-offset
    Function: time-tai->julian-day time
    Function: time-tai->modified-julian-day time
    Function: time-tai->time-monotonic time
    Function: time-tai->time-monotonic! time
    Function: time-tai->time-utc time
    Function: time-tai->time-utc! time
    [SRFI-19] Conversions from time-tai to various date/time types.

    Function: time-utc->date time &optional tz-offset
    Function: time-utc->julian-day time
    Function: time-utc->modified-julian-day time
    Function: time-utc->time-monotonic time
    Function: time-utc->time-monotonic! time
    Function: time-utc->time-tai time
    Function: time-utc->time-tai! time
    [SRFI-19] Conversions from time-utc to various date/time types.

    10.9.5 Date reader and writer

    Function: date->string date &optional format-string
    [SRFI-19]

    Function: string->date string template-string
    [SRFI-19]

    10.10 srfi-27 - Sources of Random Bits

    Module: srfi-27
    This module provides SRFI-27 pseudo random generator interface, using Mersenne Twister algorithm (See section 11.8 math.mt-random - Mersenne Twister Random number generator) as the backbone.

    Function: random-integer n
    [SRFI-27] Returns a random exact integer between [0, n-1], inclusive, using the default random source. To set a random seed for this procedure, use random-source-randomize! or random-source-pseudo-randomize! on default-random-source.

    Function: random-real
    [SRFI-27] Returns a random real number between (0, 1), exclusive, using the default random source. To set a random seed for this procedure, use random-source-randomize! or random-source-pseudo-randomize! on default-random-source.

    Variable: default-random-source
    [SRFI-27] Keeps the default random source that is used by random-integer and random-real.

    Function: make-random-source
    [SRFI-27] Creates and returns a new random source. In the current Gauche implementation, it is just a <mersenne-twister> object. It may be changed in the future implementation.

    Function: random-source? obj
    [SRFI-27] Returns #t if obj is a random source object.

    Function: random-source-state-ref s
    Function: random-source-state-set! s state
    [SRFI-27] Gets and sets the "snapshot" of the state of the random source s. State is an opaque object whose content depends on the backbone generator.

    Function: random-source-randomize! s
    [SRFI-27] Makes an effort to set the state of the random source s to a truly random state. The current implementation uses the current time and the process ID to set the random seed.

    Function: random-source-pseudo-randomize! s i j
    [SRFI-27] Changes the state of the random source s into the initial state of the (i, j)-th independent random source, where i and j are non-negative integers. This procedure can be used to reuse a random source s as large number of independent random source, indexed by two non-negative integers. Note that this procedure is entirely deterministic.

    Function: random-source-make-integers s
    [SRFI-27] Returns a procedure, that takes one integer argument n and returns a random integer between 0 and n-1 inclusive for every invocation, from the random source s.

    Function: random-source-make-reals s &optional unit
    [SRFI-27] Returns a procedure, that takes no argument and returns a random real between 0 and 1 exclusive for every invocation, from the random source s. If unit is given, the random real the returned procedure generates will be quantized by the given unit, where 0 < unit < 1.

    11. Library modules - Utilities

    11.1 dbm - Generic DBM interface

    Module: dbm
    DBM-like libraries provides an easy way to store values to a file, indexed by keys. You can think it as a persistent associative memory.

    This modules defines <dbm> abstract class, which has a common interface to use various DBM-type database packages. As far as you operate on the already opened database, importing dbm module is enough.

    To create or open a database, you need a concrete implementation of the database. Gauche currently has the following impelentations. Each module defines its own low-level accessing functions as well as the common interface. Note that your system may not have one or more of those DBM libraries; Gauche defines only what the system provides.

    dbm.gdbm
    GDBM library (See section 11.2 dbm.gdbm - GDBM interface).
    dbm.ndbm
    NDBM library (See section 11.3 dbm.ndbm - NDBM interface).
    dbm.odbm
    DBM library (See section 11.4 dbm.odbm - Original DBM interface).

    The following code shows a typical usage of the database.

    (use dbm)         ; dbm abstract interface
    (use dbm.gdbm)    ; dbm concrete interface
    
    ; open the database
    (define *db* (dbm-open <gdbm> :path "mydb" :rw-mode :write))
    
    ; put the value to the database
    (dbm-put! *db* "key1" "value1")
    
    ; get the value from the database
    (define val (dbm-get *db* "key1"))
    
    ; iterate over the database
    (dbm-for-each *db* (lambda (key val) (foo key val)))
    
    ; close the database
    (dbm-close *db*)
    

    11.1.1 Opening and closing a dbm database

    Class: <dbm>
    An abstract class for dbm-style database. Defindes the common database operations. This class has the following instance slots. They must be set before the database is actually opened by dbm-open.

    The concrete class may add more slots for finer control on the database, such as locking.

    Instance Variable: <dbm> path
    Pathname of the dbm database. Some dbm implementation may append suffixes to this.

    Instance Variable: <dbm> rw-mode
    Specifies read/write mode. Can be either one of the following keywords:
    :read
    The database will be opened in read-only mode. The database file must exist when dbm-open is called. This is the default value.
    :write
    The database will be opened in Read-write mode. If the database file does not exist, dbm-open creates one.
    :create
    The database will be created and opened in Read-write mode. If the database file exists, dbm-open truncates it.

    Instance Variable: <dbm> file-mode
    Specifies the file permissions (as sys-chmod) to create the database. The default value is #o664.

    Instance Variable: <dbm> key-convert
    Instance Variable: <dbm> value-convert
    By default, you can use only strings for both key and values. With this option, however, you can specify how to convert other Scheme values to/from string to be stored in the database. The possible values are the followings:
    #f
    The default value. Keys (values) are not converted. They must be a string.
    #t
    Keys (values) are converted to its string representation, using write, to store in the database, and converted back to Scheme values, using read, to retrieve from the database. The data must have an external representation that can be read back. (But it is not checked when the data is written; you'll get an error when you read the data). The key comparison is done in the string level, so the external representation of the same key must match.
    a list of two procedures
    Both procedure must take a single argument. The first procedure must receive a Scheme object and returns a string. It is used to convert the keys (values) to store in the database. The second procedure must receive a string and returns a Scheme object. It is used to convert the stored data in the database to a Scheme object. The key comparison is done in the string level, so the external representation of the same key must match.

    Metaclass: <dbm-meta>
    A metaclass of <dbm> and its subclasses.

    Method: dbm-open (dbm <dbm>)
    Opens a dbm database. dbm must be an instance of one of the concrete classes that derived from the <dbm> class, and its slots must be set appropriately. On success, it returns the dbm itself. On failure, it signals an error.

    Method: dbm-open (dbm-class <dbm-meta>) options ...
    A convenient method that creates dbm instance and opens it. It is defined as follows.
    (define-method dbm-open ((class <class>) . initargs)
      (dbm-open (apply make class initargs)))
    

    Database file is closed when it is garbage collected. However, to ensure the modification is properly synchornized, you should close the database explicitly.

    Method: dbm-close (dbm <dbm>)
    Closes a database dbm. Once the database is closed, any operation to access the database content raises an error.

    Method: dbm-closed? (dbm <dbm>)
    Returns true if a database dbm is already closed, false otherwise.

    11.1.2 Accessing a dbm database

    Once a database is opened, you can use the following methods to access individual key/value pairs.

    Method: dbm-put! (dbm <dbm>) key value
    Put a value with key.

    Method: dbm-get (dbm <dbm>) key &optional default
    Get a value associated with key. If no value exists for key and default is specified, it is returned. If no value exists for key and default is not specified, an error is signalled.

    Method: dbm-exists? (dbm <dbm>) key
    Return true if a value exists for key, false otherwise.

    Method: dbm-delete! (dbm <dbm>) key
    Delete a value associated with key.

    11.1.3 Iterating on a dbm database

    To walk over the entire database, following methos are provided.

    Method: dbm-fold (dbm <dbm>) procedure knil
    The basic iterator. For each key/value pair, procedure is called as (procedure key value r), where r is knil for the fist call of procedure, and the return value of the previous call for subsequent calls. Returns the result of the last call of procedure. If no data is in the database, knil is returned.

    The following method returns the sum of all the integer values.

    (dbm-fold dbm (lambda (k v r) (if (integer? v) (+ v r) r) 0))
    

    Method: dbm-for-each (dbm <dbm>) procedure
    For each key/value pair in the database dbm, procedure is called. Two arguments are passed to procedure---a key and a value. The result of procedure is discarded.

    Method: dbm-map (dbm <dbm>) procedure
    For each key/value pair in the database dbm, procedure is called. Two arguments are passed to procedure---a key and a value. The result of procedure is accumulated to a list which is returned as a result of dbm-map.

    11.2 dbm.gdbm - GDBM interface

    Module: dbm.gdbm

    Class: <gdbm>
    Inherits <dbm>. Provides an implementation for GDBM library. This module is only installed when your system already has GDBM (1.8.0 is preferred, but works with older 1.7.x with some limitations).

    Instance Variable: <gdbm> sync
    Instance Variable: <gdbm> nolock
    Instance Variable: <gdbm> bsize

    Besides the unified DBM interface (See section 11.1 dbm - Generic DBM interface), this module provides the following low-level functions that provides direct access to the gdbm API. See gdbm manual for details of these APIs.

    Function: gdbm-open path &optional size rwmode fmode error-callback

    Variable: GDBM_READER

    Variable: GDBM_WRITER

    Variable: GDBM_WRCREAT

    Variable: GDBM_NEWDB

    Variable: GDBM_FAST

    Variable: GDBM_SYNC

    Variable: GDBM_NOLOCK

    Function: gdbm-close gdbm-object

    Function: gdbm-closed? gdbm-object

    Function: gdbm-store key value &optional flag

    Variable: GDBM_INSERT

    Variable: GDBM_REPLACE

    Function: gdbm-fetch gdbm-object key

    Function: gdbm-delete gdbm-object key

    Function: gdbm-firstkey gdbm-object

    Function: gdbm-nextkey gdbm-object key

    Function: gdbm-reorganize gdbm-object

    Function: gdbm-sync gdbm-object

    Function: gdbm-exists gdbm-object key

    Function: gdbm-strerror errno

    Function: gdbm-setopt gdbm-object option value

    Variable: GDBM_CACHESIZE

    Variable: GDBM_FASTMODE

    Variable: GDBM_SYNCMODE

    Variable: GDBM_CENTFREE

    Variable: GDBM_COALESCEBLKS

    Function: gdbm-version

    Function: gdbm-errno

    11.3 dbm.ndbm - NDBM interface

    Module: dbm.ndbm

    Class: <ndbm>
    Inherits <dbm>. Provides an implementation for NDBM library. This module is only installed when your system already has NDBM.

    Besides the unified DBM interface (See section 11.1 dbm - Generic DBM interface), this module provides the following low-level functions that provides direct access to the ndbm API. See ndbm manual for details of these APIs.

    Function: ndbm-open path flags mode

    Function: ndbm-close ndbm-object

    Function: ndbm-closed? ndbm-object

    Function: ndbm-store ndbm-object key content &optional flag

    Function: ndbm-fetch ndbm-object key

    Function: ndbm-delete ndbm-object key

    Function: ndbm-firstkey ndbm-object

    Function: ndbm-nextkey ndbm-object

    Function: ndbm-error ndbm-object

    Function: ndbm-clear-error ndbm-object

    11.4 dbm.odbm - Original DBM interface

    Module: dbm.odbm

    Class: <odbm>
    Inherits <dbm>. Provides an implementation for legacy DBM library. This module is only installed when your system already has DBM.

    The biggest limitation of the legacy DBM is that you can only open one database at a time. You can create a multiple <odbm> instances, but you can open at most one of it at a time, or you'll get an error.

    Besides the unified DBM interface (See section 11.1 dbm - Generic DBM interface), this module provides the following low-level functions that provides direct access to the dbm API. See dbm manual for details of these APIs.

    Function: odbm-init path

    Function: odbm-close

    Function: odbm-store key value

    Function: odbm-fetch key

    Function: odbm-delete key

    Function: odbm-firstkey

    Function: odbm-nextkey key

    11.5 file.filter - Filtering file content

    Module: file.filter
    This module provides utilities for a common pattern in filter-type commands, that is, to take an input, to process the content, and to write the result. The common occurring pattern is:
    • Input may be a specified file, or an input port (the current input port by default).
    • Output may be a specified file, or an output port (the current output port by default).
    • Output may be a temporary file, which will be renamed upon completion of the processing.
    • Output file may be removed when an error occurs in the processing.

    Function: file-filter proc &keyword input output temporary-file keep-output?
    Calls proc with two arguments, an input port and an output port. Returns the result(s) of proc. The input port and output port are chosen depending on the keyword arguments.
    input
    The argument must be either an input port or a string that specifies a file name. If it's an input port, it is passed to proc as is. If it's a string, the named file is opened for input and the resulting port is passed to proc, and the port is closed when proc returns. If this argument is omitted, the current input port is passed.
    output
    The argument must be either an output port or a string that specifies a file name. If it's an output port, it is passed to proc as is. If it's a string, the named file is opened for output (unless temporary-file is given, in that case a temporary file is opened instead), and the resulting port is passed to proc. This port is closed when proc returns. If this argument is omitted, the current output port is passed.
    temporary-file
    If a string file name is given to this argument, the named file is opened for output during the processing, instead of the file name as output. The output port proc receives is connected to this file. When proc returns normally, the file is renamed to the name given to output keyword argument. If the given file name begins with characters except "/", "./" or "../", the directory of the file name given to output argument is attached before it. Furthermore, a unique name is attached to the temporary file name (the temporary file is opened by sys-mkstemp.) This argument is ignored when output argument is not a string file name.
    keep-output?
    If a true value is given, the output is not deleted even when proc signals an error. By default, the output (or the temporary file when temporary-file is given) will be deleted on error.

    11.6 file.util - Filesystem utilities

    Module: file.util
    Provides convenient utility functions handling files and directories. Those functions are built on top of the primitive system procedures described in section 6.21.3 Filesystems.

    Many procedures in this module takes a keyword argument follow-link?, which specifies the behavior when the procedure sees a symbolic link. If true value is given to follow-link? (which is the default), the procedure operates on the file referenced by the link; if false is given, it operates on the link itself.

    Note on the naming convention: Some Scheme implementations "create" new directories and files, while the others "make" them. Some implementations "delete" them, while the others "remove" them. It seems that both conventions are equally popular. So Gauche provides both.

    11.6.1 Directory utilities

    Function: current-directory &optional new-directory
    When called with no argument, this returns the pathname of the current working directory. When called with a string argument new-directory, this sets the current working directory of the process to it. If the process can't change directory to new-directory, an error is signalled.

    This function is in ChezScheme, MzScheme and some other Scheme implementations.

    Function: home-directory &optional user
    Returns the home directory of the given user, which may be a string user name or an integer user id. If user is omitted, the current user is assumed. If the given user cannot be found, or the home directory of the user cannot be determined, #f is returned.

    Function: directory-list path &keyword children? add-path? filter
    Returns a list of entries in the directory path. The result is sorted by dictionary order.

    By default, only the basename (the last component) of the entries returned. If add-path? is given and true, path is appended to each entry. If children? is given and true, "." and ".." are excluded from the result. If filter is given, it must be a predicate that takes one argument. It is called on every element of the entry basename, and only the entries on which filter returns true are included in the result.

    If path is not a directory, an error is signalled.

    (directory-list "test")
     => ("." ".." "test.scm" "test.scm~")
    
    (directory-list "test" :add-path? #t)
     => ("test/." "test/.." "test/test.scm" "test/test.scm~")
    
    (directory-list "test" :children? #t)
     => ("test.scm" "test.scm~")
    
    (directory-list "test" :children? #t :add-path? #t
       :filter (lambda (e) (not (string-suffix? "~" e))))
     => ("test/test.scm")
    

    Function: directory-list2 path &keyword children? add-path? filter follow-link?
    Like directory-list, but returns two values; the first one is a list of subdirectories, and the second one is a list of the rest. The keyword arguments children?, add-path? and filter are the same as directory-list.

    Giving false value to follow-link? makes directory-list2 not follow the symbolic links; if the path contains a symlink to a directory, it will be included in the first list if follow-link? is omitted or true, while it will be in the second list if follow-link? is false.

    Function: directory-fold path proc knil &keyword lister follow-link?
    A fundamental directory traverser. Conceptually it works as follows, in recursive way.
    • If path is not a directory, calls (proc path knil) and returns the result.
    • If path is a directory, calls (lister path knil). The procedure lister is expected to return a list of pathnames. Then directory-fold is called on each returned pathname. Each result of directory-fold is passed as the knil argument of the next recursive invocation. Returns the result of the last recursive call.

    The default procedure of lister is just a call to directory-list, as follows.

    (lambda (path knil)
      (directory-list path :add-path? #t :children? #t)))))
    

    Note that lister shouldn't return the given path itself (".") nor the parent directory (".."), or the recursion wouldn't terminate. Also note lister is expected to return a path accesible from the current directory, i.e. if path is "/usr/lib/foo" and it contains "libfoo.a" and "libfoo.so", lister should return '("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so").

    The keyword argument follow-link? is used to determine whether lister should be called on a symbolic link pointing to a directory. When follow-link? is true (default), lister is called with the symbolic link if it points to a directory. When follow-link? is false, proc is not called.

    The following examble returns a list of pathnames of the emacs backup files (whose name ends with "~") under the given path.

    (use srfi-13) ;; for string-suffix?
    (directory-fold path
                    (lambda (entry result) 
                      (if (string-suffix? "~" entry)
                          (cons entry result)
                          result))
                    '())
    

    Function: make-directory* name &optional perm
    Function: create-directory* name &optional perm
    Creates a directory name. If the intermediate path to the directory doesn't exist, they are also created (like mkdir -p command on Unix). If the directory name already exist, these procedure does nothing. Perm specifies the integer flag for permission bits of the directory.

    Function: remove-directory* name
    Function: delete-directory* name
    Deletes directory name and its content recursively (like rm -r command on Unix). Symbolic links are not followed.

    11.6.2 Pathname utilities

    Function: build-path base-path component ...
    Appends pathname components component to the base-path. Component can be a symbol up or same; in Unix, they are synonym to ".." and ".". This API is taken from MzScheme.

    Function: absolute-path? path
    Function: relative-path? path
    Returns #t if path is absolute or relative, respectively.

    Function: expand-path path
    Expands tilda-notation of path if it contains one. Otherwise, path is returned. This function does not check if path exists and/or readable.

    Function: resolve-path path
    Expands path like expand-path, then resolve symbolic links for every components of the path. If path does not exist, or contains dangling link, or contains unreadable directory, an error is signalled.

    Function: simplify-path path
    Remove 'up' ("..") components and 'same' (".") components from path as much as possible. This function does not access the filesystem.

    Function: find-file-in-paths name &keyword paths pred
    Looks for a file that has name name in the given list of pathnames paths and that satisfies a predicate pred. If found, the absolute pathname of the file is returned. Otherwise, #f is returned.

    If name is an absolute path, only the existence of name and whether it satisfies pred are checked.

    The default value of paths is taken from the environment variable PATH, and the default value of pred is file-is-executable? (See section 11.6.3 File attibute utilities). That is, find-file-in-paths searches the named executable file in the command search paths by default.

    (find-file-in-paths "ls")
      => "/bin/ls"
    
    ;; example of searchin user preference file of my application
    (find-file-in-paths "userpref"
      :paths `(,(expand-path "~/.myapp")
               "/usr/local/share/myapp"
               "/usr/share/myapp")
      :pred  file-is-readable?)
    

    11.6.3 File attibute utilities

    Function: file-type path &keyword follow-link?
    Function: file-perm path &keyword follow-link?
    Function: file-mode path &keyword follow-link?
    Function: file-ino path &keyword follow-link?
    Function: file-dev path &keyword follow-link?
    Function: file-rdev path &keyword follow-link?
    Function: file-nlink path &keyword follow-link?
    Function: file-uid path &keyword follow-link?
    Function: file-gid path &keyword follow-link?
    Function: file-size path &keyword follow-link?
    Function: file-atime path &keyword follow-link?
    Function: file-mtime path &keyword follow-link?
    Function: file-ctime path &keyword follow-link?
    These functions return the attribute of file/directory specified by path. The attribute name corresponds to the slot name of <sys-stat> class (See section 6.21.3.4 File stats). If the named path doesn't exist, #f is returned.

    If path is a symbolic link, these functions queries the attributes of the file pointed by the link, unless an optional argument follow-link? is given and false.

    MzScheme and Chicken have file-size. Chicken also has file-modification-time, which is file-mtime.

    Function: file-is-readable? path
    Function: file-is-writable? path
    Function: file-is-executable? path
    Returns #t if path exists and readable/writable/executable by the current effective user, respectively. This API is taken from STk.

    Function: file-eq? path1 path2
    Function: file-eqv? path1 path2
    Function: file-equal? path1 path2
    Compares two files specified by path1 and path2. file-eq? and file-eqv? checks if path1 and path2 refers to the identical file, that is, whether they are on the same device and have the identical inode number. The only difference is when the last component of path1 and/or path2 is a symbolic link, file-eq? doesn't resolve the link (so compares the links themselves) while file-eqv? resolves the link and compares the files referred by the link(s).

    file-equal? compares path1 and path2 considering their content, that is, when two are not the identical file in the sense of file-eqv?, file-equal? compares their content and returns #t if all the bytes match.

    The behavior of file-equal? is undefined when path1 and path2 are both directories. Later, it may be extended to scan the directory contents.

    Generic Function: file-mtime=? f1 f2
    Generic Function: file-mtime<? f1 f2
    Generic Function: file-mtime<=? f1 f2
    Generic Function: file-mtime>? f1 f2
    Generic Function: file-mtime>=? f1 f2
    Compares file modification time stamps. There are a bunch of methods defined, so each argument can be either one of the followings.
    • String pathname. The mtime of the specified path is used.
    • <sys-stat> object (See section 6.21.3.4 File stats). The mtime is taken from the stat structure.
    • <time> object. The time is used as the mtime.
    • Number. It is considered as the number of seconds since Unix Epoch, and used as mtime.
    ;; compare "foo.c" is newer than "foo.o"
    (file-mtime>? "foo.c" "foo.o")
    
    ;; see if "foo.log" is updated within last 24 hours
    (file-mtime>? "foo.c" (- (sys-time) 86400))
    

    Generic Function: file-ctime=? f1 f2
    Generic Function: file-atime=? f1 f2
    Same as file-mtime=?, except these checks file's change time and access time, respectively. All the variants of <, <=, >, >= are also defined.

    11.6.4 File operations

    Function: touch-file path
    Updates timestamp of path to the current time. If path doesn't exist, a new file with size zero is created. See also sys-utime (See section 6.21.3.4 File stats).

    Function: copy-file src dst &keyword if-exists backup-suffix safe keep-timestamp
    Copies file from src to dst. The source file src must exist. The behavior when the destination dst exists varies by the keyword argument if-exists;
    :error
    (Default) Signals an error when dst exists.
    :supersede
    Replaces dst to the copy of src.
    :backup
    Keeps dst by renaming it.
    #f
    Doesn't copy and returns #f when dst exists.

    Copy-file returns #t after completion.

    If if-exists is :backup, the keyword argument backup-suffix specifies the suffix attached to the dst to be renamed. The default value is ".orig".

    By default, copy-file starts copying to dst directly. However, if the keyword argument safe is a true value, it copies the file to a temporary file in the same directory of dst, then renames it to dst when copy is completed. If copy is interrupted for some reason, the filesystem is "rolled back" properly.

    If the keyword argument keep-timestamp is true, copy-file sets the destination's timestamp to the same as the source's timestamp after copying.

    Function: move-file src dst &keyword if-exists backup-suffix
    Moves file src to dst. The source src must exist. The behavior when dst exists varies by the keyword argument if-exists, as follows.
    :error
    (Default) Signals an error when dst exists.
    :supersede
    Replaces dst by src.
    :backup
    Keeps dst by renaming it.
    #f
    Doesn't move and returns #f when dst exists.

    Move-file returns #t after completion.

    If if-exists is :backup, the keyword argument backup-suffix specifies the suffix attached to the dst to be renamed. The default value is ".orig".

    The file src and dst can be on the different filesystem. In such a case, move-file first copies src to the temporary file on the same directory as dst, then renames it to dst, then removes src.

    11.7 math.const - Mathematic constants

    Module: math.const
    This module defines several commonly-used mathematic constants.

    Constant: pi
    Constant: pi/2
    Constant: pi/4
    Constant: pi/180
    Constant: 1/pi
    Constant: 180/pi
    Bound to pi, pi/2, pi/4, pi/180, 1/pi and 180/pi, respectively.

    Constant: e
    e.

    11.8 math.mt-random - Mersenne Twister Random number generator

    Module: math.mt-random
    Provides a pseudo random number generator (RNG) based on "Mersenne Twister" algorithm developed by Makoto Matsumoto and Takuji Nishimura. It is fast, and has huge period of 2^19937-1. See @xref{MT,,MT}, for details about the algorithm.

    Class: <mersenne-twister>
    A class to encapsulate the state of Mersenne Twister RNG. Each instance of this class has its own state, and can be used as an independent source of random bits if initialized by individual seed.

    The random seed value can be given at the instantiation time by :seed initialization argument, or by using mt-random-set-seed! described below.

    (define m (make <mersenne-twister> :seed (sys-time)))
    
    (mt-random-real m) => 0.10284287848537865
    (mt-random-real m) => 0.463227748348805
    (mt-random-real m) => 0.8628500643709712
    ...
    

    Function: mt-random-set-seed! mt seed
    Sets random seed value seed to the Mersenne Twister RNG mt. Seed can be an arbitrary positive exact integer, or arbitrary length of u32vector (See section 10.4 srfi-4 - Homogeneous vectors). If it is an integer, the lower 32bits are used for initialization. If it is a u32vector, up to 624 elements are used for initialization.

    Function: mt-random-get-state mt
    Function: mt-random-set-state! mt state
    Retrieves and reinstalls the state of Mersenne Twister RNG mt. The state is represented by a u32vector of 625 elements. The state can be stored elsewhere, and then restored to an instance of <mersenne-twister> to continue to generate the pseudo random sequence.

    Function: mt-random-real mt
    Function: mt-random-real0 mt
    Returns a random real number between 0.0 and 1.0. 1.0 is not included in the range. Mt-random-real doesn't include 0.0 either, while mt-random-real0 does. Excluding 0.0 is from the draft SRFI-27.

    Function: mt-random-integer mt range
    Returns a random exact positive integer between 0 and range-1. Range can be any positive exact integer.

    Function: mt-random-fill-u32vector! mt u32vector
    Function: mt-random-fill-f32vector! mt f32vector
    Function: mt-random-fill-f64vector! mt f64vector
    Fills the given uniform vector by the random numbers. For mt-random-fill-u32vector!, the elements are filled by exact positive integers between 0 and 2^32-1. For mt-random-fill-f32vector! and mt-random-fill-f64vector!, it is filled by an inexact real number between 0.0 and 1.0, exclusive.

    If you need a bunch of random numbers at once, these are much faster than getting one by one.

    11.9 rfc.822 - RFC822 message parsing

    Module: rfc.822
    Defines a set of functions that parses and constructs the "Internet Message Format", a text format used to exchange e-mails. The most recent specification can be found in RFC2822 (@xref{rfc2822,[RFC2822],RFC2822}). The format was originally defined in RFC 822, and people still call it "RFC822 format", hence I named this module. In the following document, I also refer to the format as "RFC822 format".

    Say (use rfc.822) to use this module.

    Function: rfc822-header->list iport &optional strict?
    Reads RFC822 format message from an input port iport, until it reaches the end of the message header. The header fields are unfolded, and broken into a list of the following format:
    ((name body) ...)
    

    Name ... are the field names, and body ... are the corresponding field body, both as strings. Field names are converted to lower-case characters. Field bodies are not modified, except the folded line is concatenated, CRLFs removed. The order of fields are preserved.

    Function: rfc822-parse-date string
    Takes RFC-822 type date string, and returns eight values:
    year, month, day-of-month, hour, minutes, seconds, timezone, day-of-week.
    

    Timezone is an offset from UT in minutes. Day-of-week is a day from sunday, and may be #f if that information is not available. If the string is not parsable, all the elements are #f.

    Note: This function follows the new definition of date format in RFC2822, but may fail to recognize "obsolete" format, which allows arbitrary comments appear between words.

    11.10 rfc.base64 - Base64 encoding/decoding

    Module: rfc.base64
    This module defines a few functions to encode/decode Base64 format, defined in RFC 2045 (@xref{rfc2045, [RFC2045], RFC2045}), section 6.3.

    Function: base64-encode
    Reads byte stream from the current input port, encodes it in Base64 format and writes the result character stream to the current output port. The conversion ends when it reads EOF from the current input port.

    Function: base64-encode-string string
    Converts contents of string to Base64 encoded format. Input string can be either complete or incomplete string; it is always interpreted as a byte sequence.

    Function: base64-decode
    Reads character stream from the current input port, decodes it from Base64 format and writes the result byte stream to the current output port. The conversion ends when it reads EOF or the termination character (=). The characters which does not in legal Base64 encoded character set are silently ignored.

    Function: base64-decode-string string
    Decodes a Base64 encoded string string and returns the result as a string. The conversion terminates at the end of string or the termination character (=). The characters which does not in legal Base64 encoded character set are silently ignored.

    11.11 rfc.cookie - HTTP cookie handling

    Module: rfc.cookie
    Defines a set of functions to parse and construct a "cookie" information defined in RFC 2965 (@xref{rfc2965,,RFC2965}).

    Function: parse-cookie-string string &optional version
    Parse a cookie string string, which is the value of "Cookie" request header. Usually, the same information is available to CGI program via the environemnt variable HTTP_COOKIE.

    If the cookie version is known, via "Cookie2" request header, the integer version must be passed to version. Otherwise, parse-cookie figures out the version from string.

    The result has the following format.

    ((<name> <value> [:path <path>] [:domain <domain>] [:port <port>])
     ...)
    

    where <name> is the attribute name, and <value> is the corresponding value. If the attribute doesn't have value, <value> is #f. (Note that it differs from the attribute having null value, "".) If the attribute has path, domain or port options, it is given as a form of keyword-value pair.

    Function: construct-cookie-string specs &optional version
    Given list of cookie specs, creates a cookie string suitable for Set-cookie2 or Set-cookie header.

    Optional version argument specifies cookie protocol version. 0 for the old Netscape style format, and 1 for RFC2965 style format. When omitted, version 1 is assumed.

    Each cookie spec has the following format.

    (<name> <value> [:comment <comment>] [:comment-url <url>]
                    [:discard <bool>] [:domain <domain>]
                    [:max-age <age>] [:path <path>]
                    [:port <port-list>] [:secure <bool>]
                    [:version <version>] [:expires <date>])
    

    Where,

    <name>
    A string. Name of the cookie.
    <value>
    Value of the cookie. May be a string, or #f if no value is needed.
    <comment> <url> <domain> <path> <port-list>
    Strings.
    <bool>
    Boolean value
    <age> <version>
    Integers
    <date>
    Either an integer (seconds since Epoch) or a formatted date string following the netscape cookie specification.

    The attribute values are quoted appropriately. If the specified attribute is irrelevant for the version, it is ignored. So you can pass the same specs to generate both old-style and new-style cookie strings.

    Return value is a list of cookie strings, each of which stands for each cookie. For old-style protocol (using Set-cookie header) you must send each of them by individual header. For new-style protocol (using Set-cookie2 header), you can join them with comma and send it at once. See RFC2965 for further details.

    Some examples:

    (construct-cookie-string
       '(("name" "foo" :domain "foo.com :path "/"
                       :expires (+ (sys-time) 86400) :max-age 86400)))
     => ("name=foo;Domain=foo.com;Path=/;Max-age=86400")
    
    (construct-cookie-string
       '(("name" "foo" :domain "foo.com :path "/"
                       :expires (+ (sys-time) 86400) :max-age 86400))
       0)
     =>
     ("name=foo;Domain=foo.com;Path=/;Expires=Sun, 09-Sep-2001 01:46:40 GMT")
    

    11.12 rfc.http - HTTP

    Module: rfc.http
    This module provides a simple client API for HTTP/1.1, defined in RFC2616, "Hypertext Transfer Protocol -- HTTP/1.1" (@xref{rfc2616, [RFC2616], RFC2616}).

    Current API implements only a part of the protocol. Only GET, HEAD, and POST requests are supported, it doesn't talk with HTTP/1.0 server yet, and it doesn't support HTTP/1.1 advanced features such as persistent connection. Support for those features may be added in the future versions.

    Function: http-get server request-uri &keyword sink flusher no-redirect ...
    Function: http-head server request-uri &keyword no-redirect ...
    Function: http-post server request-uri body &keyword sink flusher no-redirect ...

    Send http GET, HEAD and POST requests to the http server, and returns the server's reply.

    If the server returns "3xx" redirection reply, these procedures try to follow the URI returned in the "location" reply message header by default. See the "keyword arguments" heading below to suppress redirection following.

    Required arguments: The server argument specifies http server name in a string. A server name can be optionally followed by colon and a port number. Examples: "w3c.org", "mycompany.com:8080".

    The request-uri argument is the request-uri specified in RFC2616; usually, this is the path part of http url.

    Http-post takes the third argument, body, which is a string to be posted to the server. The body is sent "as is"; the caller has to take care of necessary escaping or encoding.

    So, the most simple form of retrieving the content will be something like this:

    (http-get "www.shiro.dreamhost.com" "/scheme/index.html")
    

    Access via proxy can be done by specifying proxy server to server and passing the entire URI to request-uri, but the author haven't tested yet.

    Return values: All procedures return three values.

    The first value is the status code defined in RFC2616 in a string (such as "200" for success, "404" for "not found").

    The second value is a list of parsed headers--each element of list is a list of (header-name value ...), where header-name is a string name of the header (such as "content-type" or "location"), and value is the corresponding value in a string. The header name is converted to lowercase letters. The value is untouched except that "soft line breaks" are removed, as defined in RFC2822. If the server returns more than one headers with the same name, their values are consolidated to one list. Except that, the order of the header list in the second return value is the same as the order in the server's reply.

    The third value is for the message body of the server's reply. By default, it is a message body itself in a string. If the server's reply doesn't have a body, the third value is #f. You can change how the message body is handled by keyword arguments; for example, you can directly store the returned message body to a file without creating intermediate string. The details are explained below.

    Keyword arguments: By default, these procedures only attaches "Host" header field to the request message. You can give keyword arguments to add more header fields.

    (http-get "foo.bar.com" "/index.html"
      :accept-language "ja"
      :user-agent "My Scheme Program/1.0")
    

    The following keyword arguments are recognized by the procedure and do not appear in the request headers.

    no-redirect
    If a true value is given, suppress the redirection tracking; i.e. the procedures return "3xx" message as is.
    sink, flusher
    You can customize how the message body is handled by these keyword arguments. You have to pass an output port to sink, and a procedure that takes two arguments to flusher. When the procedure starts receiving the message body, it feeds the received chunk to sink. When the procedure receives entire message body, flusher method is called with sink and a list of message header fields (in the same format to be returned in the second value from the procedure). The return value of flusher becomes the third return value from the procedure. So, the default value of sink is a newly opened string port and the default value of flusher is (lambda (sink headers) (get-output-string sink)). The following example saves the message body directly to a file, without allocating (potentially very big) string buffer.
    (call-with-output-file "page.html"
      (lambda (out)
        (http-get "www.schemers.org" "/"
           :sink out :flusher (lambda _ #t))))
    

    11.13 rfc.quoted-printable - Quoted-printable encoding/decoding

    Module: rfc.quoted-printable
    This module defines a few functions to encode/decode Quoted-printable format, defined in RFC 2045 (@xref{rfc2045, [RFC2045], RFC2045}), section 6.7.

    Function: quoted-printable-encode
    Reads byte stream from the current input port, encodes it in Quoted-printable format and writes the result character stream to the current output port. The conversion ends when it reads EOF from the current input port.

    Function: quoted-printable-encode-string string
    Converts contents of string to Quoted-printable encoded format. Input string can be either complete or incomplete string; it is always interpreted as a byte sequence.

    Function: quoted-printable-decode
    Reads character stream from the current input port, decodes it from Quoted-printable format and writes the result byte stream to the current output port. The conversion ends when it reads EOF. If it encounters illegal character sequence (such as '=' followed by non-hexadecimal characters), it copies them literally to the output.

    Function: quoted-printable-decode-string string
    Decodes a Quoted-printable encoded string string and returns the result as a string.

    11.14 rfc.uri - URI parsing and construction

    Module: rfc.uri
    Provides a set of functions to parse Uniform Resource Identifiers defined in RFC 2396 (@xref{rfc2396, [RFC2396], RFC2396}).

    Function: uri-scheme&specific uri
    Function: uri-decompose-hierarchical specific
    Function: uri-decompose-authority authority
    General parser of URI. These functions does not decode URI encoding.

    uri-scheme&specific takes a URI uri, and returns two values, its scheme part and its scheme-specific part. If uri doesn't have a scheme part, #f is returned for it.

    (uri-scheme&specific "mailto:sclaus@north.pole")
      => "mailto" and "sclaus@north.pole"
    (uri-scheme&specific "/icons/new.gif")
      => #f and "/icons/new.gif"
    

    If the URI scheme uses hierarchical notation, i.e. "//authority/path?query#fragment", you can pass the scheme-specific part to uri-decompose-hierarchical and it returns four values, authority, path, query and fragment.

    (uri-decompose-hierarchical "//www.foo.com/about/company.html")
      => "www.foo.com", "/about/company.html", #f and #f
    (uri-decompose-hierarchical "//zzz.org/search?key=%3fhelp")
      => "zzz.org", "/search", "key=%3fhelp" and #f
    (uri-decompose-hierarchical "//jjj.jp/index.html#whatsnew")
      => "jjj.jp", "/index.html", #f and "whatsnew"
    (uri-decompose-hierarchical "my@address")
      => #f, #f, #f and #f
    

    Furthermore, you can parse authority part of the hierarchical URI by uri-decompose-authority. It returns userinfo, host and port.

    (uri-decompose-authority "yyy.jp:8080")
      => #f, "yyy.jp" and "8080"
    (uri-decompose-authority "mylogin@yyy.jp")
      => "mylogin", "yyy.jp" and #f
    

    Function: uri-compose &keyword scheme userinfo host port authority path path* query fragment specific
    Compose a URI from given components. There can be various combinations of components to create a valid URI--the following diagram shows the possible 'paths' of combinations:
            /-----------------specific-------------------\
            |                                            |
     scheme-+------authority-----+-+-------path*---------+-
            |                    | |                     |
            \-userinfo-host-port-/ \-path-query-fragment-/
    

    If #f is given to a keyword argument, it is equivalent to the absense of that keyword argument. It is particulary useful to pass the results of parsed uri.

    If a component contains a character that is not appropriate for that component, it must be properly escaped before being passed to url-compose.

    Some examples:

    (uri-compose :scheme "http" :host "foo.com" :port 80
                 :path "/index.html" :fragment "top")
      => "http://foo.com:80/index.html#top"
    
    (uri-compose :scheme "http" :host "foo.net"
                 :path* "/cgi-bin/query.cgi?keyword=foo")
      => "http://foo.net/cgi-bin/query.cgi?keyword=foo"
    
    (uri-compose :scheme "mailto" :specific "a@foo.org")
      => "mailto:a@foo.org"
    
    (receive (authority path query fragment)
       (uri-decompose-hierarchical "//foo.jp/index.html#whatsnew")
     (uri-compose :authority authority :path path
                  :query query :fragment fragment))
      => "//foo.jp/index.html#whatsnew"
    

    Function: uri-decode &keyword :cgi-decode
    Function: uri-decode-string string &keyword :cgi-decode
    Decodes "URI encoding", i.e. %-escapes. uri-decode takes input from the current input port, and writes decoded result to the current output port. uri-decode-string takes input from string and returns decoded string.

    If cgi-decode is true, also replaces + to a space character.

    Function: uri-encode &keyword :noescape
    Function: uri-encode-string string &keyword :noescape
    Encodes unsafe characters by %-escape. uri-encode takes input from the current input port and writes the result to the current output port. uri-encode-string takes input from string and returns the encoded string.

    By default, characters that are not specified "unreserved" in RFC2396 are escaped. You can pass different character set to noescape argument to keep from being encoded.

    The multibyte characters are encoded as the octed stream of Gauche's native multibyte representation.

    11.15 slib - SLIB interface

    Module: slib
    This module is the interface to the Aubrey Jaffer's SLIB. To use SLIB, say (use slib). SLIB itself is not included in Gauche distribution. If you don't have it on your system, get it from http://www-swiss.ai.mit.edu/~jaffer/SLIB.html.

    This module redefines require, shadowing the Gauche's original require. If it gets a symbol as an argument, it works as SLIB's require, while if it gets a string, it works as Gauche's require. The same applies to provide and provided?.

    All SLIB symbol bindings, loaded by require, stay in the module slib.

    (use slib)         ; load and set up slib
    (require 'getopt)  ; load SLIB's getopt module
    (require "foo")    ; load Gauche's foo module
    

    11.16 text.csv - CSV tables

    Module: text.csv
    Provides a function to parse/generate CSV (comma separated value) tables. Actually, the separater is not limited to comma; you can customize it.

    CSV format is widely used to exchange table-type data in plain text, although there are apparently no "formal" specification.

    CSV table is consisted by a series of records, separated by a newline. Each record contains number of fields, separated by a separator character (by default, a comma). A field can contain comma or newline if quoted, i.e. surrounded by double-quote characters. To include double-quote character in a quoted field, use two consecutive double-quote character. Usually, the whitespaces around the field are ignored.

    Right now, the following two low-level procedures are exported. A plan is to provide higher features, such as labelling fields and automatic conversions.

    Function: make-csv-reader separator
    Returns a procedure with one argument, input port. When the procedure is called, it reads one record from the port, and returns a list of fields. If input reaches EOF, it returns EOF.

    Function: make-csv-writer separator &optional newline
    Returns a procedure with two arguments, output port and a list of fields. When the procedure is called, it outputs a separater-separated fields with proper escapes, to the output port. You can also specify the record delimiter string by newline; for example, you can pass "\r\n" to prepare a file to be read by Windows programs.

    11.17 text.html-lite - Simple HTML document construction

    Module: text.html-lite
    Provides procedures to construct an HTML document easily. For example, you can construct an HTML table by the following code:
    (html:table
      (html:tr (html:th "Item No") (html:th "Quantity"))
      (html:tr (html:td 1) (html:td 120))
      (html:tr (html:td 2) (html:td 30))
      (html:tr (html:td 3) (html:td 215)))
    

    See the description of html:element below for details.

    This module does little check for the constructed html documents, such as whether the attributes are valid, and whether the content of the element matches DTD. It does not provide a feature to parse the html document neither. Hence the name `lite'.

    Function: html-escape
    Function: html-escape-string string
    Escapes the "unsafe" characters in HTML. html-escape reads input string from the current input port and writes the result to the current output port. html-escape-string takes the input from string and returns the result in a string.

    Function: html-doctype &keyword type
    Returns a doctype declaration for an HTML document. type can be either one of :strict, :transitional, or :frameset, corresponding HTML4.01 strict, transitional or frameset DTD, respectively.

    Function: html:element args ...
    Construct an HTML element element. Right now, the following elements are provided. (The elements defined in HTML 4.01 DTD, http://www.w3.org/TR/html4/sgml/dtd.html).
    a        abbr       acronym    address     area      b
    base     bdo        big        blockquote  body      br
    button   caption    cite       code        col       colgroup
    dd       del        dfn        div         dl        dt
    em       fieldset   form       h1          h2        h3
    h4       h5         h6         head        hr        html
    i        img        input      ins         kbd       label
    legend   li         link       map         meta      noscript
    object   ol         optgroup   option      p         param
    pre      q          samp       script      select    small
    span     strong     style      sub         sup       table
    tbody    td         textarea   tfoot       th        thead
    title    tr         tt         ul          var
    

    The result of these functions is a tree of text segments, which can be written out to a port by write-tree or can be converted to a string by tree->string (See section 11.20 text.tree - Lazy text construction).

    You can specify attributes of the element by using a keyword-value notation before the actual content.

    (tree->string (html:a :href "http://foo/bar" "foobar"))
      =>
      "<a href=\"http://foo/bar\">foobar</a>\n"
    
    (tree->string
      (html:table :width "100%" :cellpading 0 "content here"))
      =>
      "<table width=\"100%\" cellpadding=\"0\">content here</table>\n"
    

    The boolean value given to the attribute has a special meaning. If #t is given, the attribute is renfered without a value. If #f is given, the attribute is not rendered.

    (tree->string (html:table :border #t))
      => "<table border></table>\n"
    
    (tree->string (html:table :border #f))
      => "<table></table>\n"
    

    Special characters in attribute values are escaped by the function, but the ones in the content are not. It is caller's responsibility to escape them.

    The functions signal an error if a content is given to the HTML element that doesn't take a content. They do not check if the given attribute is valid, neither if the given content is valid for the element.

    11.18 text.parse - Parsing input stream

    Module: text.parse
    A collection of utilities that does simple parsing from the input port. The API is inspired, and compatible with Oleg Kiselyov's input parsing library (@xref{oleg1,,OLEG1}). His library is used in lots of other libraries, notably, a full-Scheme XML parser/generator SSAX (@xref{ssax,,SSAX}).

    You can use this module in place of his input-parse.scm and look-for-str.scm.

    I reimplemented the functions to be efficient on Gauche. Especially, usage of string-set! is totally avoided. I extended the interface a bit so that they can deal with character sets and predicates, as well as a list of characters.

    These functions work sequentially on the given input port, that is, they read from the port as much as they need, without buffering extra characters.

    Function: find-string-from-port? str in-port &optional max-no-chars
    Looks for a string str from the input port in-port. The optional argument max-no-chars limits the maximum number of characters to be read from the port; if omitted, the search span is until EOF.

    If str is found, this function returns the number of characters it has read. The next read from in-port returns the next char of str. If str is not found, it returns #f.

    Note: Although this procedure has `?' in its name, it may return non-boolean value, contrary to the Scheme convention.

    Function: peek-next-char &optional port
    Discards the current character and peeks the next character from port. Useful to look ahead one character. If port is omitted, the current input port is used.

    In the following functions, char-list refers to one of the followings:

    That denotes a set of characters. If a symbol *eof* is included, the EOF condition is also included. Without *eof*, the EOF condition is regarded as an error.

    Function: assert-curr-char char-list string &optional port
    Reads a character from port. If it is included in char-list, returns the character. Otherwise, signals an error with a message containing string. If port is omitted, the current input port is used.

    Function: skip-until char-list/number &optional port
    char-list/number is either a char-list or a number. If it is a number; it reas that many characters and returns #f. If the input is not long enough, an error is signalled. IF char-list/number is a char-list, it reads from port until it sees a character that belongs to the char-list. Then the character is returned. If port is omitted, the current input port is used.

    Function: skip-while char-list &optional port
    Reads from port until it sees a character that does not belong to char-list. The character remains in the stream. If it reaches EOF, an EOF is returned. If port is omitted, the current input port is used.

    This example skips whitespaces from input. Next read from port returns the first non-whitespace character.

    (skip-while #[\s] port)
    

    Function: next-token prefix-char-list break-char-list &optional comment port
    Skips any number of characters in prefix-char-list, then collects the characters until it sees break-char-list. The collected characters are returned as a string. The break character remains in the port.

    If the function encounters EOF and *eof* is not included in break-char-list, an error is signalled with comment is included in the message.

    Function: next-token-of char-list/pred &optional port
    Reads and collects the characters as far as it belongs to char-list/pred, then returns them as a string. The first character that doesn't belong to char-list/pred remains on the port.

    char-list/pred may be a char-list or a predicate that takes a character. If it is a predicate, each character is passed to it, and the character is regarded to "belong to" char-list/pred when it returns a true value.

    Function: read-string n &optional port
    Reads up to n characters, collects them into a string, and returns it. If the input stream contains less characters, the returns string contains as many characters available.

    11.19 text.tr - Transliterate characters

    Module: text.tr
    This module implements a transliterate function, that substitutes characters of the input string. This functionality is realized in Unix tr(1) command, and incorporated in various programs such as sed(1) and perl.

    Gauche's tr is aware of multibyte characters.

    Function: tr from-list to-list &keyword :complement :delete :squeeze :table-size :input :output
    Reads from input and writes to output, with transliterating characters in from-list to the corresponding ones in to-list. Characters that doesn't appear in from-list are passed through.

    The default values of input and output are current input port and current output port, respectively.

    Both from-list and to-list must be strings. They may contain the following special syntax. Other characters that doesn't fits in the syntax are taken as they are.

    x-y
    Expanded to the increasing sequence of characters from x to y, inclusive. The order is determined by the internal character encoding system; generally it is safer to limit use of this within the range of the same character class. The character x must be before y.
    x*n
    Repeat x for n times. n is a decimal number notation. Meaningful only in to-list; it is an error to use this form in from-list. If n is omitted or zero, x is repeated until to-list matches the length of from-list (any character after it is ignored).
    \x
    Represents x itself. Use this escape to avoid a special character to be interpreted as itself. Note that if you place a backslash in a string, you must write \\, for the Scheme reader also interprets backslash as a special character. There's no special sequence to represent non-graphical characters, for you can put such characters by the string syntax.

    Here's some basic examples.

    ;; swaps case of input
    (tr "A-Za-z" "a-zA-Z")
    
    ;; replaces 7-bit non-graphical characters to `?'
    (tr "\x00-\x19\x7f" "?*")
    

    If to-list is shorter than from-list, the behavior depends on the keyword argument delete. If a true value is given, characters that appear in from-list but not in to-list are deleted. Otherwise, the extra characters in from-list are just passed through.

    When a true value is specified to complement, the character set in from-list is complemented. Note that it implies huge set of characters, so it is not very useful unless either output character set is a single character (using `*') or used with delete keyword.

    When a true value is specified to squeeze, the sequence of the same replaced characters is squeezed to one. If to-list is empty, the sequence of the same characters in from-list is squeezed.

    Internally, tr builds a table to map the characters for efficiency. Since Gauche can deal with potentially huge set of characters, it limits the use of the table for only smaller characters (<256 by default). If you want to transliterate multibyte characters on the large text, however, you might want to use larger table, trading off the memory usage. You can specify the internal table size by table-size keyword argument. For example, if you transliterate lots of EUC-JP hiragana text to katakana, you may want to set table size greater than 42483 (the character code of the last katakana).

    Note that the pre-calculation to build the transliterate table needs some overhead. If you want to call tr many times inside loop, consider to use build-transliterator described below.

    Function: string-tr string from-list to-list &keyword :complement :delete :squeeze :table-size
    Works like tr, except that input is taken from a string string.

    Function: build-transliterator from-list to-list &keyword :complement :delete :squeeze :table-size :input :output
    Returns a procedure that does the actual transliteration. This effectively "pre-compiles" the internal data structure. If you want to run tr with the same sets repeatedly, you may build the procedure once and apply it repeatedly, saving the overhead of initialization.
    (with-input-from-file "huge-file.txt"
      (lambda ()
        (let loop ((line (read-line)))
          (unless (eof-object? line) (tr "A-Za-z" "a-zA-Z")))))
    
    ;; runs more efficiently...
    
    (with-input-from-file "huge-file.txt"
      (lambda ()
        (let ((ptr (build-transliterator "A-Za-z" "a-zA-Z")))
          (let loop ((line (read-line)))
            (unless (eof-object? line) (ptr))))))
    

    11.20 text.tree - Lazy text construction

    Module: text.tree
    Defines simple but commonly used functions for a text construction.

    When you generate a text by a program, It is a very common operation to concatenate text segments. However, using string-append repeatedly causes unnecessary copying of intermediate strings, and sometimes such intermediate strings are discarded due to the error situation (for example, think about constucting an HTML document in the CGI script).

    The efficient technique is to delay concatenation of those text segments until it is needed. In Scheme it is done very easily by just consing the text segments together, thus forming a tree of text, and then traverse the tree to construct a text. You can even directly writes out the text during traversal, avoiding intermediate string buffer. (Hans Boehm's "cord" library, which comes with his garbage collector library, uses this technique and proves it is very efficient for editor-type application).

    Although the traversal of the tree can be written in a few lines of Scheme, I provide this module in the spirits of OnceAndOnlyOnce. Also it's easier if we have a common interface.

    Generic Function: write-tree tree &optional out
    Writes out an tree as a tree of text, to the output port out. If out is omitted, the current output port is used.

    Two methods are defined for this generic function, as shown below. If you have more complex behavior, you can define more methods to customize the behavior.

    Method: write-tree ((tree <list>) out)
    Method: write-tree ((tree <top>) out)
    Default methods. For a list, write-tree is recursively called for each element. Any objects other than list is written out using display.

    Function: tree->string tree
    Just calls the write-tree method for tree using an output string port, and returns the result string.

    11.21 util.isomorph - Determine isomorphism

    Module: util.isomorph
    Provides a procedure that determines whether two structures are isomorphic.

    Function: isomorphic? obj1 obj2 &optional context
    Returns #t if obj1 and obj2 are isomorphic.

    context is used if you want to call isomorphic? recursively inside object-isomorphic? described below.

    (isomorphic? '(a b) '(a b)) => #t
    
    (define x (cons 0 0))
    (define y (cons 0 0))
    (isomorphic? (cons x x)
                 (cons x y))
     => #f
    (isomorphic? (cons x x)
                 (cons y y))
     => #t
    

    Generic Function: object-isomorphic? obj1 obj2 context
    With this method, you can customize how to determine isomorphism of two objects. Basically, you will call isomorphic? recursively for each slots of object you want to traverse; the method should return #t if all of the test succeeds, or return #f otherwise. context is an opaque structure that keeps the traversal context, and you should pass it to isomorphic? as is.

    The default method returns #t if obj1 and obj2 are equal (in the sense of equal?).

    11.22 util.queue - Queue

    Module: util.queue
    Provides a queue (FIFO). This implementation is tuned for speed than safety; a queue is simply a pair that keeps head and tail of the queue, and minimal check is done in most of the operations.

    SLIB (See section 11.15 slib - SLIB interface) provides the queue library that is safer. This API is upper compatible to the SLIB's. The idea is that this queue is used inside other procedure or structure that you know you don't need the strict checks. Use either one depending on your requirement.

    Function: make-queue
    Creates and returns an empty queue.

    Function: queue? obj
    Returns #t if obj is a queue. This operation checks obj is really in a shape of the queue.

    Function: queue-empty? queue
    Returns #t if obj is an empty queue.

    Function: queue-length queue
    Returns the number of the items in the queue.

    Function: enqueue! queue obj &optional more-objs ...
    Add obj to the end of queue. You may give more than one object, and each of them are enqueued in order. (Note: SLIB version doesn't take the optional arguments).

    Function: queue-push! queue obj &optional more-objs ...
    Add obj in front of queue. You may give more than one object, and each of them are pushed in order. (Note: SLIB version doesn't take the optional arguments).

    Function: dequeue! queue
    Function: queue-pop! queue
    Take one object from the front of the queue queue and returns it. Both function works the same, but queue-pop! may be used to emphasize it works with queue-push!. An error is signalled if queue is empty.

    Function: dequeue-all! queue
    Returns the whole content of the queue by a list, with emptying queue. If queue is already empty, returns an empty list. See also queue->list below.

    Function: queue-front queue
    Function: queue-rear queue
    Peek the head or the tail of the queue and returns the object, respectively. util.queue - Queue is not modified. An error is signalled if queue is empty.

    Function: list->queue list
    Returns a new queue whose content is the elements in list, in the given order.

    Function: queue->list queue
    Returns a list whose content is the items in the queue in order. Unlike dequeue-all!, the content of queue remains intact.

    In Gauche, queue->list copies the content of the queue to a freshly allocated list, while dequeue-all! doesn't copy but directly returns the queue's internal list. There are some Scheme systems that has queue->list but doesn't guarantee the content is copied, so if you're planning to share the code among these implementations, it's better not to rely on the fact that queue->list copies the content.

    Function: find-in-queue pred queue
    Returns the first item in queue that satisfies a predicate pred. The order of arguments follows find in SRFI-1 (See section 10.2.7 List searching).

    Function: remove-from-queue! pred queue
    Removes all items in the queue that satisfies pred. Returns #t if any item is removed. Otherwise returns #f. The order of arguments follows remove in SRFI-1 (See section 10.2.6 List filtering & partitioning).

    Note on portability: Scheme48 has delete-from-queue!, which takes object to remove rather than predicate, and also takes arguments in reversed order (i.e. queue comes first). Avoid conflicting with that I intentionally left out delete-from-queue!; it's easy to write one in either Scheme48 compatible way or consistent to SRFI-1 argument order.

    11.23 util.toposort - Topological sort

    Module: util.toposort
    Implements topological sort algorithm.

    Function: topological-sort graph &optional eqproc
    Graph represents a directed acyclic graph (DAG) by a list of connections, where each connection is the form
    (<node> <downstream> <downstream2> ...)
    

    that means a node <node> is connected to other nodes <downstream> etc. <node> can be arbitrary object, as far as it can be compared by the procedure eqproc, which is eqv? by default (See section 6.1 Equivalence). Returns a list of <node>s sorted topologically.

    If the graph contains circular reference, an error is signalled.

    11.24 www.cgi - CGI utility

    Module: www.cgi
    Provides a few basic functions useful to write a CGI script.

    In order to write CGI script easily, you may want to use other modules, such as rfc.uri (See section 11.14 rfc.uri - URI parsing and construction), text.html-lite (See section 11.17 text.html-lite - Simple HTML document construction) and text.tree (See section 11.20 text.tree - Lazy text construction).

    Note: it seems that there is no active formal specification for CGI. See http://w3c.org/CGI/ for more information.

    Function: cgi-parse-parameters &keyword :query-string :merge-cookies
    Parses query string and returns associative list of parameters. When a keyword argument query-string is given, it is used as a source query string. Otherwise, the function checks the environment variable REQUEST_METHOD and obtain the query string depending on the value (either from stdin or from the environment variable QUERY_STRING). If such an environment variable is not defined and the current input port is a terminal, the function prompts the user to type parameters; useful for interactive debugging.

    When a true value is given to merge-cookies, the cookie values obtained from the environment variable HTTP_COOKIE are appended to the result.

    Note that the query parameter may have multiple values, so cdr of each element in the result is a list, not an atom. If no value is given to the parameter, #t is placed as its value. See the following example:

    (cgi-parse-parameters
      :query-string "foo=123&bar=%22%3f%3f%22&bar=zz&buzz")
     => (("foo" "123") ("bar "\"??\"" "zz") ("buzz #t))
    

    Function: cgi-get-parameter name params &keyword :default :list :convert
    A convenient function to obtain a value of the parameter name from parsed query string params, which is the value cgi-parse-parameters returns.

    Unless true value is given to list, the returned value is a scalar value. If more than one value is associated to name, only the first value is returned. If list is true, the returned value is always a list, even name has only one value.

    After the value is retrieved, you can apply a procedure to convert the string value to the appropriate type by giving a procedure to the convert argument. The procedure must take one string argument. If list is true, the convert procedure is applied to each values.

    If no value is defined for name, a value given to the keyword argument default is returned; the default value of default is #f if list is false, or () otherwise.

    Function: cgi-header &keyword content-type location cookies
    Creates a text tree (See section 11.20 text.tree - Lazy text construction) for the HTTP header of the reply message. The most simple form is like this:
    (tree->string (cgi-header))
      => "Content-type: text/html\r\n\r\n"
    

    You can specify alternative content-type by the keyword argument content-type. If you want to set cookies to the client, specify a list of cookie strings to the keyword argument cookies. You can use construct-cookie-string (See section 11.11 rfc.cookie - HTTP cookie handling) to build such a list of cookie strings.

    The keyword argument location may be used to generate a Location: header to redirect the client to the specified URI.

    Function: cgi-main proc &keyword on-error merge-cookies
    A convenient wrapper function for CGI script. This function calls cgi-parse-parameters, then calls proc with the result of cgi-parse-parameters. The keyword argument merge-cookies is passed to cgi-parse-parameters.

    proc has to return a tree of strings (See section 11.20 text.tree - Lazy text construction), including the HTTP header. cgi-main outputs the returned tree to the current output port by write-tree, then returns zero.

    If an error is signalled in proc, it is caught and an HTML page reporting the error is generated. You can customize the error page by providing a procedure to the on-error keyword argument. The procedure takes an <exception> object (See section 6.16.3 Exception object), and has to return a tree of string for the error reporting HTML page, including an HTTP header.

    The following example shows the parameters given to the CGI program.

    #!/usr/local/bin/gosh
    
    (use text.html-lite)
    (use www.cgi)
    
    (define (main args)
      (cgi-main
        (lambda (params)
          `(,(cgi-header)
            ,(html-doctype)
            ,(html:html
              (html:head (html:title "Example"))
              (html:body
               (html:table
                :border 1
                (html:tr (html:th "Name") (html:th "Value"))
                (map (lambda (p)
                       (html:tr
                        (html:td (html-escape-string (car p)))
                        (html:td (html-escape-string (x->string (cdr p))))))
                     params))))
           ))))
    

    A. References

    @anchor{r5rs}
    [R5RS]
    R. Kelsey, W. Clinger, J. Rees (eds.), Revised^5 Report on the Algorithmic Language Scheme, Higher-Order and Symbolic Computation, 11(1), September, 1998 and ACM SIGPLAN Notices, 33(9), October, 1998.
    http://www.schemers.org/Documents/Standards/R5RS/. @anchor{onecont}
    [1CC]
    Carl Bruggeman, Oscar Waddell and R. Kent Dybvig, Representing control in the presence of one-shot continuations, in Proceedings of SIGPLAN '96, pp. 99--107, 1996. @anchor{mop}
    [MOP]
    Gregor Kiczales, Jim Des Rivieres, Daniel Bobrow, The Art of Metaobject Protocol, The MIT Press. @anchor{rfc2045}
    [RFC2045]
    N. Freed, N. Borenstein: Multipurpose Internet Mail Extension (MIME) Part One: Format of Internet Message Bodies, November 1996.
    ftp://ftp.isi.edu/in-notes/rfc2045.txt. @anchor{rfc2396}
    [RFC2396]
    T. Berners-Lee, R. Fielding, L. Masinter, Uniform Resource Identifiers (URI): Generic Syntax, August 1998.
    ftp://ftp.isi.edu/in-notes/rfc2396.txt. @anchor{rfc2616}
    [RFC2616]
    R. Fielding et al, Hypertext Transfer Protocol -- HTTP/1.1, June 1999.
    ftp://ftp.isi.edu/in-notes/rfc2616.txt. @anchor{rfc2822}
    [RFC2822]
    P. Resnick (ed.), Internet Message Format, April 2001.
    ftp://ftp.isi.edu/in-notes/rfc2822.txt. @anchor{rfc2965}
    [RFC2965]
    D. Kristol, L. Montulli, HTTP State Management Mechanism, October 2000.
    ftp://ftp.isi.edu/in-notes/rfc2965.txt. @anchor{srfi-0}
    [SRFI-0]
    Marc Feeley, Feature-based conditional expansion construct, May 1999.
    http://srfi.schemers.org/srfi-0/srfi-0.html. @anchor{srfi-1}
    [SRFI-1]
    Olin Shivers, List Library, October 1999.
    http://srfi.schemers.org/srfi-1/srfi-1.html. @anchor{srfi-2}
    [SRFI-2]
    Oleg Kiselyov, AND-LET*: an AND with local bindings, a guarded LET* special form, March 1998.
    http://srfi.schemers.org/srfi-2/srfi-2.html. @anchor{srfi-4}
    [SRFI-4]
    Marc Feeley, Homogeneous numeric vector types, May 1999.
    http://srfi.schemers.org/srfi-4/srfi-4.html. @anchor{srfi-6}
    [SRFI-6]
    William D Clinger, Basic String Ports, July 1999.
    http://srfi.schemers.org/srfi-6/srfi-6.html. @anchor{srfi-8}
    [SRFI-8]
    John David Stone, receive: Binding to multiple values, August 1999.
    http://srfi.schemers.org/srfi-8/srfi-8.html. @anchor{srfi-9}
    [SRFI-9]
    Richard Kelsey, Defining Record Types, September 1999.
    http://srfi.schemers.org/srfi-9/srfi-9.html. @anchor{srfi-10}
    [SRFI-10]
    Oleg Kiselyov, #, external form, January 2000.
    http://srfi.schemers.org/srfi-10/srfi-10.html. @anchor{srfi-11}
    [SRFI-11]
    Lars T Hansen, Syntax for receiving multiple values, March 2000.
    http://srfi.schemers.org/srfi-11/srfi-11.html. @anchor{srfi-13}
    [SRFI-13]
    Olin Shivers, String Libraries, December 2000.
    http://srfi.schemers.org/srfi-13/srfi-13.html. @anchor{srfi-14}
    [SRFI-14]
    Olin Shivers, Character-set Library, December 2000.
    http://srfi.schemers.org/srfi-14/srfi-14.html. @anchor{srfi-17}
    [SRFI-17]
    Per Bothner, Generalized set!, July 2000.
    http://srfi.schemers.org/srfi-17/srfi-17.html. @anchor{srfi-18}
    [SRFI-18]
    Marc Feeley, Multithreading Support, April 2000.
    http://srfi.schemers.org/srfi-18/srfi-18.html. @anchor{srfi-19}
    [SRFI-19]
    Will Fitzgerald, Time Data Types and Procedures, August 2000.
    http://srfi.schemers.org/srfi-19/srfi-19.html. @anchor{srfi-21}
    [SRFI-21]
    Marc Feeley, Readl-time Multithreading Support, April 2000.
    http://srfi.schemers.org/srfi-21/srfi-21.html. @anchor{srfi-22}
    [SRFI-22]
    Martin Gasbichler and Michael Sperber, Running Scheme Scripts on Unix, January 2002.
    http://srfi.schemers.org/srfi-22/srfi-22.html. @anchor{srfi-23}
    [SRFI-23]
    Stephan Housen, Error reporting mechanism, April 2001.
    http://srfi.schemers.org/srfi-23/srfi-23.html. @anchor{srfi-25}
    [SRFI-25]
    Jussi Piitulainen, Multi-dimensional Array Primitives, June 2002.
    http://srfi.schemers.org/srfi-25/srfi-25.html. @anchor{srfi-26}
    [SRFI-26]
    Sebastian Egner, Notation for Specializing Parameters without Currying, June 2002.
    http://srfi.schemers.org/srfi-26/srfi-26.html. @anchor{srfi-27}
    [SRFI-27]
    Sebastian Egner, Sources of Random Bits, June 2002.
    http://srfi.schemers.org/srfi-27/srfi-27.html. @anchor{srfi-28}
    [SRFI-28]
    Scott G. Miller, Basic Format Strings, June 2002.
    http://srfi.schemers.org/srfi-28/srfi-28.html. @anchor{ssax}
    [SSAX]
    Oleg Kiselyov, XML and Scheme,
    http://pobox.com/~oleg/ftp/Scheme/xml.html.
    The SSAX distribution is also available at sourceforge:
    http://ssax.sourceforge.net/. @anchor{MT}
    [MT]
    M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator", ACM Trans. on Modeling and Computer Simulation Vol. 8, No. 1, Januray pp.3-30 1998.
    http://www.math.keio.ac.jp/~matumoto/emt.html @anchor{oleg1}
    [OLEG1]
    Oleg Kiselyov, Making sense of an input stream,
    http://pobox.com/~oleg/ftp/Scheme/parsing.html. @anchor{oleg2}
    [OLEG2]
    Oleg Kiselyov, General ways to traverse collections,,
    http://pobox.com/~oleg/ftp/Scheme/enumerators-callcc.html. 2000.

    B. C to Scheme mapping

    For the convenience of the programmers familiar to C, I composed a simple table of C operators and library functions with the corresponding Scheme functions.

    +
    R5RS arithmetic procedure +. See section 6.2.4 Arithmetics.
    +=
    Gauche inc! macro. See section 4.4 Assignments.
    -
    R5RS arithmetic procedure -. See section 6.2.4 Arithmetics.
    -=
    Gauche dec! macro. See section 4.4 Assignments.
    ->
    Gauche slot-ref is something close to this. See section 7.5 Accessing Instance.
    * (binary)
    R5RS arithmetic procedure *. See section 6.2.4 Arithmetics.
    * (unary)
    No equivalent procedure. Scheme doesn't have explicit notation of pointers.
    *=
    No equivalent procedure.
    /
    R5RS arithmetic procedure /. See section 6.2.4 Arithmetics.
    /=
    No equivalent procedure.
    & (binary)
    Gauche logand. See section 6.2.6 Bitwise operations.
    & (unary)
    No equivalent procedure. Scheme doesn't have explicit notation of pointers.
    &&
    R5RS syntax and. See section 4.5 Conditionals.
    &=
    No equivalent procedure.
    |
    Gauche logior. See section 6.2.6 Bitwise operations.
    ||
    R5RS syntax or. See section 4.5 Conditionals.
    |=
    No equivalent procedure.
    ^
    Gauche logxor. See section 6.2.6 Bitwise operations.
    =
    R5RS syntax set!. See section 4.4 Assignments.
    ==
    R5RS equivalence procedure, eq?, eqv? and equal?. See section 6.1 Equivalence.
    <
    <=
    R5RS arithmetic procedure < and <=. See section 6.2.3 Numerical comparison. Unlike C operator, Scheme version is transitive.
    <<
    Gauche ash. See section 6.2.6 Bitwise operations.
    <<=
    No equivalent procedure.
    >
    >=
    R5RS arithmetic procedure > and >=. See section 6.2.3 Numerical comparison. Unlike C operator, Scheme version is transitive.
    >>
    Gauche ash. See section 6.2.6 Bitwise operations.
    >>=
    No equivalent procedure.
    %
    R5RS operator modulo and remainder. See section 6.2.4 Arithmetics.
    %=
    No equivalent procedure.
    []
    R5RS vector-ref (See section 6.12 Vectors) is something close. Or you can use Gauche's generic function ref (See section 9.18 gauche.sequence - Sequence framework) for arbitrary sequences.
    .
    Gauche slot-ref is something close to this. See section 7.5 Accessing Instance.
    ~
    Gauche lognot. See section 6.2.6 Bitwise operations.
    ~=
    No equivalent procedure.
    !
    R5RS procedure not. See section 6.3 Booleans.
    !=
    No equivalent procedure.
    abort
    Gauche sys-abort. See section 6.21.1 Program termination
    abs
    R5RS abs. See section 6.2.4 Arithmetics.
    access
    Gauche sys-access. See section 6.21.3.4 File stats.
    acos
    R5RS acos. See section 6.2.4 Arithmetics.
    alarm
    Gauche sys-alarm. See section 6.21.11 Miscellaneous system calls.
    asctime
    Gauche sys-asctime. See section 6.21.8 Time.
    asin
    R5RS asin. See section 6.2.4 Arithmetics.
    assert
    No equivalent function in Gauche.
    atan
    atan2
    R5RS atan. See section 6.2.4 Arithmetics.
    atexit
    No equivalent function in Gauche, but the "after" thunk of active dynamic handlers are called when exit is called. See section 6.21.1 Program termination, and See section 6.15.3 Continuation.
    atof
    atoi
    atol
    You can use string->number. See section 6.2.5 Numerical conversions.
    bsearch
    No equivalent function in Gauche.
    calloc
    Allocation is handled automatically in Scheme.
    ceil
    R5RS ceiling. See section 6.2.4 Arithmetics.
    cfgetispeed
    cfgetospeed
    cfsetispeed
    cfsetospeed
    Gauche sys-cfgetispeed, sys-cfgetospeed, sys-cfsetispeed, sys-cfsetospeed. See section 9.20 gauche.termios - Termios.
    chdir
    Gauche sys-chdir. See section 6.21.3.5 Other file operations.
    chmod
    Gauche sys-chmod. See section 6.21.3.4 File stats.
    chown
    Gauche sys-chown. See section 6.21.3.4 File stats
    clearerr
    Not supported yet.
    clock
    No equivalent function in Gauche. You can use sys-times to get information about CPU time.
    close
    You can't directly close the file descriptor, but when you use close-input-port or close-output-port, underlying file is closed. Some port-related functions, such as call-with-output-file, automatically closes the file when operation is finished. The file is also closed when its governing port is garbage collected. See section 6.18.2 Common port operations.
    closedir
    No equivalent function in Gauche. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 Directories.
    cos
    cosh
    cos and cosh. See section 6.2.4 Arithmetics.
    creat
    A file is implictly created by default when you open it for writing. See section 6.18.3 File ports for more control over the creation of files.
    ctermid
    Gauche sys-ctermid. See section 6.21.7 System Inquiry.
    ctime
    Gauche sys-ctime. See section 6.21.8 Time.
    cuserid
    No equivalent function. This is removed from the newer POSIX. You can use alternative functions, such as sys-getlogin or sys-getpwuid with sys-getuid.
    difftime
    Gauche sys-difftime. See section 6.21.8 Time.
    div
    You can use R5RS quotient and remainder. See section 6.2.4 Arithmetics.
    dup
    dup2
    No equivalent function. If you want to use this function to set up I/Os for the child process, you can use `iomap' argument of sys-exec. See section 6.21.9.1 Fork and exec.
    execl
    execle
    execlp
    execv
    execve
    execvp
    Gauche sys-exec. See section 6.21.9.1 Fork and exec. For higher level interface, section 9.14 gauche.process - High Level Process Interface.
    exit
    _exit
    Use exit or sys-exit, depends on what you need. See section 6.21.1 Program termination.
    exp
    R5RS exp. See section 6.2.4 Arithmetics.
    fabs
    R5RS abs. See section 6.2.4 Arithmetics.
    fclose
    You can't directly close the file stream, but when you use close-input-port or close-output-port, underlying file is closed. Some port-related functions, such as call-with-output-file, automatically closes the file when operation is finished. The file is also closed when its governing port is garbage collected.
    fcntl
    Implented as sys-fcntl in gauche.fcntl module. See section 9.5 gauche.fcntl - Low-level file operations.
    fdopen
    Gauche's open-input-fd-port or open-output-fd-port. See section 6.18.3 File ports.
    feof
    Not supported yet.
    ferror
    Not supported yet.
    fflush
    Gauche's flush. See section 6.18.7 Output.
    fgetc
    Use read-char or read-byte. See section 6.18.6 Input.
    fgetpos
    Not supported yet.
    fgets
    Use read-line or read-block. See section 6.18.6 Input.
    fileno
    port-file-numer. See section 6.18.2 Common port operations.
    floor
    R5RS floor. See section 6.2.4 Arithmetics.
    fmod
    Gauche's fmod.
    fopen
    R5RS open-input-file or open-output-file corresponds to this operation. See section 6.18.3 File ports.
    fork
    Gauche's sys-fork. See section 6.21.9.1 Fork and exec.
    forkpty
    Use sys-forkpty. See section 9.20 gauche.termios - Termios.
    fpathconf
    Not supported.
    fprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 Output. SLIB has printf implementation.
    fputc
    Use write-char or write-byte. See section 6.18.7 Output.
    fputs
    Use display. See section 6.18.7 Output.
    fread
    Not directly supported. If you want to read a chunk of bytes, you may be able to use read-block.
    free
    You don't need this in Scheme.
    freopen
    Not supported.
    frexp
    Gauche's frexp
    fscanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 Regular expression, also section 9.15 gauche.regexp - Regular expression utilities.
    fseek
    Not implemented yet.
    fsetpos
    Not implemented yet.
    fstat
    Gauche's sys-stat. See section 6.21.3.4 File stats.
    ftell
    Not implemented yet.
    fwrite
    Not directly supported. If you want to write a chunk of bytes, you can simply use display. See section 6.18.7 Output.
    getc
    getchar
    Use read-char or read-byte. See section 6.18.6 Input.
    getcwd
    Gauche's sys-getcwd. See section 6.21.7 System Inquiry.
    getdomainname
    Gauche's sys-getdomainname. See section 6.21.7 System Inquiry.
    getegid
    Gauche's sys-getegid. See section 6.21.7 System Inquiry.
    getenv
    Gauche's sys-getenv. See section 6.21.2 Environment Inquiry.
    geteuid
    Gauche's sys-geteuid. See section 6.21.7 System Inquiry.
    gethostname
    Gauche's sys-gethostname. See section 6.21.7 System Inquiry.
    getgid
    Gauche's sys-getgid. See section 6.21.7 System Inquiry.
    getgrgid
    getgrnam
    Gauche's sys-getgrgid and sys-getgrnam. See section 6.21.4.1 Unix Group.
    getgroups
    Gauche's sys-getgroups. See section 6.21.7 System Inquiry.
    getlogin
    Gauche's sys-getlogin. See section 6.21.7 System Inquiry.
    getpgrp
    Gauche's sys-getpgrp. See section 6.21.7 System Inquiry.
    getpid
    getppid
    Gauche's sys-getpid. See section 6.21.7 System Inquiry.
    getpwnam
    getpwuid
    Gauche's sys-getpwnam and sys-getpwuid. See section 6.21.4.2 Unix users.
    gets
    Use read-line or read-block. See section 6.18.6 Input.
    gettimeofday
    Gauche's sys-gettimeofday. See section 6.21.8 Time.
    getuid
    Gauche's sys-getuid. See section 6.21.7 System Inquiry.
    gmtime
    Gauche's sys-gmtime. See section 6.21.8 Time.
    isalnum
    Not directly supported, but you can use R5RS char-alphabetic? and char-numeric?. See section 6.8 Characters. You can also use character set. See section 6.9 Character Set, also section 10.8 srfi-14 - Character-set library.
    isalpha
    R5RS char-alphabetic?. See section 6.8 Characters. See also section 6.9 Character Set and section 10.8 srfi-14 - Character-set library.
    isatty
    Gauche's sys-isatty. See section 6.21.3.5 Other file operations.
    iscntrl
    Not directly supported, but you can use (char-set-contains? char-set:iso-control c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isdigit
    R5RS char-numeric?. See section 6.8 Characters. You can also use (char-set-contains? char-set:digit c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isgraph
    Not directly supported, but you can use (char-set-contains? char-set:graphic c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    islower
    R5RS char-lower-case?. See section 6.8 Characters. You can also use (char-set-contains? char-set:lower-case c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isprint
    Not directly supported, but you can use (char-set-contains? char-set:printing c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    ispunct
    Not directly supported, but you can use (char-set-contains? char-set:punctuation c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isspace
    R5RS char-whitespace?. See section 6.8 Characters. You can also use (char-set-contains? char-set:whitespace c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isupper
    R5RS char-upper-case?. See section 6.8 Characters. You can also use (char-set-contains? char-set:upper-case c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isxdigit
    Not directly supported, but you can use (char-set-contains? char-set:hex-digit c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    kill
    Gauche's sys-kill. See section 6.21.6 Signal.
    labs
    R5RS abs. See section 6.2.4 Arithmetics.
    ldexp
    Gauche's ldexp.
    ldiv
    Use R5RS quotient and remainder. See section 6.2.4 Arithmetics.
    link
    Gauche's sys-link. See section 6.21.3.2 Directory manipulation.
    localeconv
    Gauche's sys-localeconv. See section 6.21.5 Locale.
    localtime
    Gauche's sys-localtime. See section 6.21.8 Time.
    log
    R5RS log. See section 6.2.4 Arithmetics.
    log10
    Not directly supported. log10(z) == (/ (log z) (log 10)).
    longjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 Continuation.
    lseek
    Not supported yet.
    malloc
    Not necessary in Scheme.
    mblen
    mbstowcs
    mbtowc
    Gauche handles multibyte strings internally, so generally you don't need to care about multibyte-ness of the string. string-length always returns a number of characters for a string in supported encoding. If you want to convert the character encoding, see section 9.2 gauche.charconv - Character Code Conversion.
    memcmp
    memcpy
    memmove
    memset
    No equivalent functions.
    mkdir
    Gauche's sys-mkdir. See section 6.21.3.2 Directory manipulation.
    mkfifo
    Gauche's sys-mkfifo.
    mkstemp
    Gauche's sys-mkstemp. See section 6.21.3.2 Directory manipulation. Use this instead of tmpnam.
    mktime
    Gauche's sys-mktime. See section 6.21.8 Time.
    modf
    Gauche's modf.
    open
    Not directly supported. R5RS open-input-file or open-output-file corresponds to this operation. See section 6.18.3 File ports.
    opendir
    Not directly supported. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 Directories.
    openpty
    Use sys-openpty. See section 9.20 gauche.termios - Termios.
    pathconf
    Not supported.
    pause
    Gauche's sys-pause. See section 6.21.11 Miscellaneous system calls.
    perror
    No equivalent function in Gauche. System calls generally throws an error (<system-error>), including the description of the reason of failure.
    pipe
    Gauche's sys-pipe. See section 6.21.3.5 Other file operations.
    pow
    R5RS expt. See section 6.2.4 Arithmetics.
    printf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 Output. SLIB has printf implementation.
    putc
    putchar
    Use write-char or write-byte. See section 6.18.7 Output.
    puts
    Use display. See section 6.18.7 Output.
    qsort
    Gauche's sort and sort! provides a convenient way to sort list of items. See section 6.20 Comparison and sorting.
    raise
    No equivalent function in Gauche. Scheme function raise (SRFI-18) is to raise an exception. You can use (sys-kill (sys-getpid) SIG) to send a signal SIG to the current process.
    rand
    Not supported directly, but on most platforms a better RNG is available as sys-random. See section 6.21.11 Miscellaneous system calls.
    read
    Not supported directly, but you may be able to use read-block (See section 6.18.6 Input) or read-block! (See section 9.24.4 Uvector block I/O).
    readdir
    Not supported directly. Gauche's sys-readdir reads the directly at once. See section 6.21.3.1 Directories.
    readlink
    Gauche's sys-readlink. See section 6.21.3.2 Directory manipulation. This function is available on systems that support symbolink links.
    realloc
    Not necessary in Scheme.
    remove
    Gauche's sys-remove. See section 6.21.3.2 Directory manipulation.
    rename
    Gauche's sys-rename. See section 6.21.3.2 Directory manipulation.
    rewind
    Not supported yet.
    rewinddir
    Not supported directly. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 Directories.
    rmdir
    Gauche's sys-rmdir. See section 6.21.3.2 Directory manipulation.
    scanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 Regular expression, also section 9.15 gauche.regexp - Regular expression utilities.
    select
    Gauche sys-select. See section 6.21.10 I/O multiplexing.
    setbuf
    Not necessary.
    setgid
    Gauche's sys-setgid.
    setjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 Continuation.
    setlocale
    Gauche's sys-setlocale. See section 6.21.5 Locale.
    setpgid
    Gauche's sys-setpgid. See section 6.21.7 System Inquiry.
    setsid
    Gauche's sys-setsid. See section 6.21.7 System Inquiry.
    setuid
    Gauche's sys-setuid. See section 6.21.7 System Inquiry.
    setvbuf
    Not necessary.
    sigaction
    You can use with-signal-handlers to install signal handlers. See section 6.21.6.3 Handling signals.
    sigaddset
    sigdelset
    sigemptyset
    sigfillset
    Gauche's sys-sigset-add! and sys-sigset-delete!. See section 6.21.6.1 Signals and signal sets.
    sigismember
    Not supported yet.
    siglongjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 Continuation.
    signal
    You can use with-signal-handlers to install signal handlers. See section 6.21.6.3 Handling signals.
    sigpending
    Not supported yet.
    sigprocmask
    Signal mask is handled internally. See See section 6.21.6.3 Handling signals.
    sigsetjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 Continuation.
    sigsuspend
    Not supported yet.
    sin
    sinh
    Use sin and sinh. See section 6.2.4 Arithmetics.
    sleep
    Gauche's sys-sleep. See section 6.21.11 Miscellaneous system calls.
    sprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 Output. SLIB has printf implementation.
    sqrt
    R5RS sqrt. See section 6.2.4 Arithmetics.
    srand
    Not supported directly, but on most platforms a better RNG is available as sys-srandom. See section 6.21.11 Miscellaneous system calls.
    sscanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 Regular expression, also section 9.15 gauche.regexp - Regular expression utilities.
    stat
    Gauche's sys-stat. See section 6.21.3.4 File stats.
    strcasecmp
    R5RS string-ci=? and other comparison functions. See section 6.10.6 String Comparison.
    strcat
    R5RS string-append. See section 6.10.7 String utilities.
    strchr
    SRFI-13 string-index. See section 10.7.7 String searching.
    strcmp
    R5RS string=? and other comparison functions. See section 6.10.6 String Comparison.
    strcoll
    Not supported yet.
    strcpy
    R5RS string-copy. See section 6.10.7 String utilities.
    strcspn
    Not directly supported, but you can use SRFI-13 string-skip with a character set. See section 10.7.7 String searching.
    strerror
    Not supported.
    strftime
    Gauche's sys-strftime. See section 6.21.8 Time.
    strlen
    R5RS string-length. See section 6.10.5 String Accessors & Modifiers.
    strncat
    Not directly supported, but you can use string-append and substring.
    strncasecmp
    SRFI-13 string-compare-ci provides the most flexible (but a bit difficult to use) functionality. See section 10.7.5 String comparison. If what you want is just to check the fixed-length prefixes of two string matches, you can use SRFI-13 string-prefix-ci?.
    strncmp
    SRFI-13 string-compare provides the most flexible (but a bit difficult to use) functionality. See section 10.7.5 String comparison. If what you want is just to check the fixed-length prefixes of two string matches, you can use SRFI-13 string-prefix?. See section 10.7.6 String Prefixes & Suffixes.
    strncpy
    SRFI-13 substring. See section 6.10.7 String utilities.
    strpbrk
    Not directly supported, but you can use SRFI-13 string-skip with a character set. See section 10.7.7 String searching.
    strrchr
    SRFI-13 string-index-right. See section 10.7.7 String searching.
    strspn
    Not directly supported, but you can use SRFI-13 string-index with a character set. See section 10.7.7 String searching.
    strstr
    SRFI-13 string-contains. See section 10.7.7 String searching.
    strtod
    You can use R5RS string->number. See section 6.2.5 Numerical conversions.
    strtok
    SRFI-13 string-tokenize. See section 10.7.12 Other string operations.
    strtol
    strtoul
    You can use R5RS string->number. See section 6.2.5 Numerical conversions.
    strxfrm
    Not supported yet.
    symlink
    Gauche's sys-symlink. See section 6.21.3.2 Directory manipulation. This function is available on systems that support symbolink links.
    sysconf
    Not supported yet.
    system
    Gauche sys-system. See section 6.21.9.1 Fork and exec. It is generally recommended to use the process library (section 9.14 gauche.process - High Level Process Interface).
    tan
    tanh
    R5RS tan and Gauche tanh. See section 6.2.4 Arithmetics.
    tcdrain
    tcflow
    tcflush
    tcgetattr
    tcgetpgrp
    tcsendbreak
    tcsetattr
    tcsetpgrp
    Corresponding functions are: sys-tcdrain, sys-tcflow, sys-tcflush, sys-tcgetattr, sys-tcgetpgrp, sys-tcsendbreak, sys-tcsetattr, sys-tcsetpgrp. See section 9.20 gauche.termios - Termios
    time
    Gauche's sys-time. See section 6.21.8 Time.
    times
    Gauche's sys-times. See section 6.21.7 System Inquiry.
    tmpfile
    Not exactly supported.
    tmpnam
    Gauche's sys-tmpnam. This function is provided since it is in POSIX, but its use is discouraged for the potential security risk. Use sys-mkstemp instead. See section 6.21.3.2 Directory manipulation.
    tolower
    toupper
    R5RS char-upcase and char-downcase. See section 6.8 Characters.
    ttyname
    Gauche's sys-ttyname. See section 6.21.3.5 Other file operations.
    tzset
    Not supported yet.
    umask
    Gauche's sys-umask. See section 6.21.3.2 Directory manipulation.
    uname
    Gauche's sys-uname. See section 6.21.7 System Inquiry.
    ungetc
    Not directly supported. You can use peek-char to look one character ahead, instead of pushing back.
    unlink
    Gauche's sys-unlink. See section 6.21.3.2 Directory manipulation.
    utime
    Not supported yet.
    va_arg
    va_end
    va_start
    Not necessary, for Scheme handles variable number of arguments naturally.
    vfprintf
    vprintf
    vsprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 Output. SLIB has printf implementation.
    wait
    Gauche's sys-wait. See section 6.21.9.2 Wait.
    waitpid
    Gauche's sys-waitpid. See section 6.21.9.2 Wait.
    wcstombs
    wctomb
    Gauche handles multibyte strings internally, so generally you don't need to care about multibyte-ness of the string. string-length always returns a number of characters for a string in supported encoding. If you want to convert the character encoding, see section 9.2 gauche.charconv - Character Code Conversion.
    write
    R5RS display (See section 6.18.7 Output). Or write-block (See section 9.24.4 Uvector block I/O).

    C. Indices

    C.1 Function and Syntax Index

    Jump to: % - ( - * - + - - - / - < - = - > - a - b - c - d - e - f - g - h - i - j - k - l - m - n - o - p - q - r - s - t - u - v - w - x - z

    %

  • %macroexpand
  • %macroexpand-1
  • (

  • (setter object-apply)
  • (setter port-buffering)
  • (setter ref)
  • (setter subseq), (setter subseq)
  • *

  • *
  • +

  • +
  • -

  • -
  • ->char-set
  • /

  • /
  • <

  • <
  • <=
  • =

  • =
  • >

  • >
  • >=
  • a

  • abandoned-mutex-exception?
  • abs
  • absolute-path?
  • acons
  • acos
  • acosh
  • add-duration
  • add-duration!
  • add-load-path
  • alist-cons
  • alist-copy
  • alist-delete
  • alist-delete!
  • all-modules
  • and
  • and-let*
  • angle
  • any
  • any$
  • any-pred
  • append
  • append!
  • append-map
  • append-map!
  • append-reverse
  • append-reverse!
  • apply
  • apply$
  • apply-generic
  • apply-method
  • apply-methods
  • apropos
  • arity
  • arity-at-least-value
  • arity-at-least?
  • array
  • array->list
  • array->vector
  • array-end
  • array-for-each-index
  • array-length
  • array-map, array-map
  • array-map!, array-map!
  • array-rank
  • array-ref, array-ref
  • array-retabulate!, array-retabulate!
  • array-set!, array-set!
  • array-shape
  • array-size
  • array-start
  • array?
  • ash
  • asin
  • asinh
  • assert-curr-char
  • assoc
  • assoc$
  • assq
  • assv
  • atan, atan
  • atanh
  • autoload
  • b

  • base64-decode
  • base64-decode-string
  • base64-encode
  • base64-encode-string
  • begin
  • begin0
  • bignum?
  • bit-field
  • boolean?
  • break
  • break!
  • build-path
  • build-transliterator
  • c

  • caaaar
  • caaadr
  • caaar
  • caadar
  • caaddr
  • caadr
  • caar
  • cadaar
  • cadadr
  • cadar
  • caddar
  • cadddr
  • caddr
  • cadr
  • call-with-builder
  • call-with-client-socket
  • call-with-current-continuation
  • call-with-input-file, call-with-input-file
  • call-with-input-process
  • call-with-input-string
  • call-with-iterator
  • call-with-iterators
  • call-with-output-file, call-with-output-file
  • call-with-output-process
  • call-with-output-string
  • call-with-process-io
  • call-with-string-io
  • call-with-values
  • call/cc
  • car
  • car+cdr
  • case
  • cdaaar
  • cdaadr
  • cdaar
  • cdadar
  • cdaddr
  • cdadr
  • cdar
  • cddaar
  • cddadr
  • cddar
  • cdddar
  • cddddr
  • cdddr
  • cddr
  • cdr
  • ceiling
  • ces-conversion-supported?
  • ces-convert
  • ces-guess-from-string
  • cgi-get-parameter
  • cgi-header
  • cgi-main
  • cgi-parse-parameters
  • char->integer
  • char->ucs
  • char-alphabetic?
  • char-ci<=?
  • char-ci<?
  • char-ci=?
  • char-ci>=?
  • char-ci>?
  • char-downcase
  • char-lower-case?
  • char-numeric?
  • char-ready?
  • char-set
  • char-set->list
  • char-set->string
  • char-set-adjoin
  • char-set-adjoin!
  • char-set-any
  • char-set-complement
  • char-set-complement!
  • char-set-contains?
  • char-set-copy
  • char-set-count
  • char-set-cursor
  • char-set-cursor-next
  • char-set-delete
  • char-set-delete!
  • char-set-diff+intersection
  • char-set-diff+intersection!
  • char-set-difference
  • char-set-difference!
  • char-set-every
  • char-set-filter
  • char-set-filter!
  • char-set-fold
  • char-set-for-each
  • char-set-hash
  • char-set-intersection
  • char-set-intersection!
  • char-set-map
  • char-set-ref
  • char-set-size
  • char-set-unfold
  • char-set-unfold!
  • char-set-union
  • char-set-union!
  • char-set-xor
  • char-set-xor!
  • char-set<=
  • char-set=
  • char-set?
  • char-upcase
  • char-upper-case?
  • char-whitespace?
  • char<=?
  • char<?
  • char=?
  • char>=?
  • char>?
  • char?
  • check-substring-spec
  • circular-list
  • circular-list?
  • clamp
  • class-direct-slots
  • class-direct-supers
  • class-name
  • class-of
  • class-precedence-list
  • class-slot-accessor
  • class-slot-definition
  • class-slot-ref
  • class-slot-set!
  • class-slots
  • close-input-port
  • close-output-port
  • coerce-to
  • compare
  • complete-sexp?
  • complex?
  • compose
  • compute-get-n-set
  • compute-slots
  • concatenate
  • concatenate!
  • cond
  • cond-expand
  • condition-variable-broadcast!
  • condition-variable-name
  • condition-variable-signal!
  • condition-variable-specific
  • condition-variable-specific-set!
  • condition-variable?
  • cons
  • cons*
  • construct-cookie-string
  • copy-bit
  • copy-bit-field
  • copy-file
  • copy-port
  • copy-time
  • cos
  • cosh
  • count
  • count$
  • create-directory*
  • current-date
  • current-directory
  • current-error-port
  • current-exception-handler
  • current-input-port
  • current-julian-day
  • current-load-history
  • current-load-next
  • current-load-port
  • current-modified-julian-day
  • current-module
  • current-output-port
  • current-thread
  • current-time, current-time
  • cut
  • cute
  • d

  • d
  • date->julian-day
  • date->modified-julian-day
  • date->string
  • date->time-monotonic
  • date->time-tai
  • date->time-utc
  • date-day
  • date-hour
  • date-minute
  • date-month
  • date-nanosecond
  • date-second
  • date-week-day
  • date-week-number
  • date-year
  • date-year-day
  • date-zone-offset
  • date?
  • dbm-close
  • dbm-closed?
  • dbm-delete!
  • dbm-exists?
  • dbm-fold
  • dbm-for-each
  • dbm-get
  • dbm-map
  • dbm-open, dbm-open
  • dbm-put!
  • dec!
  • decode-float
  • define, define
  • define-class
  • define-constant, define-constant
  • define-generic
  • define-in-module, define-in-module
  • define-macro, define-macro
  • define-method
  • define-module
  • define-read-ctor
  • define-record-type
  • define-syntax
  • define-values
  • delay
  • delete
  • delete!
  • delete$
  • delete-directory*
  • delete-duplicates
  • delete-duplicates!
  • denominator
  • dequeue!
  • dequeue-all!
  • describe
  • digit->integer
  • directory-fold
  • directory-list
  • directory-list2
  • display
  • do
  • dolist
  • dotimes
  • dotted-list?
  • drop
  • drop-right
  • drop-right!
  • drop-while
  • dynamic-load
  • dynamic-wind
  • e

  • eighth
  • end-of-char-set?
  • enqueue!
  • eof-object?
  • eq?
  • equal?
  • eqv?
  • error
  • errorf
  • eval
  • even?
  • every
  • every$
  • every-pred
  • exact->inexact
  • exact?
  • exit
  • exp
  • expand-path
  • export
  • export-all
  • expt
  • extend
  • f

  • f32vector
  • f32vector->list
  • f32vector->vector
  • f32vector-add
  • f32vector-add!
  • f32vector-clamp
  • f32vector-clamp!
  • f32vector-copy
  • f32vector-copy!
  • f32vector-div
  • f32vector-div!
  • f32vector-dot
  • f32vector-length
  • f32vector-mul
  • f32vector-mul!
  • f32vector-range-check
  • f32vector-ref
  • f32vector-set!
  • f32vector-sub
  • f32vector-sub!
  • f32vector?
  • f64vector
  • f64vector->list
  • f64vector->vector
  • f64vector-add
  • f64vector-add!
  • f64vector-clamp
  • f64vector-clamp!
  • f64vector-copy
  • f64vector-copy!
  • f64vector-div
  • f64vector-div!
  • f64vector-dot
  • f64vector-length
  • f64vector-mul
  • f64vector-mul!
  • f64vector-range-check
  • f64vector-ref
  • f64vector-set!
  • f64vector-sub
  • f64vector-sub!
  • f64vector?
  • fifth
  • file-atime
  • file-atime<=?
  • file-atime<?
  • file-atime=?
  • file-atime>=?
  • file-atime>?
  • file-ctime
  • file-ctime<=?
  • file-ctime<?
  • file-ctime=?
  • file-ctime>=?
  • file-ctime>?
  • file-dev
  • file-eq?
  • file-equal?
  • file-eqv?
  • file-exists?
  • file-filter
  • file-gid
  • file-ino
  • file-is-directory?
  • file-is-executable?
  • file-is-readable?
  • file-is-regular?
  • file-is-writable?
  • file-mode
  • file-mtime
  • file-mtime<=?
  • file-mtime<?
  • file-mtime=?
  • file-mtime>=?
  • file-mtime>?
  • file-nlink
  • file-perm
  • file-rdev
  • file-size
  • file-type
  • file-uid
  • filter
  • filter!
  • filter$
  • filter-map
  • filter-to
  • find, find
  • find$
  • find-file-in-paths
  • find-in-queue
  • find-module
  • find-string-from-port?
  • find-tail
  • find-tail$
  • first
  • fixnum?
  • floor
  • flush
  • flush-all-ports
  • fmod
  • fold, fold
  • fold$, fold$, fold$
  • fold-right
  • fold-right$
  • for-each, for-each
  • for-each$, for-each$
  • force
  • format, format
  • fourth
  • frexp
  • g

  • gauche-architecture
  • gauche-architecture-directory
  • gauche-character-encoding
  • gauche-config
  • gauche-library-directory
  • gauche-site-architecture-directory
  • gauche-site-library-directory
  • gauche-thread-type
  • gauche-version
  • gcd
  • gdbm-close
  • gdbm-closed?
  • gdbm-delete
  • gdbm-errno
  • gdbm-exists
  • gdbm-fetch
  • gdbm-firstkey
  • gdbm-nextkey
  • gdbm-open
  • gdbm-reorganize
  • gdbm-setopt
  • gdbm-store
  • gdbm-strerror
  • gdbm-sync
  • gdbm-version
  • gensym
  • get-keyword
  • get-keyword*
  • get-optional
  • get-output-string
  • get-signal-handler
  • get-signal-handlers
  • getter-with-setter
  • h

  • hash-table-delete!
  • hash-table-exists?
  • hash-table-for-each
  • hash-table-get
  • hash-table-keys
  • hash-table-map
  • hash-table-pop!
  • hash-table-push!
  • hash-table-put!
  • hash-table-values
  • hash-table?
  • home-directory
  • html-doctype
  • html-escape
  • html-escape-string
  • html:a
  • html:abbr
  • html:acronym
  • html:address
  • html:area
  • html:b
  • html:base
  • html:bdo
  • html:big
  • html:blockquote
  • html:body
  • html:br
  • html:button
  • html:caption
  • html:cite
  • html:code
  • html:col
  • html:colgroup
  • html:dd
  • html:del
  • html:dfn
  • html:div
  • html:dl
  • html:dt
  • html:em
  • html:fieldset
  • html:form
  • html:h1
  • html:h2
  • html:h3
  • html:h4
  • html:h5
  • html:h6
  • html:head
  • html:hr
  • html:html
  • html:i
  • html:img
  • html:input
  • html:ins
  • html:kbd
  • html:label
  • html:legend
  • html:li
  • html:link
  • html:map
  • html:meta
  • html:noscript
  • html:object
  • html:ol
  • html:optgroup
  • html:option
  • html:p
  • html:param
  • html:pre
  • html:q
  • html:samp
  • html:script
  • html:select
  • html:small
  • html:span
  • html:strong
  • html:style
  • html:sub
  • html:sup
  • html:table
  • html:tbody
  • html:td
  • html:textarea
  • html:tfoot
  • html:th
  • html:thead
  • html:title
  • html:tr
  • html:tt
  • html:ul
  • html:var
  • http-get
  • http-head
  • http-post
  • i

  • identifier->symbol
  • identifier?
  • if, if
  • imag-part
  • import
  • inc!
  • inexact->exact
  • inexact?
  • info
  • initialize
  • input-port?
  • instance-of
  • integer->char
  • integer->digit
  • integer-length
  • integer-range->char-set
  • integer-range->char-set!
  • integer?
  • interaction-environment
  • iota
  • is-a?
  • isomorphic?
  • j

  • join-timeout-exception?
  • julian-day->date
  • julian-day->time-monotonic
  • julian-day->time-tai
  • julian-day->time-utc
  • k

  • keyword->string
  • keyword?
  • kmp-step
  • l

  • lambda
  • last
  • last-pair
  • lazy-size-of
  • lcm
  • ldexp
  • length
  • length+
  • let, let
  • let*
  • let*-values
  • let-keywords*
  • let-optionals*, let-optionals*
  • let-string-start+end
  • let-syntax
  • let-values
  • let1
  • letrec
  • letrec-syntax
  • list
  • list*
  • list->char-set
  • list->char-set!
  • list->f32vector
  • list->f64vector
  • list->queue
  • list->s16vector
  • list->s32vector
  • list->s64vector
  • list->s8vector
  • list->string
  • list->u16vector
  • list->u32vector
  • list->u64vector
  • list->u8vector
  • list->vector
  • list-copy
  • list-index
  • list-ref
  • list-tabulate
  • list-tail
  • list=
  • list?
  • listener-read-handler
  • listener-show-prompt
  • load
  • load-from-port
  • log
  • log-format, log-format
  • log-open
  • logand
  • logbit?
  • logcount
  • logior
  • lognot
  • logtest
  • logxor
  • lset-adjoin
  • lset-diff+intersection
  • lset-diff+intersection!
  • lset-difference
  • lset-difference!
  • lset-intersection
  • lset-intersection!
  • lset-union
  • lset-union!
  • lset-xor
  • lset-xor!
  • lset<=
  • lset=
  • m

  • macroexpand
  • macroexpand-1
  • magnitude
  • make, make, make, make, make, make
  • make-array
  • make-client-socket
  • make-condition-variable
  • make-csv-reader
  • make-csv-writer
  • make-date
  • make-directory*
  • make-f32vector
  • make-f64vector
  • make-hash-table
  • make-keyword
  • make-kmp-restart-vector
  • make-list
  • make-mutex
  • make-option-parser
  • make-parameter
  • make-polar
  • make-queue
  • make-random-source
  • make-rectangular
  • make-s16vector
  • make-s32vector
  • make-s64vector
  • make-s8vector
  • make-server-socket
  • make-socket
  • make-string
  • make-string-pointer
  • make-thread
  • make-time
  • make-u16vector
  • make-u32vector
  • make-u64vector
  • make-u8vector
  • make-vector
  • make-weak-vector
  • map, map
  • map!
  • map$, map$
  • map-in-order
  • map-to
  • max
  • member
  • member$
  • memq
  • memv
  • method-more-specific?
  • min
  • min&max
  • modf
  • modified-julian-day->date
  • modified-julian-day->time-monotonic
  • modified-julian-day->time-tai
  • modified-julian-day->time-utc
  • modifier
  • module-exports
  • module-imports
  • module-name
  • module-parents
  • module-precedence-list
  • module-reload-rules
  • module-table
  • module?
  • modulo
  • move-file
  • mt-random-fill-f32vector!
  • mt-random-fill-f64vector!
  • mt-random-fill-u32vector!
  • mt-random-get-state
  • mt-random-integer
  • mt-random-real
  • mt-random-real0
  • mt-random-set-seed!
  • mt-random-set-state!
  • mutex-lock!
  • mutex-name
  • mutex-specific
  • mutex-specific-set!
  • mutex-state
  • mutex-unlock!
  • mutex?
  • n

  • ndbm-clear-error
  • ndbm-close
  • ndbm-closed?
  • ndbm-delete
  • ndbm-error
  • ndbm-fetch
  • ndbm-firstkey
  • ndbm-nextkey
  • ndbm-open
  • ndbm-store
  • negative?
  • newline
  • next-token
  • next-token-of
  • ninth
  • not
  • not-pair?
  • null-environment
  • null-list?
  • null?
  • number->string
  • number?
  • numerator
  • o

  • object-apply
  • object-compare
  • object-equal?
  • object-isomorphic?
  • odbm-close
  • odbm-delete
  • odbm-fetch
  • odbm-firstkey
  • odbm-init
  • odbm-nextkey
  • odbm-store
  • odd?
  • open-input-buffered-port
  • open-input-conversion-port
  • open-input-fd-port
  • open-input-file, open-input-file
  • open-input-process-port
  • open-input-string
  • open-output-buffered-port
  • open-output-conversion-port
  • open-output-fd-port
  • open-output-file, open-output-file
  • open-output-process-port
  • open-output-string
  • or
  • output-port?
  • p

  • pa$
  • pair-fold
  • pair-fold-right
  • pair-for-each
  • pair?
  • parameterize
  • parse-cookie-string
  • parse-options
  • partition, partition
  • partition!
  • partition$
  • partition-to
  • peek-char
  • peek-next-char
  • pop!
  • port->list
  • port->sexp-list
  • port->string
  • port->string-list
  • port-buffering
  • port-closed?
  • port-current-line
  • port-file-number
  • port-fold
  • port-fold-right
  • port-for-each
  • port-map
  • port-name
  • port-type
  • port?
  • positive?
  • print
  • procedure-arity-includes?
  • procedure?
  • process-alive?
  • process-command
  • process-continue
  • process-error
  • process-input
  • process-kill
  • process-list
  • process-output
  • process-output->string
  • process-output->string-list
  • process-pid
  • process-send-signal
  • process-stop
  • process-wait
  • process?
  • proper-list?
  • provide
  • provided?
  • push!
  • q

  • quasiquote
  • queue->list
  • queue-empty?
  • queue-front
  • queue-length
  • queue-pop!
  • queue-push!
  • queue-rear
  • queue?
  • quote
  • quoted-printable-decode
  • quoted-printable-decode-string
  • quoted-printable-encode
  • quoted-printable-encode-string
  • quotient
  • quotient&remainder
  • r

  • raise
  • random-integer
  • random-real
  • random-source-make-integers
  • random-source-make-reals
  • random-source-pseudo-randomize!
  • random-source-randomize!
  • random-source-state-ref
  • random-source-state-set!
  • random-source?
  • rational?
  • read
  • read-block
  • read-block!
  • read-byte
  • read-char
  • read-eval-print-loop
  • read-from-string
  • read-line
  • read-string
  • real-part
  • real?
  • receive
  • reduce
  • reduce$
  • reduce-right
  • reduce-right$
  • ref
  • referencer
  • regexp->string
  • regexp-replace
  • regexp-replace-all
  • regexp?
  • relative-path?
  • relnum-compare
  • reload
  • reload-modified-modules
  • reload-verbose
  • remainder
  • remove, remove
  • remove!
  • remove$
  • remove-directory*
  • remove-from-queue!
  • remove-to
  • require
  • resolve-path
  • reverse
  • reverse!
  • reverse-list->string
  • rfc822-header->list
  • rfc822-parse-date
  • round
  • run-process
  • rxmatch
  • rxmatch-after
  • rxmatch-before
  • rxmatch-case
  • rxmatch-cond
  • rxmatch-end
  • rxmatch-if
  • rxmatch-let
  • rxmatch-start
  • rxmatch-substring
  • s

  • s16vector
  • s16vector->list
  • s16vector->vector
  • s16vector-add
  • s16vector-add!
  • s16vector-and
  • s16vector-and!
  • s16vector-clamp
  • s16vector-clamp!
  • s16vector-copy
  • s16vector-copy!
  • s16vector-dot
  • s16vector-ior
  • s16vector-ior!
  • s16vector-length
  • s16vector-mul
  • s16vector-mul!
  • s16vector-range-check
  • s16vector-ref
  • s16vector-set!
  • s16vector-sub
  • s16vector-sub!
  • s16vector-xor
  • s16vector-xor!
  • s16vector?
  • s32vector
  • s32vector->list
  • s32vector->string
  • s32vector->vector
  • s32vector-add
  • s32vector-add!
  • s32vector-and
  • s32vector-and!
  • s32vector-clamp
  • s32vector-clamp!
  • s32vector-copy
  • s32vector-copy!
  • s32vector-dot
  • s32vector-ior
  • s32vector-ior!
  • s32vector-length
  • s32vector-mul
  • s32vector-mul!
  • s32vector-range-check
  • s32vector-ref
  • s32vector-set!
  • s32vector-sub
  • s32vector-sub!
  • s32vector-xor
  • s32vector-xor!
  • s32vector?
  • s64vector
  • s64vector->list
  • s64vector->vector
  • s64vector-add
  • s64vector-add!
  • s64vector-and
  • s64vector-and!
  • s64vector-clamp
  • s64vector-clamp!
  • s64vector-copy
  • s64vector-copy!
  • s64vector-dot
  • s64vector-ior
  • s64vector-ior!
  • s64vector-length
  • s64vector-mul
  • s64vector-mul!
  • s64vector-range-check
  • s64vector-ref
  • s64vector-set!
  • s64vector-sub
  • s64vector-sub!
  • s64vector-xor
  • s64vector-xor!
  • s64vector?
  • s8vector
  • s8vector->list
  • s8vector->string
  • s8vector->vector
  • s8vector-add
  • s8vector-add!
  • s8vector-and
  • s8vector-and!
  • s8vector-clamp
  • s8vector-clamp!
  • s8vector-copy
  • s8vector-copy!
  • s8vector-dot
  • s8vector-ior
  • s8vector-ior!
  • s8vector-length
  • s8vector-mul
  • s8vector-mul!
  • s8vector-range-check
  • s8vector-ref
  • s8vector-set!
  • s8vector-sub
  • s8vector-sub!
  • s8vector-xor
  • s8vector-xor!
  • s8vector?
  • scheme-report-environment
  • second
  • seconds->time
  • select-module
  • selector-add!
  • selector-delete!
  • selector-select
  • set!, set!
  • set!-values
  • set-car!
  • set-cdr!
  • set-signal-handler!
  • set-time-nanosecond!
  • set-time-second!
  • set-time-type!
  • setter
  • seventh
  • shape
  • shape-for-each
  • share-array
  • simplify-path
  • sin
  • sinh
  • sixth
  • size-of
  • skip-until
  • skip-while
  • slot-bound?
  • slot-defininion-setter
  • slot-definition-accessor
  • slot-definition-allocation
  • slot-definition-getter
  • slot-definition-name
  • slot-definition-option
  • slot-definition-options
  • slot-exists?
  • slot-missing, slot-missing
  • slot-ref
  • slot-ref-using-accessor
  • slot-set!
  • slot-set-using-accessor
  • slot-unbound, slot-unbound
  • sockaddr-family, sockaddr-family, sockaddr-family
  • sockaddr-name, sockaddr-name, sockaddr-name
  • socket-accept
  • socket-address
  • socket-bind
  • socket-close
  • socket-connect
  • socket-fd
  • socket-getsockopt
  • socket-input-port
  • socket-listen
  • socket-output-port
  • socket-setsockopt
  • socket-shutdown
  • socket-status
  • sort
  • sort!
  • sort-applicable-methods
  • span
  • span!
  • split-at
  • split-at!
  • sqrt
  • standard-error-port
  • standard-input-port
  • standard-output-port
  • string
  • string->char-set
  • string->char-set!
  • string->date
  • string->list
  • string->number
  • string->regexp
  • string->s32vector
  • string->s8vector
  • string->symbol
  • string->u32vector
  • string->u8vector
  • string-any
  • string-append
  • string-append/shared
  • string-byte-ref
  • string-byte-set!
  • string-ci<
  • string-ci<=
  • string-ci<=?
  • string-ci<>
  • string-ci<?
  • string-ci=
  • string-ci=?
  • string-ci>
  • string-ci>=
  • string-ci>=?
  • string-ci>?
  • string-compare
  • string-compare-ci
  • string-complete->incomplete
  • string-concatenate
  • string-concatenate-reverse
  • string-concatenate-reverse/shared
  • string-concatenate/shared
  • string-contains
  • string-contains-ci
  • string-copy
  • string-copy!
  • string-count
  • string-delete
  • string-downcase
  • string-downcase!
  • string-drop
  • string-drop-right
  • string-every
  • string-fill!
  • string-filter
  • string-fold
  • string-fold-right
  • string-for-each
  • string-for-each-index
  • string-hash
  • string-hash-ci
  • string-immutable?
  • string-incomplete->complete
  • string-incomplete?
  • string-index
  • string-index-right
  • string-join
  • string-kmp-partial-search
  • string-length
  • string-map
  • string-map!
  • string-null?
  • string-pad
  • string-pad-right
  • string-parse-final-start+end
  • string-parse-start+end
  • string-pointer-byte-index
  • string-pointer-copy
  • string-pointer-index
  • string-pointer-next!
  • string-pointer-prev!
  • string-pointer-set!
  • string-pointer-substring
  • string-pointer?
  • string-prefix-ci?
  • string-prefix-length
  • string-prefix-length-ci
  • string-prefix?
  • string-ref
  • string-replace
  • string-reverse
  • string-reverse!
  • string-scan
  • string-set!
  • string-size
  • string-skip
  • string-skip-right
  • string-split
  • string-suffix-ci?
  • string-suffix-length
  • string-suffix-length-ci
  • string-suffix?
  • string-tabulate
  • string-take
  • string-take-right
  • string-titlecase
  • string-titlecase!
  • string-tokenize
  • string-tr
  • string-trim
  • string-trim-both
  • string-trim-right
  • string-unfold
  • string-unfold-right
  • string-upcase
  • string-upcase!
  • string-xcopy!
  • string<
  • string<=
  • string<=?
  • string<>
  • string<?
  • string=
  • string=?
  • string>
  • string>=
  • string>=?
  • string>?
  • string?
  • subseq
  • substring
  • substring-spec-ok?
  • substring/shared
  • subtract-duration
  • subtract-duration!
  • supported-character-encodings
  • symbol->string
  • symbol?
  • syntax-error
  • syntax-errorf
  • syntax-rules
  • sys-abort
  • sys-access
  • sys-alarm
  • sys-asctime
  • sys-basename
  • sys-cfgetispeed
  • sys-cfgetospeed
  • sys-cfsetispeed
  • sys-cfsetospeed
  • sys-chdir
  • sys-chmod
  • sys-chown
  • sys-closelog
  • sys-crypt
  • sys-ctermid
  • sys-ctime
  • sys-difftime
  • sys-dirname
  • sys-exec
  • sys-exit
  • sys-fcntl
  • sys-fdset-max-fd
  • sys-fdset-ref
  • sys-fdset-set!
  • sys-fork
  • sys-forkpty
  • sys-fstat
  • sys-getcwd
  • sys-getdomainname
  • sys-getegid
  • sys-getenv
  • sys-geteuid
  • sys-getgid
  • sys-getgrgid
  • sys-getgrnam
  • sys-getgroups
  • sys-gethostbyaddr
  • sys-gethostbyname
  • sys-gethostname
  • sys-getlogin
  • sys-getpgid
  • sys-getpgrp
  • sys-getpid
  • sys-getppid
  • sys-getprotobyname
  • sys-getprotobynumber
  • sys-getpwnam
  • sys-getpwuid
  • sys-getservbyname
  • sys-getservbyport
  • sys-gettimeofday
  • sys-getuid
  • sys-gid->group->name
  • sys-glob
  • sys-gmtime
  • sys-group-name->gid
  • sys-isatty
  • sys-kill
  • sys-link
  • sys-localeconv
  • sys-localtime
  • sys-logmask
  • sys-lstat
  • sys-mkdir
  • sys-mkfifo
  • sys-mkstemp
  • sys-mktime
  • sys-nanosleep
  • sys-normalize-pathname
  • sys-openlog
  • sys-openpty
  • sys-pause
  • sys-pipe
  • sys-putenv
  • sys-random
  • sys-readdir
  • sys-readlink
  • sys-remove
  • sys-rename
  • sys-rmdir
  • sys-select
  • sys-select!
  • sys-setgid
  • sys-setlocate
  • sys-setlogmask
  • sys-setpgid
  • sys-setsid
  • sys-setuid
  • sys-sigmask
  • sys-signal-name
  • sys-sigset-add!
  • sys-sigset-delete!
  • sys-sigset-empty!
  • sys-sigset-fill!
  • sys-sigsuspend
  • sys-sleep
  • sys-srandom
  • sys-stat
  • sys-stat->atime
  • sys-stat->ctime
  • sys-stat->dev
  • sys-stat->file-type
  • sys-stat->gid
  • sys-stat->ino
  • sys-stat->mode
  • sys-stat->mtime
  • sys-stat->nlink
  • sys-stat->rdev
  • sys-stat->size
  • sys-stat->uid
  • sys-strftime
  • sys-symlink
  • sys-syslog
  • sys-system
  • sys-tcdrain
  • sys-tcflow
  • sys-tcflush
  • sys-tcgetattr
  • sys-tcgetpgrp
  • sys-tcsendbreak
  • sys-tcsetattr
  • sys-tcsetpgrp
  • sys-time
  • sys-times
  • sys-tm->alist
  • sys-tmpnam
  • sys-ttyname
  • sys-uid->user-name
  • sys-umask
  • sys-uname
  • sys-unlink
  • sys-user-name->uid
  • sys-utime
  • sys-wait
  • sys-wait-exit-status
  • sys-wait-exited?
  • sys-wait-signaled?
  • sys-wait-stopped?
  • sys-wait-stopsig
  • sys-wait-termsig
  • sys-waitpid
  • t

  • tabulate-array
  • take
  • take!
  • take-right
  • take-while
  • take-while!
  • tan
  • tanh
  • tenth
  • terminated-thread-exception?
  • test
  • test-end
  • test-section
  • test-start
  • third
  • thread-join!
  • thread-name
  • thread-sleep!
  • thread-specific
  • thread-specific-set!
  • thread-start!
  • thread-terminate!
  • thread-yield!
  • thread?
  • time
  • time->seconds
  • time-counter-reset!
  • time-counter-start!
  • time-counter-stop!
  • time-counter-value
  • time-difference
  • time-difference!
  • time-monotonic->date
  • time-monotonic->julian-day
  • time-monotonic->modified-julian-day
  • time-monotonic->time-tai
  • time-monotonic->time-tai!
  • time-monotonic->time-utc
  • time-monotonic->time-utc!
  • time-nanosecond
  • time-resolution
  • time-second
  • time-tai->date
  • time-tai->julian-day
  • time-tai->modified-julian-day
  • time-tai->time-monotonic
  • time-tai->time-monotonic!
  • time-tai->time-utc
  • time-tai->time-utc!
  • time-type
  • time-utc->date
  • time-utc->julian-day
  • time-utc->modified-julian-day
  • time-utc->time-monotonic
  • time-utc->time-monotonic!
  • time-utc->time-tai
  • time-utc->time-tai!
  • time<=?
  • time<?
  • time=?
  • time>=?
  • time>?
  • time?
  • topological-sort
  • touch-file
  • tr
  • tree->string
  • truncate
  • u

  • u16vector
  • u16vector->list
  • u16vector->vector
  • u16vector-add
  • u16vector-add!
  • u16vector-and
  • u16vector-and!
  • u16vector-clamp
  • u16vector-clamp!
  • u16vector-copy
  • u16vector-copy!
  • u16vector-dot
  • u16vector-ior
  • u16vector-ior!
  • u16vector-length
  • u16vector-mul
  • u16vector-mul!
  • u16vector-range-check
  • u16vector-ref
  • u16vector-set!
  • u16vector-sub
  • u16vector-sub!
  • u16vector-xor
  • u16vector-xor!
  • u16vector?
  • u32vector
  • u32vector->list
  • u32vector->string
  • u32vector->vector
  • u32vector-add
  • u32vector-add!
  • u32vector-and
  • u32vector-and!
  • u32vector-clamp
  • u32vector-clamp!
  • u32vector-copy
  • u32vector-copy!
  • u32vector-dot
  • u32vector-ior
  • u32vector-ior!
  • u32vector-length
  • u32vector-mul
  • u32vector-mul!
  • u32vector-range-check
  • u32vector-ref
  • u32vector-set!
  • u32vector-sub
  • u32vector-sub!
  • u32vector-xor
  • u32vector-xor!
  • u32vector?
  • u64vector
  • u64vector->list
  • u64vector->vector
  • u64vector-add
  • u64vector-add!
  • u64vector-and
  • u64vector-and!
  • u64vector-clamp
  • u64vector-clamp!
  • u64vector-copy
  • u64vector-copy!
  • u64vector-dot
  • u64vector-ior
  • u64vector-ior!
  • u64vector-length
  • u64vector-mul
  • u64vector-mul!
  • u64vector-range-check
  • u64vector-ref
  • u64vector-set!
  • u64vector-sub
  • u64vector-sub!
  • u64vector-xor
  • u64vector-xor!
  • u64vector?
  • u8vector
  • u8vector->list
  • u8vector->string
  • u8vector->vector
  • u8vector-add
  • u8vector-add!
  • u8vector-and
  • u8vector-and!
  • u8vector-clamp
  • u8vector-clamp!
  • u8vector-copy
  • u8vector-copy!
  • u8vector-dot
  • u8vector-ior
  • u8vector-ior!
  • u8vector-length
  • u8vector-mul
  • u8vector-mul!
  • u8vector-range-check
  • u8vector-ref
  • u8vector-set!
  • u8vector-sub
  • u8vector-sub!
  • u8vector-xor
  • u8vector-xor!
  • u8vector?
  • ucs->char
  • ucs-range->char-set
  • ucs-range->char-set!
  • uncaught-exception-reason
  • uncaught-exception?
  • unfold
  • unfold-right
  • unless
  • unwrap-syntax
  • unzip1
  • unzip2
  • unzip3
  • unzip4
  • unzip5
  • update!
  • uri-compose
  • uri-decode
  • uri-decode-string
  • uri-decompose-authority
  • uri-decompose-hierarchical
  • uri-encode
  • uri-encode-string
  • uri-scheme&specific
  • use
  • uvector-alias
  • v

  • values
  • vector
  • vector->f32vector
  • vector->f64vector
  • vector->list
  • vector->s16vector
  • vector->s32vector
  • vector->s64vector
  • vector->s8vector
  • vector->u16vector
  • vector->u32vector
  • vector->u64vector
  • vector->u8vector
  • vector-copy
  • vector-fill!
  • vector-length
  • vector-ref
  • vector-set!
  • vector?
  • version-compare
  • version<=?
  • version<?
  • version=?
  • version>=?
  • version>?
  • w

  • weak-vector-length
  • weak-vector-ref
  • weak-vector-set!
  • when
  • with-builder
  • with-error-handler
  • with-error-to-port
  • with-exception-handler
  • with-input-from-file, with-input-from-file
  • with-input-from-port
  • with-input-from-process
  • with-input-from-string
  • with-iterator
  • with-module
  • with-output-to-file, with-output-to-file
  • with-output-to-port
  • with-output-to-process
  • with-output-to-string
  • with-signal-handlers
  • with-string-io
  • with-time-counter
  • write
  • write*
  • write-block
  • write-byte
  • write-char
  • write-object
  • write-to-string
  • write-tree, write-tree, write-tree
  • x

  • x->integer
  • x->number
  • x->string
  • xcons
  • xsubstring
  • z

  • zero?
  • zip
  • C.2 Module Index

    Jump to: d - f - g - m - n - r - s - t - u - w

    d

  • dbm
  • dbm.gdbm
  • dbm.ndbm
  • dbm.odbm
  • f

  • file.filter
  • file.util
  • g

  • gauche
  • gauche.array
  • gauche.charconv
  • gauche.collection
  • gauche.config
  • gauche.fcntl
  • gauche.interactive
  • gauche.listener
  • gauche.logger
  • gauche.mop.singleton
  • gauche.mop.validator
  • gauche.net
  • gauche.parameter
  • gauche.parseopt
  • gauche.process
  • gauche.regexp
  • gauche.reload
  • gauche.selector
  • gauche.sequence
  • gauche.syslog
  • gauche.termios
  • gauche.test
  • gauche.threads
  • gauche.time
  • gauche.uvector
  • gauche.version
  • m

  • math.const
  • math.mt-random
  • n

  • null
  • r

  • rfc.822
  • rfc.base64
  • rfc.cookie
  • rfc.http
  • rfc.quoted-printable
  • rfc.uri
  • s

  • scheme
  • slib
  • srfi-0
  • srfi-1
  • srfi-11
  • srfi-13
  • srfi-14
  • srfi-2
  • srfi-27
  • srfi-4
  • srfi-9
  • t

  • text.csv
  • text.html-lite
  • text.parse
  • text.tr
  • text.tree
  • u

  • user
  • util.isomorph
  • util.queue
  • util.toposort
  • w

  • www.cgi
  • C.3 Class Index

    For readability, the surrounding < and > are stripped off.

    Jump to: a - b - c - d - e - f - g - h - i - j - k - l - m - n - o - p - r - s - t - u - v - w

    a

  • abandoned-mutex-exception
  • array
  • b

  • boolean
  • c

  • char
  • char-set
  • class
  • complex
  • condition-variable
  • d

  • date
  • dbm
  • dbm-meta
  • e

  • exception
  • f

  • f32vector
  • f64vector
  • g

  • gdbm
  • generic
  • h

  • hash-table
  • i

  • identifier
  • integer
  • j

  • join-timeout-exception
  • k

  • keyword
  • l

  • list
  • log-drain
  • m

  • mersenne-twister
  • method
  • module
  • mutex
  • n

  • ndbm
  • null
  • number
  • o

  • object
  • odbm
  • p

  • pair
  • port
  • procedure
  • process
  • process-time-counter
  • r

  • real
  • real-time-counter
  • regexp
  • regmatch
  • s

  • s16vector
  • s32vector
  • s64vector
  • s8vector
  • selector
  • singleton-meta
  • singleton-mixin
  • slot-accessor
  • sockaddr
  • sockaddr-in
  • sockaddr-un
  • socket
  • string
  • string-pointer
  • symbol
  • sys-fdset
  • sys-flock
  • sys-group
  • sys-hostent
  • sys-passwd
  • sys-protoent
  • sys-servent
  • sys-sigset
  • sys-stat
  • sys-termios
  • sys-tm
  • system-time-counter
  • t

  • terminated-thread-exception
  • thread
  • thread-exception
  • time
  • time-counter
  • top
  • u

  • u16vector
  • u32vector
  • u64vector
  • u8vector
  • uncaught-exception
  • user-time-counter
  • v

  • validator-meta
  • vector
  • w

  • weak-vector
  • C.4 Variable Index

    Jump to: * - 1 - a - b - c - d - e - f - g - h - i - k - l - m - n - o - p - r - s - t - u - v - w - x - y

    *

  • *argv*
  • *load-path*
  • *program-name*
  • 1

  • 1/pi
  • 180/pi
  • a

  • addresses
  • AF_INET
  • AF_UNIX
  • aliases, aliases, aliases
  • atime
  • b

  • bsize
  • c

  • cflag
  • char-set:ascii
  • char-set:blank
  • char-set:digit
  • char-set:empty
  • char-set:full
  • char-set:graphic
  • char-set:hex-digit
  • char-set:iso-control
  • char-set:letter
  • char-set:lower-case
  • char-set:printing
  • char-set:punctuation
  • char-set:symbol
  • char-set:title-case
  • char-set:upper-case
  • char-set:whitespace
  • class
  • ctime
  • d

  • default-random-source
  • dev
  • dir
  • e

  • e
  • environment
  • error-handler
  • error-port
  • evaluator
  • f

  • F_DUPFD
  • F_GETFD
  • F_GETFL
  • F_GETLK
  • F_OK
  • F_RDLCK
  • F_SETFD
  • F_SETFL
  • F_SETLK
  • F_SETLKW
  • F_UNLCK
  • F_WRLCK
  • FD_CLOEXEC
  • file-mode
  • finalizer
  • g

  • GDBM_CACHESIZE
  • GDBM_CENTFREE
  • GDBM_COALESCEBLKS
  • GDBM_FAST
  • GDBM_FASTMODE
  • GDBM_INSERT
  • GDBM_NEWDB
  • GDBM_NOLOCK
  • GDBM_READER
  • GDBM_REPLACE
  • GDBM_SYNC
  • GDBM_SYNCMODE
  • GDBM_WRCREAT
  • GDBM_WRITER
  • gecos
  • gid, gid, gid
  • h

  • hour
  • i

  • iflag
  • ino
  • input-port
  • isdst
  • k

  • key-convert
  • l

  • LC_ALL
  • LC_COLLATE
  • LC_CTYPE
  • LC_MONETARY
  • LC_NUMERIC
  • LC_TIME
  • len
  • lflag
  • m

  • mday
  • mem
  • message
  • min
  • mode
  • mon
  • mtime
  • mutex
  • n

  • name, name, name, name, name, name, name, name
  • nanosecond
  • nlink
  • nolock
  • o

  • O_ACCMODE
  • O_APPEND
  • O_CREAT
  • O_EXCL
  • O_NOCTTY
  • O_NONBLOCK
  • O_RDONLY
  • O_RDWR
  • O_TRUNC
  • O_WRONLY
  • oflag
  • output-port
  • p

  • passwd, passwd
  • path, path
  • perm
  • PF_INET
  • PF_UNIX
  • pi
  • pi/180
  • pi/2
  • pi/4
  • pid
  • port
  • prefix
  • printer
  • program-name
  • prompter
  • proto, proto
  • r

  • R_OK
  • RAND_MAX
  • rdev
  • reader
  • reason
  • rw-mode
  • s

  • sec
  • second
  • shell
  • SIGABRT
  • SIGALRM
  • SIGBUS
  • SIGCHLD
  • SIGCONT
  • SIGFPE
  • SIGHUP
  • SIGILL
  • SIGINT
  • SIGIO
  • SIGIOT
  • SIGKILL
  • SIGPIPE
  • SIGPOLL
  • SIGPROF
  • SIGPWR
  • SIGQUIT
  • SIGSEGV
  • SIGSTKFLT
  • SIGSTOP
  • SIGTERM
  • SIGTRAP
  • SIGTSTP
  • SIGTTIN
  • SIGTTOU
  • SIGURG
  • SIGUSR1
  • SIGUSR2
  • SIGVTALRM
  • SIGWINCH
  • SIGXCPU
  • SIGXFSZ
  • size
  • SO_BROADCAST
  • SO_ERROR
  • SO_KEEPALIVE
  • SO_OOBINLINE
  • SO_PRIORITY
  • SO_REUSEADDR
  • SO_TYPE
  • SOCK_DGRAM
  • SOCK_RAW
  • SOCK_STREAM
  • SOL_IP
  • SOL_SOCKET
  • SOL_TCP
  • specific, specific, specific
  • start
  • state
  • sync
  • syslog-facility
  • syslog-option
  • syslog-priority
  • t

  • TCIFLUSH
  • TCIOFF
  • TCIOFLUSH
  • TCION
  • TCOFLUSH
  • TCOOFF
  • TCOON
  • TCSADRAIN
  • TCSAFLUSH
  • TCSANOW
  • terminator
  • thread
  • time-duration
  • time-monotonic
  • time-process
  • time-tai
  • time-thread
  • time-utc
  • type, type, type
  • u

  • uid, uid
  • v

  • value-convert
  • w

  • W_OK
  • wday
  • whence
  • x

  • X_OK
  • y

  • yday
  • year

  • This document was generated on 29 November 2002 using texi2html 1.56k.