Guile Reference Manual

$Id: guile-ref.texi,v 1.22 1998/04/29 21:29:03 rosalia Exp $ For use with Guile 1.2a

Mark Galassi Cygnus Solution and Los Alamos National Laboratory

rosalia@cygnus.com

Jim Blandy Free Software Foundation and MIT AI Lab

jimb@red-bean.com

Gary Houston

ghouston@actrix.gen.nz

Tim Pierce

twp@skepsis.com

Copyright \begin{matrix}c \\ ◯ \end{matrix} 1996 Free Software Foundation Copyright \begin{matrix}c \\ ◯ \end{matrix} 1997 Free Software Foundation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by Free Software Foundation.

OK, enough is enough. I can see that I’m not going to be able to fool you guys. I confess everything. You’re right. It all was an evil conspiracy. There really isn’t a shred of merit in Tcl, or C++, or Perl, or C; there is not a single reason on earth why anyone should use any of these languages for any programming task. Scheme truly is the perfect language that solves every problem and combines the virtues of every other language. For years we’ve been plotting to trick programmers into using bad languages. Yes, I mean “we”. Many many people have participated in this sinister plot, including Larry Wall, Dennis Ritchie, Bill Gates, the Bureau of ATF, most of the LAPD, and Mark Fuhrman (sorry you guys, but the truth has overwhelmed me so I’ve been forced to expose you). I feel just terrible at how I have set the programming world back, and I promise to be a good boy from now on.

— John Ousterhout

Part I: Preliminaries

1 Introduction

Guile is an interpreter for the Scheme programming language, packaged for use in a wide variety of environments. Guile implements Scheme as described in the Revised^{4} Report on the Algorithmic Language Scheme (usually known as R4RS), providing clean and general data and control structures. Guile goes beyond the rather austere language presented in R4RS, extending it with a module system, full access to POSIX system calls, networking support, multiple threads, dynamic linking, a foreign function call interface, powerful string processing, and many other features needed for programming in the real world.

Like a shell, Guile can run interactively, reading expressions from the user, evaluating them, and displaying the results, or as a script interpreter, reading and executing Scheme code from a file. However, Guile is also packaged as an object library, allowing other applications to easily incorporate a complete Scheme interpreter. An application can use Guile as an extension language, a clean and powerful configuration language, or as multipurpose “glue”, connecting primitives provided by the application. It is easy to call Scheme code from C code and vice versa, giving the application designer full control of how and when to invoke the interpreter. Applications can add new functions, data types, control structures, and even syntax to Guile, creating a domain-specific language tailored to the task at hand, but based on a robust language design.

Guile’s module system allows one to break up a large program into manageable sections with well-defined interfaces between them. Modules may contain a mixture of interpreted and compiled code; Guile can use either static or dynamic linking to incorporate compiled code. Modules also encourage developers to package up useful collections of routines for general distribution; as of this writing, one can find Emacs interfaces, database access routines, compilers, GUI toolkit interfaces, and HTTP client functions, among others.

In the future, we hope to expand Guile to support other languages like Tcl and Perl by compiling them to Scheme code. This means that users can program applications which use Guile in the language of their choice, rather than having the tastes of the application’s author imposed on them.

This manual assumes you know Scheme, as described in R4RS. From there, it describes:

Part I how to use Guile interactively and as an interpreter, how to link Guile into your own applications, and how to write modules of interpreted and compiled code for use with Guile,

Part II Guile’s extensions to the language described in R4RS,

Part III how to call Guile from C code, and how to add new functions written in C to Guile, using C functions which (we hope) will also someday work with other Scheme interpreters, allowing you to write C code which will work with any of several Scheme systems, and

Part IV further functions available to the C level which are specific to Guile, but provide more thorough access to Guile’s internals.

Finally, the appendices explain how to obtain the latest version of Guile, how to install it, where to find modules to work with Guile, and how to use the Guile debugger.

2 Running Guile Interactively

In its simplest form, Guile acts as an interactive interpreter for the Scheme programming language, reading and evaluating Scheme expressions the user enters from the terminal. Here is a sample interaction between Guile and a user; the user’s input appears after the $ and guile> prompts:

$ guile
guile> (+ 1 2 3)                ; add some numbers
6
guile> (define (factorial n)    ; define a function
         (if (zero? n) 1 (* n (factorial (- n 1)))))
guile> (factorial 20)
2432902008176640000
guile> (getpwnam "jimb")        ; find my entry in /etc/passwd
#("jimb" ".0krIpK2VqNbU" 4008 10 "Jim Blandy" "/u/jimb"
  "/usr/local/bin/bash")
guile> C-d
$

3 Guile Scripts

Like AWK, Perl, or any shell, Guile can interpret script files. A Guile script is simply a file of Scheme code with some extra information at the beginning which tells the operating system how to invoke Guile, and then tells Guile how to handle the Scheme code.

Before we present the details, here is a trivial Guile script:

#!/usr/local/bin/guile -s
!#
(display "Hello, world!")
(newline)

3.1 The Top of a script file

The first line of a Guile script must tell the operating system to use Guile to evaluate the script, and then tell Guile how to go about doing that. Here is the simplest case:

• The first two characters of the file must be ‘#!’.

The operating system interprets this to mean that the rest of the line is the name of an executable that can interpret the script. Guile, however, interprets these characters as the beginning of a multi-line comment, terminated by the characters ‘!#’ on a line by themselves. (This is an extension to the syntax described in R4RS, added to support shell scripts.)

• Immediately after those two characters must come the full pathname to the Guile interpreter. On most systems, this would be ‘/usr/local/bin/guile’.

• Then must come a space, followed by a command-line argument to pass to Guile; this should be ‘-s’. This switch tells Guile to run a script, instead of soliciting the user for input from the terminal. There are more elaborate things one can do here; see ⟨undefined⟩ [The Meta Switch], page ⟨undefined⟩.

• Follow this with a newline.

• The second line of the script should contain only the characters ‘!#’ — just like the top of the file, but reversed. The operating system never reads this far, but Guile treats this as the end of the comment begun on the first line by the ‘#!’ characters.

• The rest of the file should be a Scheme program.

Guile reads the program, evaluating expressions in the order that they appear. Upon reaching the end of the file, Guile exits.

The function command-line returns the name of the script file and any command-line arguments passed by the user, as a list of strings.

For example, consider the following script file:

#!/usr/local/bin/guile -s
!#
(write (command-line))
(newline)

If you put that text in a file called ‘foo’ in the current directory, then you could make it executable and try it out like this:

$ chmod a+x foo
$ ./foo
("./foo")
$ ./foo bar baz
("./foo" "bar" "baz")
$

As another example, here is a simple replacement for the POSIX echo command:

#!/usr/local/bin/guile -s
!#
(for-each (lambda (s) (display s) (display " "))
  (cdr (command-line)))
(newline)

procedure command-line primitive program-arguments

Return a list of the command-line arguments passed to the currently running program. If the program invoked Guile with the ‘-s’, ‘-c’ or ‘--’ switches, these procedures ignore everything up to and including those switches.

3.2 Invoking Guile

Here we describe Guile’s command-line processing in detail. Guile processes its arguments from left to right, recognizing the switches described below. For examples, see ⟨undefined⟩ [Scripting Examples], page ⟨undefined⟩.

-s script arg...

Read and evaluate Scheme source code from the file script, as the load function would. After loading script, exit. Any command-line arguments arg... following script become the script’s arguments; the command-line function returns a list of strings of the form (script arg...).

-c expr arg...

Evaluate expr as Scheme code, and then exit. Any command-line arguments arg... following expr become command-line arguments; the command-line function returns a list of strings of the form (guile arg...), where guile is the path of the Guile executable.

-- arg... Run interactively, prompting the user for expressions and evaluating them. Any command-line arguments arg... following the -- become command-line arguments for the interactive session; the command-line function returns a list of strings of the form (guile arg...), where guile is the path of the Guile executable.

-l file Load Scheme source code from file, and continue processing the command line.

-e function Make function the entry point of the script. After loading the script file (with -s) or evaluating the expression (with -c), apply function to a list containing the program name and the command-line arguments — the list provided by the

command-line function.

A -e switch can appear anywhere in the argument list, but Guile always invokes the function as the last action it performs. This is weird, but because of the way script invocation works under POSIX, the -s option must always come last in the list. See ⟨undefined⟩ [Scripting Examples], page ⟨undefined⟩.

-ds Treat a final -s option as if it occurred at this point in the command line; load the script here. This switch is necessary because, although the POSIX script invocation mechanism effectively requires the -s option to appear last, the programmer may well want to run the script before other actions requested on the command line. For examples, see ⟨undefined⟩ [Scripting Examples], page ⟨undefined⟩.

\ Read more command-line arguments, starting from the second line of the script file. See ⟨undefined⟩ [The Meta Switch], page ⟨undefined⟩.

--emacs Assume Guile is running as an inferior process of Emacs, and use a special protocol to communicate with Emacs’s Guile interaction mode. This switch sets the global variable use-emacs-interface to #t. This switch is still experimental.

-h, --help

Display help on invoking Guile, and then exit.

-v, --version

Display the current version of Guile, and then exit.

3.3 The Meta Switch

Guile’s command-line switches allow the programmer to describe reasonably complicated actions in scripts. Unfortunately, the POSIX script invocation mechanism only allows one argument to appear on the ‘#!’ line after the path to the Guile executable, and imposes arbitrary limits on that argument’s length. Suppose you wrote a script starting like this:

     #!/usr/local/bin/guile -e main -s
     !#
     (define (main args)
       (map (lambda (arg) (display arg) (display " "))
            (cdr args))
       (newline))

The intended meaning is clear: load the file, and then call main on the command-line arguments. However, the system will treat everything after the Guile path as a single argument — the string "-e main -s" — which is not what we want.

As a workaround, the meta switch \ allows the Guile programmer to specify an arbitrary number of options without patching the kernel. If the first argument to Guile is \, Guile will open the script file whose name follows the \, parse arguments starting from the file’s second line (according to rules described below), and substitute them for the \ switch.

Working in concert with the meta switch, Guile treats the characters ‘#!’ as the beginning of a comment which extends through the next line containing only the characters ‘!#’. This sort of comment may appear anywhere in a Guile program, but it is most useful at the top of a file, meshing magically with the POSIX script invocation mechanism.

Thus, consider a script named ‘/u/jimb/ekko’ which starts like this:

     #!/usr/local/bin/guile \
     -e main -s
     !#
     (define (main args)
             (map (lambda (arg) (display arg) (display " "))
                  (cdr args))
             (newline))

Suppose a user invokes this script as follows:

     $ /u/jimb/ekko a b c

Here’s what happens:

• the operating system recognizes the ‘#!’ token at the top of the file, and rewrites the

command line to:

         /usr/local/bin/guile \ /u/jimb/ekko a b c

This is the usual behavior, prescribed by POSIX.

• When Guile sees the first two arguments, \ /u/jimb/ekko, it opens ‘/u/jimb/ekko’, parses the three arguments -e, main, and -s from it, and substitutes them for the \ switch. Thus, Guile’s command line now reads:

         /usr/local/bin/guile -e main -s /u/jimb/ekko a b c

• Guile then processes these switches: it loads ‘/u/jimb/ekko’ as a file of Scheme code (treating the first three lines as a comment), and then performs the application (main

    "/u/jimb/ekko" "a" "b" "c").

When Guile sees the meta switch \, it parses command-line argument from the script file according to the following rules:

• Each space character terminates an argument. This means that two spaces in a row introduce an argument "".

• The tab character is not permitted (unless you quote it with the backslash character, as described below), to avoid confusion.

• The newline character terminates the sequence of arguments, and will also terminate a final non-empty argument. (However, a newline following a space will not introduce a final empty-string argument; it only terminates the argument list.)

• The backslash character is the escape character. It escapes backslash, space, tab, and newline. The ANSI C escape sequences like \n and \t are also supported. These produce argument constituents; the two-character combination \n doesn’t act like a terminating newline. The escape sequence \NNN for exactly three octal digits reads as the character whose ASCII code is NNN. As above, characters produced this way are argument constituents. Backslash followed by other characters is not allowed.

3.4 Scripting Examples

To start with, here are some examples of invoking Guile directly:

guile -- a b c
          Run Guile interactively; (command-line) will return ("/usr/local/bin/guile"
          "a" "b" "c").
guile -s /u/jimb/ex2 a b c
          Load the file ‘/u/jimb/ex2’; (command-line) will return ("/u/jimb/ex2" "a"
          "b" "c").
guile -c '(write %load-path) (newline)'

Write the value of the variable %load-path, print a newline, and exit.

guile -e main -s /u/jimb/ex4 foo

Load the file ‘/u/jimb/ex4’, and then call the function main, passing it the list

          ("/u/jimb/ex4" "foo").
guile -l first -ds -l last -s script

Load the files ‘first’, ‘script’, and ‘last’, in that order. The -ds switch says when to process the -s switch. For a more motivated example, see the scripts below.

Here is a very simple Guile script:

     #!/usr/local/bin/guile -s
     !#
     (display "Hello, world!")
     (newline)

The first line marks the file as a Guile script. When the user invokes it, the system runs ‘/usr/local/bin/guile’ to interpret the script, passing -s, the script’s filename, and any arguments given to the script as command-line arguments. When Guile sees -s script, it loads script. Thus, running this program produces the output:

Hello, world!

Here is a script which prints the factorial of its argument:

#!/usr/local/bin/guile -s
!#
(define (fact n)
  (if (zero? n) 1
    (* n (fact (- n 1)))))
(display (fact (string->number (cadr (command-line)))))
(newline)

In action:

$ fact 5
120
$

However, suppose we want to use the definition of fact in this file from another script. We can’t simply load the script file, and then use fact’s definition, because the script will try to compute and display a factorial when we load it. To avoid this problem, we might write the script this way:

#!/usr/local/bin/guile \
-e main -s
!#
(define (fact n)
  (if (zero? n) 1
    (* n (fact (- n 1)))))
(define (main args)
  (display (fact (string->number (cadr args))))
  (newline))

This version packages the actions the script should perform in a function, main. This allows us to load the file purely for its definitions, without any extraneous computation taking place. Then we used the meta switch \ and the entry point switch -e to tell Guile to call main after loading the script.

$ fact 50
30414093201713378043612608166064768844377641568960512000000000000

Suppose that we now want to write a script which computes the choose function: given a set of m distinct objects, (choose n m) is the number of distinct subsets containing n objects each. It’s easy to write choose given fact, so we might write the script this way:

#!/usr/local/bin/guile \
-l fact -e main -s
!#
(define (choose n m)
  (/ (fact m) (* (fact (- m n)) (fact n))))
(define (main args)
  (let ((n (string->number (cadr args)))
        (m (string->number (caddr args))))

    (display (choose n m))
    (newline)))

The command-line arguments here tell Guile to first load the file ‘fact’, and then run the script, with main as the entry point. In other words, the choose script can use definitions made in the fact script. Here are some sample runs:

$ choose 0 4
1
$ choose 1 4
4
$ choose 2 4
6
$ choose 3 4
4
$ choose 4 4
1
$ choose 50 100
100891344545564193334812497256

4 Linking Programs With Guile

The Guile interpreter is available as an object library, to be linked into applications using Scheme as a configuration or extension language. This chapter covers the mechanics of linking your program with Guile on a typical POSIX system.

Parts III and IV of this manual describe the C functions Guile provides. Furthermore, any Scheme function described in this manual as a “Primitive” is also callable from C; see ⟨undefined⟩ [Relationship between Scheme and C functions], page ⟨undefined⟩.

The header file <libguile.h> provides declarations for all of Guile’s functions and constants. You should #include it at the head of any C source file that uses identifiers described in this manual.

Once you’ve compiled your source files, you can link them against Guile by passing the flag -lguile to your linker. If you installed Guile with multi-thread support (by passing --enable-threads to the configure script), you may also need to link against the QuickThreads library, -lqt. Guile refers to various mathematical functions, so you will probably need to link against the mathematical library, -lm, as well.

4.1 Guile Initialization Functions

To initialize Guile, use this function:

Function void scm boot guile (int argc, char **argv, void

(*main func) (), void *closure) Initialize the Guile Scheme interpreter. Then call main func, passing it closure, argc, and argv. main func should do all the work of the program (initializing other packages, defining application-specific functions, reading user input, and so on) before returning. When main func returns, call exit (0); scm_boot_ guile never returns. If you want some other exit value, have main func call exit itself. scm_boot_guile arranges for the Scheme command-line function to return the strings given by argc and argv. If main func modifies argc or argv, it should call scm_set_program_arguments with the final list, so Scheme code will know which arguments have been processed. scm_boot_guile establishes a catch-all error handler which prints an error message and exits the process. This means that Guile exits in a coherent way if a system error occurs and the user isn’t prepared to handle it. If the user doesn’t like this behavior, they can establish their own universal catcher in main func to shadow this one. Why must the caller do all the real work from main func? Guile’s garbage collector assumes that all local variables which reference Scheme objects will be above scm_boot_guile’s stack frame on the stack. If you try to manipulate Scheme objects after this function returns, it’s the luck of the draw whether Guile’s storage manager will be able to find the objects you allocate. So, scm_ boot_guile function exits, rather than returning, to discourage you from making that mistake.

One common way to use Guile is to write a set of C functions which perform some useful task, make them callable from Scheme, and then link the program with Guile. This yields a Scheme interpreter just like guile, but augmented with extra functions for some specific application — a special-purpose scripting language.

In this situation, the application should probably process its command-line arguments in the same manner as the stock Guile interpreter. To make that straightforward, Guile provides this function:

Function void scm shell (int argc, char **argv)

Process command-line arguments in the manner of the guile executable. This includes loading the normal Guile initialization files, interacting with the user or running any scripts or expressions specified by -s or -e options, and then exiting. See ⟨undefined⟩ [Invoking Guile], page ⟨undefined⟩, for more details. Since this function does not return, you must do all application-specific initialization before calling this function. If you do not use this function to start Guile, you are responsible for making sure Guile’s usual initialization files, ‘init.scm’ and ‘ice-9/boot-9.scm’, get loaded. This will change soon.

4.2 A Sample Guile Main Program

Here is ‘simple-guile.c’, source code for a main and an inner_main function that will produce a complete Guile interpreter.

/* simple-guile.c --- how to start up the Guile
   interpreter from C code.  */

/* Get declarations for all the scm_functions.  */
#include <libguile.h>
static void
inner_main (void *closure, int argc, char **argv)
{
  /* module initializations would go here */
  scm_shell (argc, argv);
}
int
main (int argc, char **argv)
{
  scm_boot_guile (argc, argv, inner_main, 0);
  return 0; /* never reached */
}

The main function calls scm_boot_guile to initialize Guile, passing it inner_main. Once scm_boot_guile is ready, it invokes inner_main, which calls scm_shell to process the command-line arguments in the usual way.

Here is a Makefile which you can use to compile the above program.

# Use GCC, if you have it installed.
CC=gcc
# Tell the C compiler where to find <libguile.h> and -lguile.
CFLAGS=-I/usr/local/include -L/usr/local/lib
# Include -lqt and -lrx if they are present on your system.
LIBS=-lguile -lqt -lrx -lm
simple-guile: simple-guile.o
        ${CC} ${CFLAGS} simple-guile.o ${LIBS} -o simple-guile
simple-guile.o: simple-guile.c
        ${CC} -c ${CFLAGS} simple-guile.c

If you are using the GNU Autoconf package to make your application more portable, Autoconf will settle many of the details in the Makefile above automatically, making it much simpler and more portable; we recommend using Autoconf with Guile. Here is a ‘configure.in’ file for simple-guile, which Autoconf can use as a template to generate

a configure script:
AC_INIT(simple-guile.c)
# Find a C compiler.
AC_PROG_CC
# Check for libraries.
AC_CHECK_LIB(m, sin)
AC_CHECK_LIB(rx, regcomp)

AC_CHECK_LIB(qt, main)
AC_CHECK_LIB(guile, scm_boot_guile)
# Generate a Makefile, based on the results.
AC_OUTPUT(Makefile)

Here is a Makefile.in template, from which the configure script produces a Makefile customized for the host system:

# The configure script fills in these values.
CC=@CC@
CFLAGS=@CFLAGS@
LIBS=@LIBS@
simple-guile: simple-guile.o
        ${CC} ${CFLAGS} simple-guile.o ${LIBS} -o simple-guile
simple-guile.o: simple-guile.c
        ${CC} -c ${CFLAGS} simple-guile.c

The developer should use Autoconf to generate the ‘configure’ script from the ‘configure.in’ template, and distribute ‘configure’ with the application. Here’s how a user might go about building the application:

$ ls
Makefile.in     configure*      configure.in    simple-guile.c
$ ./configure
creating cache ./config.cache
checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for sin in -lm... yes
checking for regcomp in -lrx... yes
checking for main in -lqt... yes
checking for scm_boot_guile in -lguile... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
$ make
gcc -c -g -O2 simple-guile.c
gcc -g -O2 simple-guile.o -lguile -lqt -lrx -lm  -o simple-guile
$ ./simple-guile
guile> (+ 1 2 3)
6
guile> (getpwnam "jimb")
#("jimb" "83Z7d75W2tyJQ" 4008 10 "Jim Blandy" "/u/jimb"
  "/usr/local/bin/bash")
guile> (exit)
$

Chapter 5: Writing Guile Modules 13

5 Writing Guile Modules

14 Guile Reference Manual

Part II: Scheme Extensions 6 Extensions to Scheme

The current “standard” for the Scheme language is the Revised^4 Report on the Algorithmic Language Scheme (r4rs), and it is commonly referred to as R4RS. Most Scheme implementations conform to all the required features in R4RS as well as the optional ones.

But most Scheme implementations go beyond R4RS in some ways, mostly because R4RS does not give specifications (or even recommendations) regarding some issues that are quite important in practical programming.

[FIXME: hmm; what else goes in this chapter? we have chapters for just about everything. I’ll put a reference to R4RS and leave it.]

The Scheme language implemented in Guile is R4RS compliant, so R4RS is a valid document describing the basic Guile language. This part of the Guile Reference Manual describes the extensions to Scheme provided in Guile.

In this chapter we describe some minor configurable differences from R4RS, mostly introduced to make eventual Emacs Lisp translation easier. Later chapters will introduce major extensions to Scheme.

6.1 Guile options interface

Guile’s behaviour can be modified by setting options. For example, is the language that Guile accepts case sensitive, or should the debugger automatically show a backtrace on error?

Guile has two levels of interface for managing options: a low-level control interface, and a user-level interface which allows the enabling or disabling of options.

Moreover, the options are classified in groups according to whether they configure reading, printing, debugging or evaluating.

6.1.1 General option interface

We will use the expression <group> to represent read, print, debug or evaluator.

Low level

primitive <group>-options-interface primitive read-options-interface [SOME-INT] primitive print-options-interface [SOME-INT] primitive evaluator-traps-interface [SOME-INT] primitive read-options-interface [SOME-INT]

[FIXME: I have just taken the comments for C routine scm options that implements all of these. It needs to be presented better.] If scm options is called without arguments, the current option setting is returned. If the argument is an option setting, options are altered and the old setting is returned. If the argument isn’t a list, a list of sublists is returned, where each sublist contains option name, value and documentation string.

User level

procedure <group>-options [arg] procedure read-options [arg] procedure print-options [arg] procedure debug-options [arg] procedure traps [arg]

These functions list the options in their group. The optional argument arg is a symbol which modifies the form in which the options are presented. With no arguments, <group>-options returns the values of the options in that particular group. If arg is 'help, a description of each option is given. If arg is 'full, programmers’ options are also shown. arg can also be a list representing the state of all options. In this case, the list contains single symbols (for enabled boolean options) and symbols followed by values.

[FIXME: I don’t think ’full is ever any different from ’help. What’s up?]

procedure <group>-enable option-symbol

procedure read-enable option-symbol procedure print-enable option-symbol procedure debug-enable option-symbol procedure trap-enable option-symbol

These functions set the specified option-symbol in their options group. They only work if the option is boolean, and throw an error otherwise.

procedure <group>-disable option-symbol

procedure read-disable option-symbol

procedure print-disable option-symbol procedure debug-disable option-symbol

procedure trap-disable option-symbol These functions turn off the specified option-symbol in their options group. They only work if the option is boolean, and throw an error otherwise.

syntax <group>-set! option-symbol value syntax read-set! option-symbol value syntax print-set! option-symbol value syntax debug-set! option-symbol value syntax trap-set! option-symbol value

These functions set a non-boolean option-symbol to the specified value.

6.1.2 Reader options

Here is the list of reader options generated by typing (read-options 'full) in Guile. You can also see the default values.

keywords         #f      Style of keyword recognition: #f or 'prefix
case-insensitive no      Convert symbols to lower case.

positions        yes     Record positions of source code expressions.
copy             no      Copy source code expressions.

Notice that while Standard Scheme is case insensitive, to ease translation of other Lisp dialects, notably Emacs Lisp, into Guile, Guile is case-sensitive by default.

To make Guile case insensitive, you can type

(read-enable 'case-insensitive)

6.1.3 Printing options

Here is the list of print options generated by typing (print-options 'full) in Guile. You can also see the default values.

source          no      Print closures with source.
closure-hook    #f      Hook for printing closures.

6.1.4 Evaluator options

Here is the list of print options generated by typing (traps 'full) in Guile. You can also see the default values.

exit-frame      no      Trap when exiting eval or apply.
apply-frame     no      Trap when entering apply.
enter-frame     no      Trap when eval enters new frame.

6.1.5 Debugger options

Here is the list of print options generated by typing (debug-options 'full) in Guile. You can also see the default values.

stack           20000   Stack size limit (0 = no check).
debug           yes     Use the debugging evaluator.
backtrace       no      Show backtrace on error.
depth           20      Maximal length of printed backtrace.
maxdepth        1000    Maximal number of stored backtrace frames.
frames          3       Maximum number of tail-recursive frames in backtrace.
indent          10      Maximal indentation in backtrace.
backwards       no      Display backtrace in anti-chronological order.
procnames       yes     Record procedure names at definition.
trace           no      *Trace mode.
breakpoints     no      *Check for breakpoints.
cheap           yes     *Flyweight representation of the stack at traps.

6.1.6 Examples of option use

Here is an example of a session in which some read and debug option handling procedures are used. In this example, the user

1. Notices that the symbols abc and aBc are not the same

2. Examines the read-options, and sees that case-insensitive is set to “no”.

3. Enables case-insensitive

4. Verifies that now aBc and abc are the same

5. Disables case-insensitive and enables debugging backtrace

6. Reproduces the error of displaying aBc with backtracing enabled [FIXME: this last example is lame because there is no depth in the backtrace. Need to give a better example, possibly putting debugging option examples in a separate session.]

guile> (define abc "hello")
guile> abc
"hello"
guile> aBc
ERROR: In expression aBc:
ERROR: Unbound variable: aBc
ABORT: (misc-error)
Type "(backtrace)" to get more information.
guile> (read-options 'help)
keywords #f Style of keyword recognition: #f or 'prefix
case-insensitive no Convert symbols to lower case.
positions yes Record positions of source code expressions.
copy no Copy source code expressions.
guile> (debug-options 'help)
stack 20000 Stack size limit (0 = no check).
debug yes Use the debugging evaluator.
backtrace no Show backtrace on error.
depth 20 Maximal length of printed backtrace.
maxdepth 1000 Maximal number of stored backtrace frames.
frames 3 Maximum number of tail-recursive frames in backtrace.
indent 10 Maximal indentation in backtrace.
backwards no Display backtrace in anti-chronological order.
procnames yes Record procedure names at definition.
trace no *Trace mode.
breakpoints no *Check for breakpoints.
cheap yes *Flyweight representation of the stack at traps.
guile> (read-enable 'case-insensitive)
(keywords #f case-insensitive positions)
guile> aBc
"hello"
guile> (read-disable 'case-insensitive)
(keywords #f positions)
guile> (debug-enable 'backtrace)
(stack 20000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 procnames cheap)
guile> aBc
Backtrace:
0* aBc
ERROR: In expression aBc:
ERROR: Unbound variable: aBc
ABORT: (misc-error)

Chapter 6: Extensions to Scheme 19

     guile>

7 SLIB

Before the the SLIB facilities can be used, the following Scheme expression must be executed:

     (use-modules (ice-9 slib))

require can then be used as described in section “SLIB” in The SLIB Manual. For example:

     (require 'format)
     (format "~8,48D" 10)

7.1 JACAL

Jacal is a symbolic math package written in Scheme by Aubrey Jaffer. It is usually installed as an extra package in SLIB (see ⟨undefined⟩ [Packages not shipped with Guile], page ⟨undefined⟩).

You can use Guile’s interface to SLIB to invoke Jacal:

     (use-modules (ice-9 slib))
     (slib:load "math")
     (math)

For complete documentation on Jacal, please read the Jacal manual. If it has been installed on line, you can look at section “Jacal” in The SLIB Manual. Otherwise you can find it on

the web at http://www-swiss.ai.mit.edu/~jaffer/JACAL.html

8 Evaluation

This chapter describes Guile functions that are concerned with loading and evaluating Scheme code at run time. R4RS Scheme, because of strong differences in opinion among implementors, only provides a load function. There are many useful programs that are difficult or impossible to write without more powerful evaluation procedures, so we have provided some.

[FIXME: This needs some more text on the difference between procedures, macros and memoizing macros. Also, any definitions listed here should be double-checked by someone who knows what’s going on. Ask Mikael, Jim or Aubrey for help. -twp]

primitive procedure-documentation proc

Return the documentation string associated with proc. By convention, if a procedure contains more than one expression and the first expression is a string constant, that string is assumed to contain documentation for that procedure.

primitive procedure->syntax proc

[FIXME: Get documentation from SCM/SLIB.]

primitive procedure->macro proc

[FIXME: Get documentation from SCM/SLIB.]

primitive procedure->memoizing-macro proc

[FIXME: Get documentation from SCM/SLIB.]

primitive macro? obj

Return #t if obj is a regular macro, a memoizing macro or a syntax transformer.

primitive macro-type obj

Return one of the symbols syntax, macro or macro!, depending on whether obj is a syntax tranformer, a regular macro, or a memoizing macro, respectively. If obj is not a macro, #f is returned.

primitive macro-name

primitive macro-transformer

primitive promise? obj

Return true if obj is a promise, i.e. a delayed computation (see section “Delayed evaluation” in The Revised^4 Report on Scheme).

primitive copy-tree obj

Recursively copy the data tree that is bound to obj, and return a pointer to the new data structure. copy-tree recurses down the contents of both pairs and vectors (since both cons cells and vector cells may point to arbitrary objects), and stops recursing when it hits any other object.

primitive eval exp

Evaluate exp, a list representing a Scheme expression, in the top-level environment. primitive eval2 exp lookup

Evaluate exp, a Scheme expression, in the environment designated by lookup, a symbol-lookup function. (eval exp) is equivalent to (eval2 exp *top-level-

lookup-closure*).

primitive local-eval! exp [env]

Evaluate exp in its environment. If env is supplied, it is the environment in which to evaluate exp. Otherwise, exp must be a memoized code object (in which case, its environment is implicit).

primitive defined? sym

Return #t if sym is defined in the top-level environment.

primitive read-and-eval! [port]

Read a form from port (standard input by default), and evaluate it (memoizing it in the process) in the top-level environment. If no data is left to be read from port, an end-of-file error is signalled.

primitive primitive-load file

Load file and evaluate its contents in the top-level environment. The load paths are not searched; file must either be a full pathname or be a pathname relative to the current directory. If the variable %load-hook is defined, it should be bound to a procedure that will be called before any code is loaded. See documentation for %load-hook later in this section.

primitive primitive-load-path file

Search %load-path for file and load it into the top-level environment. If file is a relative pathname and is not found in the list of search paths, an error is signalled.

primitive %search-load-path file

Search %load-path for file, which must be readable by the current user. If file is found in the list of paths to search or is an absolute pathname, return its full pathname. Otherwise, return #f. Filenames may have any of the optional

extensions in the %load-extensions list; %search-load-path will try each

extension automatically.

Variable %load-hook

A procedure to be run whenever primitive-load is called. If this procedure is defined, it will be called with the filename argument that was passed to

primitive-load.
     (define %load-hook (lambda (file)
                          (display "Loading ")
                          (display file)
                          (write-line "...."))) ⇒ undefined
     (load-from-path "foo.scm")
     ⊣ Loading /usr/local/share/guile/site/foo.scm....

Variable %load-extensions

A list of default file extensions for files containing Scheme code. %search-load-path tries each of these extensions when looking for a file to load. By default,

%load-extensions is bound to the list ("" ".scm").

9 Lists

This chapter describes Guile list functions not found in standard Scheme.

primitive append! [lst…]

A destructive version of append (see section “Pairs and Lists” in The Revised^4 Report on Scheme). The cdr field of each list’s final pair is changed to point to the head of the next list, so no consing is performed. Return a pointer to the mutated list.

primitive last-pair lst

Return a pointer to the last pair in lst, signalling an error if lst is circular.

primitive reverse! lst [newtail] A destructive version of reverse (see section “Pairs and Lists” in The Revised^4 Report on Scheme). The cdr of each cell in lst is modified to point to the previous list element. Return a pointer to the head of the reversed list. Caveat: because the list is modified in place, the tail of the original list now becomes its head, and the head of the original list now becomes the tail. Therefore, the lst symbol to which the head of the original list was bound now points to the tail. To ensure that the head of the modified list is not lost, it is wise to save the return value of reverse!

primitive list-set! lst k val

Set the kth element of lst to val.

primitive list-cdr-ref lst k primitive list-tail lst k

Return the "tail" of lst beginning with its kth element. The first element of the list is considered to be element 0. list-cdr-ref and list-tail are identical. It may help to think of list-cdr-ref as accessing the kth cdr of the list, or returning the results of cdring k times down lst.

primitive list-cdr-set! lst k val

Set the kth cdr of lst to val.

primitive list-head lst k

Copy the first k elements from lst into a new list, and return it.

primitive list-copy lst

Return a (newly-created) copy of lst.

primitive delq item lst primitive delv item lst primitive delete item lst

Return a newly-created copy of lst with item removed. These procedures mirror memq, memv and member: delq compares elements of lst against item with eq?,

delv uses eqv? and delete uses equal?

primitive delq! item lst primitive delv! item lst

primitive delete! item lst

These procedures are destructive versions of delq, delv and delete: they modify the pointers in the existing lst rather than creating a new list. Caveat evaluator: Like other destructive list functions, these functions cannot modify the binding of lst, and so cannot be used to delete the first element of lst destructively.

[FIXME: is there any reason to have the ‘sloppy’ functions available at high level at all? Maybe these docs should be relegated to a "Guile Internals" node or something. -twp]

primitive sloppy-memq primitive sloppy-memv primitive sloppy-member

These procedures behave like memq, memv and member (see section “Pairs and Lists” in The Revised^4 Report on Scheme), but do not perform any type or error checking. Their use is recommended only in writing Guile internals, not for high-level Scheme programs.

10 Data Structures

To make it easier to write powerful applications, Guile provides many data structures not found in standard Scheme.

10.1 Records

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed] A record type is a first class object representing a user-defined data type. A record is

an instance of a record type.

procedure record? obj

Returns #t if obj is a record of any type and #f otherwise. Note that record? may be true of any Scheme value; there is no promise that records are disjoint with other Scheme types.

procedure make-record-type type-name field-names Returns a record-type descriptor, a value representing a new data type disjoint from all others. The type-name argument must be a string, but is only used for debugging purposes (such as the printed representation of a record of the new type). The field-names argument is a list of symbols naming the fields of a record of the new type. It is an error if the list contains any duplicates. It is unspecified how record-type descriptors are represented.

procedure record-constructor rtd [field-names]

Returns a procedure for constructing new members of the type represented by rtd. The returned procedure accepts exactly as many arguments as there are symbols in the given list, field-names; these are used, in order, as the initial values of those fields in a new record, which is returned by the constructor procedure. The values of any fields not named in that list are unspecified. The field-names argument defaults to the list of field names in the call to make-record-type that created the type represented by rtd; if the field-names argument is provided, it is an error if it contains any duplicates or any symbols not in the default list.

procedure record-predicate rtd

Returns a procedure for testing membership in the type represented by rtd. The returned procedure accepts exactly one argument and returns a true value if the argument is a member of the indicated record type; it returns a false value otherwise.

procedure record-accessor rtd field-name

Returns a procedure for reading the value of a particular field of a member of the type represented by rtd. The returned procedure accepts exactly one argument which must be a record of the appropriate type; it returns the current value of the field named by the symbol field-name in that record. The symbol field-name must be a member of the list of field-names in the call to make-record-type that created the type represented by rtd.

procedure record-modifier rtd field-name

Returns a procedure for writing the value of a particular field of a member of the type represented by rtd. The returned procedure accepts exactly two arguments: first, a record of the appropriate type, and second, an arbitrary Scheme value; it modifies the field named by the symbol field-name in that record to contain the given value. The returned value of the modifier procedure is unspecified. The symbol field-name must be a member of the list of fieldnames in the call to make-record-type that created the type represented by rtd.

procedure record-type-descriptor record

Returns a record-type descriptor representing the type of the given record. That is, for example, if the returned descriptor were passed to record-predicate, the resulting predicate would return a true value when passed the given record. Note that it is not necessarily the case that the returned descriptor is the one that was passed to record-constructor in the call that created the constructor procedure that created the given record.

procedure record-type-name rtd

Returns the type-name associated with the type represented by rtd. The returned value is eqv? to the type-name argument given in the call to makerecord-type that created the type represented by rtd.

procedure record-type-fields rtd

Returns a list of the symbols naming the fields in members of the type represented by rtd. The returned value is equal? to the field-names argument given in the call to make-record-type that created the type represented by rtd.

10.2 Structures

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed] A structure type is a first class user-defined data type. A structure is an instance of a

structure type. A structure type is itself a structure.

Structures are less abstract and more general than traditional records. In fact, in Guile Scheme, records are implemented using structures.

10.2.1 Structure Concepts

A structure object consists of a handle, structure data, and a vtable. The handle is a Scheme value which points to both the vtable and the structure’s data. Structure data is a dynamically allocated region of memory, private to the structure, divided up into typed fields. A vtable is another structure used to hold type-specific data. Multiple structures can share a common vtable.

Three concepts are key to understanding structures.

• layout specifications Layout specifications determine how memory allocated to structures is divided up into fields. Programmers must write a layout specification whenever a new type of structure is defined.

• structural accessors Structure access is by field number. There is only one set of accessors common to all structure objects.

• vtables Vtables, themselves structures, are first class representations of disjoint sub-types of structures in general. In most cases, when a new structure is created, programmers must specifiy a vtable for the new structure. Each vtable has a field describing the layout of its instances. Vtables can have additional, user-defined fields as well.

10.2.2 Structure Layout

When a structure is created, a region of memory is allocated to hold its state. The layout of the structure’s type determines how that memory is divided into fields.

Each field has a specified type. There are only three types allowed, each corresponding to a one letter code. The allowed types are:

• ’u’ – unprotected The field holds binary data that is not GC protected.

• ’p’ – protected The field holds a Scheme value and is GC protected.

• ’s’ – self The field holds a Scheme value and is GC protected. When a structure is created with this type of field, the field is initialized to refer to the structure’s own handle. This kind of field is mainly useful when mixing Scheme and C code in which the C code may need to compute a structure’s handle given only the address of its malloced data.

Each field also has an associated access protection. There are only three kinds of protection, each corresponding to a one letter code. The allowed protections are:

• ’w’ – writable The field can be read and written.

• ’r’ – readable The field can be read, but not written.

• ’o’ – opaque The field can be neither read nor written. This kind of protection is for fields useful only to built-in routines.

A layout specification is described by stringing together pairs of letters: one to specify a field type and one to specify a field protection. For example, a traditional cons pair type object could be described as:

; cons pairs have two writable fields of Scheme data
"pwpw"

A pair object in which the first field is held constant could be:

"prpw"

Binary fields, (fields of type "u"), hold one word each. The size of a word is a machine dependent value defined to be equal to the value of the C expression: sizeof (long).

The last field of a structure layout may specify a tail array. A tail array is indicated by capitalizing the field’s protection code (’W’, ’R’ or ’O’). A tail-array field is replaced by a read-only binary data field containing an array size. The array size is determined at the time the structure is created. It is followed by a corresponding number of fields of the type specified for the tail array. For example, a conventional Scheme vector can be described as:

; A vector is an arbitrary number of writable fields holding Scheme
; values:
"pW"

In the above example, field 0 contains the size of the vector and fields beginning at 1 contain the vector elements.

A kind of tagged vector (a constant tag followed by conventioal vector elements) might be:

"prpW"

Structure layouts are represented by specially interned symbols whose name is a string of type and protection codes. To create a new structure layout, use this procedure:

primitive make-struct-layout fields

Return a new structure layout object. fields must be a read-only string made up of pairs of characters strung together. The first character of each pair describes a field type, the second a field protection. Allowed types are ’p’ for GC-protected Scheme data, ’u’ for unprotected binary data, and ’s’ for fields that should point to the structure itself. Allowed protections are ’w’ for mutable fields, ’r’ for read-only fields, and ’o’ for opaque fields. The last field protection specification may be capitalized to indicate that the field is a tail-array.

10.2.3 Structure Basics

This section describes the basic procedures for creating and accessing structures.

primitive make-struct type tail-elts . inits Create a new structure. type must be a vtable structure (See ⟨undefined⟩ [Vtables], page ⟨undefined⟩). tail-elts must be a non-negative integer. If the layout specification indicated by type includes a tail-array, this is the number of elements allocated to that array. The inits are optional arguments describing how successive fields of the structure should be initialized. Only fields with protection ’r’ or ’w’ can be initialized

– fields of protection ’s’ are automatically initialized to point to the new structure itself; fields of protection ’o’ can not be initialized by Scheme programs.

primitive struct? obj

Return #t iff obj is a structure object.

primitive struct-ref struct n

primitive struct-set! struct n value Access (or modify) the nth field of struct. If the field is of type ’p’, then it can be set to an arbitrary value. If the field is of type ’u’, then it can only be set to a non-negative integer value small enough to fit in one machine word.

10.2.4 Vtables

Vtables are structures that are used to represent structure types. Each vtable contains a layout specification in field vtable-index-layout – instances of the type are laid out according to that specification. Vtables contain additional fields which are used only internally to libguile. The variable vtable-offset-user is bound to a field number. Vtable fields at that position or greater are user definable.

primitive struct-vtable struct

Return the vtable structure that describes the type of struct.

primitive struct-vtable? obj

Return #t iff obj is a vtable structure.

If you have a vtable structure, V, you can create an instance of the type it describes by using (make-struct V ...). But where does V itself come from? One possibility is that V is an instance of a user-defined vtable type, V', so that V is created by using (make-struct V' ...). Another possibility is that V is an instance of the type it itself describes. Vtable structures of the second sort are created by this procedure:

primitive make-vtable-vtable new-fields tail-size . inits Return a new, self-describing vtable structure. new-fields is a layout specification describing fields of the resulting structure beginning at the position bound to vtable-offset-user. tail-size specifies the size of the tail-array (if any) of this vtable. inits initializes the fields of the vtable. Minimally, one initializer must be provided: the layout specification for instances of the type this vtable will describe. If a second initializer is provided, it will be interpreted as a print call-back function.

;;; loading ,a...
(define x
  (make-vtable-vtable (make-struct-layout (quote pw))
                      0
                      'foo))
(struct? x)
⇒ #t
(struct-vtable? x)
⇒ #t
(eq? x (struct-vtable x))
⇒ #t
(struct-ref x vtable-offset-user)
⇒ foo
(struct-ref x 0)
⇒ pruosrpwpw

(define y
  (make-struct x
               0
               (make-struct-layout (quote pwpwpw))
               'bar))
(struct? y)
⇒ #t
(struct-vtable? y)
⇒ #t
(eq? x y)
⇒ ()
(eq? x (struct-vtable y))
⇒ #t
(struct-ref y 0)
⇒ pwpwpw
(struct-ref y vtable-offset-user)
⇒ bar

(define z (make-struct y 0 'a 'b 'c))
(struct? z)

⇒ #t
(struct-vtable? z)
⇒ ()
(eq? y (struct-vtable z))
⇒ #t
(map (lambda (n) (struct-ref z n)) '(0 1 2))
⇒ (a b c)

10.3 Arrays

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed]

10.3.1 Conventional Arrays

Arrays read and write as a # followed by the rank (number of dimensions) followed by what appear as lists (of lists) of elements. The lists must be nested to the depth of the rank. For each depth, all lists must be the same length.

(make-array 'ho 3 3) ⇒
#2((ho ho ho) (ho ho ho) (ho ho ho))

Unshared conventional (not uniform) 0-based arrays of rank 1 (dimension) are equivalent to (and can’t be distinguished from) vectors.

(make-array 'ho 3) ⇒ (ho ho ho)

When constructing an array, bound is either an inclusive range of indices expressed as a two element list, or an upper bound expressed as a single integer. So

(make-array 'foo 3 3) ≡ (make-array 'foo '(0 2) '(0 2))

primitive array? obj

Returns #t if the obj is an array, and #f if not.

procedure make-array initial-value bound1 bound2 … Creates and returns an array that has as many dimensions as there are bounds and fills it with initial-value.

primitive array-ref array index1 index2 … Returns the element at the (index1, index2) element in array.

primitive array-in-bounds? array index1 index2 … Returns #t if its arguments would be acceptable to array-ref.

primitive array-set! array new-value index1 index2 … Sets the element at the (index1, index2) element in array to new-value. The value returned by array-set! is unspecified.

primitive make-shared-array array mapper bound1 bound2 … make-shared-array can be used to create shared subarrays of other arrays. The mapper is a function that translates coordinates in the new array into coordinates in the old array. A mapper must be linear, and its range must stay within the bounds of the old array, but it can be otherwise arbitrary. A simple example:

     (define fred (make-array #f 8 8))
     (define freds-diagonal
       (make-shared-array fred (lambda (i) (list i i)) 8))
     (array-set! freds-diagonal 'foo 3)
     (array-ref fred 3 3) ⇒ foo
     (define freds-center
       (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
     (array-ref freds-center 0 0) ⇒ foo

primitive transpose-array array dim0 dim1 …

Returns an array sharing contents with array, but with dimensions arranged in a different order. There must be one dim argument for each dimension of array. dim0, dim1, … should be integers between 0 and the rank of the array to be returned. Each integer in that range must appear at least once in the argument list. The values of dim0, dim1, … correspond to dimensions in the array to be returned, their positions in the argument list to dimensions of array. Several dims may have the same value, in which case the returned array will have smaller rank than array. examples:

     (transpose-array '#2((a b) (c d)) 1 0) ⇒ #2((a c) (b d))
     (transpose-array '#2((a b) (c d)) 0 0) ⇒ #1(a d)
     (transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) ⇒
                     #2((a 4) (b 5) (c 6))

primitive enclose-array array dim0 dim1 …

dim0, dim1 … should be nonnegative integers less than the rank of array. enclose-array returns an array resembling an array of shared arrays. The dimensions of each shared array are the same as the dimth dimensions of the original array, the dimensions of the outer array are the same as those of the original array that did not match a dim. An enclosed array is not a general Scheme array. Its elements may not be set using array-set!. Two references to the same element of an enclosed array will be equal? but will not in general be eq?. The value returned by arrayprototype when given an enclosed array is unspecified. examples:

     (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) ⇒
        #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>
     (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) ⇒
        #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>

procedure array-shape array

Returns a list of inclusive bounds of integers.

     (array-shape (make-array 'foo '(-1 3) 5)) ⇒ ((-1 3) (0 4))

primitive array-dimensions array

Array-dimensions is similar to array-shape but replaces elements with a 0 minimum with one greater than the maximum. So:

     (array-dimensions (make-array 'foo '(-1 3) 5)) ⇒ ((-1 3) 5)

primitive array-rank obj

Returns the number of dimensions of obj. If obj is not an array, 0 is returned.

primitive array->list array

Returns a list consisting of all the elements, in order, of array. primitive array-copy! source destination

Copies every element from vector or array source to the corresponding element of destination. destination must have the same rank as source, and be at least as large in each dimension. The order is unspecified.

primitive serial-array-copy! source destination

Same as array-copy! but guaranteed to copy in row-major order.

primitive array-fill! array fill

Stores fill in every element of array. The value returned is unspecified.

primitive array-equal? array0 array1 …

Returns #t iff all arguments are arrays with the same shape, the same type, and have corresponding elements which are either equal? or array-equal?. This function differs from equal? in that a one dimensional shared array may be array-equal? but not equal? to a vector or uniform vector.

primitive array-contents array primitive array-contents array strict

If array may be unrolled into a one dimensional shared array without changing their order (last subscript changing fastest), then array-contents returns that shared array, otherwise it returns #f. All arrays made by make-array and makeuniform-array may be unrolled, some arrays made by make-shared-array may not be. If the optional argument strict is provided, a shared array will be returned only if its elements are stored internally contiguous in memory.

10.3.2 Array Mapping

primitive array-map! array0 proc array1 … array1, … must have the same number of dimensions as array0 and have a range for each index which includes the range for the corresponding index in array0. proc is applied to each tuple of elements of array1 … and the result is stored as the corresponding element in array0. The value returned is unspecified. The order of application is unspecified.

primitive serial-array-map! array0 proc array1 …

Same as array-map!, but guaranteed to apply proc in row-major order.

primitive array-for-each proc array0 …

proc is applied to each tuple of elements of array0 … in row-major order. The value returned is unspecified.

primitive array-index-map! array proc

applies proc to the indices of each element of array in turn, storing the result in the corresponding element. The value returned and the order of application are unspecified. One can implement array-indexes as

     (define (array-indexes array)
         (let ((ra (apply make-array #f (array-shape array))))
           (array-index-map! ra (lambda x x))
           ra))

Another example:

     (define (apl:index-generator n)
         (let ((v (make-uniform-vector n 1)))
           (array-index-map! v (lambda (i) i))
           v))

10.3.3 Uniform Array

Uniform Array and vectors are arrays whose elements are all of the same type. Uniform vectors occupy less storage than conventional vectors. Uniform Array procedures also work on vectors, uniform-vectors, bit-vectors, and strings. prototype arguments in the following procedures are interpreted according to the table:

prototype       type                            printing character
#t              boolean (bit-vector)                    b
#\a             char (string)                           a
integer >0      unsigned integer                        u
integer <0      signed integer                          e
1.0             float (single precision)                s
1/3             double (double precision float)         i
+i              complex (double precision)              c
()              conventional vector

Unshared uniform character 0-based arrays of rank 1 (dimension) are equivalent to (and can’t be distinguished from) strings.

(make-uniform-array #\a 3) ⇒ "$q2"

Unshared uniform boolean 0-based arrays of rank 1 (dimension) are equivalent to (and can’t be distinguished from) ⟨undefined⟩ [Bit Vectors], page ⟨undefined⟩.

(make-uniform-array #t 3) ⇒ #*000

≡

#b(#f #f #f) ⇒ #*000

≡

#1b(#f #f #f) ⇒ #*000

Other uniform vectors are written in a form similar to that of vectors, except that a single character from the above table is put between # and (. For example, '#e(3 5 9) returns a uniform vector of signed integers.

primitive array? obj prototype Returns #t if the obj is an array of type corresponding to prototype, and #f if not.

procedure make-uniform-array prototype bound1 bound2 … Creates and returns a uniform array of type corresponding to prototype that has as many dimensions as there are bounds and fills it with prototype.

primitive array-prototype array

Returns an object that would produce an array of the same type as array, if used as the prototype for make-uniform-array.

primitive list->uniform-array rank prot lst procedure list->uniform-vector prot lst

Returns a uniform array of the type indicated by prototype prot with elements the same as those of lst. Elements must be of the appropriate type, no coercions are done.

primitive uniform-vector-fill! uve fill

Stores fill in every element of uve. The value returned is unspecified.

primitive uniform-vector-length uve

Returns the number of elements in uve.

primitive dimensions->uniform-array dims prototype [fill]

primitive make-uniform-vector length prototype [fill] Creates and returns a uniform array or vector of type corresponding to prototype with dimensions dims or length length. If the fill argument is supplied, the returned array is filled with this value.

primitive uniform-array-read! ura [port-or-fdes] [start] [end] primitive uniform-vector-read! uve [port-or-fdes] [start] [end]

Attempts to read all elements of ura, in lexicographic order, as binary objects from port-or-fdes. If an end of file is encountered during uniform-array-read! the objects up to that point only are put into ura (starting at the beginning) and the remainder of the array is unchanged. The optional arguments start and end allow a specified region of a vector (or linearized array) to be read, leaving the remainder of the vector unchanged. uniform-array-read! returns the number of objects read. port-or-fdes may be omitted, in which case it defaults to the value returned by (current-input-

port).

primitive uniform-array-write ura [port-or-fdes] [start] [end] primitive uniform-vector-write uve [port-or-fdes] [start] [end]

Writes all elements of ura as binary objects to port-or-fdes. The optional arguments start and end allow a specified region of a vector (or linearized array) to be written. The number of objects actually written is returned. port-or-fdes may be omitted, in which case it defaults to the value returned by (current-output-port).

10.3.4 Bit Vectors

Bit vectors can be written and read as a sequence of 0s and 1s prefixed by #*.

#b(#f #f #f #t #f #t #f) ⇒ #*0001010

Some of these operations will eventually be generalized to other uniform-arrays.

primitive bit-count bool bv

Returns the number occurrences of bool in bv.

primitive bit-position bool bv k

Returns the minimum index of an occurrence of bool in bv which is at least k.

If no bool occurs within the specified range #f is returned.

primitive bit-invert! bv

Modifies bv by replacing each element with its negation.

primitive bit-set*! bv uve bool

If uve is a bit-vector bv and uve must be of the same length. If bool is #t, uve is OR’ed into bv; If bool is #f, the inversion of uve is AND’ed into bv. If uve is a unsigned integer vector all the elements of uve must be between 0 and the LENGTH of bv. The bits of bv corresponding to the indexes in uve are set to bool. The return value is unspecified.

primitive bit-count* bv uve bool

Returns

          (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).

bv is not modified.

10.4 Association Lists and Hash Tables

This chapter discusses dictionary objects: data structures that are useful for organizing and indexing large bodies of information.

10.4.1 Dictionary Types

A dictionary object is a data structure used to index information in a user-defined way. In standard Scheme, the main aggregate data types are lists and vectors. Lists are not really indexed at all, and vectors are indexed only by number (e.g. (vector-ref foo 5)). Often you will find it useful to index your data on some other type; for example, in a library catalog you might want to look up a book by the name of its author. Dictionaries are used to help you organize information in such a way.

An association list (or alist for short) is a list of key-value pairs. Each pair represents a single quantity or object; the car of the pair is a key which is used to identify the object, and the cdr is the object’s value.

A hash table also permits you to index objects with arbitrary keys, but in a way that makes looking up any one object extremely fast. A well-designed hash system makes hash table lookups almost as fast as conventional array or vector references.

Alists are popular among Lisp programmers because they use only the language’s primitive operations (lists, car, cdr and the equality primitives). No changes to the language core are necessary. Therefore, with Scheme’s built-in list manipulation facilities, it is very convenient to handle data stored in an association list. Also, alists are highly portable and can be easily implemented on even the most minimal Lisp systems.

However, alists are inefficient, especially for storing large quantities of data. Because we want Guile to be useful for large software systems as well as small ones, Guile provides a rich set of tools for using either association lists or hash tables.

10.4.2 Association Lists

primitive acons key value alist Adds a new key-value pair to alist. A new pair is created whose car is key and whose cdr is value, and the pair is consed onto alist, and the new list is returned. This function is not destructive; alist is not modified.

primitive assq key alist primitive assv key alist primitive assoc key alist

Fetches the entry in alist that is associated with key. To decide whether the argument key matches a particular entry in alist, assq compares keys with eq?, assv uses eqv? and assoc uses equal?. If key cannot be found in alist (according to whichever equality predicate is in use), then #f is returned. These functions return the entire alist entry found (i.e. both the key and the value).

primitive assq-ref alist key primitive assv-ref alist key primitive assoc-ref alist key

Like assq, assv and assoc, except that only the value associated with key in alist is returned. These functions are equivalent to

(let ((ent (associator key alist)))

       (and ent (cdr ent)))

where associator is one of assq, assv or assoc.

primitive assq-set! alist key value primitive assv-set! alist key value primitive assoc-set! alist key value

Reassociate key in alist with value: find any existing alist entry for key and associate it with the new value. If alist does not contain an entry for key, add a new one. Return the (possibly new) alist. These functions do not attempt to verify the structure of alist, and so may cause unusual results if passed an object that is not an association list.

primitive assq-remove! alist key primitive assv-remove! alist key primitive assoc-remove! alist key

Delete any entry in alist associated with key, and return the resulting alist.

Caution: it is important to remember that the set! and remove! functions do not always operate as intended. In some circumstances, the functions will try to modify the first element in the list; for example, when adding a new entry to an alist, assoc-set! conses the new key-value pair on to the beginning of the alist. However, when this happens, the symbol to which the alist is bound has not been modified—it still points to the old “beginning” of the list, which still does not contain the new entry. In order to be sure that these functions always succeed, even when modifying the beginning of the alist, you will have to rebind the alist symbol explicitly to point to the value returned by assoc-set!, like so:

(set! my-alist
      (assq-set! my-alist 'sun4 "sparc-sun-solaris"))

Because of this restriction, you may find it more convenient to use hash tables to store dictionary data. If your application will not be modifying the contents of an alist very often, this may not make much difference to you.

Here is a longer example of how alists may be used in practice.

(define capitals '(("New York" . "Albany")
                   ("Oregon"   . "Salem")
                   ("Florida"  . "Miami")))
;; What's the capital of Oregon?
(assoc "Oregon" capitals)  ⇒ ("Oregon" . "Salem")
(assoc-ref capitals "Oregon") ⇒ "Salem"
;; We left out South Dakota.
(set! capitals
      (assoc-set! capitals "South Dakota" "Bismarck"))
capitals
⇒ (("South Dakota" . "Bismarck")
    ("New York" . "Albany")
    ("Oregon" . "Salem")
    ("Florida" . "Miami"))
;; And we got Florida wrong.
(set! capitals
      (assoc-set! capitals "Florida" "Tallahassee"))
capitals
⇒ (("South Dakota" . "Bismarck")
    ("New York" . "Albany")
    ("Oregon" . "Salem")
    ("Florida" . "Tallahassee"))
;; After Oregon secedes, we can remove it.
(set! capitals
      (assoc-remove! capitals "Oregon"))
capitals
⇒ (("South Dakota" . "Bismarck")
    ("New York" . "Albany")
    ("Florida" . "Tallahassee"))

10.4.3 Hash Tables

Like the association list functions, the hash table functions come in several varieties: hashq, hashv, and hash. The hashq functions use eq? to determine whether two keys match. The hashv functions use eqv?, and the hash functions use equal?.

In each of the functions that follow, the table argument must be a vector. The key and value arguments may be any Scheme object.

primitive hashq-ref table key [default] primitive hashv-ref table key [default] primitive hash-ref table key [default]

Look up key in the hash table table, and return the value (if any) associated with it. If key is not found, return default (or #f if no default argument is supplied).

primitive hashq-set! table key value primitive hashv-set! table key value primitive hash-set! table key value

Find the entry in table associated with key, and store value there.

primitive hashq-remove! table key primitive hashv-remove! table key primitive hash-remove! table key

Remove key (and any value associated with it) from table.

The standard hash table functions may be too limited for some applications. For example, you may want a hash table to store strings in a case-insensitive manner, so that references to keys named “foobar”, “FOOBAR” and “FooBaR” will all yield the same item. Guile provides you with extended hash tables that permit you to specify a hash function and associator function of your choosing. The functions described in the rest of this section can be used to implement such custom hash table structures.

If you are unfamiliar with the inner workings of hash tables, then this facility will probably be a little too abstract for you to use comfortably. If you are interested in learning more, see an introductory textbook on data structures or algorithms for an explanation of how hash tables are implemented.

primitive hashq key size primitive hashv key size primitive hash key size

Default hash functions for Guile hash tables. key is the object to be hashed, and size is the size of the target hash table. Each function returns an integer in the range 0 to size-1.

primitive hashx-ref hasher assoc table key [default] primitive hashx-set! hasher assoc table key value primitive hashx-remove! hasher assoc table key

These behave the same way as the corresponding ref and set! functions described above, but use hasher as a hash function and assoc to compare keys. hasher must be a function that takes two arguments, a key to be hashed and a table size. assoc must be an associator function, like assoc, assq or assv. By way of illustration, hashq-ref table key is equivalent to hashx-ref hashq

assq table key.

primitive hashq-get-handle table key primitive hashv-get-handle table key primitive hash-get-handle table key

primitive hashx-get-handle hasher assoc table key These procedures are similar to their -ref cousins, but return a handle from the hash table rather than the value associated with key. By convention, a handle in a hash table is the pair which associates a key with a value. Where hashq-

ref table key returns only a value, hashq-get-handle table key returns the
pair (key . value).

primitive hashq-create-handle! table key init primitive hashv-create-handle! table key init primitive hash-create-handle! table key init

primitive hashx-create-handle! hasher assoc table key init These functions look up key in table and return its handle, If key is not already present, a new handle is created which associates key with init.

11 Strings

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed] For the sake of efficiency, two special kinds of strings are available in Guile: shared

substrings and the misleadingly named “read-only” strings. It is not necessary to know about these to program in Guile, but you are likely to run into one or both of these special string types eventually, and it will be helpful to know how they work.

11.1 String Fun

primitive string-index str chr [frm [to]] Return the index of the first occurrence of chr in str. The optional integer arguments frm and to limit the search to a portion of the string. This procedure essentially implements the index or strchr functions from the C library.

primitive string-rindex str chr [frm [to]] Like string-index, but search from the right of the string rather than from the left. This procedure essentially implements the rindex or strrchr functions from the C library.

primitive substring-move-right! str1 start1 end1 str2 start2 primitive substring-move-left! str1 start1 end1 str2 start2

Copy the substring of str1 bounded by start1 and end1 into str2 beginning at position end2. substring-move-right! begins copying from the rightmost character and moves left, and substring-move-left! copies from the leftmost character moving right. It is useful to have two functions that copy in different directions so that substrings can be copied back and forth within a single string. If you wish to copy text from the left-hand side of a string to the right-hand side of the same string, and the source and destination overlap, you must be careful to copy the rightmost characters of the text first, to avoid clobbering your data. Hence, when str1 and str2 are the same string, you should use substring-move-right! when moving text from left to right, and substring-move-left! otherwise. If str1 and ‘str2’ are different strings, it does not matter which function you use.

primitive vector-move-right! vec1 start1 end1 vec2 start2 primitive vector-move-left! vec1 start1 end1 vec2 start2

Vector versions of substring-move-right! and substring-move-left!

primitive substring-fill! str start end fill-char Change every character in str between start and end to fill-char.

primitive string-null? str

Return #t if str’s length is nonzero, and #f otherwise.

primitive string-upcase! str primitive string-downcase! str

Upcase or downcase every character in str, respectively.

11.2 Shared Substrings

Whenever you extract a substring using substring, the Scheme interpreter allocates a new string and copies data from the old string. This is expensive, but substring is so convenient for manipulating text that programmers use it often.

Guile Scheme provides the concept of the shared substring to improve performance of many substring-related operations. A shared substring is an object that mostly behaves just like an ordinary substring, except that it actually shares storage space with its parent string.

primitive make-shared-substring str start [end]

Return a shared substring of str. The semantics are the same as for the substring function: the shared substring returned includes all of the text from str between indexes start (inclusive) and end (exclusive). If end is omitted, it defaults to the end of str. The shared substring returned by make-shared-substring occupies the same storage space as str.

Example:

     (define foo "the quick brown fox")
     (define bar (make-shared-substring some-string 4 9))
     foo => "t h e   q u i c k   b r o w n   f o x"
     bar =========> |---------|

The shared substring bar is not given its own storage space. Instead, the Guile interpreter notes internally that bar points to a portion of the memory allocated to foo. However, bar behaves like an ordinary string in most respects: it may be used with string primitives like string-length, string-ref, string=?. Guile makes the necessary translation between indices of bar and indices of foo automatically.

     (string-length? bar) ⇒ 5 ; bar only extends from indices 4 to 9
     (string-ref bar 3) ⇒ #\c ; same as (string-ref foo 7)
     (make-shared-substring bar 2)
       ⇒ "ick" ; can even make a shared substring!

Because creating a shared substring does not require allocating new storage from the heap, it is a very fast operation. However, because it shares memory with its parent string, a change to the contents of the parent string will implicitly change the contents of its shared substrings.

     (string-set! foo 7 #\r)
     bar ⇒ "quirk"

Guile considers shared substrings to be immutable. This is because programmers might not always be aware that a given string is really a shared substring, and might innocently try to mutate it without realizing that the change would affect its parent string. (We are currently considering a "copy-on-write" strategy that would permit modifying shared substrings without affecting the parent string.)

In general, shared substrings are useful in circumstances where it is important to divide a string into smaller portions, but you do not expect to change the contents of any of the strings involved.

11.3 Read Only Strings

Type-checking in Guile primitives distinguishes between mutable strings and read only strings. Mutable strings answer #t to string? while read only strings may or may not. All kinds of strings, whether or not they are mutable return #t to this:

primitive read-only-string? OBJ

Return true of OBJ can be read as a string,

This illustrates the difference between string? and read-only-string?:

          (string? "a string") ⇒ #t
          (string? 'a-symbol") ⇒ #f
          (read-only-string? "a string") ⇒ #t
          (read-only-string? 'a-symbol") ⇒ #t

"Read-only" refers to how the string will be used, not how the string is permitted to be used. In particular, all strings are "read-only strings" even if they are mutable, because a function that only reads from a string can certainly operate on even a mutable string.

Symbols are an example of read-only strings. Many string functions, such as stringappend are happy to operate on symbols. Many functions that expect a string argument, such as open-file, will accept a symbol as well.

Shared substrings, discussed in the previous chapter, also happen to be read-only strings.

12 Characters

Most of the characters in the ASCII character set may be referred to by name: for example, #\tab, #\esc, #\stx, and so on. The following table describes the ASCII names for each character.

0 = #\nul  1 = #\soh  2 = #\stx  3 = #\etx
4 = #\eot  5 = #\enq  6 = #\ack  7 = #\bel
8 = #\bs  9 = #\ht  10 = #\nl  11 = #\vt
12 = #\np  13 = #\cr  14 = #\so  15 = #\si
16 = #\dle  17 = #\dc1  18 = #\dc2  19 = #\dc3
20 = #\dc4  21 = #\nak  22 = #\syn  23 = #\etb
24 = #\can  25 = #\em  26 = #\sub  27 = #\esc
28 = #\fs  29 = #\gs  30 = #\rs  31 = #\us

32 = #\sp

The delete character (octal 177) may be referred to with the name #\del.

Several characters have more than one name:

• #\space, #\sp

• #\newline, #\nl

• #\tab, #\ht

• #\backspace, #\bs

• #\return, #\cr

• #\page, #\np

• #\null, #\nul

13 Property Lists

Every object in the system can have a property list that may be used for information about that object. For example, a function may have a property list that includes information about the source file in which it is defined.

Property lists are implemented as assq lists (see ⟨undefined⟩ [Association Lists], page ⟨undefined⟩).

Currently, property lists are implemented differently for procedures and closures than for other kinds of objects. Therefore, when manipulating a property list associated with a procedure object, use the procedure functions; otherwise, use the object functions.

primitive object-properties obj primitive procedure-properties obj

Return obj’s property list.

primitive set-object-properties! obj alist primitive set-procedure-properties! obj alist

Set obj’s property list to alist.

primitive object-property obj key primitive procedure-property obj key

Return the property of obj with name key.

primitive set-object-property! obj key value primitive set-procedure-property! obj key value

In obj’s property list, set the property named key to value.

[Interface bug: there should be a second level of interface in which the user provides a "property table" that is possibly private.]

14 Ports

Input and output devices in Scheme are represented by ports. All input and output in Scheme programs is accomplished by operating on a port: characters are read from an input port and written to an output port. This chapter explains the operations that Guile provides for working with ports.

The formal definition of a port is very generic: an input port is simply “an object which can deliver characters on command,” and an output port is “an object which can accept characters.” Because this definition is so loose, it is easy to write functions that simulate ports in software. Soft ports and string ports are two interesting and powerful examples of this technique.

14.1 File Ports

The following procedures are used to open file ports. See also ⟨undefined⟩ [Ports and File Descriptors], page ⟨undefined⟩, for an interface to the Unix open system call.

primitive open-file string mode Open the file whose name is string, and return a port representing that file. Whether an input or output port is allocated is determined by the mode string. This is interpreted in the traditional Unix manner: use ‘r’ for reading, ‘w’ for writing, and ‘a’ for appending. In addition, ‘0’ can be used to specifiy an unbuffered port. See the stdio documentation for your system for more I/O mode options. If a file cannot be opened, open-file throws an exception.

procedure open-input-file filename

Open filename for input. Equivalent to

     (open-file filename "r")

procedure open-output-file filename

Open filename for output. Equivalent to

     (open-file filename "w")

primitive port-mode port

Return the mode flags from the open port.

primitive port-filename [port]

Return the filename associated with port. This function returns the strings "standard input", "standard output" and "standard error" when called on the current input, output and error ports respectively.

primitive set-port-filename! [port] filename

Change the filename associated with port, using the current input port if none is specified. Note that this does not change the port’s source of data, but only the value that is returned by port-filename and reported in diagnostic output.

primitive %make-void-port mode

Create and return a new void port. The mode argument describes the permissions to use for this port; for a description, see the documentation for open-file in ⟨undefined⟩ [File Ports], page ⟨undefined⟩.

14.2 Soft Ports

A soft-port is a port based on a vector of procedures capable of accepting or delivering characters. It allows emulation of I/O ports.

primitive make-soft-port vector modes

Returns a port capable of receiving or delivering characters as specified by the modes string (see ⟨undefined⟩ [File Ports], page ⟨undefined⟩). vector must be a vector of length 6. Its components are as follows:

0. procedure accepting one character for output

1. procedure accepting a string for output

2. thunk for flushing output

3. thunk for getting one character

4. thunk for closing port (not by garbage collection)

For an output-only port only elements 0, 1, 2, and 4 need be procedures. For an input-only port only elements 3 and 4 need be procedures. Thunks 2 and 4 can instead be #f if there is no useful operation for them to perform.

If thunk 3 returns #f or an eof-object (see section “Input” in The Revised^4 Report on Scheme) it indicates that the port has reached end-of-file. For example:

     (define stdout (current-output-port))
     (define p (make-soft-port
                (vector
                 (lambda (c) (write c stdout))
                 (lambda (s) (display s stdout))
                 (lambda () (display "." stdout))
                 (lambda () (char-upcase (read-char)))
                 (lambda () (display "@" stdout)))
                "rw"))
     (write p p) ⇒ #<input-output-soft#\space45d10#\>

14.3 String Ports

primitive call-with-output-string proc

proc must be a procedure of one argument. This procedure calls proc with one argument: a (newly created) output port. When the function returns, the string composed of the characters written into the port is returned.

primitive call-with-input-string string proc

proc must be a procedure of one argument. This procedure calls proc with one argument: an (newly created) input port from which string’s contents may be read. When proc returns, the port is closed and the value yielded by the procedure proc is returned.

primitive eval-string string

Evaluate string as the text representation of a Scheme form or forms, and return whatever value they produce. [FIXME: figure out where this should go... evalstring is not really closely related to other string port functions. It just happens to appear in strports.c because it uses a string port to read from the string. -twp]

14.4 Closing Ports

The following procedures return #t if they successfully close a port or #f if it was already closed. They can also raise exceptions if an error occurs: some errors arising from writing output may be delayed until close. See also ⟨undefined⟩ [Ports and File Descriptors], page ⟨undefined⟩, for a procedure which can close file descriptors.

primitive close-port port

Close the specified port object.

primitive close-input-port port

Close the specified input port object. This procedure is required by R4RS.

primitive close-output-port port

Close the specified output port object. This procedure is required by R4RS.

14.5 Port Operations

These procedures obtain and modify information about ports, but are not specific to one kind of port.

primitive current-error-port

Return the port to which errors and warnings should be sent (the standard error in Unix and C terminology).

primitive set-current-input-port port primitive set-current-output-port port primitive set-current-error-port port

Change the ports returned by current-input-port, current-output-port

and current-error-port, respectively, so that they use the supplied port for input or output.

primitive port-column [input-port] primitive port-line [input-port]

Return the current column number or line number of input-port, using the current input port if none is specified. If the number is unknown, the result is #f. Otherwise, the result is a 0-origin integer - i.e. the first character of the first line is line 0, column 0. (However, when you display a file position, for example in an error message, we recommand you add 1 to get 1-origin integers. This is because lines and column numbers traditionally start with 1, and that is what non-programmers will find most natural.)

primitive set-port-column! [input-port] column primitive set-port-line! [input-port] line

Set the current column or line number of input-port, using the current input port if none is specified.

14.6 Extended I/O (fseek and line read/write)

Extended I/O procedures are available which read or write lines of text, read text delimited by a specified set of characters, or report or set the current position of a port.

Interfaces to read/fread and write/fwrite are also available, as uniform-array-read!

and uniform-array-write!, ⟨undefined⟩ [Uniform Array], page ⟨undefined⟩.

procedure read-line [port] [handle-delim] Return a line of text from port if specified, otherwise from the value returned by (current-input-port). Under Unix, a line of text is terminated by the first end-of-line character or by end-of-file. If handle-delim is specified, it should be one of the following symbols:

trim Discard the terminating delimiter. This is the default, but it will be impossible to tell whether the read terminated with a delimiter or end-of-file.

concat Append the terminating delimiter (if any) to the returned string.

peek Push the terminating delimiter (if any) back on to the port.

split Return a pair containing the string read from the port and the terminating delimiter or end-of-file object. NOTE: if the scsh module is loaded then multiple values are returned instead of a pair.

procedure read-line! buf [port]

Read a line of text into the supplied string buf and return the number of characters added to buf. If buf is filled, then #f is returned. Read from port if specified, otherwise from the value returned by (current-input-port).

procedure read-delimited delims [port] [handle-delim] Read text until one of the characters in the string delims is found or end-of-file is reached. Read from port if supplied, otherwise from the value returned by (current-input-port). handle-delim takes the same values as described for

read-line.

NOTE: if the scsh module is loaded then delims must be an scsh char-set, not a string. procedure read-delimited! delims buf [port] [handle-delim] [start] [end]

Read text into the supplied string buf and return the number of characters added to buf (subject to handle-delim, which takes the same values specified for read-line. If buf is filled, #f is returned for both the number of characters read and the delimiter. Also terminates if one of the characters in the string delims is found or end-of-file is reached. Read from port if supplied, otherwise from the value returned by (current-input-port). NOTE: if the scsh module is loaded then delims must be an scsh char-set, not a string.

primitive write-line obj [port]

Display obj and a newline character to port. If port is not specified, (currentoutput-port) is used. This function is equivalent to:

     (display obj [port])
     (newline [port])

primitive ftell fd/port Returns an integer representing the current position of fd/port, measured from the beginning. If fd/port is a file descriptor, the underlying system call is lseek.

primitive fseek fd/port offset whence Sets the current position of fd/port to the integer offset, which is interpreted according to the value of whence. One of the following variables should be supplied for whence:

Variable SEEK SET

Seek from the beginning of the file.

Variable SEEK CUR

Seek from the current position.

Variable SEEK END

Seek from the end of the file.

If fd/port is a file descriptor the underlying system call is lseek. The return value is unspecified.

Some of the abovementioned I/O functions rely on the following C primitives. These will mainly be of interest to people hacking Guile internals.

primitive %read-delimited! delims buf gobble? [port [start [end]]] Read characters from port into buf until one of the characters in the delims string is encountered. If gobble? is true, store the delimiter character in buf as well; otherwise, discard it. If port is not specified, use the value of (currentinput-port). If start or end are specified, store data only into the substring of buf bounded by start and end (which default to the beginning and end of the buffer, respectively).

Return a pair consisting of the delimiter that terminated the string and the number of characters read. If reading stopped at the end of file, the delimiter returned is the eof-object; if the buffer was filled without encountering a delimiter, this value is #f.

primitive %read-line [port]

Read a newline-terminated line from port, allocating storage as necessary. The newline terminator (if any) is removed from the string, and a pair consisting of the line and its delimiter is returned. The delimiter may be either a newline or the eof-object; if %read-line is called at the end of file, it returns the pair

(#<eof> . #<eof>).

15 Bitwise Operations

primitive logand n1 n2

Returns the integer which is the bit-wise AND of the two integer arguments. Example:

(number->string (logand #b1100 #b1010) 2)
   ⇒ "1000"

primitive logior n1 n2

Returns the integer which is the bit-wise OR of the two integer arguments. Example:

(number->string (logior #b1100 #b1010) 2)
   ⇒ "1110"

primitive logxor n1 n2

Returns the integer which is the bit-wise XOR of the two integer arguments. Example:

(number->string (logxor #b1100 #b1010) 2)
   ⇒ "110"

primitive lognot n

Returns the integer which is the 2s-complement of the integer argument. Example:

(number->string (lognot #b10000000) 2)
   ⇒ "-10000001"
(number->string (lognot #b0) 2)
   ⇒ "-1"

primitive logtest j k

(logtest j k) ≡ (not (zero? (logand j k)))
(logtest #b0100 #b1011) ⇒ #f
(logtest #b0100 #b0111) ⇒ #t

primitive logbit? index j

(logbit? index j) ≡ (logtest (integer-expt 2 index) j)
(logbit? 0 #b1101) ⇒ #t
(logbit? 1 #b1101) ⇒ #f
(logbit? 2 #b1101) ⇒ #t
(logbit? 3 #b1101) ⇒ #t
(logbit? 4 #b1101) ⇒ #f

primitive ash int count Returns an integer equivalent to (inexact->exact (floor (* int (expt 2 count)))). Example:

(number->string (ash #b1 3) 2)
   ⇒ "1000"
(number->string (ash #b1010 -1) 2)
   ⇒ "101"

primitive logcount n

Returns the number of bits in integer n. If integer is positive, the 1-bits in its binary representation are counted. If negative, the 0-bits in its two’s-complement binary representation are counted. If 0, 0 is returned. Example:

(logcount #b10101010)
   ⇒ 4
(logcount 0)
   ⇒ 0
(logcount -2)
   ⇒ 1

primitive integer-length n

Returns the number of bits neccessary to represent n. Example:

(integer-length #b10101010)
   ⇒ 8
(integer-length 0)
   ⇒ 0
(integer-length #b1111)
   ⇒ 4

primitive integer-expt n k

Returns n raised to the non-negative integer exponent k. Example:

(integer-expt 2 5)
   ⇒ 32
(integer-expt -3 3)
   ⇒ -27

primitive bit-extract n start end

Returns the integer composed of the start (inclusive) through end (exclusive) bits of n. The startth bit becomes the 0-th bit in the result. Example:

(number->string (bit-extract #b1101101010 0 4) 2)
   ⇒ "1010"
(number->string (bit-extract #b1101101010 4 9) 2)
   ⇒ "10110"

16 Regular Expressions

A regular expression (or regexp) is a pattern that describes a whole class of strings. A full description of regular expressions and their syntax is beyond the scope of this manual; an introduction can be found in the Emacs manual (see section “Syntax of Regular Expressions” in The GNU Emacs Manual, or in many general Unix reference books.

If your system does not include a POSIX regular expression library, and you have not linked Guile with a third-party regexp library such as Rx, these functions will not be available. You can tell whether your Guile installation includes regular expression support by checking whether the *features* list includes the regex symbol.

[FIXME: it may be useful to include an Examples section. Parts of this interface are bewildering on first glance.]

16.1 Regexp Functions

By default, Guile supports POSIX extended regular expressions. That means that the characters ‘(’, ‘)’, ‘+’ and ‘?’ are special, and must be escaped if you wish to match the literal characters.

This regular expression interface was modeled after that implemented by SCSH, the Scheme Shell. It is intended to be upwardly compatible with SCSH regular expressions.

procedure string-match pattern str [start] Compile the string pattern into a regular expression and compare it with str. The optional numeric argument start specifies the position of str at which to begin matching. string-match returns a match structure which describes what, if anything, was matched by the regular expression. See ⟨undefined⟩ [Match Structures], page ⟨undefined⟩. If str does not match pattern at all, string-match returns

     #f.

Each time string-match is called, it must compile its pattern argument into a regular expression structure. This operation is expensive, which makes string-match inefficient if the same regular expression is used several times (for example, in a loop). For better performance, you can compile a regular expression in advance and then match strings against the compiled regexp.

primitive make-regexp str [flag …]

Compile the regular expression described by str, and return the compiled regexp structure. If str does not describe a legal regular expression, make-regexp

     throws a regular-expression-syntax error.

The flag arguments change the behavior of the compiled regexp. The following flags may be supplied:

     regexp/icase

Consider uppercase and lowercase letters to be the same when matching.

regexp/newline

If a newline appears in the target string, then permit the ‘^’ and ‘$’ operators to match immediately after or immediately before the newline, respectively. Also, the ‘.’ and ‘[^...]’ operators will never match a newline character. The intent of this flag is to treat the target string as a buffer containing many lines of text, and the regular expression as a pattern that may match a single one of those lines.

regexp/basic

Compile a basic (“obsolete”) regexp instead of the extended (“modern”) regexps that are the default. Basic regexps do not consider ‘|’, ‘+’ or ‘?’ to be special characters, and require the ‘{...}’ and ‘(...)’ metacharacters to be backslash-escaped (see ⟨undefined⟩ [Backslash Escapes], page ⟨undefined⟩). There are several other differences between basic and extended regular expressions, but these are the most significant.

regexp/extended

Compile an extended regular expression rather than a basic regexp. This is the default behavior; this flag will not usually be needed. If a call to make-regexp includes both regexp/basic and regexp/extended flags, the one which comes last will override the earlier one.

primitive regexp-exec regexp str [start] Match the compiled regular expression regexp against str. If the optional integer start argument is provided, begin matching from that position in the string. Return a match structure describing the results of the match, or #f if no match could be found.

primitive regexp? obj

Return #t if obj is a compiled regular expression, or #f otherwise.

Regular expressions are commonly used to find patterns in one string and replace them with the contents of another string.

procedure regexp-substitute port match [item…]

Write to the output port port selected contents of the match structure match. Each item specifies what should be written, and may be one of the following arguments:

• A string. String arguments are written out verbatim.

• An integer. The submatch with that number is written.

• The symbol ‘pre’. The portion of the matched string preceding the regexp match is written.

• The symbol ‘post’. The portion of the matched string following the regexp match is written. port may be #f, in which case nothing is written; instead, regexp-substitute constructs a string from the specified items and returns that.

procedure regexp-substitute/global port regexp target [item…]

Similar to regexp-substitute, but can be used to perform global substitutions on str. Instead of taking a match structure as an argument, regexpsubstitute/global takes two string arguments: a regexp string describing a regular expression, and a target string which should be matched against this regular expression. Each item behaves as in regexp-substitute, with the following exceptions:

• A function may be supplied. When this function is called, it will be passed one argument: a match structure for a given regular expression match. It should return a string to be written out to port.

• The ‘post’ symbol causes regexp-substitute/global to recurse on the unmatched portion of str. This must be supplied in order to perform global search-and-replace on str; if it is not present among the items, then regexp-substitute/global will return after processing a single match.

16.2 Match Structures

A match structure is the object returned by string-match and regexp-exec. It describes which portion of a string, if any, matched the given regular expression. Match structures include: a reference to the string that was checked for matches; the starting and ending positions of the regexp match; and, if the regexp included any parenthesized subexpressions, the starting and ending positions of each submatch.

In each of the regexp match functions described below, the match argument must be a match structure returned by a previous call to string-match or regexp-exec. Most of these functions return some information about the original target string that was matched against a regular expression; we will call that string target for easy reference.

procedure regexp-match? obj

Return #t if obj is a match structure returned by a previous call to regexpexec, or #f otherwise.

procedure match:substring match [n]

Return the portion of target matched by subexpression number n. Submatch 0 (the default) represents the entire regexp match. If the regular expression as a whole matched, but the subexpression number n did not match, return #f.

procedure match:start match [n]

Return the starting position of submatch number n.

procedure match:end match [n]

Return the ending position of submatch number n.

procedure match:prefix match

Return the unmatched portion of target preceding the regexp match.

procedure match:suffix match

Return the unmatched portion of target following the regexp match.

procedure match:count match

Return the number of parenthesized subexpressions from match. Note that the entire regular expression match itself counts as a subexpression, and failed submatches are included in the count.

procedure match:string match

Return the original target string.

16.3 Backslash Escapes

Sometimes you will want a regexp to match characters like ‘*’ or ‘$’ exactly. For example, to check whether a particular string represents a menu entry from an Info node, it would be useful to match it against a regexp like ‘^* [^:]*::’. However, this won’t work; because the asterisk is a metacharacter, it won’t match the ‘*’ at the beginning of the string. In this case, we want to make the first asterisk un-magic.

You can do this by preceding the metacharacter with a backslash character ‘\’. (This is also called quoting the metacharacter, and is known as a backslash escape.) When Guile sees a backslash in a regular expression, it considers the following glyph to be an ordinary character, no matter what special meaning it would ordinarily have. Therefore, we can make the above example work by changing the regexp to ‘^\* [^:]*::’. The ‘\*’ sequence tells the regular expression engine to match only a single asterisk in the target string.

Since the backslash is itself a metacharacter, you may force a regexp to match a backslash in the target string by preceding the backslash with itself. For example, to find variable references in a TEX program, you might want to find occurrences of the string ‘\let\’ followed by any number of alphabetic characters. The regular expression ‘\\let\\[A-Za-z]*’ would do this: the double backslashes in the regexp each match a single backslash in the target string.

procedure regexp-quote str

Quote each special character found in str with a backslash, and return the resulting string.

Very important: Using backslash escapes in Guile source code (as in Emacs Lisp or C) can be tricky, because the backslash character has special meaning for the Guile reader. For example, if Guile encounters the character sequence ‘\n’ in the middle of a string while processing Scheme code, it replaces those characters with a newline character. Similarly, the character sequence ‘\t’ is replaced by a horizontal tab. Several of these escape sequences are processed by the Guile reader before your code is executed. Unrecognized escape sequences are ignored: if the characters ‘\*’ appear in a string, they will be translated to the single character ‘*’.

This translation is obviously undesirable for regular expressions, since we want to be able to include backslashes in a string in order to escape regexp metacharacters. Therefore, to make sure that a backslash is preserved in a string in your Guile program, you must use two consecutive backslashes:

     (define Info-menu-entry-pattern (make-regexp "^\\* [^:]*"))

The string in this example is preprocessed by the Guile reader before any code is executed. The resulting argument to make-regexp is the string ‘^\* [^:]*’, which is what we really want.

This also means that in order to write a regular expression that matches a single backslash character, the regular expression string in the source code must include four backslashes. Each consecutive pair of backslashes gets translated by the Guile reader to a single backslash, and the resulting double-backslash is interpreted by the regexp engine as matching a single backslash character. Hence:

     (define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*"))

The reason for the unwieldiness of this syntax is historical. Both regular expression pattern matchers and Unix string processing systems have traditionally used backslashes with the special meanings described above. The POSIX regular expression specification and ANSI C standard both require these semantics. Attempting to abandon either convention would cause other kinds of compatibility problems, possibly more severe ones. Therefore, without extending the Scheme reader to support strings with different quoting conventions (an ungainly and confusing extension when implemented in other languages), we must adhere to this cumbersome escape syntax.

16.4 Rx Interface

[FIXME: this is taken from Gary and Mark’s quick summaries and should be reviewed and expanded. Rx is pretty stable, so could already be done!]

Guile includes an interface to Tom Lord’s Rx library (currently only to POSIX regular expressions). Use of the library requires a two step process: compile a regular expression into an efficient structure, then use the structure in any number of string comparisons.

For example, given the regular expression ‘abc.’ (which matches any string containing ‘abc’ followed by any single character):

     guile> (define r (regcomp "abc."))
     guile> r
     #<rgx abc.>
     guile> (regexec r "abc")
     #f
     guile> (regexec r "abcd")
     #((0 . 4))
     guile>

The definitions of regcomp and regexec are as follows:

primitive regcomp pattern [flags] Compile the regular expression pattern using POSIX rules. Flags is optional and should be specified using symbolic names:

Variable REG EXTENDED

use extended POSIX syntax

Variable REG ICASE

use case-insensitive matching

Variable REG NEWLINE

allow anchors to match after newline characters in the string and prevents . or [^...] from matching newlines.

The logior procedure can be used to combine multiple flags. The default is to use POSIX basic syntax, which makes + and ? literals and \+ and \? operators. Backslashes in pattern must be escaped if specified in a literal string

e.g., "\\(a\\)\\?".

primitive regexec regex string [match-pick] [flags] Match string against the compiled POSIX regular expression regex. match-pick and flags are optional. Possible flags (which can be combined using the logior procedure) are:

Variable REG NOTBOL

The beginning of line operator won’t match the beginning of string (presumably because it’s not the beginning of a line)

Variable REG NOTEOL

Similar to REG NOTBOL, but prevents the end of line operator from matching the end of string.

If no match is possible, regexec returns #f. Otherwise match-pick determines the return value: #t or unspecified: a newly-allocated vector is returned, containing pairs with the indices of the matched part of string and any substrings. "": a list is returned: the first element contains a nested list with the matched part of string surrounded by the the unmatched parts. Remaining elements are matched substrings (if any). All returned substrings share memory with string. #f: regexec returns #t if a match is made, otherwise #f. vector: the supplied vector is returned, with the first element replaced by a pair containing the indices of the matched portion of string and further elements replaced by pairs containing the indices of matched substrings (if any). list: a list will be returned, with each member of the list specified by a code in the corresponding position of the supplied list: a number: the numbered matching substring (0 for the entire match). #\<: the beginning of string to the beginning of the part matched by regex. #\>: the end of the matched part of string to the end of string. #\c: the "final tag", which seems to be associated with the "cut operator", which doesn’t seem to be available through the posix interface. e.g., (list #\< 0 1 #\>). The returned substrings share memory with string.

Here are some other procedures that might be used when using regular expressions:

primitive compiled-regexp? obj

Test whether obj is a compiled regular expression.

primitive regexp->dfa regex [flags] primitive dfa-fork dfa primitive reset-dfa! dfa primitive dfa-final-tag dfa primitive dfa-continuable? dfa primitive advance-dfa! dfa string

17 Keywords

[FIXME: need some initial schmooze about keywords; this is all taken from the NEWS file, and is accurate but not very useful to someone who has not used keywords before.]

Guile supports a new R4RS–compliant syntax for keywords. A token of the form #:NAME, where NAME has the same syntax as a Scheme symbol, is the external representation of the keyword named NAME. Keyword objects print using this syntax as well, so values containing keyword objects can be read back into Guile. When used in an expression, keywords are self-quoting objects.

Guile suports this read syntax, and uses this print syntax, regardless of the current setting of the ‘keyword’ read option. The ‘keyword’ read option only controls whether Guile recognizes the ‘:NAME’ syntax, which is incompatible with R4RS. (R4RS says such token represent symbols.)

The default behaviour is the R4RS–compliant one (#:xxx instead of :xxx).

To change between the two keyword syntaxes you use the read-options procedure documented in ⟨undefined⟩ [General option interface], page ⟨undefined⟩ and ⟨undefined⟩ [Reader options], page ⟨undefined⟩.

To use the :xxx keyword syntax, use

     (read-set! keywords 'prefix)

To make keyword syntax R4RS compliant, with the #:xxx syntax, use:

     (read-set! keywords #f)

[FIXME: in state of flux right now; here are the Scheme primitives defined in ‘kw.c’:]

primitive keyword? kw

keyword? returns #t if the argument kw is a keyword; it returns #f otherwise.

primitive keyword-dash-symbol arg

keyword-dash-symbol [FIXME: have no idea what this does; it is not commented.]

18 Exceptions

primitive catch key thunk handler Invoke thunk in the dynamic context of handler for exceptions matching key. If thunk throws to the symbol key, then handler is invoked this way:

     (handler key args ...)

key is a symbol or #t. thunk takes no arguments. If thunk returns normally, that is the return value

of catch.

Handler is invoked outside the scope of its own catch. If handler again throws to the same key, a new handler from further up the call chain is invoked. If the key is #t, then a throw to any symbol will match this call to catch.

primitive throw key &rest args ...

Invoke the catch form matching key, passing args to the handler. key is a symbol. It will match catches of the same symbol or of #t. If there is no handler at all, an error is signaled.

procedure error msg args … Raise an error with key misc-error and a message constructed by displaying msg and writing args.

primitive scm-error key subr message args data Raise an error with key key. subr can be a string naming the procedure associated with the error, or #f. message is the error message string, possibly containing %S and %s escapes. When an error is reported, these are replaced by formating the corresponding members of args: %s formats using display and %S formats using write. data is a list or #f depending on key: if key is system-error then it should be a list containing the Unix errno value; If key is signal then it should be a list containing the Unix signal number; otherwise it will usually be #f.

primitive strerror errno

Returns the Unix error message corresponding to errno, an integer.

syntax false-if-exception expr

Returns the result of evaluating its argument; however if an exception occurs then #f is returned instead.

It is traditional in Scheme to implement exception systems using call-with-current-continuation, but his has not been done, for performance reasons. The implementation of call-with-current-continuation is a stack copying implementation. This allows it to interact well with ordinary C code. Unfortunately, a stack-copying implementation can be slow – creating a new continuation involves a block copy of the stack.

Instead of using call-with-current-continuation, the exception primitives are implemented as built-ins that take advantage of the upward only nature of exceptions.

19 Modules

[FIXME: somewhat babbling; should be reviewed by someone who understands modules, once the new module system is in place]

When programs become large, naming conflicts can occur when a function or global variable defined in one file has the same name as a function or global variable in another file. Even just a similarity between function names can cause hard-to-find bugs, since a programmer might type the wrong function name.

The approach used to tackle this problem is called information encapsulation, which consists of packaging functional units into a given name space that is clearly separated from other name spaces.

The language features that allow this are usually called the module system because programs are broken up into modules that are compiled separately (or loaded separately in an interpreter).

Older languages, like C, have limited support for name space manipulation and protection. In C a variable or function is public by default, and can be made local to a module with the static keyword. But you cannot reference public variables and functions from another module with different names.

More advanced module systems have become a common feature in recently designed languages: ML, Python, Perl, and Modula 3 all allow the renaming of objects from a foreign module, so they will not clutter the global name space.

19.1 Scheme and modules

Scheme, as defined in R4RS, does not have a module system at all.

Aubrey Jaffer, mostly to support his portable Scheme library SLIB, implemented a provide/require mechanism for many Scheme implementations. Library files in SLIB provide a feature, and when user programs require that feature, the library file is loaded in.

For example, the file ‘random.scm’ in the SLIB package contains the line

     (provide 'random)

so to use its procedures, a user would type

     (require 'random)

and they would magically become available, but still have the same names! So this method is nice, but not as good as a full-featured module system.

19.2 The Guile module system

In 1996 Tom Lord implemented a full-featured module system for Guile which allows loading Scheme source files into a private name space.

This module system is regarded as being rather idiosyncratic, and will probably change to something more like the ML module system, so for now I will simply descrive how it works for a couple of simple cases.

First of all, the Guile module system sets up a hierarchical name space, and that name space can be represented like Unix pathnames preceded by a ^{⟨}\underline{\overline{#}}^{⟩} character. The root name space for all Guile-supplied modules is called ice-9.

So for example, the SLIB interface, contained in ‘$srcdir/ice-9/slib.scm’, starts out with

     (define-module (ice-9 slib))

and a user program can use

     (use-modules (ice-9 slib))

to have access to all procedures and variables defined within the slib module with

(define-public ...).

So here are the functions involved:

syntax define-module module-specification

module-specification is of the form (hierarchy file). One example of this is

          (use-modules (ice-9 slib))

define-module makes this module available to Guile programs under the given module-specification.

syntax define-public …

Makes a procedure or variable available to programs that use the current module.

syntax use-modules module-specification

module-specification is of the form (hierarchy file). One example of this is

          (use-modules (ice-9 slib))

use-modules allows the current Guile program to use all publicly defined procedures and variables in the module denoted by module-specification.

[FIXME: must say more, and explain, and also demonstrate a private name space use, and demonstrate how one would do Python’s "from Tkinter import *" versus "import Tkinter". Must also add something about paths and standards for contributed modules.]

Some modules are included in the Guile distribution; here are references to the entries in this manual which describe them in more detail:

boot-9 boot-9 is Guile’s initialization module, and it is always loaded when Guile starts up.

(ice-9 debug)

Mikael Djurfeldt’s source-level debugging support for Guile (see ⟨undefined⟩ [debugger user interface], page ⟨undefined⟩).

(ice-9 threads)

Guile’s support for multi threaded execution (see ⟨undefined⟩ [Threads and Dynamic Roots], page ⟨undefined⟩).

(ice-9 slib)

This module contains hooks for using Aubrey Jaffer’s portable Scheme library SLIB from Guile (see ⟨undefined⟩ [SLIB], page ⟨undefined⟩).

(ice-9 jacal)

This module contains hooks for using Aubrey Jaffer’s symbolic math packge Jacal from Guile (see ⟨undefined⟩ [JACAL], page ⟨undefined⟩).

20 Module Internals

20.1 First-class Variables

20.2 First-class Modules

20.3 Dynamic Libraries

Often you will want to extend Guile by linking it with some existing system library. For example, linking Guile with a curses or termcap library would be useful if you want to implement a full-screen user interface for a Guile application. However, if you were to link Guile with these libraries at compile time, it would bloat the interpreter considerably, affecting everyone on the system even if the new libraries are useful only to you. Also, every time a new library is installed, you would have to reconfigure, recompile and relink Guile merely in order to provide a new interface.

Many Unix systems permit you to get around this problem by using dynamic loading. When a new library is linked, it can be made a dynamic library by passing certain switches to the linker. A dynamic library does not need to be linked with an executable image at link time; instead, the executable may choose to load it dynamically at run time. This is a powerful concept that permits an executable to link itself with almost any library without reconfiguration, if it has been written properly.

Guile’s dynamic linking functions make it relatively easy to write a module that incorporates code from third-party object code libraries.

primitive dynamic-link library-file

Open the dynamic library library-file. A library handle representing the opened library is returned; this handle should be used as the lib argument to the following functions.

primitive dynamic-object? obj

Return #t if obj is a dynamic library handle, or #f otherwise.

primitive dynamic-unlink lib

Unlink the library represented by library-handle, and remove any imported symbols from the address space.

primitive dynamic-func func lib

Import the symbol func from lib (a dynamic library handle). A function handle representing the imported function is returned.

primitive dynamic-call lib-thunk lib

Call lib-thunk, a procedure of no arguments. If lib-thunk is a string, it is assumed to be a symbol found in the dynamic library lib and is fetched with dynamic-func. Otherwise, it should be a function handle returned by a previous call to dynamic-func. The return value is unspecified.

primitive dynamic-args-call proc lib args

Call proc, a dynamically loaded function, passing it the argument list args (a list of strings). As with dynamic-call, proc should be either a function handle or a string, in which case it is first fetched from lib with dynamic-func. proc is assumed to return an integer, which is used as the return value from

dynamic-args-call.

primitive c-registered-modules

Return a list of the object code modules that have been imported into the current Guile process. Each element of the list is a pair whose car is the name of the module (as it might be used by use-modules, for instance), and whose cdr is the function handle for that module’s initializer function.

primitive c-clear-registered-modules

Destroy the list of modules registered with the current Guile process. The return value is unspecified. Warning: this function does not actually unlink or deallocate these modules, but only destroys the records of which modules have been loaded. It should therefore be used only by module bookkeeping operations.

[FIXME: provide a brief example here of writing the C hooks for an object code module, and using dynamic-link and dynamic-call to load the module.]

21 Dynamic Linking from Marius

Most modern Unices have something called shared libraries. This ordinarily means that they have the capability to share the executable image of a library between several running programs to save memory and disk space. But generally, shared libraries give a lot of additional flexibility compared to the traditional static libraries. In fact, calling them ‘dynamic’ libraries is as correct as calling them ‘shared’.

Shared libraries really give you a lot of flexibility in addition to the memory and disk space savings. When you link a program against a shared library, that library is not closely incorporated into the final executable. Instead, the executable of your program only contains enough information to find the needed shared libraries when the program is actually run. Only then, when the program is starting, is the final step of the linking process performed. This means that you need not recompile all programs when you install a new, only slightly modified version of a shared library. The programs will pick up the changes automatically the next time they are run.

Now, when all the necessary machinery is there to perform part of the linking at runtime, why not take the next step and allow the programmer to explicitly take advantage of it from within his program? Of course, many operating systems that support shared libraries do just that, and chances are that Guile will allow you to access this feature from within your Scheme programs. As you might have guessed already, this feature is called dynamic linking^{1}

As with many aspects of Guile, there is a low-level way to access the dynamic linking apparatus, and a more high-level interface that integrates dynamically linked libraries into the module system.

21.1 Low level dynamic linking

When using the low level procedures to do your dynamic linking, you have complete control over which library is loaded when and what get’s done with it.

primitive dynamic-link library

Find the shared library denoted by library (a string) and link it into the running Guile application. When everything works out, return a Scheme object suitable for representing the linked object file. Otherwise an error is thrown. How object files are searched is system dependent. Normally, library is just the name of some shared library file that will be searched for in the places where shared libraries usually reside, such as in

     ‘/usr/lib’ and ‘/usr/local/lib’.

primitive dynamic-object? val

Determine whether val represents a dynamically linked object file.

1 Some people also refer to the final linking stage at program startup as ‘dynamic linking’, so if you want to make yourself perfectly clear, it is probably best to use the more technical term dlopening, as suggested by Gordon Matzigkeit in his libtool documentation.

primitive dynamic-unlink dynobj

Unlink the indicated object file from the application. The argument dynobj should be one of the values returned by dynamic-link. When dynamic-unlink has been called on dynobj, it is no longer usable as an argument to the functions below and you will get type mismatch errors when you try to.

primitive dynamic-func function dynobj Search the C function indicated by function (a string or symbol) in dynobj and return some Scheme object that can later be used with dynamic-call to actually call this function. Right now, these Scheme objects are formed by casting the address of the function to long and converting this number to its Scheme representation. Regardless whether your C compiler prepends an underscore ‘_’ to the global names in a program, you should not include this underscore in function. Guile knows whether the underscore is needed or not and will add it when necessary.

primitive dynamic-call function dynobj Call the C function indicated by function and dynobj. The function is passed no arguments and its return value is ignored. When function is something returned by dynamic-func, call that function and ignore dynobj. When function is a string (or symbol, etc.), look it up in dynobj; this is equivalent to

     (dynamic-call (dynamic-func function dynobj #f))

Interrupts are deferred while the C function is executing (with SCM_DEFER_

INTS/SCM_ALLOW_INTS).

primitive dynamic-args-call function dynobj args Call the C function indicated by function and dynobj, just like dynamic-call, but pass it some arguments and return its return value. The C function is expected to take two arguments and return an int, just like main:

     int c_func (int argc, char **argv);

The parameter args must be a list of strings and is converted into an array of char *. The array is passed in argv and its size in argc. The return value is converted to a Scheme number and returned from the call to dynamic-args-

call.

When dynamic linking is disabled or not supported on your system, the above functions throw errors, but they are still available.

Here is a small example that works on GNU/Linux:

(define libc-obj (dynamic-link "libc.so"))
libc-obj
⇒ #<dynamic-object "libc.so">
(dynamic-args-call 'rand libc-obj '())
⇒ 269167349
(dynamic-unlink libc-obj)
libc-obj
⇒ #<dynamic-object "libc.so" (unlinked)>

As you can see, after calling dynamic-unlink on a dynamically linked library, it is marked as ‘(unlinked)’ and you are no longer able to use it with dynamic-call, etc. Whether the library is really removed from you program is system-dependent and will generally not happen when some other parts of your program still use it. In the example above, libc is almost certainly not removed from your program because it is badly needed by almost everything.

The functions to call a function from a dynamically linked library, dynamic-call and dynamic-args-call, are not very powerful. They are mostly intended to be used for calling specially written initialization functions that will then add new primitives to Guile. For example, we do not expect that you will dynamically link ‘libX11’ with dynamic-link and then construct a beautiful graphical user interface just by using dynamic-call and dynamic-args-call. Instead, the usual way would be to write a special Guile<->X11 glue library that has intimate knowledge about both Guile and X11 and does whatever is necessary to make them inter-operate smoothly. This glue library could then be dynamically linked into a vanilla Guile interpreter and activated by calling its initialization function. That function would add all the new types and primitives to the Guile interpreter that it has to offer.

>From this setup the next logical step is to integrate these glue libraries into the module system of Guile so that you can load new primitives into a running system just as you can load new Scheme code.

There is, however, another possibility to get a more thorough access to the functions contained in a dynamically linked library. Anthony Green has written ‘libffi’, a library that implements a foreign function interface for a number of different platforms. With it, you can extend the Spartan functionality of dynamic-call and dynamic-args-call considerably. There is glue code available in the Guile contrib archive to make ‘libffi’ accessible from Guile.

21.2 Putting Compiled Code into Modules

The new primitives that you add to Guile with gh_new_procedure or with any of the other mechanisms are normally placed into the same module as all the other builtin procedures (like display). However, it is also possible to put new primitives into their own module.

The mechanism for doing so is not very well thought out and is likely to change when the module system of Guile itself is revised, but it is simple and useful enough to document it as it stands.

What gh_new_procedure and the functions used by the snarfer really do is to add the new primitives to whatever module is the current module when they are called. This is analogous to the way Scheme code is put into modules: the define-module expression at the top of a Scheme source file creates a new module and makes it the current module while the rest of the file is evaluated. The define expressions in that file then add their new definitions to this current module.

Therefore, all we need to do is to make sure that the right module is current when calling gh_new_procedure for our new primitives. Unfortunately, there is not yet an easy way to access the module system from C, so we are better off with a more indirect approach.

Instead of adding our primitives at initialization time we merely register with Guile that we are ready to provide the contents of a certain module, should it ever be needed.

Function void scm register module xxx (char *name, void

(*initfunc)(void)) Register with Guile that initfunc will provide the contents of the module name. The function initfunc should perform the usual initialization actions for your new primitives, like calling gh_new_procedure or including the file produced by the snarfer. When initfunc is called, the current module is a newly created module with a name as indicated by name. Each definition that is added to it will be automatically exported. The string name indicates the hierachical name of the new module. It should consist of the individual components of the module name separated by single spaces. That is, the Scheme module name (foo bar), which is a list, should be written as "foo bar" for the name parameter. You can call scm_register_module_xxx at any time, even before Guile has been initialized. This might be useful when you want to put the call to it in some initialization code that is magically called before main, like constructors for global C++ objects. An example for scm_register_module_xxx appears in the next section.

Now, instead of calling the initialization function at program startup, you should simply call scm_register_module_xxx and pass it the initialization function. When the named module is later requested by Scheme code with use-modules for example, Guile will notice that it knows how to create this module and will call the initialization function at the right time in the right context.

21.3 Dynamic Linking and Compiled Code Modules

The most interesting application of dynamically linked libraries is probably to use them for providing compiled code modules to Scheme programs. As much fun as programming in Scheme is, every now and then comes the need to write some low-level C stuff to make Scheme even more fun.

Not only can you put these new primitives into their own module (see the previous section), you can even put them into a shared library that is only then linked to your running Guile image when it is actually needed.

An example will hopefully make everything clear. Suppose we want to make the Bessel functions of the C library available to Scheme in the module ‘(math bessel)’. First we need to write the appropriate glue code to convert the arguments and return values of the functions from Scheme to C and back. Additionally, we need a function that will add them to the set of Guile primitives. Because this is just an example, we will only implement this for the j0 function, tho.

     #include <math.h>
     #include <guile/gh.h>

     SCM
     j0_wrapper (SCM x)
     {
       return gh_double2scm (j0 (gh_scm2double (x)));
     }
     void
     init_math_bessel ()
     {
       gh_new_procedure1_0 ("j0", j0_wrapper);
     }

We can already try to bring this into action by manually calling the low level functions for performing dynamic linking. The C source file needs to be compiled into a shared library. Here is how to do it on GNU/Linux, please refer to the libtool documentation for how to create dynamically linkable libraries portably.

     gcc -shared -o libbessel.so -fPIC bessel.c

Now fire up Guile:

     (define bessel-lib (dynamic-link "./libbessel.so"))
     (dynamic-call "init_math_bessel" bessel-lib)
     (j0 2)
     ⇒ 0.223890779141236

The filename ‘./libbessel.so’ should be pointing to the shared library produced with the gcc command above, of course. The second line of the Guile interaction will call the init_math_bessel function which in turn will register the C function j0_wrapper with the Guile interpreter under the name j0. This function becomes immediately available and we can call it from Scheme.

Fun, isn’t it? But we are only half way there. This is what apropos has to say about

j0:
     (apropos 'j0)
     ⊣ the-root-module: j0     #<primitive-procedure j0>

As you can see, j0 is contained in the root module, where all the other Guile primitives like display, etc live. In general, a primitive is put into whatever module is the current module at the time gh_new_procedure is called. To put j0 into its own module named ‘(math bessel)’, we need to make a call to scm_register_module_xxx. Additionally, to have Guile perform the dynamic linking automatically, we need to put ‘libbessel.so’ into a place where Guile can find it. The call to scm_register_module_xxx should be contained in a specially named module init function. Guile knows about this special name and will call that function automatically after having linked in the shared library. For our example, we add the following code to ‘bessel.c’:

     void scm_init_math_bessel_module ()
     {
       scm_register_module_xxx ("math bessel", init_math_bessel);
     }

The general pattern for the name of a module init function is: ‘scm_init_’, followed by the name of the module where the individual hierarchical components are concatenated with underscores, followed by ‘_module’. It should call scm_register_module_xxx with the correct module name and the appropriate initialization function. When that initialization function will be called, a newly created module with the right name will be the current module so that all definitions that the initialization functions makes will end up in the correct module.

After ‘libbessel.so’ has been rebuild, we need to place the shared library into the right place. When Guile tries to autoload the ‘(math bessel)’ module, it looks not only for a

file called ‘math/bessel.scm’ in its %load-path, but also for ‘math/libbessel.so’. So all

we need to do is to create a directory called ‘math’ somewhere in Guile’s %load-path and place ‘libbessel.so’ there. Normally, the current directory ‘.’ is in the %load-path, so we just use that for this example.

     % mkdir maths
     % cd maths
     % ln -s ../libbessel.so .
     % cd ..
     % guile
     guile> (use-modules (math bessel))
     guile> (j0 2)
     0.223890779141236
     guile> (apropos 'j0)
     ⊣ bessel: j0      #<primitive-procedure j0>

That’s it!

Note that we used a symlink to make ‘libbessel.so’ appear in the right spot. This is probably not a bad idea in general. The directories that the ‘%load-path’ normally contains are supposed to contain only architecture independent files. They are not really the right place for a shared library. You might want to install the libraries somewhere below ‘exec_prefix’ and then symlink to them from the architecture independent directory. This will at least work on heterogenous systems where the architecture dependent stuff resides in the same place on all machines (which seems like a good idea to me anyway).

22 Dynamic Wind

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed]

primitive dynamic-wind in-guard thunk out-guard All three arguments must be 0-argument procedures. in-guard is called, then thunk, then out-guard. If, any time during the execution of thunk, the continuation of the dynamicwind expression is escaped non-locally, out-guard is called. If the continuation of the dynamic-wind is re-entered, in-guard is called. Thus in-guard and outguard may be called any number of times.

(define x 'normal-binding)
⇒ x
(define a-cont  (call-with-current-continuation
  (lambda (escape)
     (let ((old-x x))
       (dynamic-wind
  ;; in-guard:
  ;;
  (lambda () (set! x 'special-binding))
  ;; thunk
  ;;
    (lambda () (display x) (newline)
     (call-with-current-continuation escape)
     (display x) (newline)
     x)
  ;; out-guard:
  ;;
  (lambda () (set! x old-x)))))))
;; Prints:
special-binding
;; Evaluates to:
⇒ a-cont
x
⇒ normal-binding
(a-cont #f)
;; Prints:
special-binding
;; Evaluates to:
⇒ a-cont  ;; the value of the (define a-cont...)

Chapter 22: Dynamic Wind 77

⇒ normal-binding
a-cont
⇒ special-binding

23 Threads and Dynamic Roots

[FIXME: This is pasted in from Tom Lord’s original guile.texi chapter plus the Cygnus programmer’s manual; it should be *very* carefully reviewed and largely reorganized.]

23.1 Dynamic Roots

A dynamic root is a root frame of Scheme evaluation. The top-level repl, for example, is an instance of a dynamic root.

Each dynamic root has its own chain of dynamic-wind information. Each has its own set of continuations, jump-buffers, and pending CATCH statements which are inaccessible from the dynamic scope of any other dynamic root.

In a thread-based system, each thread has its own dynamic root. Therefore, continuations created by one thread may not be invoked by another.

Even in a single-threaded system, it is sometimes useful to create a new dynamic root. For example, if you want to apply a procedure, but to not allow that procedure to capture the current continuation, calling the procedure under a new dynamic root will do the job.

primitive call-with-dynamic-root thunk handler

Evaluate (thunk) in a new dynamic context, returning its value. If an error occurs during evaluation, apply handler to the arguments to the throw, just as throw would. If this happens, handler is called outside the scope of the new root – it is called in the same dynamic context in which call-with-dynamic-root was evaluated. If thunk captures a continuation, the continuation is rooted at the call to thunk. In particular, the call to call-with-dynamic-root is not captured. Therefore, call-with-dynamic-root always returns at most one time. Before calling thunk, the dynamic-wind chain is un-wound back to the root and a new chain started for thunk. Therefore, this call may not do what you expect:

     ;; Almost certainly a bug:
     (with-output-to-port
      some-port
      (lambda ()
        (call-with-dynamic-root
         (lambda ()
           (display 'fnord)
           (newline))
         (lambda (errcode) errcode))))

The problem is, on what port will ‘fnord\n’ be displayed? You might expect that because of the with-output-to-port that it will be displayed on the port bound to some-port. But it probably won’t – before evaluating the thunk, dynamic winds are unwound, including those created by with-output-to-port. So, the standard output port will have been re-set to its default value before display is evaluated.

(This function was added to Guile mostly to help calls to functions in C libraries that can not tolerate non-local exits or calls that return multiple times. If such functions call back to the interpreter, it should be under a new dynamic root.)

primitive dynamic-root

Return an object representing the current dynamic root. These objects are only useful for comparison using eq?. They are currently represented as numbers, but your code should in no way depend on this.

procedure quit [exit val] Throw back to the error handler of the current dynamic root. If integer exit val is specified and if Guile is being used stand-alone and if quit is called from the initial dynamic-root, exit val becomes the exit status of the Guile process and the process exits.

When Guile is run interactively, errors are caught from within the read-eval-print loop. An error message will be printed and abort called. A default set of signal handlers is installed, e.g., to allow user interrupt of the interpreter.

It is possible to switch to a "batch mode", in which the interpreter will terminate after an error and in which all signals cause their default actions. Switching to batch mode causes any handlers installed from Scheme code to be removed. An example of where this is useful is after forking a new process intended to run non-interactively.

procedure batch-mode?

Returns a boolean indicating whether the interpreter is in batch mode.

procedure set-batch-mode?! arg

If arg is true, switches the interpreter to batch mode. The #f case has not been implemented.

23.2 Threads

[NOTE: this chapter was written for Cygnus Guile and has not yet been updated for the Guile 1.x release.]

Here is a the reference for Guile’s threads. In this chapter I simply quote verbatim Tom Lord’s description of the low-level primitives written in C (basically an interface to the POSIX threads library) and Anthony Green’s description of the higher-level thread procedures written in scheme.

When using Guile threads, keep in mind that each guile thread is executed in a new dynamic root.

23.2.1 Low level thread primitives

primitive call-with-new-thread thunk error-thunk

Evaluate (thunk) in a new thread, and new dynamic context, returning a new thread object representing the thread.

If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition. [Error codes are currently meaningless integers. In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root – it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread. All the evaluation rules for dynamic roots apply to threads.

primitive join-thread thread

Suspend execution of the calling thread until the target thread terminates, unless the target thread has already terminated.

primitive yield

If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect.

primitive make-mutex

Create a new mutex object.

primitive lock-mutex mutex

Lock mutex. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on mutex.

primitive unlock-mutex mutex

Unlocks mutex if the calling thread owns the lock on mutex. Calling unlockmutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on mutex is awakened and grabs the mutex lock.

23.2.2 Higher level thread procedures

primitive call-with-new-thread thunk error-thunk

Evaluate (thunk) in a new thread, and new dynamic context, returning a new thread object representing the thread. If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition. [Error codes are currently meaningless integers. In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root – it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread. All the evaluation rules for dynamic roots apply to threads.

primitive join-thread thread

Suspend execution of the calling thread until the target thread terminates, unless the target thread has already terminated.

primitive yield

If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect.

primitive make-mutex

Create a new mutex object.

primitive lock-mutex mutex

Lock mutex. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on mutex.

primitive unlock-mutex mutex

Unlocks mutex if the calling thread owns the lock on mutex. Calling unlockmutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on mutex is awakened and grabs the mutex lock.

82 Guile Reference Manual

24 Reflection

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed]

24.1 eval 24.2 Tag Values

25 Weak References

[FIXME: This chapter is based on Mikael Djurfeldt’s answer to a question by Michael Livshin. Any mistakes are not theirs, of course. ]

Weak references let you attach bookkeeping information to data so that the additional information automatically disappears when the original data is no longer in use and gets garbage collected. In a weak key hash, the hash entry for that key disappears as soon as the key is no longer referneced from anywhere else. For weak value hashes, the same happens as soon as the value is no longer in use. Entries in a doubly weak hash disappear when either the key or the value are not used anywhere else anymore.

Property lists offer the same kind of functionality as weak key hashes in many situations. (see ⟨undefined⟩ [Property Lists], page ⟨undefined⟩)

Here’s an example (a little bit strained perhaps, but one of the examples is actually used in Guile):

Assume that you’re implementing a debugging system where you want to associate information about filename and position of source code expressions with the expressions themselves.

Hashtables can be used for that, but if you use ordinary hash tables it will be impossible for the scheme interpreter to "forget" old source when, for example, a file is reloaded.

To implement the mapping from source code expressions to positional information it is necessary to use weak-key tables since we don’t want the expressions to be remembered just because they are in our table.

To implement a mapping from source file line numbers to source code expressions you would use a weak-value table.

To implement a mapping from source code expressions to the procedures they constitute a doubly-weak table has to be used.

25.1 Weak key hashes

primitive make-weak-key-hash-table size primitive make-weak-value-hash-table size primitive make-doubly-weak-hash-table size

Return a weak hash table with size buckets. As with any hash table, choosing a good size for the table requires some caution.

You can modify weak hash tables in exactly the same way you would modify regular hash tables. (see ⟨undefined⟩ [Hash Tables], page ⟨undefined⟩)

primitive weak-key-hash-table? obj primitive weak-value-hash-table? obj primitive doubly-weak-hash-table? obj

Return #t if obj is the specified weak hash table. Note that a doubly weak hash table is neither a weak key nor a weak value hash table.

25.2 Weak vectors

Weak vectors are mainly useful in Guile’s implementation of weak hash tables.

primitive make-weak-vector size [fill]

Return a weak vector with size elements. If the optional argument fill is given, all entries in the vector will be set to fill. The default value for fill is the empty list.

primitive weak-vector . rest primitive list->weak-vector l

Construct a weak vector from a list: weak-vector uses the list of its arguments while list->weak-vector uses its only argument l (a list) to construct a weak vector the same way vector->list would.

primitive weak-vector? obj

Return #t if obj is a weak vector. Note that all weak hashes are also weak vectors.

26 Garbage Collection

[FIXME: this is pasted in from Tom Lord’s original guile.texi and should be reviewed]

primitive gc

Scans all of SCM objects and reclaims for further use those that are no longer accessible.

primitive gc-stats

Returns an association list of statistics about Guile’s current use of storage.

primitive object-address obj

Return an integer that for the lifetime of obj is uniquely returned by this function for obj

27 Configuration Data

It is often useful to have site-specific information about the current Guile installation. This chapter describes how to find out about Guile’s configuration at run time.

primitive version primitive major-version primitive minor-version

Return a string describing Guile’s version number, or its major or minor version numbers, respectively.

     (version) ⇒ "1.3a"
     (major-version) ⇒ "1"
     (minor-version) ⇒ "3a"

primitive libguile-config-stamp

Return a string describing the date on which libguile was configured. This is used to determine whether the Guile core interpreter and the ice-9 runtime have grown out of date with one another.

primitive %package-data-dir

Return the name of the directory where Scheme packages, modules and libraries are kept. On most Unix systems, this will be ‘/usr/local/share/guile’.

Variable %load-path

Return the list of directories which should be searched for Scheme modules and libraries.

Chapter 28: Internal Debugging Interface 87

28 Internal Debugging Interface

— The name of this chapter needs to clearly distinguish it from the appendix describing the debugger UI. The intro should have a pointer to the UI appendix.

Part III: Unix Programming

29 POSIX Interface Conventions

The low-level interfaces are designed to give Scheme programs access to as much functionality as possible from the underlying Unix system. They can be used to implement higher level intefaces such as the Scheme shell ⟨undefined⟩ [The Scheme shell (scsh)], page ⟨undefined⟩.

Generally there is a single procedure for each corresponding Unix facility. There are some exceptions, such as procedures implemented for speed and convenience in Scheme with no primitive Unix equivalent, e.g., copy-file.

The interfaces are intended as far as possible to be portable across different versions of Unix, so that Scheme programmers don’t need to be concerned with implementation differences. In some cases procedures which can’t be implemented (or reimplemented) on particular systems may become no-ops, or perform limited actions. In other cases they may throw errors. It should be possible to use the feature system to determine what functionality is available.

General naming conventions are as follows:

• The Scheme name is often identical to the name of the underlying Unix facility.

• Underscores in Unix names are converted to hyphens.

• Procedures which destructively modify Scheme data gain exclaimation marks, e.g.,

    recv!.

• Predicates (returning only #t or #f) have question marks added, e.g., access?.

• Some names are changed to avoid conflict with dissimilar interfaces defined by scsh,

    e.g., primitive-fork.

• Unix preprocessor names such as EPERM or R_OK are converted to Scheme variables of the same name (underscores are not replaced with hyphens).

Most of the procedures can be relied on to return a well-specified value. Unexpected conditions are handled by raising exceptions.

There are a few procedures which return a special value if they don’t succeed, e.g., getenv returns #f if it the requested string is not found in the environment. These cases will be noted in the documentation.

For ways to deal with exceptions, ⟨undefined⟩ [Exceptions], page ⟨undefined⟩.

Errors which the C-library would report by returning a NULL pointer or through some other means are reported by raising a system-error exception. The value of the Unix errno variable is available in the data passed by the exception. Accessing the global errno value directly would be unreliable due to continuations, interrupts or multiple threads.

30 Ports and File Descriptors

Conventions largely follow those of scsh, ⟨undefined⟩ [The Scheme shell (scsh)], page ⟨undefined⟩.

Guile ports are currently based on C stdio streams. Ports can be buffered or unbuffered. Unbuffered ports can be specified by including 0 in a port mode string. Note that some system call interfaces (e.g., recv!) will accept ports as arguments, but will actually operate directly on the file descriptor underlying the port. Any port buffering is ignored, including the one character buffer used to implement peek-char and unread-char.

File descriptors are generally not useful for Scheme programs; however they can be needed when interfacing with foreign code and the Unix environment.

A file descriptor can be extracted from a port and later converted back to a port. However a file descriptor is just an integer, and the garbage collector doesn’t recognise it as a reference to the port. If all other references to the port were dropped, then it’s likely that the garbage collector would free the port, with the side-effect of closing the file descriptor prematurely.

To assist the programmer in avoiding this problem, each port has an associated "revealed count" which can be used to keep track of how many times the underlying file descriptor has been stored in other places. The idea is for the programmer to ensure that the revealed count will be greater than zero if the file descriptor is needed elsewhere.

For the simple case where a file descriptor is "imported" once to become a port, it does not matter if the file descriptor is closed when the port is garbage collected. There is no need to maintain a revealed count. Likewise when "exporting" a file descriptor to the external environment, setting the revealed count is not required if the port is kept open while the file descriptor is in use.

To correspond with traditional Unix behaviour, the three file descriptors (0, 1 and 2) are automatically imported when a program starts up and assigned to the initial values of the current input, output and error ports. The revealed count for each is initially set to one, so that dropping references to one of these ports will not result in its garbage collection: it could be retrieved with fdopen or fdes->ports.

primitive port-revealed port

Returns the revealed count for port.

primitive set-port-revealed! port count

Sets the revealed count for a port to a given value. The return value is unspecified.

primitive fileno port

Returns the integer file descriptor underlying port without changing its revealed count.

procedure port->fdes port

Returns the integer file descriptor underlying port. As a side effect the revealed count of port is incremented. primitive fdopen fdes modes

Returns a new port based on the file descriptor fdes with modes given by the string modes. The revealed count of the port is initialized to zero. The modes string is the same as that accepted by ⟨undefined⟩ [File Ports], page ⟨undefined⟩.

primitive fdes->ports fdes

Returns a list of existing ports which have fdes as an underlying file descriptor, without changing their revealed counts.

procedure fdes->inport fdes

Returns an existing input port which has fdes as its underlying file descriptor, if one exists, and increments its revealed count. Otherwise, returns a new input port with a revealed count of 1.

procedure fdes->outport fdes

Returns an existing output port which has fdes as its underlying file descriptor, if one exists, and increments its revealed count. Otherwise, returns a new output port with a revealed count of 1.

primitive primitive-move->fdes port fdes

Moves the underlying file descriptor for port to the integer value fdes without changing the revealed count of port. Any other ports already using this descriptor will be automatically shifted to new descriptors and their revealed counts reset to zero. The return value is zero if the file descriptor does not need to be moved or one if it does.

procedure move->fdes port fd

Moves the underlying file descriptor for port to the integer value fdes and sets its revealed count to one. Any other ports already using this descriptor will be automatically shifted to new descriptors and their revealed counts reset to zero. The return value is unspecified.

procedure release-port-handle port

Decrements the revealed count for a port.

primitive force-output [port]

Flush the specified output port, or the current output port if port is omitted. The return value is unspecified.

primitive flush-all-ports

Flush all open output ports. The return value is unspecified.

primitive fsync port/fd Copies any unwritten data for the specified output file descriptor to disk. If port/fd is a port, its buffer is flushed before the underlying file descriptor is fsync’d. The return value is unspecified. primitive open path flags [mode]

Open the file named by path for reading and/or writing. flags is an integer specifying how the file should be opened. mode is an integer specifying the permission bits of the file, if it needs to be created, before the umask is applied. The default is 666 (Unix itself has no default). flags can be constructed by combining variables using logior. Basic flags are:

Variable O RDONLY

Open the file read-only.

Variable O WRONLY

Open the file write-only.

Variable O RDWR

Open the file read/write.

Variable O APPEND

Append to the file instead of truncating.

Variable O CREAT

Create the file if it does not already exist.

See the Unix documentation of the open system call for additional flags.

primitive open-fdes path flags [modes] Similar to open but returns a file descriptor instead of a port.

primitive close port/fd Similar to close-port (see ⟨undefined⟩ [Closing Ports], page ⟨undefined⟩), but also works on file descriptors. A side effect of closing a file descriptor is that any ports using that file descriptor are moved to a different file descriptor and have their revealed counts set to zero.

primitive pipe

Creates a pipe which can be used for communication. The return value is a pair in which the CAR contains an input port and the CDR an output port. Data written to the output port can be read from the input port. Note that both ports are buffered so it may be necessary to flush the output port before data will actually be sent across the pipe. Alternatively a new unbuffered output port can be created using duplicate-port with an appropriate mode string.

The next group of procedures perform a dup2 system call, if newfd (an integer) is supplied, otherwise a dup. The file descriptor to be duplicated can be supplied as an integer or contained in a port. The type of value returned varies depending on which procedure is used.

All procedures also have the side effect when performing dup2 that any ports using newfd are moved to a different file descriptor and have their revealed counts set to zero.

primitive dup->fdes port/fd [newfd] Returns an integer file descriptor. procedure dup->inport port/fd [newfd]

Returns a new input port using the new file descriptor.

procedure dup->outport port/fd [newfd] Returns a new output port using the new file descriptor.

procedure dup port/fd [newfd] Returns a new port if port/fd is a port, with the same mode as the supplied port, otherwise returns an integer file descriptor.

procedure dup->port port/fd mode [newfd] Returns a new port using the new file descriptor. mode supplies a mode string for the port (see ⟨undefined⟩ [File Ports], page ⟨undefined⟩).

procedure duplicate-port port modes

Returns a new port which is opened on a duplicate of the file descriptor underlying port, with mode string modes as for ⟨undefined⟩ [File Ports], page ⟨undefined⟩. The two ports will share a file position and file status flags. Unexpected behaviour can result if both ports are subsequently used and the original and/or duplicate ports are buffered. The mode string can include 0 to obtain an unbuffered duplicate port. This procedure is equivalent to (dup->port port modes).

primitive redirect-port old-port new-port This procedure takes two ports and duplicates the underlying file descriptor from old-port into new-port. The current file descriptor in new-port will be closed. After the redirection the two ports will share a file position and file status flags. The return value is unspecified. Unexpected behaviour can result if both ports are subsequently used and the original and/or duplicate ports are buffered. This procedure does not have any side effects on other ports or revealed counts.

primitive port-mode port

Returns the port modes associated with the open port port. These will not necessarily be identical to the modes used when the port was opened, since modes such as "append" which are used only during port creation are not retained.

primitive close-all-ports-except port …

Close all open file ports used by the interpreter except for those supplied as arguments. This procedure is intended to be used before an exec call to close file descriptors which are not needed in the new process.

primitive setvbuf port mode [size] Set the buffering mode for port. mode can be:

_IONBF non-buffered _IOLBF line buffered

_IOFBF block buffered, using a newly allocated buffer of size bytes. However if size is zero or unspecified, the port will be made non-buffered.

This procedure should not be used after I/O has been performed with the port. Ports are usually block buffered by default, with a default buffer size. Procedures e.g., ⟨undefined⟩ [File Ports], page ⟨undefined⟩, which accept a mode string allow 0 to be added to request an unbuffered port.

primitive freopen filename modes port Reopen port on the specified filename with mode string modes as for ⟨undefined⟩ [File Ports], page ⟨undefined⟩.

primitive fcntl fd/port command [value] Apply command to the specified file descriptor or the underlying file descriptor of the specified port. value is an optional integer argument. Values for command are:

F_DUPFD Duplicate a file descriptor

F_GETFD Get flags associated with the file descriptor.

F_SETFD Set flags associated with the file descriptor to value.

F_GETFL Get flags associated with the open file.

F_SETFL Set flags associated with the open file to value

F_GETOWN Get the process ID of a socket’s owner, for SIGIO signals.

F_SETOWN Set the process that owns a socket to value, for SIGIO signals.

FD_CLOEXEC

The value used to indicate the "close on exec" flag with F_GETFL

          or F_SETFL.

primitive select reads writes excepts [secs] [usecs] reads, writes and excepts can be lists or vectors: it doesn’t matter which, but the corresponding object returned will be of the same type. Each element is a port or file descriptor on which to wait for readability, writeability or exceptional conditions respectively. secs and usecs optionally specify a timeout: secs can be specified alone, as either an integer or a real number, or both secs and usecs can be specified as integers, in which case usecs is an additional timeout expressed in microseconds. Buffered input or output data is (currently, but this may change) ignored: select uses the underlying file descriptor of a port (char-ready? will check input buffers, output buffers are problematic). The return value is a list of subsets of the input lists or vectors for which the requested condition has been met. It is not quite compatible with scsh’s select: scsh checks port buffers, doesn’t accept input lists or a microsecond timeout, returns multiple values instead of a list and has an additional select! interface.

31 File System

These procedures allow querying and setting file system attributes (such as owner, permissions, sizes and types of files); deleting, copying, renaming and linking files; creating and removing directories and querying their contents; syncing the file system and creating special files.

primitive access? path how

Returns #t if path corresponds to an existing file and the current process has the type of access specified by how, otherwise #f. how should be specified using the values of the variables listed below. Multiple values can be combined using a bitwise or, in which case #t will only be returned if all accesses are granted. Permissions are checked using the real id of the current process, not the effective id, although it’s the effective id which determines whether the access would actually be granted.

Variable R OK

test for read permission.

Variable W OK

test for write permission.

Variable X OK

test for execute permission.

Variable F OK

test for existence of the file.

primitive stat obj

Returns an object containing various information about the file determined by obj. obj can be a string containing a file name or a port or integer file descriptor which is open on a file (in which case fstat is used as the underlying system call). The object returned by stat can be passed as a single parameter to the following procedures, all of which return integers:

stat:dev The device containing the file.

stat:ino The file serial number, which distinguishes this file from all other files on the same device.

stat:mode

The mode of the file. This includes file type information and the file permission bits. See stat:type and stat:perms below.

stat:nlink

The number of hard links to the file.

stat:uid The user ID of the file’s owner.

stat:gid The group ID of the file.

stat:rdev

Device ID; this entry is defined only for character or block special files.

stat:size

The size of a regular file in bytes.

stat:atime

The last access time for the file.

stat:mtime

The last modification time for the file.

stat:ctime

The last modification time for the attributes of the file.

stat:blksize

The optimal block size for reading or writing the file, in bytes.

stat:blocks

The amount of disk space that the file occupies measured in units of 512 byte blocks.

In addition, the following procedures return the information from stat:mode in a more convenient form:

stat:type

A symbol representing the type of file. Possible values are regular, directory, symlink, block-special, char-special, fifo, socket and unknown

stat:perms

An integer representing the access permission bits.

primitive lstat path

Similar to stat, but does not follow symbolic links, i.e., it will return information about a symbolic link itself, not the file it points to. path must be a string.

primitive readlink path

Returns the value of the symbolic link named by path (a string), i.e., the file that the link points to.

primitive chown obj owner group Change the ownership and group of the file referred to by obj to the integer userid values owner and group. obj can be a string containing a file name or a port or integer file descriptor which is open on the file (in which case fchown is used as the underlying system call). The return value is unspecified. If obj is a symbolic link, either the ownership of the link or the ownership of the referenced file will be changed depending on the operating system (lchown is unsupported at present). If owner or group is specified as -1, then that ID is not changed. primitive chmod obj mode

Changes the permissions of the file referred to by obj. obj can be a string containing a file name or a port or integer file descriptor which is open on a file (in which case fchmod is used as the underlying system call). mode specifies the new permissions as a decimal number, e.g., (chmod "foo" #o755). The return value is unspecified.

primitive utime path [actime] [modtime] utime sets the access and modification times for the file named by path. If actime or modtime is not supplied, then the current time is used. actime and modtime must be integer time values as returned by the current-time procedure. E.g.,

     (utime "foo" (- (current-time) 3600))

will set the access time to one hour in the past and the modification time to the current time.

primitive delete-file path

Deletes (or "unlinks") the file specified by path.

primitive copy-file path-from path-to Copy the file specified by path-from to path-to. The return value is unspecified.

primitive rename-file path-from path-to Renames the file specified by path-from to path-to. The return value is unspecified.

primitive truncate-file obj size

Truncates the file referred to by obj to at most size bytes. obj can be a string containing a file name or an integer file descriptor or port open for output on the file. The underlying system calls are truncate and ftruncate. The return value is unspecified.

primitive link path-from path-to Creates a new name path-to in the file system for the file named by path-from. If path-from is a symbolic link, the link may or may not be followed depending on the system.

primitive symlink path-from path-to Create a symbolic link named path-to with the value (i.e., pointing to) pathfrom. The return value is unspecified.

primitive mkdir path [mode] Create a new directory named by path. If mode is omitted then the permissions of the directory file are set using the current umask. Otherwise they are set to the decimal value specified with mode. The return value is unspecified.

primitive rmdir path

Remove the existing directory named by path. The directory must be empty for this to succeed. The return value is unspecified.

primitive opendir path

Open the directory specified by path and return a directory port.

primitive readdir port

Return (as a string) the next directory entry from the directory port port. If there is no remaining entry to be read then the end of file object is returned.

primitive rewinddir port

Reset the directory port port so that the next call to readdir will return the first directory entry.

primitive closedir port

Close the directory port port. The return value is unspecified.

primitive sync

Flush the operating system disk buffers. The return value is unspecified.

primitive mknod path type perms dev Creates a new special file, such as a file corresponding to a device. path specifies the name of the file. type should be one of the following symbols: regular, directory, symlink, block-special, char-special, fifo, or socket. perms (an integer) specifies the file permissions. dev (an integer) specifies which device the special file refers to. Its exact interpretation depends on the kind of special file being created. E.g.,

     (mknod "/dev/fd0" 'block-special #o660 (+ (* 2 256) 2))

The return value is unspecified.

primitive tmpnam

Create a new file in the file system with a unique name. The return value is the name of the new file. This function is implemented with the tmpnam function in the system libraries.

32 User Information

The facilities in this section provide an interface to the user and group database. They should be used with care since they are not reentrant.

The following functions accept an object representing user information and return a selected component:

passwd:name

The name of the userid.

passwd:passwd

The encrypted passwd.

passwd:uid

The user id number.

passwd:gid

The group id number.

passwd:gecos

The full name.

passwd:dir

The home directory.

passwd:shell

The login shell.

procedure getpwuid uid

Look up an integer userid in the user database.

procedure getpwnam name

Look up a user name string in the user database.

procedure setpwent

Initializes a stream used by getpwent to read from the user database. The next use of getpwent will return the first entry. The return value is unspecified.

procedure getpwent

Return the next entry in the user database, using the stream set by setpwent.

procedure endpwent

Closes the stream used by getpwent. The return value is unspecified.

primitive setpw [reset?] If called with a true argument, initialize or reset the password data stream. Otherwise, close the stream. The setpwent and endpwent procedures are implemented on top of this.

primitive getpw [obj]

Look up an entry in the user database. obj can be an integer, a string, or omitted, giving the behaviour of getpwuid, getpwnam or getpwent respectively.

The following functions accept an object representing group information and return a selected component:

group:name

The group name.

group:passwd

The encrypted group password.

group:gid

The group id number.

group:mem

A list of userids which have this group as a supplimentary group.

procedure getgrgid gid

Look up an integer groupid in the group database.

procedure getgrnam name

Look up a group name in the group database.

procedure setgrent

Initializes a stream used by getgrent to read from the group database. The next use of getgrent will return the first entry. The return value is unspecified.

procedure getgrent

Return the next entry in the group database, using the stream set by setgrent.

procedure endgrent

Closes the stream used by getgrent. The return value is unspecified.

primitive setgr [reset?] If called with a true argument, initialize or reset the group data stream. Otherwise, close the stream. The setgrent and endgrent procedures are implemented on top of this.

primitive getgr [obj]

Look up an entry in the group database. obj can be an integer, a string, or omitted, giving the behaviour of getgrgid, getgrnam or getgrent respectively.

33 Time

primitive current-time

Returns the number of seconds since 1970-01-01 00:00:00 UTC, excluding leap seconds.

primitive gettimeofday

Returns a pair containing the number of seconds and microseconds since 1970-01-01 00:00:00 UTC, excluding leap seconds. Note: whether true microsecond resolution is available depends on the operating system.

The following procedures either accept an object representing a broken down time and return a selected component, or accept an object representing a broken down time and a value and set the component to the value. The numbers in parentheses give the usual range.

tm:sec, set-tm:sec

Seconds (0-59).

tm:min, set-tm:min

Minutes (0-59).

tm:hour, set-tm:hour

Hours (0-23).

tm:mday, set-tm:mday

Day of the month (1-31).

tm:mon, set-tm:mon

Month (0-11).

tm:year, set-tm:year

Year (70-), the year minus 1900.

tm:wday, set-tm:wday

Day of the week (0-6) with Sunday represented as 0.

tm:yday, set-tm:yday

Day of the year (0-364, 365 in leap years).

tm:isdst, set-tm:isdst

Daylight saving indicator (0 for "no", greater than 0 for "yes", less than 0 for "unknown").

tm:gmtoff, set-tm:gmtoff

Time zone offset in seconds west of UTC (-46800 to 43200).

tm:zone, set-tm:zone

Time zone label (a string), not necessarily unique.

primitive localtime time [zone] Returns an object representing the broken down components of time, an integer like the one returned by current-time. The time zone for the calculation is optionally specified by zone (a string), otherwise the TZ environment variable or the system default is used.

primitive gmtime time

Returns an object representing the broken down components of time, an integer like the one returned by current-time. The values are calculated for UTC.

primitive mktime bd-time [zone] bd-time is an object representing broken down time and zone is an optional time zone specifier (otherwise the TZ environment variable or the system default is used). Returns a pair: the CAR is a corresponding integer time value like that returned by current-time; the CDR is a broken down time object, similar to as bd-time but with normalized values.

primitive tzset

Initialize the timezone from the TZ environment variable or the system default. Usually this is done automatically by other procedures which use the time zone, but this procedure may need to be used if TZ is changed.

primitive strftime template time Formats a time specification time using template. time is an object with time components in the form returned by localtime or gmtime. template is a string which can include formatting specifications introduced by a % character. The formatting of month and day names is dependent on the current locale. The value returned is the formatted string. See section “Formatting Date and Time” in The GNU C Library Reference Manual.) primitive strptime template string

Performs the reverse action to strftime, parsing string according to the specification supplied in template. The interpretation of month and day names is dependent on the current locale. The value returned is a pair. The CAR has an object with time components in the form returned by localtime or gmtime, but the time zone components are not usefully set. The CDR reports the number of characters from string which were used for the conversion.

Variable internal-time-units-per-second

The value of this variable is the number of time units per second reported by the following procedures.

primitive times

Returns an object with information about real and processor time. The following procedures accept such an object as an argument and return a selected component:

tms:clock

The current real time, expressed as time units relative to an arbitrary base.

tms:utime

The CPU time units used by the calling process.

tms:stime

The CPU time units used by the system on behalf of the calling process.

tms:cutime

The CPU time units used by terminated child processes of the calling process, whose status has been collected (e.g., using waitpid).

tms:cstime

Similarly, the CPU times units used by the system on behalf of terminated child processes.

primitive get-internal-real-time

Returns the number of time units since the interpreter was started.

primitive get-internal-run-time

Returns the number of time units of processor time used by the interpreter. Both "system" and "user" time are included but subprocesses are not.

34 Processes

primitive chdir path

Change the current working directory to path. The return value is unspecified.

primitive getcwd

Returns the name of the current working directory. primitive umask [mode]

If mode is omitted, retuns a decimal number representing the current file creation mask. Otherwise the file creation mask is set to mode and the previous value is returned. E.g., (umask #o022) sets the mask to octal 22, decimal 18.

primitive getpid

Returns an integer representing the current process ID.

primitive getgroups

Returns a vector of integers representing the current supplimentary group IDs.

primitive getppid

Returns an integer representing the process ID of the parent process.

primitive getuid

Returns an integer representing the current real user ID.

primitive getgid

Returns an integer representing the current real group ID.

primitive geteuid

Returns an integer representing the current effective user ID. If the system does not support effective IDs, then the real ID is returned. (feature? 'EIDs) reports whether the system supports effective IDs.

primitive getegid

Returns an integer representing the current effective group ID. If the system does not support effective IDs, then the real ID is returned. (feature? 'EIDs) reports whether the system supports effective IDs.

primitive setuid id

Sets both the real and effective user IDs to the integer id, provided the process has appropriate privileges. The return value is unspecified.

primitive setgid id

Sets both the real and effective group IDs to the integer id, provided the process has appropriate privileges. The return value is unspecified.

primitive seteuid id

Sets the effective user ID to the integer id, provided the process has appropriate privileges. If effective IDs are not supported, the real ID is set instead – (feature? 'EIDs) reports whether the system supports effective IDs. The return value is unspecified.

primitive setegid id

Sets the effective group ID to the integer id, provided the process has appropriate privileges. If effective IDs are not supported, the real ID is set instead – (feature? 'EIDs) reports whether the system supports effective IDs. The return value is unspecified.

primitive getpgrp

Returns an integer representing the current process group ID. This is the POSIX definition, not BSD.

primitive setpgid pid pgid

Move the process pid into the process group pgid. pid or pgid must be integers: they can be zero to indicate the ID of the current process. Fails on systems that do not support job control. The return value is unspecified.

primitive setsid

Creates a new session. The current process becomes the session leader and is put in a new process group. The process will be detached from its controlling terminal if it has one. The return value is an integer representing the new process group ID.

primitive waitpid pid [options] This procedure collects status information from a child process which has terminated or (optionally) stopped. Normally it will suspend the calling process until this can be done. If more than one child process is eligible then one will be chosen by the operating system. The value of pid determines the behaviour:

pid greater than 0 Request status information from the specified child process.

pid equal to -1 or WAIT ANY Request status information for any child process.

pid equal to 0 or WAIT MYPGRP Request status information for any child process in the current process group.

pid less than -1 Request status information for any child process whose process group ID is -PID.

The options argument, if supplied, should be the bitwise OR of the values of zero or more of the following variables:

Variable WNOHANG

Return immediately even if there are no child processes to be collected.

Variable WUNTRACED

Report status information for stopped processes as well as terminated processes.

The return value is a pair containing:

1. The process ID of the child process, or 0 if WNOHANG was specified and no process was collected.

2. The integer status value.

The following three functions can be used to decode the process status code returned by

waitpid.

primitive status:exit-val status

Returns the exit status value, as would be set if a process ended normally through a call to exit or _exit, if any, otherwise #f.

primitive status:term-sig status

Returns the signal number which terminated the process, if any, otherwise #f.

primitive status:stop-sig status

Returns the signal number which stopped the process, if any, otherwise #f.

primitive system [cmd]

Executes cmd using the operating system’s "command processor". Under Unix this is usually the default shell sh. The value returned is cmd’s exit status as returned by waitpid, which can be interpreted using the functions above. If system is called without arguments, it returns a boolean indicating whether the command processor is available.

primitive primitive-exit [status]

Terminate the current process without unwinding the Scheme stack. This is would typically be useful after a fork. The exit status is status if supplied, otherwise zero.

primitive execl path [arg] ...

Executes the file named by path as a new process image. The remaining arguments are supplied to the process; from a C program they are accessable as the argv argument to main. Conventionally the first arg is the same as path. All arguments must be strings. If arg is missing, path is executed with a null argument list, which may have system-dependent side-effects. This procedure is currently implemented using the execv system call, but we call it execl because of its Scheme calling interface.

primitive execlp path [arg] ...

Similar to execl, however if filename does not contain a slash then the file to execute will be located by searching the directories listed in the PATH environment variable. This procedure is currently implemented using the execlv system call, but we call it execlp because of its Scheme calling interface.

primitive execle path env [arg] ...

Similar to execl, but the environment of the new process is specified by env, which must be a list of strings as returned by the environ procedure. This procedure is currently implemented using the execve system call, but we call it execle because of its Scheme calling interface.

primitive primitive-fork

Creates a new "child" process by duplicating the current "parent" process. In the child the return value is 0. In the parent the return value is the integer process ID of the child.

This procedure has been renamed from fork to avoid a naming conflict with the scsh fork.

primitive getenv name

Looks up the string name in the current environment. The return value is #f unless a string of the form NAME=VALUE is found, in which case the string VALUE is returned.

primitive putenv string

Modifies the environment of the current process, which is also the default environment inherited by child processes.

If string is of the form NAME=VALUE then it will be written directly into the environment, replacing any existing environment string with name matching NAME. If string does not contain an equal sign, then any existing string with name matching string will be removed.

The return value is unspecified.

procedure setenv name value Modifies the environment of the current process, which is also the default environment inherited by child processes.

If value is #f, then name is removed from the environment. Otherwise, the string name=value is added to the environment, replacing any existing string with name matching name.

The return value is unspecified.

primitive environ [env]

If env is omitted, returns the current environment as a list of strings. Otherwise it sets the current environment, which is also the default environment for child processes, to the supplied list of strings. Each member of env should be of the form NAME=VALUE and values of NAME should not be duplicated. If env is supplied then the return value is unspecified.

primitive nice incr

Increment the priority of the current process by incr. A higher priority value means that the process runs less often. The return value is unspecified.

35 Signals

Procedures to raise, handle and wait for signals.

primitive kill pid sig Sends a signal to the specified process or group of processes. pid specifies the processes to which the signal is sent:

pid greater than 0 The process whose identifier is pid.

pid equal to 0 All processes in the current process group.

pid less than -1 The process group whose identifier is -pid

pid equal to -1 If the process is privileged, all processes except for some special system processes. Otherwise, all processes with the current effective user ID.

sig should be specified using a variable corresponding to the Unix symbolic name, e.g.,

Variable SIGHUP

Hang-up signal.

Variable SIGINT

Interrupt signal.

primitive raise sig

Sends a specified signal sig to the current process, where sig is as described for the kill procedure.

primitive sigaction signum [action] [flags] Install or report the signal hander for a specified signal. signum is the signal number, which can be specified using the value of variables such as SIGINT. If action is omitted, sigaction returns a pair: the CAR is the current signal hander, which will be either an integer with the value SIG_DFL (default action) or SIG_IGN (ignore), or the Scheme procedure which handles the signal, or #f if a non-Scheme procedure handles the signal. The CDR contains the current sigaction flags for the handler. If action is provided, it is installed as the new handler for signum. action can be a Scheme procedure taking one argument, or the value of SIG_DFL (default action) or SIG_IGN (ignore), or #f to restore whatever signal handler was installed before sigaction was first used. Flags can optionally be specified for the new handler (SA_RESTART is always used if the system provides it, so need not be specified.) The return value is a pair with information about the old handler as described above. This interface does not provide access to the "signal blocking" facility. Maybe this is not needed, since the thread support may provide solutions to the problem of consistent access to data structures.

primitive restore-signals

Return all signal handlers to the values they had before any call to sigaction was made. The return value is unspecified.

primitive alarm secs

Set a timer to raise a SIGALRM signal after the specified number of seconds (an integer). It’s advisable to install a signal handler for SIGALRM beforehand, since the default action is to terminate the process. The return value indicates the time remaining for the previous alarm, if any. The new value replaces the previous alarm. If there was no previous alarm, the return value is zero.

primitive pause

Pause the current process (thread?) until a signal arrives whose action is to either terminate the current process or invoke a handler procedure. The return value is unspecified.

primitive sleep secs

Wait for the given number of seconds (an integer) or until a signal arrives. The return value is zero if the time elapses or the number of seconds remaining otherwise.

36 Terminals and Ptys

primitive isatty? port

Returns #t if port is using a serial non-file device, otherwise #f.

primitive ttyname port

Returns a string with the name of the serial terminal device underlying port.

primitive ctermid

Returns a string containing the file name of the controlling terminal for the current process.

primitive tcgetpgrp port

Returns the process group ID of the foreground process group associated with the terminal open on the file descriptor underlying port. If there is no foreground process group, the return value is a number greater than 1 that does not match the process group ID of any existing process group. This can happen if all of the processes in the job that was formerly the foreground job have terminated, and no other job has yet been moved into the foreground.

primitive tcsetpgrp port pgid

Set the foreground process group ID for the terminal used by the file descriptor underlying port to the integer pgid. The calling process must be a member of the same session as pgid and must have the same controlling terminal. The return value is unspecified.

37 Pipes

These procedures provide an interface to the popen and pclose system routines.

primitive open-pipe command modes Executes the shell command command (a string) in a subprocess. A pipe to the process is created and returned. modes specifies whether an input or output pipe to the process is created: it should be the value of OPEN_READ or OPEN_

WRITE.

procedure open-input-pipe command

Equivalent to (open-pipe command OPEN_READ).

procedure open-output-pipe command

Equivalent to (open-pipe command OPEN_WRITE).

primitive close-pipe port

Closes the pipe created by open-pipe, then waits for the process to terminate and returns its status value, See ⟨undefined⟩ [Processes], page ⟨undefined⟩, for information on how to interpret this value. close-port (see ⟨undefined⟩ [Closing Ports], page ⟨undefined⟩) can also be used to close a pipe, but doesn’t return the status.

38 Networking

38.1 Networking Databases

This section describes procedures which convert internet addresses and query various network databases. Care should be taken when using the database routines since they are not reentrant.

primitive inet-aton address

Converts a string containing an Internet host address in the traditional dotted decimal notation into an integer.

     (inet-aton "127.0.0.1") ⇒ 2130706433

primitive inet-ntoa number

Converts an integer Internet host address into a string with the traditional dotted decimal representation.

     (inet-ntoa 2130706433) ⇒ "127.0.0.1"

primitive inet-netof address

Returns the network number part of the given integer Internet address.

     (inet-netof 2130706433) ⇒ 127

primitive inet-lnaof address

Returns the local-address-with-network part of the given Internet address.

     (inet-lnaof 2130706433) ⇒ 1

primitive inet-makeaddr net lna

Makes an Internet host address by combining the network number net with the local-address-within-network number lna.

     (inet-makeaddr 127 1) ⇒ 2130706433

A host object is a structure that represents what is known about a network host, and is the usual way of representing a system’s network identity inside software. The hostent functions accept a host object and return some information about that host’s presence on the network.

procedure hostent:name host

The "official" hostname for host.

procedure hostent:aliases host

A list of aliases for host.

procedure hostent:addrtype host

The host address type. For hosts with Internet addresses, this will return AF_

INET.

procedure hostent:length host

The length of each address for host, in bytes.

procedure hostent:addr-list host

The list of network addresses associated with host.

The gethost functions are used to find a particular host’s entry in the host database.

primitive gethost [host] procedure gethostbyname hostname procedure gethostbyaddr address

Look up a host by name or address, and return a host object. The gethost procedure will accept either a string name or an integer address; if given no arguments, it behaves like gethostent (see below).

The following three procedures may be used to step through the host database from beginning to end. [FIXME: document the ‘sethost’ variant of ‘sethostent’.]

procedure sethostent

Initialize an internal stream from which host objects may be read. This procedure must be called before any calls to gethostent, and may also be called afterward to reset the host entry stream.

procedure gethostent

Return the next host object from the host database, or #f if there are no more hosts to be found (or an error has been encountered). This procedure may not be used before sethostent has been called.

procedure endhostent

Close the stream used by gethostent. The return value is unspecified.

The netent functions accept an object representing a network and return a selected component.

procedure netent:name net

The "official" network name.

procedure netent:aliases net

A list of aliases for the network.

procedure netent:addrtype net

The type of the network number. Currently, this returns only AF_INET.

procedure netent:net net

The network number.

The getnet procedures look up a particular network in the network database. Each returns a network object that describes the network’s technical nature.

primitive getnet [net] procedure getnetbyname net-name procedure getnetbyaddr net-number

Look up a network by name or net number in the network database. The netname argument must be a string, and the net-number argument must be an integer. getnet will accept either type of argument, behaving like getnetent (see below) if no arguments are given.

[FIXME: document the ‘setnet’ variant of ‘setnetent’.]

procedure setnetent

Initializes a stream used by getnetent to read from the network database. The next use of getnetent will return the first entry. The return value is unspecified.

procedure getnetent

Return the next entry from the network database.

procedure endnetent

Close the stream used by getnetent. The return value is unspecified.

The protoent procedures accept an object representing a protocol and return a selected component.

procedure protoent:name protocol

The "official" protocol name.

procedure protoent:aliases protocol

A list of aliases for the protocol.

procedure protoent:proto protocol

The protocol number.

The getproto procedures look up a particular network protocol and return a protocol object.

primitive getproto [protocol]

procedure getprotobyname name procedure getprotobynumber number

Look up a network protocol by name or by number. getprotobyname takes a string argument, and getprotobynumber takes an integer argument. getproto will accept either type, behaving like getprotoent (see below) if no arguments are supplied.

[FIXME: document the ‘setproto’ variant of ‘setprotoent’.]

procedure setprotoent

Initializes a stream used by getprotoent to read from the protocol database. The next use of getprotoent will return the first entry. The return value is unspecified.

procedure getprotoent

Return the next entry from the protocol database.

procedure endprotoent

Close the stream used by getprotoent. The return value is unspecified.

The servent procedures accept a service object and return some information about that service.

procedure servent:name serv

The "official" name of the network service.

procedure servent:aliases serv

A list of aliases for the network service.

procedure servent:port serv

The Internet port used by the service.

procedure servent:proto serv

The protocol used by the service. A service may be listed many times in the database under different protocol names.

The getserv procedures look up a network service and return a service object which describes the names and network ports conventionally assigned to the service. primitive getserv [name protocol]

procedure getservbyname name protocol procedure getservbyport port protocol

Look up a network service by name or by service number, and return a network service object. The protocol argument specifies the name of the desired protocol; if the protocol found in the network service database does not match this name, a system error is signalled. The getserv procedure will take either a service name or number as its first argument; if given no arguments, it behaves like getservent (see below).

[FIXME: document the ‘setserv’ variant of ‘setservent’.]

procedure setservent

Initializes a stream used by getservent to read from the services database. The next use of getservent will return the first entry. The return value is unspecified.

procedure getservent

Return the next entry from the services database.

procedure endservent

Close the stream used by getservent. The return value is unspecified.

38.2 Network sockets

Socket ports can be created using socket and socketpair. The ports are initially unbuffered, to makes reading and writing to the same port more reliable. Buffered ports can be obtained with duplicate-port, See ⟨undefined⟩ [Ports and File Descriptors], page ⟨undefined⟩.

These procedures convert Internet addresses and port values between "host" order and "network" order as required. The arguments and return values should be in "host" order.

primitive socket family style protocol Returns a new socket port of the type specified by family, style and protocol. All three parameters are integers. Typical values for family are the values of AF_UNIX and AF_INET. Typical values for style are the values of SOCK_STREAM,

SOCK_DGRAM and SOCK_RAW.

protocol can be obtained from a protocol name using getprotobyname. A value of zero specifies the default protocol, which is usually right. A single socket port cannot by used for communication until it has been connected to another socket.

primitive socketpair family style protocol Returns a pair of connected (but unnamed) socket ports of the type specified by family, style and protocol. Many systems support only socket pairs of the AF_UNIX family. Zero is likely to be the only meaningful value for protocol. primitive getsockopt socket level optname

Returns the value of a particular socket option for the socket port socket. level is an integer code for type of option being requested, e.g., SOL_SOCKET for socket-level options. optname is an integer code for the option required and should be specified using one of the symbols SO_DEBUG, SO_REUSEADDR etc. The returned value is typically an integer but SO_LINGER returns a pair of integers.

primitive setsockopt socket level optname value Sets the value of a particular socket option for the socket port socket. level is an integer code for type of option being set, e.g., SOL_SOCKET for socket-level options. optname is an integer code for the option to set and should be specified using one of the symbols SO_DEBUG, SO_REUSEADDR etc. value is the value to which the option should be set. For most options this must be an integer, but for SO_LINGER it must be a pair. The return value is unspecified.

primitive shutdown socket how Sockets can be closed simply by using close-port. The shutdown procedure allows reception or tranmission on a connection to be shut down individually, according to the parameter how:

0 Stop receiving data for this socket. If further data arrives, reject it.

1 Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don’t retransmit it if it is lost.

2 Stop both reception and transmission.

The return value is unspecified.

primitive connect socket family address [arg ...] Initiates a connection from socket to the address specified by address and possibly arg . . .. The format required for address and arg … depends on the family of the socket. For a socket of family AF_UNIX, only address is specified and must be a string with the filename where the socket is to be created. For a socket of family AF_INET, address must be an integer Internet host address and arg … must be a single integer port number. The return value is unspecified.

primitive bind socket family address arg ...

Assigns an address to the socket port socket. Generally this only needs to be done for server sockets, so they know where to look for incoming connections. A socket without an address will be assigned one automatically when it starts communicating. The format of address and ARG … depends on the family of the socket.

For a socket of family AF_UNIX, only address is specified and must be a string with the filename where the socket is to be created. For a socket of family AF_INET, address must be an integer Internet host address and arg … must be a single integer port number. The values of the following variables can also be used for address:

Variable INADDR ANY

Allow connections from any address.

Variable INADDR LOOPBACK

The address of the local host using the loopback device.

Variable INADDR BROADCAST

The broadcast address on the local network.

Variable INADDR NONE

No address.

The return value is unspecified.

primitive listen socket backlog This procedure enables socket to accept connection requests. backlog is an integer specifying the maximum length of the queue for pending connections. If the queue fills, new clients will fail to connect until the server calls accept to accept a connection from the queue. The return value is unspecified.

primitive accept socket

Accepts a connection on a bound, listening socket socket. If there are no pending connections in the queue, it waits until one is available unless the non-blocking option has been set on the socket. The return value is a pair in which the CAR is a new socket port for the connection and the CDR is an object with address information about the client which initiated the connection. If the address is not available then the CDR will be an empty vector. socket does not become part of the connection and will continue to accept new requests.

The following functions take a socket address object, as returned by accept and other procedures, and return a selected component.

sockaddr:fam

The socket family, typically equal to the value of AF_UNIX or AF_INET.

sockaddr:path

If the socket family is AF_UNIX, returns the path of the filename the socket is based on.

sockaddr:addr

If the socket family is AF_INET, returns the Internet host address.

sockaddr:port

If the socket family is AF_INET, returns the Internet port number.

primitive getsockname socket

Returns the address of socket, in the same form as the object returned by accept. On many systems the address of a socket in the AF_FILE namespace cannot be read.

primitive getpeername socket

Returns the address of the socket that the socket socket is connected to, in the same form as the object returned by accept. On many systems the address of a socket in the AF_FILE namespace cannot be read.

primitive recv! socket buf [flags] Receives data from the socket port socket. socket must already be bound to the address from which data is to be received. buf is a string into which the data will be written. The size of buf limits the amount of data which can be received: in the case of packet protocols, if a packet larger than this limit is encountered then some data will be irrevocably lost. The optional flags argument is a value or bitwise OR of MSG OOB, MSG PEEK, MSG DONTROUTE etc. The value returned is the number of bytes read from the socket. Note that the data is read directly from the socket file descriptor: any unread buffered port data is ignored.

primitive send socket message [flags] Transmits the string message on the socket port socket. socket must already be bound to a destination address. The value returned is the number of bytes transmitted – it’s possible for this to be less than the length of message if the socket is set to be non-blocking. The optional flags argument is a value or bitwise OR of MSG OOB, MSG PEEK, MSG DONTROUTE etc. Note that the data is written directly to the socket file descriptor: any unflushed buffered port data is ignored.

primitive recvfrom! socket buf [flags] [start] [end] Returns data from the socket port socket and also information about where the data was received from. socket must already be bound to the address from which data is to be received. buf, is a string into which the data will be written. The size of buf limits the amount of data which can be received: in the case of packet protocols, if a packet larger than this limit is encountered then some data will be irrevocably lost. The optional flags argument is a value or bitwise OR of MSG OOB, MSG PEEK, MSG DONTROUTE etc. The value returned is a pair: the CAR is the number of bytes read from the socket and the CDR an address object in the same form as returned by accept. The start and end arguments specify a substring of buf to which the data should be written.

Note that the data is read directly from the socket file descriptor: any unread buffered port data is ignored.

primitive sendto socket message family address arg ... [flags] Transmits the string message on the socket port socket. The destination address is specified using the family, address and arg arguments, in a similar way to the connect procedure. The value returned is the number of bytes transmitted

– it’s possible for this to be less than the length of message if the socket is set to be non-blocking. The optional flags argument is a value or bitwise OR of MSG OOB, MSG PEEK, MSG DONTROUTE etc. Note that the data is written directly to the socket file descriptor: any unflushed buffered port data is ignored.

39 System Identification

primitive uname

Returns an object with some information about the computer system the program is running on.

The following procedures accept an object as returned by uname and return a selected component.

utsname:sysname

The name of the operating system.

utsname:nodename

The network name of the computer.

utsname:release

The current release level of the operating system implementation.

utsname:version

The current version level within the release of the operating system.

utsname:machine

A description of the hardware.

primitive software-type

Return a symbol describing the current platform’s operating system. This may be one of AIX, VMS, UNIX, COHERENT, WINDOWS, MS-DOS, OS/2, THINKC, AMIGA, ATARIST, MACH, or ACORN. Note that most varieties of Unix are considered to be simply "UNIX". That is because when a program depends on features that are not present on every operating system, it is usually better to test for the presence or absence of that specific feature. The return value of software-type should only be used for this purpose when there is no other easy or unambiguous way of detecting such features.

40 Locales

primitive setlocale category [locale] If locale is omitted, returns the current value of the specified locale category as a system-dependent string. category should be specified using the values

LC_COLLATE, LC_ALL etc.

Otherwise the specified locale category is set to the string locale and the new value is returned as a system-dependent string. If locale is an empty string, the locale will be set using envirionment variables.

41 Expect

The macros in this section are made available with:

(use-modules (ice-9 expect))

expect is a macro for selecting actions based on the output from a port. The name comes from a tool of similar functionality by Don Libes. Actions can be taken when a particular string is matched, when a timeout occurs, or when end-of-file is seen on the port. The expect macro is described below; expect-strings is a front-end to expect based on regexec (see the regular expression documentation).

Macro expect-strings clause …

By default, expect-strings will read from the current input port. The first term in each clause consists of an expression evaluating to a string pattern (regular expression). As characters are read one-by-one from the port, they are accumulated in a buffer string which is matched against each of the patterns. When a pattern matches, the remaining expression(s) in the clause are evaluated and the value of the last is returned. For example:

     (with-input-from-file "/etc/passwd"
       (lambda ()
         (expect-strings
           ("^nobody" (display "Got a nobody user.\n")
                      (display "That's no problem.\n"))
           ("^daemon" (display "Got a daemon user.\n")))))

The regular expression is compiled with the REG_NEWLINE flag, so that the ^ and $ anchors will match at any newline, not just at the start and end of the string.

There are two other ways to write a clause:

The expression(s) to evaluate can be omitted, in which case the result of the regular expression match (converted to strings, as obtained from regexec with match-pick set to "") will be returned if the pattern matches.

The symbol => can be used to indicate that the expression is a procedure which will accept the result of a successful regular expression match. E.g.,

     ("^daemon" => write)
     ("^d\\(aemon\\)" => (lambda args (for-each write args)))
     ("^da\\(em\\)on" => (lambda (all sub)
                              (write all) (newline)
                              (write sub) (newline)))

The order of the substrings corresponds to the order in which the opening brackets occur. A number of variables can be used to control the behaviour of expect (and expect-strings). By default they are all bound at the top level to the value #f, which produces the default behaviour. They can be redefined at the top level or locally bound in a form enclosing the expect expression.

expect-port

A port to read characters from, instead of the current input port.

expect-timeout

expect will terminate after this number of seconds, returning #f or the value returned by expect-timeout-proc.

expect-timeout-proc

A procedure called if timeout occurs. The procedure takes a single argument: the accumulated string.

expect-eof-proc

A procedure called if end-of-file is detected on the input port. The procedure takes a single argument: the accumulated string.

expect-char-proc

A procedure to be called every time a character is read from the port. The procedure takes a single argument: the character which was read.

Here’s an example using all of the variables:

     (let ((expect-port (open-input-file "/etc/passwd"))
           (expect-timeout 1)
           (expect-timeout-proc
             (lambda (s) (display "Times up!\n")))
           (expect-eof-proc
             (lambda (s) (display "Reached the end of the file!\n")))
           (expect-char-proc display))
        (expect-strings
          ("^nobody"  (display "Got a nobody user\n"))))

Macro expect clause …

expect is used in the same way as expect-strings, but tests are specified not as patterns, but as procedures. The procedures are called in turn after each character is read from the port, with the value of the accumulated string as the argument. The test is successful if the procedure returns a non-false value. If the => syntax is used, then if the test succeeds it must return a list containing the arguments to be provided to the corresponding expression.

In the following example, a string will only be matched at the beginning of the file:

     (let ((expect-port (open-input-file "/etc/passwd")))
       (expect
          ((lambda (s) (string=? s "fnord!"))
             (display "Got a nobody user!\n"))))

The control variables described for expect-strings can also be used with

expect.

42 The Scheme shell (scsh)

An incomplete port of the Scheme shell (scsh) 0.5.1 is available for Guile. The idea is to allow Scheme code using scsh interfaces to be run inside the Guile interpreter.

   For information about scsh on the Web see http://www-swiss.ai.mit.edu/scsh/scsh.html.

The original scsh is available by ftp from ftp://swiss-ftp.ai.mit.edu:/pub/su.

The scsh code is distributed as a separate module, guile-scsh, which must be installed somewhere in Guile’s load path before it can be used. This is similar to the installation of slib (you may want to install that first, since it’s needed before scsh can run in Guile: see ⟨undefined⟩ [SLIB], page ⟨undefined⟩ for details).

This port of scsh does not currently use the Guile module system, but can be initialized with:

     (load-from-path "scsh/init")

Chapter 43: Tcl/Tk Interface 121

43 Tcl/Tk Interface Part IV: Using Scheme with C — a Portable Interface

44 A Portable C to Scheme Interface

The Guile interpreter is based on Aubrey Jaffer’s SCM interpreter (see section “Overview” in SCM: a portable Scheme interpreter) with some modifications to make it suitable as an embedded interpreter, and further modifications as Guile evolves.

Part of the modification has been to provide a restricted interface to limit access to the SCM internals; this is called the gh_interface, or libguile interface.

If you are programming with Guile, you should only use the C subroutines described in this manual, which all begin with gh_.

If instead you are extending Guile, you have the entire SCM source to play with. This manual will not help you at all, but you can consult Aubrey Jaffer’s SCM manual (see section “Internals” in SCM: a portable Scheme interpreter).

If you are adding a module to Guile, I recommend that you stick to the gh_interface: this interface is guaranteed to not change drastically, while the SCM internals might change as Guile is developed.

Chapter 45: gh preliminaries 123

45 gh preliminaries

To use gh, you must have the following toward the beginning of your C source:

     #include <guile/gh.h>

When you link, you will have to add at least -lguile to the list of libraries. If you are using more of Guile than the basic Scheme interpreter, you will have to add more libraries.

46 Data types and constants defined by gh

The following C constants and data types are defined in gh:

Data type SCM

This is a C data type used to store all Scheme data, no matter what the Scheme type. Values are converted between C data types and the SCM type with utility functions described below (see ⟨undefined⟩ [Converting data between C and Scheme], page ⟨undefined⟩). [FIXME: put in references to Jim’s essay and so forth.]

Constant SCM BOOL T Constant SCM BOOL F

The Scheme values returned by many boolean procedures in libguile. This can cause confusion because they are different from 0 and 1. In testing a boolean function in libguile programming, you must always make sure that you check the spec: gh_and scm_functions will usually return SCM_BOOL_T and SCM_BOOL_F, but other C functions usually can be tested against 0 and 1, so programmers’ fingers tend to just type if (boolean_function()) { ... }

Constant SCM UNSPECIFIED

This is an SCM object which does not correspond to any legal Scheme value. It can be used in C to terminate functions with variable numbers of arguments,

such as gh_list().

47 Starting and controlling the interpreter

In almost every case, your first gh_call will be

Function void gh enter (int argc, char *argv[], void (*main prog)())

Starts up a Scheme interpreter with all the builtin Scheme primitives. gh_ enter() never exits, and the user’s code should all be in the main prog() function. argc and argv will be passed to main prog.

Function void main prog (int argc, char *argv[])

This is the user’s main program. It will be invoked by gh_enter()

after Guile has been started up.

Please note that gh_enter does not load ‘ice-9/boot-9.scm’, which contains much of Guile’s basic functionality, including some necessary parts of Scheme. This is a limitation, and it is only so because the basic Scheme language functions have not yet been separated from the higher-level functionality provided

by the ‘ice-9/boot-9.scm’ module.

Here is a note from the Guile mailing list describing how to get around this problem if you want to run some Guile code before you invoke gh_repl(). It is a temporary solution, and a better way of handling the loading of ‘ice-9/boot-9.scm’ will soon be introduced.

     The next problem is that boot-9.scm may only be executed once, otherwise
     you get a stack overflow. When entering the read-eval-print-loop (repl)
     with gh_repl, guile loads boot-9.scm. Thus, if you did load boot-9.scm
     yourself and then later enter the repl, guile will abort with a stack
     overflow.
     If you look a little into the guile mailing list archives, you can find a
     temporary solution to the problem which I posted quite some time ago. It's
     a trivial fix:
     1) rename boot-9.scm into boot-9-tail.scm
     2) create a new boot-9.scm, which only contains the following code:
     (if (not (defined? 'provide))
         (primitive-load-path "ice-9/boot-9-tail.scm"))
     With this modification, boot-9.scm can be read several times.

Also note that you can use gh_repl inside gh_enter if you want the program to be controled by a Scheme read–eval–print–loop. Invoking gh_repl will load

‘ice-9/boot-9.scm’.

A convenience routine which enters the Guile interpreter with the standard Guile read– eval–print–loop (REPL) is:

Function void gh repl (int argc, char *argv[])

Enters the Scheme interpreter giving control to the Scheme REPL. Arguments are processed as if the Guile program ‘guile’ were being invoked.

Note that gh_repl should be used inside gh_enter, since any Guile interpreter calls are meaningless unless they happen in the context of the interpreter. Also note that when you use gh_repl, your program will be controlled by Guile’s REPL (which is written in Scheme and has many useful features). Use straight C code inside gh_enter if you want to maintain execution control in your C program.

You will typically use gh_enter and gh_repl() when you want a Guile interpreter enhanced by your own libraries, but otherwise quite normal. For example, to build a Guile– derived program that includes some random number routines GSL (GNU Scientific Library), you would write a C program that looks like this:

#include <guile/gh.h>
#include <gsl_ran.h>
/* random number suite */
SCM gw_ran_seed(SCM s)
{
  gsl_ran_seed(gh_scm2int(s));
  return SCM_UNSPECIFIED;
}
SCM gw_ran_random()
{
  SCM x;
  x = gh_ulong2scm(gsl_ran_random());
  return x;
}
SCM gw_ran_uniform()
{
  SCM x;
  x = gh_double2scm(gsl_ran_uniform());
  return x;
}
SCM gw_ran_max()
{
  return gh_double2scm(gsl_ran_max());
}
void
init_gsl()
{
  /* random number suite */
  gh_new_procedure("gsl-ran-seed", gw_ran_seed, 1, 0, 0);
  gh_new_procedure("gsl-ran-random", gw_ran_random, 0, 0, 0);
  gh_new_procedure("gsl-ran-uniform", gw_ran_uniform, 0, 0, 0);

  gh_new_procedure("gsl-ran-max", gw_ran_max, 0, 0, 0);
}
void
main_prog (int argc, char *argv[])
{
  init_gsl();
  gh_repl(argc, argv);
}
int
main (int argc, char *argv[])
{
  gh_enter (argc, argv, main_prog);
}

Then, supposing the C program is in ‘guile-gsl.c’, you could compile it with gcc -o

guile-gsl guile-gsl.c -lguile -lgsl.

The resulting program ‘guile-gsl’ would have new primitive procedures (gsl-ran-

random), (gsl-ran-gaussian) and so forth.

128 Guile Reference Manual

48 Error messages

[FIXME: need to fill this based on Jim’s new mechanism]

49 Executing Scheme code

Once you have an interpreter running, you can ask it to evaluate Scheme code. There are two calls that implement this:

Function SCM gh eval str (char *scheme code)

This asks the interpreter to evaluate a single string of Scheme code, and returns the result of the last expression evaluated. Note that the line of code in scheme code must be a well formed Scheme expression. If you have many lines of code before you balance parentheses, you must either concatenate them into one string, or use gh_eval_file().

Function SCM gh eval file (char *fname)

Function SCM gh load (char *fname)

gh_eval_file is completely analogous to gh_eval_str(), except that a whole file is evaluated instead of a string. Returns the result of the last expression evaluated. gh_load is identical to gh_eval_file (it’s a macro that calls gh_eval_file on its argument). It is provided to start making the gh_interface match the R4RS Scheme procedures closely.

50 Defining new Scheme procedures in C

The real interface between C and Scheme comes when you can write new Scheme procedures in C. This is done through the routine

Libguile high SCM gh new procedure (char *proc name, SCM (*fn)(),

int n required args, int n optional args, int restp) gh_new_procedure defines a new Scheme procedure. Its Scheme name will be proc name, it will be implemented by the C function (*fn)(), it will take at least n required args arguments, and at most n optional args extra arguments. When the restp parameter is 1, the procedure takes a final argument: a list of remaining parameters. gh_new_procedure returns an SCM value representing the procedure. The C function fn should have the form

Libguile high SCM fn (SCM req1, SCM req2, ..., SCM opt1, SCM

opt2, ..., SCM rest args) The arguments are all passed as SCM values, so the user will have to use the conversion functions to convert to standard C types. Examples of C functions used as new Scheme primitives can be found in the sample programs learn0 and learn1.

Rationale: this is the correct way to define new Scheme procedures in C. The ugly mess of arguments is required because of how C handles procedures with variable numbers of arguments.

Note: what about documentation strings?

There are several important considerations to be made when writing the C routine (*fn)().

First of all the C routine has to return type SCM. Second, all arguments passed to the C funcion will be of type SCM. Third: the C routine is now subject to Scheme flow control, which means that it could be

interrupted at any point, and then reentered. This means that you have to be very careful with operations such as allocating memory, modifying static data …

Fourth: to get around the latter issue, you can use GH_DEFER_INTS and GH_ALLOW_INTS.

Macro GH DEFER INTS Macro GH ALLOW INTS

These macros disable and reenable Scheme’s flow control. They

51 Converting data between C and Scheme

Guile provides mechanisms to convert data between C and Scheme. This allows new builtin procedures to understand their arguments (which are of type SCM) and return values of type SCM.

51.1 C to Scheme

Function SCM gh bool2scm (int x)

Returns #f if x is zero, #t otherwise.

Function SCM gh ulong2scm (unsigned long x)

Function SCM gh long2scm (long x) Function SCM gh double2scm (double x) Function SCM gh char2scm (char x)

Returns a Scheme object with the value of the C quantity x.

Function SCM gh str2scm (char *s, int len)

Returns a new Scheme string with the (not necessarily null-terminated) C array s data.

Function SCM gh str02scm (char *s)

Returns a new Scheme string with the null-terminated C string s data.

Function SCM gh set substr (char *src, SCM dst, int start, int len)

Copy len characters at src into the existing Scheme string dst, starting at start. start is an index into dst; zero means the beginning of the string.

If start + len is off the end of dst, signal an out-of-range error.

Function SCM gh symbol2scm (char *name)

Given a null-terminated string name, return the symbol with that name.

Function SCM gh ints2scm (int *dptr, int n) Function SCM gh doubles2scm (double *dptr, int n)

Make a scheme vector containing the n ints or doubles at memory location dptr.

Function SCM gh chars2byvect (char *dptr, int n) Function SCM gh shorts2svect (short *dptr, int n) Function SCM gh longs2ivect (long *dptr, int n) Function SCM gh ulongs2uvect (ulong *dptr, int n)

Function SCM gh floats2fvect (float *dptr, int n)

Function SCM gh doubles2dvect (double *dptr, int n)

Make a scheme uniform vector containing the n chars, shorts, longs, unsigned longs, floats or doubles at memory location dptr.

51.2 Scheme to C

Function int gh scm2bool (SCM obj) Function unsigned long gh scm2ulong (SCM obj) Function long gh scm2long (SCM obj) Function double gh scm2double (SCM obj) Function int gh scm2char (SCM obj)

These routines convert the Scheme object to the given C type.

Function char *gh scm2newstr (SCM str, int *lenp)

Given a Scheme string str, return a pointer to a new copy of its contents, followed by a null byte. If lenp is non-null, set *lenp to the string’s length. This function uses malloc to obtain storage for the copy; the caller is responsible for freeing it. Note that Scheme strings may contain arbitrary data, including null characters. This means that null termination is not a reliable way to determine the length of the returned value. However, the function always copies the complete contents of str, and sets *lenp to the true length of the string (when lenp is non-null).

Function void gh get substr (SCM str, char *return_str, int *lenp)

Copy len characters at start from the Scheme string src to memory at dst. start is an index into src; zero means the beginning of the string. dst has already been allocated by the caller. If start + len is off the end of src, signal an out-of-range error.

Function char *gh symbol2newstr (SCM sym, int *lenp)

Takes a Scheme symbol and returns a string of the form "'symbol-name". If lenp is non-null, the string’s length is returned in *lenp. This function uses malloc to obtain storage for the returned string; the caller is responsible for freeing it.

Function char *gh scm2chars (SCM vector, chars *result) Function short *gh scm2shorts (SCM vector, short *result) Function long *gh scm2longs (SCM vector, long *result) Function float *gh scm2floats (SCM vector, float *result) Function double *gh scm2doubles (SCM vector, double *result)

Copy the numbers in vector to the array pointed to by result and return it. If result is NULL, allocate a double array large enough. vector can be an ordinary vector, a weak vector, or a signed or unsigned uniform vector of the same type as the result array. For chars, vector can be a string or substring. For floats and doubles, vector can contain a mix of inexact and integer values. If vector is of unsigned type and contains values too large to fit in the signed destination array, those values will be wrapped around, that is, data will be copied as if the destination array was unsigned.

52 Type predicates

These C functions mirror Scheme’s type predicate procedures with one important difference. The C routines return C boolean values (0 and 1) instead of SCM_BOOL_T and

SCM_BOOL_F.

The Scheme notational convention of putting a ? at the end of predicate procedure names is mirrored in C by placing _p at the end of the procedure. For example, (pair? ...) maps

to gh_pair_p(...).

Function int gh boolean p (SCM val)

Returns 1 if val is a boolean, 0 otherwise.

Function int gh symbol p (SCM val)

Returns 1 if val is a symbol, 0 otherwise.

Function int gh char p (SCM val)

Returns 1 if val is a char, 0 otherwise.

Function int gh vector p (SCM val)

Returns 1 if val is a vector, 0 otherwise.

Function int gh pair p (SCM val)

Returns 1 if val is a pair, 0 otherwise.

Function int gh procedure p (SCM val)

Returns 1 if val is a procedure, 0 otherwise.

Function int gh list p (SCM val)

Returns 1 if val is a list, 0 otherwise.

Function int gh inexact p (SCM val)

Returns 1 if val is an inexact number, 0 otherwise.

Function int gh exact p (SCM val)

Returns 1 if val is an exact number, 0 otherwise.

53 Equality predicates

These C functions mirror Scheme’s equality predicate procedures with one important difference. The C routines return C boolean values (0 and 1) instead of SCM_BOOL_T and

SCM_BOOL_F.

The Scheme notational convention of putting a ? at the end of predicate procedure names is mirrored in C by placing _p at the end of the procedure. For example, (equal? ...)

maps to gh_equal_p(...).

Function int gh eq p (SCM x, SCM y)

Returns 1 if x and y are equal in the sense of Scheme’s eq? predicate, 0 otherwise.

Function int gh eqv p (SCM x, SCM y)

Returns 1 if x and y are equal in the sense of Scheme’s eqv? predicate, 0 otherwise.

Function int gh equal p (SCM x, SCM y)

Returns 1 if x and y are equal in the sense of Scheme’s equal? predicate, 0 otherwise.

Function int gh string equal p (SCM s1, SCM s2)

Returns 1 if the strings s1 and s2 are equal, 0 otherwise.

Function int gh null p (SCM l)

Returns 1 if l is an empty list or pair; 0 otherwise.

Chapter 54: Memory allocation and garbage collection 135

54 Memory allocation and garbage collection 55 Calling Scheme procedures from C

Many of the Scheme primitives are available in the gh_interface; they take and return objects of type SCM, and one could basically use them to write C code that mimics Scheme code.

I will list these routines here without much explanation, since what they do is the same as documented in section “Standard Procedures” in R4RS. But I will point out that when a procedure takes a variable number of arguments (such as gh_list), you should pass the constant SCM EOL from C to signify the end of the list.

Function SCM gh define (char *name, SCM val)

Corresponds to the Scheme (define name val): it binds a value to the given name (which is a C string). Returns the new object.

Pairs and lists

Function SCM gh cons (SCM a, SCM b)

Function SCM gh list (SCM l0, SCM l1, ... , SCM_UNDEFINED)

These correspond to the Scheme (cons a b) and (list l0 l1 ...) procedures. Note that gh_list() is a C macro that invokes scm_listify().

Function SCM gh set car (SCM obj, SCM val) Function SCM gh set cdr (SCM obj, SCM val)

These correspond to the Scheme (set-car! ...) and (set-cdr! ...) procedures.

Function SCM gh car (SCM obj) Function SCM gh cdr (SCM obj)

…

Function SCM gh c[ad][ad][ad][ad]r (SCM obj)

These correspond to the Scheme (caadar ls) procedures etc …

Function SCM gh set car x(SCM pair, SCM value)

Modifies the CAR of pair to be value. This is equivalent to the Scheme proce-

dure (set-car! ...).

Function SCM gh set cdr x(SCM pair, SCM value)

Modifies the CDR of pair to be value. This is equivalent to the Scheme proce-

dure (set-cdr! ...).

Function unsigned long gh length (SCM ls)

Returns the length of the list.

Function SCM gh append (SCM args)

Function SCM gh append2 (SCM l1, SCM l2) Function SCM gh append3 (SCM l1, SCM l2, l3) Function SCM gh append4 (SCM l1, SCM l2, l3, l4)

gh_append() takes args, which is a list of lists (list1 list2 ...), and returns a list containing all the elements of the individual lists.

A typical invocation of gh_append() to append 5 lists together would be

       gh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED));
The functions gh_append2(), gh_append2(), gh_append3() and gh_append4()

are convenience routines to make it easier for C programs to form the list of lists that goes as an argument to gh_append().

Function SCM gh reverse (SCM ls)

Returns a new list that has the same elements as ls but in the reverse order. Note that this is implemented as a macro which calls scm_reverse().

Function SCM gh list tail (SCM ls, SCM k)

Returns the sublist of ls with the last k elements.

Function SCM gh list ref (SCM ls, SCM k)

Returns the kth element of the list ls.

Function SCM gh memq (SCM x, SCM ls) Function SCM gh memv (SCM x, SCM ls) Function SCM gh member (SCM x, SCM ls)

These functions return the first sublist of ls whose CAR is x. They correspond to (memq x ls), (memv x ls) and (member x ls), and hence use (respectively) eq?, eqv? and equal? to do comparisons.

If x does not appear in ls, the value SCM_BOOL_F (not the empty list) is returned.

Note that these functions are implemented as macros which call scm_memq(),

scm_memv() and scm_member() respectively.

Function SCM gh assq (SCM x, SCM alist) Function SCM gh assv (SCM x, SCM alist) Function SCM gh assoc (SCM x, SCM alist)

These functions search an association list (list of pairs) alist for the first pair whose CAR is x, and they return that pair.

If no pair in alist has x as its CAR, the value SCM_BOOL_F (not the empty list) is returned.

Note that these functions are implemented as macros which call scm_assq(),

scm_assv() and scm_assoc() respectively.

Symbols

Vectors

Function SCM gh make vector (SCM n, SCM fill) Function SCM gh vector (SCM ls) Function SCM gh vector ref (SCM v, SCM i)

Function SCM gh vector set (SCM v, SCM i, SCM val)

Function unsigned long gh vector length (SCM v) Function SCM gh list to vector (SCM ls)

These correspond to the Scheme (make-vector n fill), (vector a b c ...)
(vector-ref v i)(vector-set v i value)(vector-length v)(list->vector

ls) procedures.

The correspondence is not perfect for gh_vector: this routine taks a list ls instead of the individual list elements, thus making it identical to gh_list_to_

vector.

There is also a difference in gh vector length: the value returned is a C unsigned long instead of an SCM object.

Procedures

Function SCM gh apply (SCM proc, SCM args)

Call the Scheme procedure proc, with the elements of args as arguments. args must be a proper list.

Function SCM gh call0 (SCM proc)

Function SCM gh call1 (SCM proc, SCM arg)
Function SCM gh call2 (SCM proc, SCM arg1, SCM arg2)
Function SCM gh call3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)

Call the Scheme procedure proc with no arguments (gh_call0), one argument (gh_call1), and so on. You can get the same effect by wrapping the arguments up into a list, and calling gh_apply; Guile provides these functions for convenience.

Function SCM gh catch (SCM key, SCM thunk, SCM handler)
Function SCM gh throw (SCM key, SCM args)

Corresponds to the Scheme catch and throw procedures, which in Guile are provided as primitives.

Function SCM gh is eq (SCM a, SCM b) Function SCM gh is eqv (SCM a, SCM b)

Function SCM gh is equal (SCM a, SCM b)

These correspond to the Scheme eq?, eqv? and equal? predicates.

Function int gh obj length (SCM obj)

Returns the raw object length.

Data lookup

For now I just include Tim Pierce’s comments from the ‘gh_data.c’ file; it should be organized into a documentation of the two functions here.

/* Data lookups between C and Scheme
Look up a symbol with a given name, and return the object to which
it is bound.  gh_lookup examines the Guile top level, and
gh_module_lookup checks the module namespace specified by the
`vec' argument.
The return value is the Scheme object to which SNAME is bound, or
SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
should this be SCM_UNSPECIFIED?  Can a symbol ever legitimately be
bound to SCM_UNDEFINED or SCM_UNSPECIFIED?  What is the difference?
-twp] */

140 Guile Reference Manual

56 Mixing gh and scm APIs

Chapter 57: Scheme data representation 141

Part V: Using Scheme with C — Guile’s Low-Level Interface 57 Scheme data representation 58 Relationship between Scheme and C functions

— this is where we explain that all the functions marked as "Primitive Functions" are also accessible from C, and how to derive the C interface given the Scheme interface, when we don’t spell it out. ... I think there’s other stuff needed here ...

59 I/O internals

60 libguile error handling

Error handling is based on catch and throw.  Errors are always thrown with
a key and four arguments:
key: a symbol which indicates the type of error.  The symbols used
by libguile are listed below.
subr: the name of the procedure from which the error is thrown, or #f.
message: a string (possibly language and system dependent) describing the
error.  The tokens %s and %S can be embedded within the message: they
will be replaced with members of the args list when the message is
printed.  %s indicates an argument printed using "display", while %S
indicates an argument printed using "write".  message can also be #f,
to allow it to be derived from the key by the error handler (may be
useful if the key is to be thrown from both C and Scheme).
args: a list of arguments to be used to expand %s and %S tokens in message.
Can also be #f if no arguments are required.
rest: a list of any additional objects required. e.g., when the key is
'system-error, this contains the C errno value.  Can also be #f if no
additional objects are required.
In addition to catch and throw, the following Scheme facilities are
available:
(scm-error key subr message args rest): throw an error, with arguments
as described above.
(error msg arg ...)  Throw an error using the key 'misc-error.  The error
message is created by displaying msg and writing the args.
The following are the error keys defined by libguile and the situations
in which they are used:
error-signal: thrown after receiving an unhandled fatal signal such as
SIGSEV, SIGBUS, SIGFPE etc.  The "rest" argument in the throw contains
the coded signal number (at present this is not the same as the usual
Unix signal number).
system-error: thrown after the operating system indicates an error
condition.  The "rest" argument in the throw contains the errno value.

numerical-overflow: numerical overflow.
out-of-range: the arguments to a procedure do not fall within the
accepted domain.
wrong-type-arg: an argument to a procedure has the wrong thpe.
wrong-number-of-args: a procedure was called with the wrong number of
arguments.
memory-allocation-error: memory allocation error.
stack-overflow: stack overflow error.
regex-error: errors generated by the regular expression library.
misc-error: other errors.
C support
=========
SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest)
Throws an error, after converting the char * arguments to Scheme strings.
subr is the Scheme name of the procedure, NULL is converted to #f.
Likewise a NULL message is converted to #f.
The following procedures invoke scm_error with various error keys and
arguments.  The first three call scm_error with the system-error key
and automatically supply errno in the "rest" argument:  scm_syserror
generates messages using strerror,  scm_sysmissing is used when
facilities are not available.  Care should be taken that the errno
value is not reset (e.g., due to an interrupt.)
void scm_syserror (char *subr);
void scm_syserror_msg (char *subr, char *message, SCM args);
void scm_sysmissing (char *subr);
void scm_num_overflow (char *subr);
void scm_out_of_range (char *subr, SCM bad_value);
void scm_wrong_num_args (SCM proc);
void scm_wrong_type_arg (char *subr, int pos, SCM bad_value);
void scm_memory_error (char *subr);
static void scm_regex_error (char *subr, int code); (only used in rgx.c).
void (*scm_error_callback) (SCM key, char *subr, char *message,
    SCM args, SCM rest));

When a pointer to a C procedure is assigned to this variable, the procedure
will be called whenever scm_error is invoked.  It can be used by C
code to retain control after a Scheme error occurs.

146 Guile Reference Manual

61 snarfing Appendices and Indices

Appendix A Obtaining and Installing Guile

Here is the information you will need to get and install Guile and extra packages and documentation you might need or find interesting.

A.1 The Basic Guile Package

Guile can be obtained from the main GNU archive site ftp://prep.ai.mit.edu/pub/gnu or any of its mirrors. The file will be named guile-version.tar.gz. The current version is 1.2a, so the file you should grab is:

   ftp://prep.ai.mit.edu/pub/gnu/guile-1.2a.tar.gz

To unbundle Guile use the instruction

     zcat guile-1.2a.tar.gz | tar xvf -

which will create a directory called ‘guile-1.2a’ with all the sources. You can look at the file ‘INSTALL’ for detailed instructions on how to build and install Guile, but you should be able to just do

     cd guile-1.2a
     ./configure
     make install

This will install the Guile executable ‘guile’, the Guile library ‘libguile.a’ and various associated header files and support libraries. It will also install the Guile tutorial and reference manual.

Since this manual frequently refers to the Scheme “standard”, also known as R4RS, or the “Revised$^4$ Report on the Algorithmic Language Scheme”, we have included the report in the Guile distribution; See section “Introduction” in Revised(4) Report on the Algorithmic Language Scheme. This will also be installed in your info directory.

A.2 Packages not shipped with Guile

We ship the Guile tutorial and reference manual with the Guile distribution [FIXME: this is not currently true (Sat Sep 20 14:13:33 MDT 1997), but will be soon.] Since the Scheme standard (R4RS) is a stable document, we ship that too.

Here are references (usually World Wide Web URLs) to some other freely redistributable documents and packages which you might find useful if you are using Guile.

SCSH the Scheme Shell. Gary Houston has ported SCSH to Guile. The relevant chapter (see ⟨undefined⟩ [The Scheme shell (scsh)], page ⟨undefined⟩) has references to the SCSH web page with all its documentation.

SLIB a portable Scheme library maintained by Aubrey Jaffer. SLIB can be obtained

          by ftp from ftp://prep.ai.mit.edu/pub/gnu/jacal/.

The SLIB package should be unpacked somewhere in Guile’s load path. It will typically be unpacked in ‘/usr/local/share/guile/site’, so that it will be

‘/usr/local/share/guile/site/slib’.

Guile might have been installed with a different prefix, in which case the load path can be checked from inside the interpreter with:

     guile> %load-path
     ("/usr/local/share/guile/site" "/usr/local/share/guile/1.3a" "/usr/local/share/guile" ".")

The relevant chapter (see ⟨undefined⟩ [SLIB], page ⟨undefined⟩) has details on how to use SLIB with Guile.

JACAL a symbolic math package by Aubrey Jaffer. The latest version of Jacal

can be obtained from ftp://prep.ai.mit.edu/pub/gnu/jacal/, and should
be unpacked in ‘/usr/local/share/guile/site/slib’ so that it will be in
‘/usr/local/share/guile/site/slib/jacal’.

The relevant section (see ⟨undefined⟩ [JACAL], page ⟨undefined⟩) has details on how to use Jacal.

Appendix B: Reporting Bugs 149

Appendix B Reporting Bugs

Any problems with the installation should be reported to bug-guile@gnu.ai.mit.edu [[how about an explanation of what makes a good bug report?]] [[don’t complain to us

about problems with contributed modules?]]

Appendix C Internals

This appendix describes many functions that may be used to inspect and modify Guile’s internal structure. These will mainly be of interest to people interested in extending, modifying or debugging Guile.

C.1 Symbols

Guile symbol tables are hash tables. Each hash table, also called an obarray (for ‘object array’), is a vector of association lists. Each entry in the alists is a pair (SYMBOL . VALUE). To intern a symbol in a symbol table means to return its (SYMBOL . VALUE) pair, adding a new entry to the symbol table (with an undefined value) if none is yet present.

primitive string->obarray-symbol obarray string [soft?]

Intern a new symbol in obarray, a symbol table, with name string. If obarray is #f, use the default system symbol table. If obarray is #t, the symbol should not be interned in any symbol table; merely return the pair (symbol . #<undefined>). The soft? argument determines whether new symbol table entries should be created when the specified symbol is not already present in obarray. If soft? is specified and is a true value, then new entries should not be added for symbols not already present in the table; instead, simply return #f.

primitive intern-symbol obarray string

Add a new symbol to obarray with name string, bound to an unspecified initial value. The symbol table is not modified if a symbol with this name is already present.

primitive unintern-symbol obarray string

Remove the symbol with name string from obarray. This function returns #t if the symbol was present and #f otherwise.

primitive symbol-binding obarray string

Look up in obarray the symbol whose name is string, and return the value to which it is bound. If obarray is #f, use the global symbol table. If string is not interned in obarray, an error is signalled.

primitive symbol-interned? obarray string

Return #t if obarray contains a symbol with name string, and #f otherwise.

primitive symbol-bound? obarray string

Return #t if obarray contains a symbol with name string bound to a defined value. This differs from symbol-bound? in that the mere mention of a symbol usually causes it to be interned; symbol-bound? determines whether a symbol has been given any meaningful value.

primitive symbol-set! obarray string value Find the symbol in obarray whose name is string, and rebind it to value. An error is signalled if string is not present in obarray.

primitive symbol-fref symbol

Return the contents of symbol’s function slot.

primitive symbol-pref symbol

Return the property list currently associated with symbol.

primitive symbol-fset! symbol

Change the binding of symbol’s function slot.

primitive symbol-pset! symbol

Change the binding of symbol’s property slot.

primitive symbol-hash symbol

Return the hash value derived from symbol’s name, i.e. the integer index into symbol’s obarray at which it is stored.

primitive builtin-bindings

Create and return a copy of the global symbol table, removing all unbound symbols.

primitive builtin-weak-bindings

primitive gensym [name [obarray]] Create a new, unique symbol in obarray, using the global symbol table by default. If name is specified, it should be used as a prefix for the new symbol’s name. The default prefix is %%gensym.

Appendix D debugger user interface

When debugging a program, programmers often find it helpful to examine the program’s internal status while it runs: the values of internal variables, the choices made in if and cond statements, and so forth. Guile Scheme provides a debugging interface that programmers can use to single-step through Scheme functions and examine symbol bindings. This is different from the ⟨undefined⟩ [Internal Debugging Interface], page ⟨undefined⟩, which permits programmers to debug the Guile interpreter itself. Most programmers will be more interested in debugging their own Scheme programs than the interpreter which evaluates them.

[FIXME: should we include examples of traditional debuggers and explain why they can’t be used to debug interpreted Scheme or Lisp?]

D.1 Single-Step

D.2 Trace

When a function is traced, it means that every call to that function is reported to the user during a program run. This can help a programmer determine whether a function is being called at the wrong time or with the wrong set of arguments.

Function trace function Enable debug tracing on function. While a program is being run, Guile will print a brief report at each call to a traced function, advising the user which function was called and the arguments that were passed to it.

Function untrace function Disable debug tracing for function.

Example:

     (define (rev ls)
       (if (null? ls)
           '()
           (append (rev (cdr ls))
                   (cons (car ls) '())))) ⇒ rev
     (trace rev) ⇒ (rev)
     (rev '(a b c d e))
     ⇒ [rev (a b c d e)]
        |  [rev (b c d e)]
        |  |  [rev (c d e)]
        |  |  |  [rev (d e)]
        |  |  |  |  [rev (e)]
        |  |  |  |  |  [rev ()]
        |  |  |  |  |  ()
        |  |  |  |  (e)

|  |  |  (e d)
|  |  (e d c)
|  (e d c b)
(e d c b a)
(e d c b a)

Note the way Guile indents the output, illustrating the depth of execution at each function call. This can be used to demonstrate, for example, that Guile implements selftail-recursion properly:

(define (rev ls sl)
(if (null? ls)
   sl
   (rev (cdr ls)
        (cons (car ls) sl)))) ⇒ rev
(trace rev) ⇒ (rev)
(rev '(a b c d e) '())
⇒ [rev (a b c d e) ()]
[rev (b c d e) (a)]
[rev (c d e) (b a)]
[rev (d e) (c b a)]
[rev (e) (d c b a)]
[rev () (e d c b a)]
(e d c b a)
(e d c b a)

Since the tail call is effectively optimized to a goto statement, there is no need for Guile to create a new stack frame for each iteration. Using trace here helps us see why this is so.

D.3 Backtrace

D.4 Stacks and Frames

When a running program is interrupted, usually upon reaching an error or breakpoint, its state is represented by a stack of suspended function calls, each of which is called a frame. The programmer can learn more about the program’s state at the point of interruption by inspecting and modifying these frames.

primitive stack? obj

Return #t if obj is a calling stack.

primitive make-stack

syntax start-stack id exp

Evaluate exp on a new calling stack with identity id. If exp is interrupted during evaluation, backtraces will not display frames farther back than exp’s top-level form. This macro is a way of artificially limiting backtraces and stack procedures, largely as a convenience to the user.

primitive stack-id stack

Return the identifier given to stack by start-stack.

primitive stack-ref primitive stack-length primitive frame? primitive last-stack-frame primitive frame-number primitive frame-source primitive frame-procedure primitive frame-arguments primitive frame-previous primitive frame-next primitive frame-real? primitive frame-procedure? primitive frame-evaluating-args? primitive frame-overflow

Concept Index

(Index is nonexistent)

Procedure Index

This is an alphabetical list of all the procedures and macros in Guile. [[Remind people to look for functions under their Scheme names as well as their C names.]]

(Index is nonexistent)

Variable Index

This is an alphabetical list of all the important variables and constants in Guile. [[Remind people to look for variables under their Scheme names as well as their C names.]]

(Index is nonexistent)

Type Index 155

Type Index

This is an alphabetical list of all the important data types defined in the Guile Programmers Manual.

(Index is nonexistent)

156 Guile Reference Manual

Table of Contents

Part I: Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1 Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Running Guile Interactively . . . . . . . . . . . . . . . . 3

3 Guile Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

3.1 The Top of a script file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3.2 Invoking Guile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.3 The Meta Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.4 Scripting Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

4 Linking Programs With Guile . . . . . . . . . . . . . . 9

4.1 Guile Initialization Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4.2 A Sample Guile Main Program . . . . . . . . . . . . . . . . . . . . . . . . . . 10

5 Writing Guile Modules . . . . . . . . . . . . . . . . . . . . 13

Part II: Scheme Extensions . . . . . . . . . . . . . . . . . . . 14

6 Extensions to Scheme . . . . . . . . . . . . . . . . . . . . . 15

6.1 Guile options interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6.1.1 General option interface . . . . . . . . . . . . . . . . . . . . . . . . 15 6.1.2 Reader options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 6.1.3 Printing options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6.1.4 Evaluator options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6.1.5 Debugger options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6.1.6 Examples of option use. . . . . . . . . . . . . . . . . . . . . . . . . 17

7 SLIB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

7.1 JACAL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

8 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

9 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 10 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . 26

10.1 Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 10.2 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

10.2.1 Structure Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 10.2.2 Structure Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 10.2.3 Structure Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 10.2.4 Vtables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

10.3 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 10.3.1 Conventional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 33 10.3.2 Array Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 10.3.3 Uniform Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 10.3.4 Bit Vectors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

10.4 Association Lists and Hash Tables . . . . . . . . . . . . . . . . . . . . . . 38 10.4.1 Dictionary Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 10.4.2 Association Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 10.4.3 Hash Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

11 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

11.1 String Fun. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 11.2 Shared Substrings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 11.3 Read Only Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

12 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

13 Property Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

14 Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

14.1 File Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 14.2 Soft Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 14.3 String Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 14.4 Closing Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 14.5 Port Operations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 14.6 Extended I/O (fseek and line read/write) . . . . . . . . . . . . . . . 51

15 Bitwise Operations . . . . . . . . . . . . . . . . . . . . . . 54

16 Regular Expressions . . . . . . . . . . . . . . . . . . . . . 56

16.1 Regexp Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 16.2 Match Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 16.3 Backslash Escapes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 16.4 Rx Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

17 Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

18 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 19 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

19.1 Scheme and modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 19.2 The Guile module system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

20 Module Internals . . . . . . . . . . . . . . . . . . . . . . . . 68

20.1 First-class Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 20.2 First-class Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 20.3 Dynamic Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

21 Dynamic Linking from Marius . . . . . . . . . . . . 70

21.1 Low level dynamic linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 21.2 Putting Compiled Code into Modules . . . . . . . . . . . . . . . . . . . 72 21.3 Dynamic Linking and Compiled Code Modules . . . . . . . . . . 73

22 Dynamic Wind . . . . . . . . . . . . . . . . . . . . . . . . . . 76

23 Threads and Dynamic Roots . . . . . . . . . . . . . 78

23.1 Dynamic Roots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 23.2 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

23.2.1 Low level thread primitives . . . . . . . . . . . . . . . . . . . . 79 23.2.2 Higher level thread procedures. . . . . . . . . . . . . . . . . 80

24 Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

24.1 eval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 24.2 Tag Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

25 Weak References . . . . . . . . . . . . . . . . . . . . . . . . 83

25.1 Weak key hashes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 25.2 Weak vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

26 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . 85

27 Configuration Data . . . . . . . . . . . . . . . . . . . . . . 86

28 Internal Debugging Interface . . . . . . . . . . . . . 87

Part III: Unix Programming . . . . . . . . . . . . . . . . . . 88

29 POSIX Interface Conventions . . . . . . . . . . . . 88

30 Ports and File Descriptors . . . . . . . . . . . . . . . 89

31 File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

iv Guile Reference Manual

32 User Information . . . . . . . . . . . . . . . . . . . . . . . . 97 33 Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 34 Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 35 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 36 Terminals and Ptys . . . . . . . . . . . . . . . . . . . . . 107 37 Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 38 Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

38.1 Networking Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 38.2 Network sockets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

39 System Identification . . . . . . . . . . . . . . . . . . . 116 40 Locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 41 Expect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 42 The Scheme shell (scsh). . . . . . . . . . . . . . . . . 120 43 Tcl/Tk Interface. . . . . . . . . . . . . . . . . . . . . . . . 121 Part IV: Using Scheme with C — a Portable

Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 44 A Portable C to Scheme Interface . . . . . . . 122 45 gh preliminaries . . . . . . . . . . . . . . . . . . . . . . . . 123 46 Data types and constants defined by gh . . 124 47 Starting and controlling the interpreter . . 125 48 Error messages . . . . . . . . . . . . . . . . . . . . . . . . . 128 49 Executing Scheme code . . . . . . . . . . . . . . . . . 129 50 Defining new Scheme procedures in C … 130 51 Converting data between C and Scheme. . 131

51.1 C to Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 51.2 Scheme to C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

52 Type predicates . . . . . . . . . . . . . . . . . . . . . . . . 133 53 Equality predicates . . . . . . . . . . . . . . . . . . . . . 134 54 Memory allocation and garbage collection

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 55 Calling Scheme procedures from C . . . . . . 136 56 Mixing gh and scm APIs . . . . . . . . . . . . . . . . 140 Part V: Using Scheme with C — Guile’s

Low-Level Interface . . . . . . . . . . . . . . . . . . . . . 141 57 Scheme data representation . . . . . . . . . . . . . 141 58 Relationship between Scheme and C functions

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 59 I/O internals . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 60 libguile error handling . . . . . . . . . . . . . . . . . . 143 61 snarfing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Appendices and Indices . . . . . . . . . . . . . . . . . . . . . 147 Appendix A Obtaining and Installing Guile

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

A.1 The Basic Guile Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 A.2 Packages not shipped with Guile . . . . . . . . . . . . . . . . . . . . . . . 147

Appendix B Reporting Bugs . . . . . . . . . . . . . . . 149 Appendix C Internals. . . . . . . . . . . . . . . . . . . . . . 150

C.1 Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

Appendix D debugger user interface . . . . . . . . 152

D.1 Single-Step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 D.2 Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 D.3 Backtrace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 D.4 Stacks and Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

Concept Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Procedure Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Variable Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Type Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155