Previous Table of Contents Next


Part III
Guile

4  Guile: An Interpreter Core for Complete Applications

Chapter 4
Guile: An Interpreter Core for Complete Applications

by Jim Blandy

An interpreter for a programming language can form the core of a powerful, flexible, and robust design for large applications. Done correctly, programs designed around an interpreter for an application-specific language are easy to configure and to extend, allow clear access to their central features, and age gracefully. However, a good interpreter is a substantial project in its own right, and it is difficult to design programming languages that age well. Thus, many developers are reluctant to use interpreter-based architectures for their projects.

Guile is Project GNU’s attempt to address these concerns. Guile is a library containing an interpreter for Scheme, a clean, economical programming language in the Lisp family. When integrated into an application, Guile provides a neutral base language that developers can customize with functions, syntax, and data types appropriate to the application at hand. Guile allows developers to escape the tasks of language design and implementation, making it easier for them to offer their users a complete and well-defined extension language.

In Guile-based programs, the performance of the interpreter is not critical because the developer does not implement the application in the interpreted language. Instead, the developer implements critical algorithms and data structures in C or C++ and exports the functions and types for use by interpreted code. The application becomes a library of primitives orchestrated by the interpreter, combining the efficiency of compiled code with the flexibility of interpretation.

The choice of a Lisp-like language for Guile is controversial; many programmers prefer a more traditional infix notation to Lisp’s parenthese-heavy prefix syntax. However, Scheme is powerful enough that Guile can conveniently translate other languages into it. Users may customize and extend Guile-based applications in any language for which a translator exists. The original developer of the application does not need to choose a language for users. At the moment, Guile has a translator for CTAX, a language syntactically very similar to C; I hope the Guile user community will contribute others.

This chapter

  Describes Guile in its natural state
  Presents an example of a Guile-based application
  Points out features that make Guile especially well suited for use as an embedded language
  Provides hints on how to use Guile most effectively
  Compares Guile with two other similar libraries, Tcl and Python

SCWM (scheme window manager) is a window manager for the X Window system based on Guile, currently under development by Maciej Stachowiak and Greg Badros. In this chapter, I frequently use SCWM as a case study, reflecting one way to embed an application’s concepts in Guile.

4.1. Pure Guile

In its simplest form, Guile is a command-line interpreter for Scheme. Like a shell, Guile can be used interactively or as an interpreter for script files. Here is a transcript of an interaction with Guile:

     $ guile
     Sum some numbers.
     guile> (+ 1 2 3)
     6
     Define a function.
     guile> (define (factorial n)
            (if (zero? n) 1 (* n (factorial (- n 1)))))
     Compute 4!.
     guile> (factorial 4)
     24
     Look up an entry in the user database.
     guile> (getpwnam “jimb”)
     #(“jimb” “.0krIpK2VqNbU” 4008 10 “Jim Blandy” “/u/jimb”
       “/usr/local/bin/bash”)
     guile> ^D
     $

Guile can also be used as a script interpreter. For example, what follows is the code for httpc, a trivial client for the HTTP protocol. It takes two command-line arguments: the HTTP operation to perform and the URL to which to apply it. Given these, it performs the request and displays the reply on its standard output.

     #!/usr/local/bin/guile -s
     !#

     ;;; Get functions from URL and HTTP modules, and prefix
     ;;; the function names with the module names, for clarity.

     ;; thanks to Tim Pierce for the WWW library
     (use-modules (www url)
          (www http))

     ;;; All error-checking code omitted, for brevity.
     (let* ((args (program-arguments))
          (method (list-ref args 1))
          (url (list-ref args 2)))
     (display (http:message-body
          (http:request method (url:parse url)))))

Here is a sample interaction with the script:

     $ httpc GET http://www.linux.org/
     <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2//EN”>
     <HTML>
     <HEAD>
     <TITLE>Welcome to the Linux Home Page</TITLE>
     </HEAD>
     <BODY>
     … the rest of the LINUX.ORG home page follows …


Previous Table of Contents Next