Each module is named more or less after what it implements rather than what it is implemented for. If the module solves one problem, both are the same. However, sometimes there are multiple ways to solve a problem, or one implementation of an algorithm can solve multiple different problems; thus it is difficult to name the modules in problem-oriented (or purpose-oriented) way.
Because of this, it may not be straightforward for a newcomer to Gauche to find an appropriate Gauche module to solve her problem, since there may be multiple algorithms to do the job, and each algorithm can be implemented in different modules.
The modules are also designed in layers; some low-level modules provide direct interface to the system calls, while some higher-level ones provide more abstract, easy-to-use interface, possibly built on top of more than one low-level modules. Which one should you use? Generally you want to use the highest level, for the very purpose of libraries are to provide easy, abstract interface. However there are times that you have to break the abstraction and to go down to tweak the machinery in the basement; then you need to use low-level modules directly.
The purpose of this section is to group the libraries by their purposes. Each category lists relevant modules with brief descriptions.
|• Library directory - data containers:|
|• Library directory - strings and characters:|
|• Library directory - data exchange:|
|• Library directory - files:|
|• Library directory - processes and threads:|
|• Library directory - networking:|
|• Library directory - input and output:|
|• Library directory - time:|
|• Library directory - bits and bytes:|
Some data containers have similar properties; for example, lists, vectors and hash tables can be seen as a collection of data. So it is handy to have generic operators, such as applying a procedure to all the elements.
Gauche provides such mechanism to a certain degree, mainly using its object system.
Basic string operations are covered in Strings and String library. A string is also a sequence of characters, so you can apply methods in Collection framework and Sequence framework.
Character and character set operations are covered in Characters, Character set, and Character-set library.
If you scan or build strings sequentially, do not use index access. String ports (see String ports) provides more efficient, and elegant way.
You can use regular expressions to search and extract character sequences from strings; see Regular expressions.
If you need to deal with low-level (i.e. byte-level) representation of strings, Uniform vectors has some tools to convert strings and byte vectors back and forth.
Are you dealing with a structure higher than a mere sequence
of characters? Then take a look at
Parsing input stream has some basic
scanners. Transliterate characters implements a
feature similar to Unix’s
You can take
diff of two texts; see
Calculate difference of text streams.
And if you want to construct large text from string fragments,
do not use
string-append—see Lazy text construction.
Last but not least, Gauche has support of various character
encoding schemes. See Character code conversion for
the basic utilities. Most higher-level functions such as
open-input-file can take
:encoding keyword argument
to perform character conversion implicitly. Also see
Multibyte scripts if you write Scheme program in
non-ASCII characters. If you want to process Gauche source code
which may contain "encoding" magic comment, see Coding-aware ports.
Gauche also has GNU gettext compatible module (Localized messages)
if you need localization.
Most useful programs need to communicate with outside world (other programs or humans). That involves reading the external data into your program understanding whatever format the data is in, and also writing the data in the format the others can understand.
Lots of network-related external formats are defined in RFC,
and there are corresponding
rfc.* module that handle
some of them. See RFC822 message parsing, for example,
to handle the pervasive RFC2822 message format.
Or, JSON can be handled by JSON parsing and construction.
When you exchange table-formatted data, one of the easiest way may be the plain text, one row per line, and columns are separated by some specific characters (e.g. comma). See CSV tables for basic parser/writer for them.
Oh, and nowadays every business user wants XML, right? You know
they are just S-expressions with extra redundancy and pointy
parentheses. So why don’t you read XML as if they’re S-exprs,
process them with familiar cars and cdrs and maps, then write them
out with extra redundancy and pointy parens?
sxml.ssax (Functional XML parser)
implements SAX XML parser, with which you
can parse XML and process them on the fly, or convert it to
SXML, S-expression XML. You can query SXML using
SXPath, an XPath counterparts of S-expression (SXML Query Language).
You can output all kinds of XML and HTML using the SXML serializer
(Serializing XML and HTML from SXML).
(But you know most web services nowadays also talks JSON, and that’s much lighter and handier than XML. See JSON parsing and construction).
It is planned that various file format handling routines would
be available as
file.* modules, though we have none ready
yet. If you plan to write one, please go ahead and let us know!
Files and directories. Roughly speaking, there are two places you want to look at.
Filesystems, in the core, has
routines close to the underlying OS provides. If you have
experience with Unix system programming you’ll find familiar
function names there. The
fcntl functionality is
gauche.fcntl (Low-level file operations), FYI.
Also you definitely want to look at
(Filesystem utilities), which implements higher-level
routines on top of system-level ones.
Process-related routines also come in two levels.
gauche.process module provides
high-level routines (High Level Process Interface);
you can pipe the data into and out of child processes easily, for example.
Gauche core provides the primitive
as well as the convenient
(see Process management). Use them when you want a precise
control over what you’re doing.
Gauche has preemptive threads on most Unix platforms including OSX.
Check out Threads for the basic thread support, including
primitive mutexes. The
data.queue module (see Queue)
provides thread-safe queue that can also be handy for synchronization.
Thread pool is available in
control.thread-pool (see Thread pools).
We have multi-layer abstraction here. At the bottom, we have APIs corresponding to socket-level system calls. In the middle, a convenience library that automates host name lookups, connection and shutdown, etc. On top of them we have several modules that handles specific protocols (e.g. http).
gauche.net module (Networking) provides the bottom
and middle layer. For the top layer, look for
More protocol support is coming (there are
rfc.imap4 written by users, which are waiting for being
integrated into Gauche—maybe in next release).
There’s a plan of even higher level of libraries, under the name
net.*, which will abstract more than one network protocols.
The planned ones include sending emails, or
universal resource access by uri. Code contributions are welcome.
As the bottom level,
Gauche includes primitive byte I/O (
as well as block I/O (
write-uvector) in its core.
(See Reading data, Output, and Uvector block I/O).
As the middle level, the module
(Binary I/O) has routines to retrieve specific datatype
with optional endian specification.
And as the top level, the module
(Packing Binary Data) allows packing and unpacking structured
binary data, a la Perl’s
Gauche core provides bitshift and mask operations. See Bitwise operations.