This chapter presents a quick tour of all the ways that Guile can be used.
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
$
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)
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:
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)
To start with, here are some examples of invoking Guile directly:
guile -- a b c
(command-line) will return ("/usr/local/bin/guile" "a" "b" "c").
guile -s /u/jimb/ex2 a b c
(command-line) will return ("/u/jimb/ex2" "a" "b" "c").
guile -c '(write %load-path) (newline)'
%load-path, print a newline,
and exit.
guile -e main -s /u/jimb/ex4 foo
main, passing it the list ("/u/jimb/ex4" "foo").
guile -l first -ds -l last -s script
-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
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 section Identical Function in both Scheme and C.
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 need to link them
against the Guile object code library, libguile.
On most systems, you should not need to tell the compiler and linker
explicitly where they can find `libguile.h' and `libguile'.
When Guile has been installed in a peculiar way, or when you are on a
peculiar system, things might not be so easy and you might need to pass
additional -I or -L options to the compiler. Guile
provides the utility program guile-config to help you find the
right values for these options. You would typically run
guile-config during the configuration phase of your program and
use the obtained information in the Makefile.
To initialize Guile, you can use one of two functions. The first,
scm_boot_guile, is the most portable way to initialize Guile. It
should be used whenever you have control over the main function of your
program because it never returns. The second function,
scm_init_guile, does return and can thus be used in more
situations. However, scm_init_guile is not as widely available
as scm_boot_guile because it needs to rely on non-portable code
to find the stack bounds. When Guile does not know how to find these
bounds on your system, it will not provide scm_init_guile.
When you can tolerate the limits of scm_boot_guile, you should
use it in favor of scm_init_guile since that will make your
program more portable.
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.
Why must the caller do all the real work from main_func? Guile's
garbage collector scans the stack to find all local variables that
reference Scheme objects. To do this, it needs to know the bounds of
the stack that might contain such references. Because there is no
portable way in C to find the base of the stack, scm_boot_guile
assumes that all references are above its own stack frame. 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.
See scm_init_guile, below, for a function that can find the real
base of the stack, but not in a portable way.
In contrast to scm_boot_guile, this function knows how to find
the true base of the stack and thus does not need to usurp the control
flow of your program. However, since finding the stack base can not be
done portably, this function might not be available in all installations
of Guile. If you can, you should use scm_boot_guile instead.
Note that scm_init_guile does not inform Guile about the command
line arguments that should be returned by the Scheme function
command-line. You can use scm_set_program_arguments to do
this.
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:
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 section Invoking Guile, for more details.
Since this function does not return, you must do all application-specific initialization before calling this function.
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. It
uses guile-config to learn about the necessary compiler and
linker flags.
# Use GCC, if you have it installed.
CC=gcc
# Tell the C compiler where to find <libguile.h>
CFLAGS=`guile-config compile`
# Tell the linker what libraries to use and where to find them.
LIBS=`guile-config link`
simple-guile: simple-guile.o
${CC} 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. Guile also provides the GUILE_FLAGS
macro for autoconf that performs all necessary checks. Here is a
`configure.in' file for simple-guile that uses this macro.
Autoconf can use as this file as template to generate a configure
script. In order for Autoconf to find the GUILE_FLAGS macro, you
will need to run aclocal first. This is not really Guile
specific, so you should refer to the Autoconf documentation REFFIXME
when in doubt.
AC_INIT(simple-guile.c) # Find a C compiler. AC_PROG_CC # Check for Guile GUILE_FLAGS # 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=@GUILE_CFLAGS@
LIBS=@GUILE_LDFLAGS@
simple-guile: simple-guile.o
${CC} 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... (cached) 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... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for Guile... yes
creating ./config.status
creating Makefile
$ make
gcc -c -I/usr/local/include simple-guile.c
gcc simple-guile.o -L/usr/local/lib -lguile -lqthreads -lpthread -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)
$
The previous sections have briefly explained how to write programs that
make use of an embedded Guile interpreter. But sometimes, all you want
to do is make new primitive procedures and data types available to the
Scheme programmer. Writing a new version of guile is
inconvenient in this case and it would in fact make the life of the
users of your new features needlessly hard.
For example, suppose that there is a program guile-db that is a
version of Guile with additional features for accessing a database.
People who want to write Scheme programs that use these features would
have to use guile-db instead of the usual guile program.
Now suppose that there is also a program guile-gtk that extends
Guile with access to the popular Gtk+ toolkit for graphical user
interfaces. People who want to write GUIs in Scheme would have to use
guile-gtk. Now, what happens when you want to write a Scheme
application that uses a GUI to let the user access a database? You
would have to write a third program that incorporates both the
database stuff and the GUI stuff. This might not be easy (because
guile-gtk might be a quite obscure program, say) and taking this
example further makes it easy to see that this approach can not work in
practice.
It would have been much better if both the database features and the GUI
feature had been provided as libraries that can just be linked with
guile. Guile makes it easy to do just this, and we encourage you
to make your extensions to Guile available as libraries whenever
possible.
You write the new primitive procedures and data types in the normal fashion, and link them into a shared library instead of into a stand-alone program. The shared library can then be loaded dynamically by Guile.
This section explains how to make the Bessel functions of the C library
available to Scheme. 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.
Consider the following file `bessel.c'.
#include <math.h>
#include <libguile.h>
SCM
j0_wrapper (SCM x)
{
return scm_make_real (j0 (scm_num2dbl (x, "j0")));
}
void
init_bessel ()
{
scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
}
This C source file needs to be compiled into a shared library. Here is how to do it on GNU/Linux:
gcc -shared -o libguile-bessel.so -fPIC bessel.c
For creating shared libraries portably, we recommend the use of
GNU Libtool.
A shared library can be loaded into a running Guile process with the
function load-extension. In addition to the name of the
library to load, this function also expects the name of function from
that library that will be called to initialize it. For our example,
we are going to call the function init_bessel which will make
j0_wrapper available to Scheme programs with the name
j0. Note that we do not specify a filename extension such as
`.so' when invoking load-extension. The right extension for
the host platform will be provided automatically.
(load-extension "libguile-bessel" "init_bessel") (j0 2) => 0.223890779141236
For this to work, load-extension must be able to find
`libguile-bessel', of course. It will look in the places that
are usual for your operating system, and it will additionally look
into the directories listed in the LTDL_LIBRARY_PATH
environment variable.
To see how these Guile extensions via shared libraries relate to the module system, see below See section Intro to Modules and Extensions.
Guile has support for dividing a program into modules. By using modules, you can group related code together and manage the composition of complete programs from largely independent parts.
(Although the module system implementation is in flux, feel free to use it anyway. Guile will provide reasonable backwards compatibility.)
Details on the module system beyond this introductory material can be found in See section Modules.
Guile comes with a lot of useful modules, for example for string processing or command line parsing. Additionally, there exist many Guile modules written by other Guile hackers, but which have to be installed manually.
Existing modules have to be placed in places where Guile looks for them
by default or in colon-separated directories in the environment variable
GUILE_LOAD_PATH. When this variable is set, those directories
are searched first, then the the default. The following command
shows the complete list of directories searched:
guile -c '(write %load-path) (newline)'
Suppose you want to use the procedures and variables exported by the
module (ice-9 popen), which provides the means for communicating
with other processes over pipes. Add the following line to your
currently running Guile REPL or the top of your script file.
(use-modules (ice-9 popen))
This will load the module and make the procedures exported by
(ice-9 popen) automatically available. The next step could be to
open a pipe to `ls' and read the contents of the current directory,
one line at a time.
(define p (open-input-pipe "ls -l")) (read-line p) => "total 30" (read-line p) => "drwxr-sr-x 2 mgrabmue mgrabmue 1024 Mar 29 19:57 CVS"
Of course it is possible to write modules yourself. Using modules for structuring your programs makes them more readable and lets you distribute them more easily. Also, explicitly defining the procedures and variables which are exported from a module adds documentation to the source and specifies the interface a module provides.
In Guile, you can create new modules and switch to existing modules in
order to add bindings to them using the syntactic form
define-module.
(define-module (foo bar)) (define (frob x) x)
Will create the module (foo bar).(1) All definitions following this statement will add bindings
to the module (foo bar), and these bindings will not be visible
outside of the module. To make the bindings accessible to other
modules, you have to export them explicitly using one of the following
means:
export form:
(export frob)
define-module form with the keyword
export:
(define-module (foo bar) #:export (frob))
frob to use define-public, which
is a combination of define and export.
(define-public (frob x) x)
After exporting, other modules can access the exported items simply by
using use-modules to load the module (foo bar).
In addition to Scheme code you can also put things that are defined in C into a module.
You do this by writing a small Scheme file that defines the module.
That Scheme file in turn invokes load-extension to make the
features defined in C available. This works since all definitions
made by scm_c_define_gsubr etc. go into the current
module and define-module causes the newly defined module to be
current while the code that follows it is executed.
Suppose we want to put the Bessel function j0 from the example
extension into a module called (math bessel). We would have to
write a Scheme file with this contents
(define-module (math bessel)) (export j0) (load-extension "libguile-bessel" "init_bessel")
This file should of course be saved in the right place for autoloading, for example as `/usr/local/share/guile/math/bessel.scm'.
When init_bessel is called, the new (math bessel) module
is the current one. Thus, the call to scm_c_define_gsubr will
put the new definition for j0 into it, just as we want it.
The definitions made in the C code are not automatically exported from
a module. You need to explicitly list the ones you want to export in
export statements or with the :export option of
define-module.
There is also a way to manipulate the module system from C but only Scheme files can be autoloaded. Thus, we recommend that you define your modules in Scheme.
Go to the first, previous, next, last section, table of contents.