The Guile Reference Manual ************************** This reference manual documents Guile, GNU's Ubiquitous Intelligent Language for Extensions. This is edition 1.1 corresponding to Guile 1.8.5. Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with the no Invariant Sections, with the Front-Cover Texts being "A GNU Manual," and with the Back-Cover Text "You are free to copy and modify this GNU Manual.". A copy of the license is included in the section entitled "GNU Free Documentation License". Table of Contents ***************** The Guile Reference Manual 1 Preface 1.1 Layout of this Manual 1.2 Conventions used in this Manual 1.3 Contributors to this Manual 1.4 The Guile License 2 Introduction to Guile 2.1 What is Guile? 2.2 Obtaining and Installing Guile 2.3 A Whirlwind Tour 2.3.1 Running Guile Interactively 2.3.2 Running Guile Scripts 2.3.3 Linking Guile into Programs 2.3.4 Writing Guile Extensions 2.3.5 Using the Guile Module System 2.3.5.1 Using Modules 2.3.5.2 Writing new Modules 2.3.5.3 Putting Extensions into Modules 2.4 Discouraged and Deprecated 2.5 Reporting Bugs 3 Programming in Scheme 3.1 Basic Ideas in Scheme 3.1.1 Data Types, Values and Variables 3.1.1.1 Latent Typing 3.1.1.2 Values and Variables 3.1.1.3 Defining and Setting Variables 3.1.2 The Representation and Use of Procedures 3.1.2.1 Procedures as Values 3.1.2.2 Simple Procedure Invocation 3.1.2.3 Creating and Using a New Procedure 3.1.2.4 Lambda Alternatives 3.1.3 Expressions and Evaluation 3.1.3.1 Evaluating Expressions and Executing Programs 3.1.3.2 Tail calls 3.1.3.3 Using the Guile REPL 3.1.3.4 Summary of Common Syntax 3.1.4 The Concept of Closure 3.1.4.1 Names, Locations, Values and Environments 3.1.4.2 Local Variables and Environments 3.1.4.3 Environment Chaining 3.1.4.4 Lexical Scope 3.1.4.5 Closure 3.1.4.6 Example 1: A Serial Number Generator 3.1.4.7 Example 2: A Shared Persistent Variable 3.1.4.8 Example 3: The Callback Closure Problem 3.1.4.9 Example 4: Object Orientation 3.2 Guile's Implementation of Scheme 3.3 Guile Scripting 3.3.1 The Top of a Script File 3.3.2 Invoking Guile 3.3.3 The Meta Switch 3.3.4 Command Line Handling 3.3.5 Scripting Examples 3.4 Using Guile Interactively 3.4.1 Readline 3.4.2 Value History 3.4.3 Error Handling 3.4.4 Using the Interactive Debugger 3.4.4.1 Display Backtrace 3.4.4.2 Frame Selection 3.4.4.3 Frame Information 3.4.4.4 Frame Evaluation 3.4.4.5 Single Stepping and Continuing Execution 3.5 Using Guile in Emacs 3.5.1 GDS Introduction 3.5.2 GDS Architecture 3.5.3 Getting Started with GDS 3.5.3.1 Invoking GDS when an Exception Occurs 3.5.3.2 Accepting GDS Instructions at Any Time 3.5.3.3 Utility Guile Implementation 3.5.4 Working with GDS in Scheme Buffers 3.5.4.1 Access to Guile Help and Completion 3.5.4.2 Evaluating Scheme Code 3.5.5 Displaying the Scheme Stack 3.5.6 Continuing Execution 3.5.7 Associating Buffers with Clients 3.5.8 An Example GDS Session 3.6 Further Reading 4 Programming in C 4.1 Linking Programs With Guile 4.1.1 Guile Initialization Functions 4.1.2 A Sample Guile Main Program 4.2 Linking Guile with Libraries 4.2.1 A Sample Guile Extension 4.3 General concepts for using libguile 4.3.1 Dynamic Types 4.3.2 Garbage Collection 4.3.3 Control Flow 4.3.4 Asynchronous Signals 4.3.5 Multi-Threading 4.4 Defining New Types (Smobs) 4.4.1 Describing a New Type 4.4.2 Creating Instances 4.4.3 Type checking 4.4.4 Garbage Collecting Smobs 4.4.5 Garbage Collecting Simple Smobs 4.4.6 Remembering During Operations 4.4.7 Double Smobs 4.4.8 The Complete Example 4.5 Function Snarfing 4.6 An Overview of Guile Programming 4.6.1 How One Might Extend Dia Using Guile 4.6.1.1 Deciding Why You Want to Add Guile 4.6.1.2 Four Steps Required to Add Guile 4.6.1.3 How to Represent Dia Data in Scheme 4.6.1.4 Writing Guile Primitives for Dia 4.6.1.5 Providing a Hook for the Evaluation of Scheme Code 4.6.1.6 Top-level Structure of Guile-enabled Dia 4.6.1.7 Going Further with Dia and Guile 4.6.2 Why Scheme is More Hackable Than C 4.6.3 Example: Using Guile for an Application Testbed 4.6.4 A Choice of Programming Options 4.6.4.1 What Functionality is Already Available? 4.6.4.2 Functional and Performance Constraints 4.6.4.3 Your Preferred Programming Style 4.6.4.4 What Controls Program Execution? 4.6.5 How About Application Users? 5 API Reference 5.1 Overview of the Guile API 5.2 The SCM Type 5.3 Initializing Guile 5.4 Snarfing Macros 5.5 Simple Generic Data Types 5.5.1 Booleans 5.5.2 Numerical data types 5.5.2.1 Scheme's Numerical "Tower" 5.5.2.2 Integers 5.5.2.3 Real and Rational Numbers 5.5.2.4 Complex Numbers 5.5.2.5 Exact and Inexact Numbers 5.5.2.6 Read Syntax for Numerical Data 5.5.2.7 Operations on Integer Values 5.5.2.8 Comparison Predicates 5.5.2.9 Converting Numbers To and From Strings 5.5.2.10 Complex Number Operations 5.5.2.11 Arithmetic Functions 5.5.2.12 Scientific Functions 5.5.2.13 Primitive Numeric Functions 5.5.2.14 Bitwise Operations 5.5.2.15 Random Number Generation 5.5.3 Characters 5.5.4 Character Sets 5.5.4.1 Character Set Predicates/Comparison 5.5.4.2 Iterating Over Character Sets 5.5.4.3 Creating Character Sets 5.5.4.4 Querying Character Sets 5.5.4.5 Character-Set Algebra 5.5.4.6 Standard Character Sets 5.5.5 Strings 5.5.5.1 String Read Syntax 5.5.5.2 String Predicates 5.5.5.3 String Constructors 5.5.5.4 List/String conversion 5.5.5.5 String Selection 5.5.5.6 String Modification 5.5.5.7 String Comparison 5.5.5.8 String Searching 5.5.5.9 Alphabetic Case Mapping 5.5.5.10 Reversing and Appending Strings 5.5.5.11 Mapping, Folding, and Unfolding 5.5.5.12 Miscellaneous String Operations 5.5.5.13 Conversion to/from C 5.5.6 Regular Expressions 5.5.6.1 Regexp Functions 5.5.6.2 Match Structures 5.5.6.3 Backslash Escapes 5.5.7 Symbols 5.5.7.1 Symbols as Discrete Data 5.5.7.2 Symbols as Lookup Keys 5.5.7.3 Symbols as Denoting Variables 5.5.7.4 Operations Related to Symbols 5.5.7.5 Function Slots and Property Lists 5.5.7.6 Extended Read Syntax for Symbols 5.5.7.7 Uninterned Symbols 5.5.8 Keywords 5.5.8.1 Why Use Keywords? 5.5.8.2 Coding With Keywords 5.5.8.3 Keyword Read Syntax 5.5.8.4 Keyword Procedures 5.5.9 "Functionality-Centric" Data Types 5.6 Compound Data Types 5.6.1 Pairs 5.6.2 Lists 5.6.2.1 List Read Syntax 5.6.2.2 List Predicates 5.6.2.3 List Constructors 5.6.2.4 List Selection 5.6.2.5 Append and Reverse 5.6.2.6 List Modification 5.6.2.7 List Searching 5.6.2.8 List Mapping 5.6.3 Vectors 5.6.3.1 Read Syntax for Vectors 5.6.3.2 Dynamic Vector Creation and Validation 5.6.3.3 Accessing and Modifying Vector Contents 5.6.3.4 Vector Accessing from C 5.6.4 Uniform Numeric Vectors 5.6.5 Bit Vectors 5.6.6 Generalized Vectors 5.6.7 Arrays 5.6.7.1 Array Syntax 5.6.7.2 Array Procedures 5.6.7.3 Shared Arrays 5.6.7.4 Accessing Arrays from C 5.6.8 Records 5.6.9 Structures 5.6.9.1 Vtables 5.6.9.2 Structure Basics 5.6.9.3 Vtable Contents 5.6.9.4 Vtable Vtables 5.6.10 Dictionary Types 5.6.11 Association Lists 5.6.11.1 Alist Key Equality 5.6.11.2 Adding or Setting Alist Entries 5.6.11.3 Retrieving Alist Entries 5.6.11.4 Removing Alist Entries 5.6.11.5 Sloppy Alist Functions 5.6.11.6 Alist Example 5.6.12 Hash Tables 5.6.12.1 Hash Table Examples 5.6.12.2 Hash Table Reference 5.7 Smobs 5.8 Procedures and Macros 5.8.1 Lambda: Basic Procedure Creation 5.8.2 Primitive Procedures 5.8.3 Optional Arguments 5.8.3.1 let-optional Reference 5.8.3.2 let-keywords Reference 5.8.3.3 lambda* Reference 5.8.3.4 define* Reference 5.8.4 Procedure Properties and Meta-information 5.8.5 Procedures with Setters 5.8.6 Lisp Style Macro Definitions 5.8.7 The R5RS `syntax-rules' System 5.8.7.1 The `syntax-rules' Pattern Language 5.8.7.2 Top Level Syntax Definitions 5.8.7.3 Local Syntax Definitions 5.8.8 Support for the `syntax-case' System 5.8.9 Internal Representation of Macros and Syntax 5.9 General Utility Functions 5.9.1 Equality 5.9.2 Object Properties 5.9.2.1 Low Level Property Implementation. 5.9.2.2 An Older Approach to Properties 5.9.3 Sorting 5.9.4 Copying Deep Structures 5.9.5 General String Conversion 5.9.6 Hooks 5.9.6.1 Hook Usage by Example 5.9.6.2 Hook Reference 5.9.6.3 Handling Scheme-level hooks from C code 5.9.6.4 Hooks For C Code. 5.9.6.5 Hooks for Garbage Collection 5.9.6.6 Hooks into the Guile REPL 5.10 Definitions and Variable Bindings 5.10.1 Top Level Variable Definitions 5.10.2 Local Variable Bindings 5.10.3 Internal definitions 5.10.4 Querying variable bindings 5.11 Controlling the Flow of Program Execution 5.11.1 Evaluating a Sequence of Expressions 5.11.2 Simple Conditional Evaluation 5.11.3 Conditional Evaluation of a Sequence of Expressions 5.11.4 Iteration mechanisms 5.11.5 Continuations 5.11.6 Returning and Accepting Multiple Values 5.11.7 Exceptions 5.11.7.1 Exception Terminology 5.11.7.2 Catching Exceptions 5.11.7.3 Throw Handlers 5.11.7.4 Catch Without Unwinding 5.11.7.5 Throwing Exceptions 5.11.7.6 How Guile Implements Exceptions 5.11.8 Procedures for Signaling Errors 5.11.9 Dynamic Wind 5.11.10 How to Handle Errors 5.11.10.1 C Support 5.12 Input and Output 5.12.1 Ports 5.12.2 Reading 5.12.3 Writing 5.12.4 Closing 5.12.5 Random Access 5.12.6 Line Oriented and Delimited Text 5.12.7 Block reading and writing 5.12.8 Default Ports for Input, Output and Errors 5.12.9 Types of Port 5.12.9.1 File Ports 5.12.9.2 String Ports 5.12.9.3 Soft Ports 5.12.9.4 Void Ports 5.12.10 Using and Extending Ports in C 5.12.10.1 C Port Interface 5.12.10.2 Port Implementation 5.13 Reading and Evaluating Scheme Code 5.13.1 Scheme Syntax: Standard and Guile Extensions 5.13.1.1 Expression Syntax 5.13.1.2 Comments 5.13.1.3 Block Comments 5.13.1.4 Case Sensitivity 5.13.1.5 Keyword Syntax 5.13.1.6 Reader Extensions 5.13.2 Reading Scheme Code 5.13.3 Procedures for On the Fly Evaluation 5.13.4 Loading Scheme Code from File 5.13.5 Delayed Evaluation 5.13.6 Local Evaluation 5.13.7 Evaluator Behaviour 5.14 Memory Management and Garbage Collection 5.14.1 Function related to Garbage Collection 5.14.2 Memory Blocks 5.14.2.1 Upgrading from scm_must_malloc et al. 5.14.3 Weak References 5.14.3.1 Weak hash tables 5.14.3.2 Weak vectors 5.14.4 Guardians 5.15 Objects 5.16 Modules 5.16.1 provide and require 5.16.2 Environments 5.16.3 The Guile module system 5.16.3.1 General Information about Modules 5.16.3.2 Using Guile Modules 5.16.3.3 Creating Guile Modules 5.16.3.4 Module System Reflection 5.16.3.5 Module System Quirks 5.16.3.6 Included Guile Modules 5.16.3.7 Accessing Modules from C 5.16.4 Dynamic Libraries 5.16.4.1 Low level dynamic linking 5.16.4.2 Putting Compiled Code into Modules 5.16.4.3 Dynamic Linking and Compiled Code Modules 5.16.4.4 Compiled Code Installation 5.16.5 Variables 5.17 Threads, Mutexes, Asyncs and Dynamic Roots 5.17.1 Arbiters 5.17.2 Asyncs 5.17.2.1 System asyncs 5.17.2.2 User asyncs 5.17.3 Continuation Barriers 5.17.4 Threads 5.17.5 Mutexes and Condition Variables 5.17.6 Blocking in Guile Mode 5.17.7 Critical Sections 5.17.8 Fluids and Dynamic States 5.17.9 Parallel forms 5.18 Configuration, Features and Runtime Options 5.18.1 Configuration, Build and Installation 5.18.2 Feature Tracking 5.18.2.1 Feature Manipulation 5.18.2.2 Common Feature Symbols 5.18.3 Runtime Options 5.18.3.1 Low Level Options Interfaces 5.18.3.2 User Level Options Interfaces 5.18.3.3 Reader options 5.18.3.4 Printing options 5.18.3.5 Evaluator options 5.18.3.6 Evaluator trap options 5.18.3.7 Debugger options 5.18.3.8 Examples of option use 5.19 Support for Translating Other Languages 5.19.1 Emacs Lisp Support 5.20 Support for Internationalization 5.21 Debugging Infrastructure 5.21.1 Evaluation and the Scheme Stack 5.21.1.1 Capturing the Stack or Innermost Stack Frame 5.21.1.2 Examining the Stack 5.21.1.3 Examining Stack Frames 5.21.1.4 Source Properties 5.21.1.5 Decoding Memoized Source Expressions 5.21.1.6 Starting a New Stack 5.21.2 Debugging when an error occurs 5.21.2.1 Intercepting basic error information 5.21.2.2 Capturing the full error stack 5.21.2.3 Displaying or interrogating the captured stack 5.21.2.4 What the Guile REPL does 5.21.3 Traps 5.21.3.1 A Quick Note on Terminology 5.21.3.2 How to Set a Trap 5.21.3.3 Specifying Trap Behaviour 5.21.3.4 Trap Context 5.21.3.5 Tracing Examples 5.21.3.6 Tracing Configuration 5.21.3.7 Tracing and (ice-9 debug) 5.21.3.8 Traps Installing More Traps 5.21.3.9 Common Trap Options 5.21.3.10 Procedure Traps 5.21.3.11 Exit Traps 5.21.3.12 Entry Traps 5.21.3.13 Apply Traps 5.21.3.14 Step Traps 5.21.3.15 Source Traps 5.21.3.16 Location Traps 5.21.3.17 Trap Shorthands 5.21.3.18 Trap Utilities 5.21.4 Debugging Examples 5.21.4.1 Single Stepping through a Procedure's Code 5.21.4.2 Profiling or Tracing a Procedure's Code 5.22 GH: A Portable C to Scheme Interface 5.22.1 Why the GH Interface is Now Deprecated 5.22.2 Transitioning away from GH 5.22.3 GH preliminaries 5.22.4 Data types and constants defined by GH 5.22.5 Starting and controlling the interpreter 5.22.6 Error messages 5.22.7 Executing Scheme code 5.22.8 Defining new Scheme procedures in C 5.22.9 Converting data between C and Scheme 5.22.9.1 C to Scheme 5.22.9.2 Scheme to C 5.22.10 Type predicates 5.22.11 Equality predicates 5.22.12 Memory allocation and garbage collection 5.22.13 Calling Scheme procedures from C 6 Guile Modules 6.1 SLIB 6.1.1 SLIB installation 6.1.2 JACAL 6.2 POSIX System Calls and Networking 6.2.1 POSIX Interface Conventions 6.2.2 Ports and File Descriptors 6.2.3 File System 6.2.4 User Information 6.2.5 Time 6.2.6 Runtime Environment 6.2.7 Processes 6.2.8 Signals 6.2.9 Terminals and Ptys 6.2.10 Pipes 6.2.11 Networking 6.2.11.1 Network Address Conversion 6.2.11.2 Network Databases 6.2.11.3 Network Socket Address 6.2.11.4 Network Sockets and Communication 6.2.11.5 Network Socket Examples 6.2.12 System Identification 6.2.13 Locales 6.2.14 Encryption 6.3 The (ice-9 getopt-long) Module 6.3.1 A Short getopt-long Example 6.3.2 How to Write an Option Specification 6.3.3 Expected Command Line Format 6.3.4 Reference Documentation for `getopt-long' 6.3.5 Reference Documentation for `option-ref' 6.4 SRFI Support Modules 6.4.1 About SRFI Usage 6.4.2 SRFI-0 - cond-expand 6.4.3 SRFI-1 - List library 6.4.3.1 Constructors 6.4.3.2 Predicates 6.4.3.3 Selectors 6.4.3.4 Length, Append, Concatenate, etc. 6.4.3.5 Fold, Unfold & Map 6.4.3.6 Filtering and Partitioning 6.4.3.7 Searching 6.4.3.8 Deleting 6.4.3.9 Association Lists 6.4.3.10 Set Operations on Lists 6.4.4 SRFI-2 - and-let* 6.4.5 SRFI-4 - Homogeneous numeric vector datatypes 6.4.6 SRFI-6 - Basic String Ports 6.4.7 SRFI-8 - receive 6.4.8 SRFI-9 - define-record-type 6.4.9 SRFI-10 - Hash-Comma Reader Extension 6.4.10 SRFI-11 - let-values 6.4.11 SRFI-13 - String Library 6.4.12 SRFI-14 - Character-set Library 6.4.13 SRFI-16 - case-lambda 6.4.14 SRFI-17 - Generalized set! 6.4.15 SRFI-19 - Time/Date Library 6.4.15.1 SRFI-19 Introduction 6.4.15.2 SRFI-19 Time 6.4.15.3 SRFI-19 Date 6.4.15.4 SRFI-19 Time/Date conversions 6.4.15.5 SRFI-19 Date to string 6.4.15.6 SRFI-19 String to date 6.4.16 SRFI-26 - specializing parameters 6.4.17 SRFI-31 - A special form `rec' for recursive evaluation 6.4.18 SRFI-34 - Exception handling for programs 6.4.19 SRFI-35 - Conditions 6.4.20 SRFI-37 - args-fold 6.4.21 SRFI-39 - Parameters 6.4.22 SRFI-55 - Requiring Features 6.4.23 SRFI-60 - Integers as Bits 6.4.24 SRFI-61 - A more general `cond' clause 6.4.25 SRFI-69 - Basic hash tables 6.4.25.1 Creating hash tables 6.4.25.2 Accessing table items 6.4.25.3 Table properties 6.4.25.4 Hash table algorithms 6.4.26 SRFI-88 Keyword Objects 6.5 Readline Support 6.5.1 Loading Readline Support 6.5.2 Readline Options 6.5.3 Readline Functions 6.5.3.1 Readline Port 6.5.3.2 Completion 6.6 Value History 6.7 Pretty Printing 6.8 Formatted Output 6.9 File Tree Walk 6.10 Queues 6.11 Streams 6.12 Buffered Input 6.13 Expect 6.14 The Scheme shell (scsh) 6.15 Tracing 7 Autoconf Support 7.1 Autoconf Background 7.2 Autoconf Macros 7.3 Using Autoconf Macros 7.4 Autofrisk 7.5 Using Autofrisk Appendix A Data Representation in Guile A.1 Data Representation in Scheme A.1.1 A Simple Representation A.1.2 Faster Integers A.1.3 Cheaper Pairs A.1.4 Guile Is Hairier A.2 How Guile does it A.2.1 General Rules A.2.2 Conservative Garbage Collection A.2.3 Immediates vs Non-immediates A.2.4 Immediate Datatypes A.2.4.1 Integers A.2.4.2 Characters A.2.4.3 Booleans A.2.4.4 Unique Values A.2.5 Non-immediate Datatypes A.2.5.1 Pairs A.2.5.2 Vectors, Strings, and Symbols A.2.5.3 Procedures A.2.5.4 Closures A.2.5.5 Subrs A.2.5.6 Ports A.2.6 Signalling Type Errors A.2.7 Unpacking the SCM Type A.2.7.1 Relationship between `SCM' and `scm_t_bits' A.2.7.2 Immediate objects A.2.7.3 Non-immediate objects A.2.7.4 Allocating Cells A.2.7.5 Heap Cell Type Information A.2.7.6 Accessing Cell Entries A.2.7.7 Basic Rules for Accessing Cell Entries Appendix B GNU Free Documentation License B.0.1 ADDENDUM: How to use this License for your documents Concept Index Procedure Index Variable Index Type Index R5RS Index 1 Preface ********* This reference manual documents Guile, GNU's Ubiquitous Intelligent Language for Extensions. It describes how to use Guile in many useful and interesting ways. This is edition 1.1 of the reference manual, and corresponds to Guile version 1.8.5. 1.1 Layout of this Manual ========================= The manual is divided into five chapters. *Chapter 1: Introduction to Guile* This part provides an overview of what Guile is and how you can use it. A whirlwind tour shows how Guile can be used interactively and as a script interpreter, how to link Guile into your own applications, and how to write modules of interpreted and compiled code for use with Guile. Everything introduced here is documented again and in full by the later parts of the manual. This part also explains how to obtain and install new versions of Guile, and how to report bugs effectively. *Chapter 2: Programming in Scheme* This part provides an overview over programming in Scheme with Guile. It covers how to invoke the `guile' program from the command-line and how to write scripts in Scheme. It also gives an introduction into the basic ideas of Scheme itself and to the various extensions that Guile offers beyond standard Scheme. *Chapter 3: Programming in C* This part provides an overview of how to use Guile in a C program. It discusses the fundamental concepts that you need to understand to access the features of Guile, such as dynamic types and the garbage collector. It explains in a tutorial like manner how to define new data types and functions for the use by Scheme programs. *Chapter 4: Guile API Reference* This part of the manual documents the Guile API in functionality-based groups with the Scheme and C interfaces presented side by side. *Chapter 5: Guile Modules* Describes some important modules, distributed as part of the Guile distribution, that extend the functionality provided by the Guile Scheme core. 1.2 Conventions used in this Manual =================================== We use some conventions in this manual. * For some procedures, notably type predicates, we use "iff" to mean "if and only if". The construct is usually something like: `Return VAL iff CONDITION', where VAL is usually "#t" or "non-#f". This typically means that VAL is returned if CONDITION holds, and that `#f' is returned otherwise. To clarify: VAL will *only* be returned when CONDITION is true. * In examples and procedure descriptions and all other places where the evaluation of Scheme expression is shown, we use some notation for denoting the output and evaluation results of expressions. The symbol `=>' is used to tell which value is returned by an evaluation: (+ 1 2) => 3 Some procedures produce some output besides returning a value. This is denoted by the symbol `-|'. (begin (display 1) (newline) 'hooray) -| 1 => hooray As you can see, this code prints `1' (denoted by `-|'), and returns `hooray' (denoted by `=>'). Do not confuse the two. 1.3 Contributors to this Manual =============================== The Guile reference and tutorial manuals were written and edited largely by Mark Galassi and Jim Blandy. In particular, Jim wrote the original tutorial on Guile's data representation and the C API for accessing Guile objects. Significant portions were contributed by Gary Houston (contributions to POSIX system calls and networking, expect, I/O internals and extensions, slib installation, error handling) and Tim Pierce (sections on script interpreter triggers, alists, function tracing). Tom Lord contributed a great deal of material with early Guile snapshots; although most of this text has been rewritten, all of it was important, and some of the structure remains. Aubrey Jaffer wrote the SCM Scheme implementation and manual upon which the Guile program and manual are based. Some portions of the SCM and SLIB manuals have been included here verbatim. Since Guile 1.4, Neil Jerram has been maintaining and improving the reference manual. Among other contributions, he wrote the Basic Ideas chapter, developed the tools for keeping the manual in sync with snarfed libguile docstrings, and reorganized the structure so as to accommodate docstrings for all Guile's primitives. Martin Grabmueller has made substantial contributions throughout the reference manual in preparation for the Guile 1.6 release, including filling out a lot of the documentation of Scheme data types, control mechanisms and procedures. In addition, he wrote the documentation for Guile's SRFI modules and modules associated with the Guile REPL. 1.4 The Guile License ===================== Guile is Free Software. Guile is copyrighted, not public domain, and there are restrictions on its distribution or redistribution, but these restrictions are designed to permit everything a cooperating person would want to do. * The Guile library (libguile) and supporting files are published under the terms of the GNU Lesser General Public License version 2.1. See the file `COPYING.LIB'. * The Guile readline module is published under the terms of the GNU General Public License version 2. See the file `COPYING'. * The manual you're now reading is published under the terms of the GNU Free Documentation License (*note GNU Free Documentation License::). C code linking to the Guile library is subject to terms of that library. Basically such code may be published on any terms, provided users can re-link against a new or modified version of Guile. C code linking to the Guile readline module is subject to the terms of that module. Basically such code must be published on Free terms. Scheme level code written to be run by Guile (but not derived from Guile itself) is not resticted in any way, and may be published on any terms. We encourage authors to publish on Free terms. You must be aware there is no warranty whatsoever for Guile. This is described in full in the licenses. 2 Introduction to Guile *********************** 2.1 What is Guile? ================== 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^5 Report on the Algorithmic Language Scheme (usually known as R5RS), providing clean and general data and control structures. Guile goes beyond the rather austere language presented in R5RS, 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 then use Guile as an extension language, a clean and powerful configuration language, or as multi-purpose "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 translating 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. 2.2 Obtaining and Installing Guile ================================== Guile can be obtained from the main GNU archive site `ftp://ftp.gnu.org' or any of its mirrors. The file will be named guile-version.tar.gz. The current version is 1.8.5, so the file you should grab is: `ftp://ftp.gnu.org/pub/gnu/guile-1.8.5.tar.gz' To unbundle Guile use the instruction zcat guile-1.8.5.tar.gz | tar xvf - which will create a directory called `guile-1.8.5' 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.8.5 ./configure make make install This will install the Guile executable `guile', the Guile library `-lguile' 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 R5RS, or the "Revised^5 Report on the Algorithmic Language Scheme", we have included the report in the Guile distribution; *Note Introduction: (r5rs)Top. This will also be installed in your info directory. 2.3 A Whirlwind Tour ==================== This chapter presents a quick tour of all the ways that Guile can be used. There are additional examples in the `examples/' directory in the Guile source distribution. The following examples assume that Guile has been installed in `/usr/local/'. 2.3.1 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 $ 2.3.2 Running 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. Here is a trivial Guile script, for more details *Note Guile Scripting::. #!/usr/local/bin/guile -s !# (display "Hello, world!") (newline) 2.3.3 Linking Guile into Programs --------------------------------- The Guile interpreter is available as an object library, to be linked into applications using Scheme as a configuration or extension language. Here is `simple-guile.c', source code for a program that will produce a complete Guile interpreter. In addition to all usual functions provided by Guile, it will also offer the function `my-hostname'. #include #include static SCM my_hostname (void) { char *s = getenv ("HOSTNAME"); if (s == NULL) return SCM_BOOL_F; else return scm_from_locale_string (s); } static void inner_main (void *data, int argc, char **argv) { scm_c_define_gsubr ("my-hostname", 0, 0, 0, my_hostname); scm_shell (argc, argv); } int main (int argc, char **argv) { scm_boot_guile (argc, argv, inner_main, 0); return 0; /* never reached */ } When Guile is correctly installed on your system, the above program can be compiled and linked like this: $ gcc -o simple-guile simple-guile.c -lguile When it is run, it behaves just like the `guile' program except that you can also call the new `my-hostname' function. $ ./simple-guile guile> (+ 1 2 3) 6 guile> (my-hostname) "burns" 2.3.4 Writing Guile Extensions ------------------------------ You can link Guile into your program and make Scheme available to the users of your program. You can also link your library into Guile and make its functionality available to all users of Guile. A library that is linked into Guile is called an "extensions", but it really just is an ordinary object library. The following example shows how to write a simple extension for Guile that makes the `j0' function available to Scheme code. #include #include 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 (*note Introduction: (libtool)Top.). A shared library can be loaded into a running Guile process with the function `load-extension'. The `j0' is then immediately available: $ guile guile> (load-extension "./libguile-bessel" "init_bessel") guile> (j0 2) 0.223890779141236 2.3.5 Using the Guile Module System ----------------------------------- 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 *Note Modules::. 2.3.5.1 Using 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. Here is a sample interactive session that shows how to use the `(ice-9 popen)' module which provides the means for communicating with other processes over pipes together with the `(ice-9 rdelim)' module that provides the function `read-line'. $ guile guile> (use-modules (ice-9 popen)) guile> (use-modules (ice-9 rdelim)) guile> (define p (open-input-pipe "ls -l")) guile> (read-line p) "total 30" guile> (read-line p) "drwxr-sr-x 2 mgrabmue mgrabmue 1024 Mar 29 19:57 CVS" 2.3.5.2 Writing new Modules ........................... You can create new modules using the syntactic form `define-module'. All definitions following this form until the next `define-module' are placed into the new module. One module is usually placed into one file, and that file is installed in a location where Guile can automatically find it. The following session shows a simple example. $ cat /usr/local/share/guile/foo/bar.scm (define-module (foo bar)) (export frob) (define (frob x) (* 2 x)) $ guile guile> (use-modules (foo bar)) guile> (frob 12) 24 2.3.5.3 Putting Extensions into Modules ....................................... 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 and call `load-extension' directly in the body of the module. $ cat /usr/local/share/guile/math/bessel.scm (define-module (math bessel)) (export j0) (load-extension "libguile-bessel" "init_bessel") $ file /usr/local/lib/libguile-bessel.so ... ELF 32-bit LSB shared object ... $ guile guile> (use-modules (math bessel)) guile> (j0 2) 0.223890779141236 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. 2.4 Discouraged and Deprecated ============================== From time to time functions and other features of Guile become obsolete. Guile has some mechanisms in place that can help you cope with this. Guile has two levels of obsoleteness: things can be _deprecated_, meaning that their use is considered harmful and should be avoided, even in old code; or they can be merely _discouraged_, meaning that they are fine in and of themselves, but that there are better alternatives that should be used in new code. When you use a feature that is deprecated, you will likely get a warning message at run-time. Also, deprecated features are not ready for production use: they might be very slow. When something is merely discouraged, it performs normally and you wont get any messages at run-time. The primary source for information about just what things are discouraged or deprecated in a given release is the file `NEWS'. That file also documents what you should use instead of the obsoleted things. The file `README' contains instructions on how to control the inclusion or removal of the deprecated and/or discouraged features from the public API of Guile, and how to control the warning messages for deprecated features. The idea behind those mechanisms is that normally all deprecated and discouraged features are available, but that you can omit them on purpose to check whether your code still relies on them. 2.5 Reporting Bugs ================== Any problems with the installation should be reported to . Whenever you have found a bug in Guile you are encouraged to report it to the Guile developers, so they can fix it. They may also be able to suggest workarounds when it is not possible for you to apply the bug-fix or install a new version of Guile yourself. Before sending in bug reports, please check with the following list that you really have found a bug. * Whenever documentation and actual behavior differ, you have certainly found a bug, either in the documentation or in the program. * When Guile crashes, it is a bug. * When Guile hangs or takes forever to complete a task, it is a bug. * When calculations produce wrong results, it is a bug. * When Guile signals an error for valid Scheme programs, it is a bug. * When Guile does not signal an error for invalid Scheme programs, it may be a bug, unless this is explicitly documented. * When some part of the documentation is not clear and does not make sense to you even after re-reading the section, it is a bug. When you write a bug report, please make sure to include as much of the information described below in the report. If you can't figure out some of the items, it is not a problem, but the more information we get, the more likely we can diagnose and fix the bug. * The version number of Guile. Without this, we won't know whether there is any point in looking for the bug in the current version of Guile. You can get the version number by invoking the command $ guile --version Guile 1.4.1 Copyright (c) 1995, 1996, 1997, 2000, 2006 Free Software Foundation Guile may be distributed under the terms of the GNU General Public License; certain other uses are permitted as well. For details, see the file `COPYING', which is included in the Guile distribution. There is no warranty, to the extent permitted by law. * The type of machine you are using, and the operating system name and version number. On GNU systems, you can get it with `uname'. $ uname -a Linux tortoise 2.2.17 #1 Thu Dec 21 17:29:05 CET 2000 i586 unknown * The operands given to the `configure' command when Guile was installed. It's often useful to augment this with the output of the command `guile-config info'. * A complete list of any modifications you have made to the Guile source. (We may not have time to investigate the bug unless it happens in an unmodified Guile. But if you've made modifications and you don't tell us, you are sending us on a wild goose chase.) Be precise about these changes. A description in English is not enough--send a context diff for them. Adding files of your own, or porting to another machine, is a modification of the source. * Details of any other deviations from the standard procedure for installing Guile. * The complete text of any source files needed to reproduce the bug. If you can tell us a way to cause the problem without loading any source files, please do so. This makes it much easier to debug. If you do need files, make sure you arrange for us to see their exact contents. * The precise Guile invocation command line we need to type to reproduce the bug. * A description of what behavior you observe that you believe is incorrect. For example, "The Guile process gets a fatal signal," or, "The resulting output is as follows, which I think is wrong." Of course, if the bug is that Guile gets a fatal signal, then one can't miss it. But if the bug is incorrect results, the maintainer might fail to notice what is wrong. Why leave it to chance? If the manifestation of the bug is a Guile error message, it is important to report the precise text of the error message, and a backtrace showing how the Scheme program arrived at the error. This can be done using the procedure `backtrace' in the REPL. * Check whether any programs you have loaded into Guile, including your `.guile' file, set any variables that may affect the functioning of Guile. Also, see whether the problem happens in a freshly started Guile without loading your `.guile' file (start Guile with the `-q' switch to prevent loading the init file). If the problem does _not_ occur then, you must report the precise contents of any programs that you must load into Guile in order to cause the problem to occur. * If the problem does depend on an init file or other Scheme programs that are not part of the standard Guile distribution, then you should make sure it is not a bug in those programs by complaining to their maintainers first. After they verify that they are using Guile in a way that is supposed to work, they should report the bug. * If you wish to mention something in the Guile source, show the line of code with a few lines of context. Don't just give a line number. The line numbers in the development sources might not match those in your sources. It would take extra work for the maintainers to determine what code is in your version at a given line number, and we could not be certain. * Additional information from a C debugger such as GDB might enable someone to find a problem on a machine which he does not have available. If you don't know how to use GDB, please read the GDB manual--it is not very long, and using GDB is easy. You can find the GDB distribution, including the GDB manual in online form, in most of the same places you can find the Guile distribution. To run Guile under GDB, you should switch to the `libguile' subdirectory in which Guile was compiled, then do `gdb guile' or `gdb .libs/guile' (if using GNU Libtool). However, you need to think when you collect the additional information if you want it to show what causes the bug. For example, many people send just a backtrace, but that is not very useful by itself. A simple backtrace with arguments often conveys little about what is happening inside Guile, because most of the arguments listed in the backtrace are pointers to Scheme objects. The numeric values of these pointers have no significance whatever; all that matters is the contents of the objects they point to (and most of the contents are themselves pointers). 3 Programming in Scheme *********************** Guile's core language is Scheme, and an awful lot can be achieved simply by using Guile to write and run Scheme programs. In this part of the manual, we explain how to use Guile in this mode, and describe the tools that Guile provides to help you with script writing, debugging and packaging your programs for distribution. For readers who are not yet familiar with the Scheme language, this part includes a chapter that presents the basic concepts of the language, and gives references to freely available Scheme tutorial material on the web. For detailed reference information on the variables, functions etc. that make up Guile's application programming interface (API), *Note API Reference::. 3.1 Basic Ideas in Scheme ========================= In this chapter, we introduce the basic concepts that underpin the elegance and power of the Scheme language. Readers who already possess a background knowledge of Scheme may happily skip this chapter. For the reader who is new to the language, however, the following discussions on data, procedures, expressions and closure are designed to provide a minimum level of Scheme understanding that is more or less assumed by the reference chapters that follow. The style of this introductory material aims about halfway between the terse precision of R5RS and the discursive randomness of a Scheme tutorial. 3.1.1 Data Types, Values and Variables -------------------------------------- This section discusses the representation of data types and values, what it means for Scheme to be a "latently typed" language, and the role of variables. We conclude by introducing the Scheme syntaxes for defining a new variable, and for changing the value of an existing variable. 3.1.1.1 Latent Typing ..................... The term "latent typing" is used to describe a computer language, such as Scheme, for which you cannot, _in general_, simply look at a program's source code and determine what type of data will be associated with a particular variable, or with the result of a particular expression. Sometimes, of course, you _can_ tell from the code what the type of an expression will be. If you have a line in your program that sets the variable `x' to the numeric value 1, you can be certain that, immediately after that line has executed (and in the absence of multiple threads), `x' has the numeric value 1. Or if you write a procedure that is designed to concatenate two strings, it is likely that the rest of your application will always invoke this procedure with two string parameters, and quite probable that the procedure would go wrong in some way if it was ever invoked with parameters that were not both strings. Nevertheless, the point is that there is nothing in Scheme which requires the procedure parameters always to be strings, or `x' always to hold a numeric value, and there is no way of declaring in your program that such constraints should always be obeyed. In the same vein, there is no way to declare the expected type of a procedure's return value. Instead, the types of variables and expressions are only known - in general - at run time. If you _need_ to check at some point that a value has the expected type, Scheme provides run time procedures that you can invoke to do so. But equally, it can be perfectly valid for two separate invocations of the same procedure to specify arguments with different types, and to return values with different types. The next subsection explains what this means in practice, for the ways that Scheme programs use data types, values and variables. 3.1.1.2 Values and Variables ............................ Scheme provides many data types that you can use to represent your data. Primitive types include characters, strings, numbers and procedures. Compound types, which allow a group of primitive and compound values to be stored together, include lists, pairs, vectors and multi-dimensional arrays. In addition, Guile allows applications to define their own data types, with the same status as the built-in standard Scheme types. As a Scheme program runs, values of all types pop in and out of existence. Sometimes values are stored in variables, but more commonly they pass seamlessly from being the result of one computation to being one of the parameters for the next. Consider an example. A string value is created because the interpreter reads in a literal string from your program's source code. Then a numeric value is created as the result of calculating the length of the string. A second numeric value is created by doubling the calculated length. Finally the program creates a list with two elements - the doubled length and the original string itself - and stores this list in a program variable. All of the values involved here - in fact, all values in Scheme - carry their type with them. In other words, every value "knows," at runtime, what kind of value it is. A number, a string, a list, whatever. A variable, on the other hand, has no fixed type. A variable - `x', say - is simply the name of a location - a box - in which you can store any kind of Scheme value. So the same variable in a program may hold a number at one moment, a list of procedures the next, and later a pair of strings. The "type" of a variable - insofar as the idea is meaningful at all - is simply the type of whatever value the variable happens to be storing at a particular moment. 3.1.1.3 Defining and Setting Variables ...................................... To define a new variable, you use Scheme's `define' syntax like this: (define VARIABLE-NAME VALUE) This makes a new variable called VARIABLE-NAME and stores VALUE in it as the variable's initial value. For example: ;; Make a variable `x' with initial numeric value 1. (define x 1) ;; Make a variable `organization' with an initial string value. (define organization "Free Software Foundation") (In Scheme, a semicolon marks the beginning of a comment that continues until the end of the line. So the lines beginning `;;' are comments.) Changing the value of an already existing variable is very similar, except that `define' is replaced by the Scheme syntax `set!', like this: (set! VARIABLE-NAME NEW-VALUE) Remember that variables do not have fixed types, so NEW-VALUE may have a completely different type from whatever was previously stored in the location named by VARIABLE-NAME. Both of the following examples are therefore correct. ;; Change the value of `x' to 5. (set! x 5) ;; Change the value of `organization' to the FSF's street number. (set! organization 545) In these examples, VALUE and NEW-VALUE are literal numeric or string values. In general, however, VALUE and NEW-VALUE can be any Scheme expression. Even though we have not yet covered the forms that Scheme expressions can take (*note About Expressions::), you can probably guess what the following `set!' example does... (set! x (+ x 1)) (Note: this is not a complete description of `define' and `set!', because we need to introduce some other aspects of Scheme before the missing pieces can be filled in. If, however, you are already familiar with the structure of Scheme, you may like to read about those missing pieces immediately by jumping ahead to the following references. * *note Lambda Alternatives::, to read about an alternative form of the `define' syntax that can be used when defining new procedures. * *note Procedures with Setters::, to read about an alternative form of the `set!' syntax that helps with changing a single value in the depths of a compound data structure.) * *Note Internal Definitions::, to read about using `define' other than at top level in a Scheme program, including a discussion of when it works to use `define' rather than `set!' to change the value of an existing variable. 3.1.2 The Representation and Use of Procedures ---------------------------------------------- This section introduces the basics of using and creating Scheme procedures. It discusses the representation of procedures as just another kind of Scheme value, and shows how procedure invocation expressions are constructed. We then explain how `lambda' is used to create new procedures, and conclude by presenting the various shorthand forms of `define' that can be used instead of writing an explicit `lambda' expression. 3.1.2.1 Procedures as Values ............................ One of the great simplifications of Scheme is that a procedure is just another type of value, and that procedure values can be passed around and stored in variables in exactly the same way as, for example, strings and lists. When we talk about a built-in standard Scheme procedure such as `open-input-file', what we actually mean is that there is a pre-defined top level variable called `open-input-file', whose value is a procedure that implements what R5RS says that `open-input-file' should do. Note that this is quite different from many dialects of Lisp -- including Emacs Lisp -- in which a program can use the same name with two quite separate meanings: one meaning identifies a Lisp function, while the other meaning identifies a Lisp variable, whose value need have nothing to do with the function that is associated with the first meaning. In these dialects, functions and variables are said to live in different "namespaces". In Scheme, on the other hand, all names belong to a single unified namespace, and the variables that these names identify can hold any kind of Scheme value, including procedure values. One consequence of the "procedures as values" idea is that, if you don't happen to like the standard name for a Scheme procedure, you can change it. For example, `call-with-current-continuation' is a very important standard Scheme procedure, but it also has a very long name! So, many programmers use the following definition to assign the same procedure value to the more convenient name `call/cc'. (define call/cc call-with-current-continuation) Let's understand exactly how this works. The definition creates a new variable `call/cc', and then sets its value to the value of the variable `call-with-current-continuation'; the latter value is a procedure that implements the behaviour that R5RS specifies under the name "call-with-current-continuation". So `call/cc' ends up holding this value as well. Now that `call/cc' holds the required procedure value, you could choose to use `call-with-current-continuation' for a completely different purpose, or just change its value so that you will get an error if you accidentally use `call-with-current-continuation' as a procedure in your program rather than `call/cc'. For example: (set! call-with-current-continuation "Not a procedure any more!") Or you could just leave `call-with-current-continuation' as it was. It's perfectly fine for more than one variable to hold the same procedure value. 3.1.2.2 Simple Procedure Invocation ................................... A procedure invocation in Scheme is written like this: (PROCEDURE [ARG1 [ARG2 ...]]) In this expression, PROCEDURE can be any Scheme expression whose value is a procedure. Most commonly, however, PROCEDURE is simply the name of a variable whose value is a procedure. For example, `string-append' is a standard Scheme procedure whose behaviour is to concatenate together all the arguments, which are expected to be strings, that it is given. So the expression (string-append "/home" "/" "andrew") is a procedure invocation whose result is the string value `"/home/andrew"'. Similarly, `string-length' is a standard Scheme procedure that returns the length of a single string argument, so (string-length "abc") is a procedure invocation whose result is the numeric value 3. Each of the parameters in a procedure invocation can itself be any Scheme expression. Since a procedure invocation is itself a type of expression, we can put these two examples together to get (string-length (string-append "/home" "/" "andrew")) -- a procedure invocation whose result is the numeric value 12. (You may be wondering what happens if the two examples are combined the other way round. If we do this, we can make a procedure invocation expression that is _syntactically_ correct: (string-append "/home" (string-length "abc")) but when this expression is executed, it will cause an error, because the result of `(string-length "abc")' is a numeric value, and `string-append' is not designed to accept a numeric value as one of its arguments.) 3.1.2.3 Creating and Using a New Procedure .......................................... Scheme has lots of standard procedures, and Guile provides all of these via predefined top level variables. All of these standard procedures are documented in the later chapters of this reference manual. Before very long, though, you will want to create new procedures that encapsulate aspects of your own applications' functionality. To do this, you can use the famous `lambda' syntax. For example, the value of the following Scheme expression (lambda (name address) EXPRESSION ...) is a newly created procedure that takes two arguments: `name' and `address'. The behaviour of the new procedure is determined by the sequence of EXPRESSIONs in the "body" of the procedure definition. (Typically, these EXPRESSIONs would use the arguments in some way, or else there wouldn't be any point in giving them to the procedure.) When invoked, the new procedure returns a value that is the value of the last EXPRESSION in the procedure body. To make things more concrete, let's suppose that the two arguments are both strings, and that the purpose of this procedure is to form a combined string that includes these arguments. Then the full lambda expression might look like this: (lambda (name address) (string-append "Name=" name ":Address=" address)) We noted in the previous subsection that the PROCEDURE part of a procedure invocation expression can be any Scheme expression whose value is a procedure. But that's exactly what a lambda expression is! So we can use a lambda expression directly in a procedure invocation, like this: ((lambda (name address) (string-append "Name=" name ":Address=" address)) "FSF" "Cambridge") This is a valid procedure invocation expression, and its result is the string `"Name=FSF:Address=Cambridge"'. It is more common, though, to store the procedure value in a variable -- (define make-combined-string (lambda (name address) (string-append "Name=" name ":Address=" address))) -- and then to use the variable name in the procedure invocation: (make-combined-string "FSF" "Cambridge") Which has exactly the same result. It's important to note that procedures created using `lambda' have exactly the same status as the standard built in Scheme procedures, and can be invoked, passed around, and stored in variables in exactly the same ways. 3.1.2.4 Lambda Alternatives ........................... Since it is so common in Scheme programs to want to create a procedure and then store it in a variable, there is an alternative form of the `define' syntax that allows you to do just that. A `define' expression of the form (define (NAME [ARG1 [ARG2 ...]]) EXPRESSION ...) is exactly equivalent to the longer form (define NAME (lambda ([ARG1 [ARG2 ...]]) EXPRESSION ...)) So, for example, the definition of `make-combined-string' in the previous subsection could equally be written: (define (make-combined-string name address) (string-append "Name=" name ":Address=" address)) This kind of procedure definition creates a procedure that requires exactly the expected number of arguments. There are two further forms of the `lambda' expression, which create a procedure that can accept a variable number of arguments: (lambda (ARG1 ... . ARGS) EXPRESSION ...) (lambda ARGS EXPRESSION ...) The corresponding forms of the alternative `define' syntax are: (define (NAME ARG1 ... . ARGS) EXPRESSION ...) (define (NAME . ARGS) EXPRESSION ...) For details on how these forms work, see *Note Lambda::. (It could be argued that the alternative `define' forms are rather confusing, especially for newcomers to the Scheme language, as they hide both the role of `lambda' and the fact that procedures are values that are stored in variables in the some way as any other kind of value. On the other hand, they are very convenient, and they are also a good example of another of Scheme's powerful features: the ability to specify arbitrary syntactic transformations at run time, which can be applied to subsequently read input.) 3.1.3 Expressions and Evaluation -------------------------------- So far, we have met expressions that _do_ things, such as the `define' expressions that create and initialize new variables, and we have also talked about expressions that have _values_, for example the value of the procedure invocation expression: (string-append "/home" "/" "andrew") but we haven't yet been precise about what causes an expression like this procedure invocation to be reduced to its "value", or how the processing of such expressions relates to the execution of a Scheme program as a whole. This section clarifies what we mean by an expression's value, by introducing the idea of "evaluation". It discusses the side effects that evaluation can have, explains how each of the various types of Scheme expression is evaluated, and describes the behaviour and use of the Guile REPL as a mechanism for exploring evaluation. The section concludes with a very brief summary of Scheme's common syntactic expressions. 3.1.3.1 Evaluating Expressions and Executing Programs ..................................................... In Scheme, the process of executing an expression is known as "evaluation". Evaluation has two kinds of result: * the "value" of the evaluated expression * the "side effects" of the evaluation, which consist of any effects of evaluating the expression that are not represented by the value. Of the expressions that we have met so far, `define' and `set!' expressions have side effects -- the creation or modification of a variable -- but no value; `lambda' expressions have values -- the newly constructed procedures -- but no side effects; and procedure invocation expressions, in general, have either values, or side effects, or both. It is tempting to try to define more intuitively what we mean by "value" and "side effects", and what the difference between them is. In general, though, this is extremely difficult. It is also unnecessary; instead, we can quite happily define the behaviour of a Scheme program by specifying how Scheme executes a program as a whole, and then by describing the value and side effects of evaluation for each type of expression individually. So, some(1) definitions... * A Scheme program consists of a sequence of expressions. * A Scheme interpreter executes the program by evaluating these expressions in order, one by one. * An expression can be * a piece of literal data, such as a number `2.3' or a string `"Hello world!"' * a variable name * a procedure invocation expression * one of Scheme's special syntactic expressions. The following subsections describe how each of these types of expression is evaluated. Evaluating Literal Data ....................... When a literal data expression is evaluated, the value of the expression is simply the value that the expression describes. The evaluation of a literal data expression has no side effects. So, for example, * the value of the expression `"abc"' is the string value `"abc"' * the value of the expression `3+4i' is the complex number 3 + 4i * the value of the expression `#(1 2 3)' is a three-element vector containing the numeric values 1, 2 and 3. For any data type which can be expressed literally like this, the syntax of the literal data expression for that data type -- in other words, what you need to write in your code to indicate a literal value of that type -- is known as the data type's "read syntax". This manual specifies the read syntax for each such data type in the section that describes that data type. Some data types do not have a read syntax. Procedures, for example, cannot be expressed as literal data; they must be created using a `lambda' expression (*note Creating a Procedure::) or implicitly using the shorthand form of `define' (*note Lambda Alternatives::). Evaluating a Variable Reference ............................... When an expression that consists simply of a variable name is evaluated, the value of the expression is the value of the named variable. The evaluation of a variable reference expression has no side effects. So, after (define key "Paul Evans") the value of the expression `key' is the string value `"Paul Evans"'. If KEY is then modified by (set! key 3.74) the value of the expression `key' is the numeric value 3.74. If there is no variable with the specified name, evaluation of the variable reference expression signals an error. Evaluating a Procedure Invocation Expression ............................................ This is where evaluation starts getting interesting! As already noted, a procedure invocation expression has the form (PROCEDURE [ARG1 [ARG2 ...]]) where PROCEDURE must be an expression whose value, when evaluated, is a procedure. The evaluation of a procedure invocation expression like this proceeds by * evaluating individually the expressions PROCEDURE, ARG1, ARG2, and so on * calling the procedure that is the value of the PROCEDURE expression with the list of values obtained from the evaluations of ARG1, ARG2 etc. as its parameters. For a procedure defined in Scheme, "calling the procedure with the list of values as its parameters" means binding the values to the procedure's formal parameters and then evaluating the sequence of expressions that make up the body of the procedure definition. The value of the procedure invocation expression is the value of the last evaluated expression in the procedure body. The side effects of calling the procedure are the combination of the side effects of the sequence of evaluations of expressions in the procedure body. For a built-in procedure, the value and side-effects of calling the procedure are best described by that procedure's documentation. Note that the complete side effects of evaluating a procedure invocation expression consist not only of the side effects of the procedure call, but also of any side effects of the preceding evaluation of the expressions PROCEDURE, ARG1, ARG2, and so on. To illustrate this, let's look again at the procedure invocation expression: (string-length (string-append "/home" "/" "andrew")) In the outermost expression, PROCEDURE is `string-length' and ARG1 is `(string-append "/home" "/" "andrew")'. * Evaluation of `string-length', which is a variable, gives a procedure value that implements the expected behaviour for "string-length". * Evaluation of `(string-append "/home" "/" "andrew")', which is another procedure invocation expression, means evaluating each of * `string-append', which gives a procedure value that implements the expected behaviour for "string-append" * `"/home"', which gives the string value `"/home"' * `"/"', which gives the string value `"/"' * `"andrew"', which gives the string value `"andrew"' and then invoking the procedure value with this list of string values as its arguments. The resulting value is a single string value that is the concatenation of all the arguments, namely `"/home/andrew"'. In the evaluation of the outermost expression, the interpreter can now invoke the procedure value obtained from PROCEDURE with the value obtained from ARG1 as its arguments. The resulting value is a numeric value that is the length of the argument string, which is 12. Evaluating Special Syntactic Expressions ........................................ When a procedure invocation expression is evaluated, the procedure and _all_ the argument expressions must be evaluated before the procedure can be invoked. Special syntactic expressions are special because they are able to manipulate their arguments in an unevaluated form, and can choose whether to evaluate any or all of the argument expressions. Why is this needed? Consider a program fragment that asks the user whether or not to delete a file, and then deletes the file if the user answers yes. (if (string=? (read-answer "Should I delete this file?") "yes") (delete-file file)) If the outermost `(if ...)' expression here was a procedure invocation expression, the expression `(delete-file file)', whose side effect is to actually delete a file, would already have been evaluated before the `if' procedure even got invoked! Clearly this is no use -- the whole point of an `if' expression is that the "consequent" expression is only evaluated if the condition of the `if' expression is "true". Therefore `if' must be special syntax, not a procedure. Other special syntaxes that we have already met are `define', `set!' and `lambda'. `define' and `set!' are syntax because they need to know the variable _name_ that is given as the first argument in a `define' or `set!' expression, not that variable's value. `lambda' is syntax because it does not immediately evaluate the expressions that define the procedure body; instead it creates a procedure object that incorporates these expressions so that they can be evaluated in the future, when that procedure is invoked. The rules for evaluating each special syntactic expression are specified individually for each special syntax. For a summary of standard special syntax, see *Note Syntax Summary::. ---------- Footnotes ---------- (1) These definitions are approximate. For the whole and detailed truth, see *Note R5RS syntax: (r5rs)Formal syntax and semantics. 3.1.3.2 Tail calls .................. Scheme is "properly tail recursive", meaning that tail calls or recursions from certain contexts do not consume stack space or other resources and can therefore be used on arbitrarily large data or for an arbitrarily long calculation. Consider for example, (define (foo n) (display n) (newline) (foo (1+ n))) (foo 1) -| 1 2 3 ... `foo' prints numbers infinitely, starting from the given N. It's implemented by printing N then recursing to itself to print N+1 and so on. This recursion is a tail call, it's the last thing done, and in Scheme such tail calls can be made without limit. Or consider a case where a value is returned, a version of the SRFI-1 `last' function (*note SRFI-1 Selectors::) returning the last element of a list, (define (my-last lst) (if (null? (cdr lst)) (car lst) (my-last (cdr lst)))) (my-last '(1 2 3)) => 3 If the list has more than one element, `my-last' applies itself to the `cdr'. This recursion is a tail call, there's no code after it, and the return value is the return value from that call. In Scheme this can be used on an arbitrarily long list argument. A proper tail call is only available from certain contexts, namely the following special form positions, * `and' -- last expression * `begin' -- last expression * `case' -- last expression in each clause * `cond' -- last expression in each clause, and the call to a `=>' procedure is a tail call * `do' -- last result expression * `if' -- "true" and "false" leg expressions * `lambda' -- last expression in body * `let', `let*', `letrec', `let-syntax', `letrec-syntax' -- last expression in body * `or' -- last expression The following core functions make tail calls, * `apply' -- tail call to given procedure * `call-with-current-continuation' -- tail call to the procedure receiving the new continuation * `call-with-values' -- tail call to the values-receiving procedure * `eval' -- tail call to evaluate the form * `string-any', `string-every' -- tail call to predicate on the last character (if that point is reached) The above are just core functions and special forms. Tail calls in other modules are described with the relevant documentation, for example SRFI-1 `any' and `every' (*note SRFI-1 Searching::). It will be noted there are a lot of places which could potentially be tail calls, for instance the last call in a `for-each', but only those explicitly described are guaranteed. 3.1.3.3 Using the Guile REPL ............................ If you start Guile without specifying a particular program for it to execute, Guile enters its standard Read Evaluate Print Loop -- or "REPL" for short. In this mode, Guile repeatedly reads in the next Scheme expression that the user types, evaluates it, and prints the resulting value. The REPL is a useful mechanism for exploring the evaluation behaviour described in the previous subsection. If you type `string-append', for example, the REPL replies `#', illustrating the relationship between the variable `string-append' and the procedure value stored in that variable. In this manual, the notation => is used to mean "evaluates to". Wherever you see an example of the form EXPRESSION => RESULT feel free to try it out yourself by typing EXPRESSION into the REPL and checking that it gives the expected RESULT. 3.1.3.4 Summary of Common Syntax ................................ This subsection lists the most commonly used Scheme syntactic expressions, simply so that you will recognize common special syntax when you see it. For a full description of each of these syntaxes, follow the appropriate reference. `lambda' (*note Lambda::) is used to construct procedure objects. `define' (*note Top Level::) is used to create a new variable and set its initial value. `set!' (*note Top Level::) is used to modify an existing variable's value. `let', `let*' and `letrec' (*note Local Bindings::) create an inner lexical environment for the evaluation of a sequence of expressions, in which a specified set of local variables is bound to the values of a corresponding set of expressions. For an introduction to environments, see *Note About Closure::. `begin' (*note begin::) executes a sequence of expressions in order and returns the value of the last expression. Note that this is not the same as a procedure which returns its last argument, because the evaluation of a procedure invocation expression does not guarantee to evaluate the arguments in order. `if' and `cond' (*note if cond case::) provide conditional evaluation of argument expressions depending on whether one or more conditions evaluate to "true" or "false". `case' (*note if cond case::) provides conditional evaluation of argument expressions depending on whether a variable has one of a specified group of values. `and' (*note and or::) executes a sequence of expressions in order until either there are no expressions left, or one of them evaluates to "false". `or' (*note and or::) executes a sequence of expressions in order until either there are no expressions left, or one of them evaluates to "true". 3.1.4 The Concept of Closure ---------------------------- The concept of "closure" is the idea that a lambda expression "captures" the variable bindings that are in lexical scope at the point where the lambda expression occurs. The procedure created by the lambda expression can refer to and mutate the captured bindings, and the values of those bindings persist between procedure calls. This section explains and explores the various parts of this idea in more detail. 3.1.4.1 Names, Locations, Values and Environments ................................................. We said earlier that a variable name in a Scheme program is associated with a location in which any kind of Scheme value may be stored. (Incidentally, the term "vcell" is often used in Lisp and Scheme circles as an alternative to "location".) Thus part of what we mean when we talk about "creating a variable" is in fact establishing an association between a name, or identifier, that is used by the Scheme program code, and the variable location to which that name refers. Although the value that is stored in that location may change, the location to which a given name refers is always the same. We can illustrate this by breaking down the operation of the `define' syntax into three parts: `define' * creates a new location * establishes an association between that location and the name specified as the first argument of the `define' expression * stores in that location the value obtained by evaluating the second argument of the `define' expression. A collection of associations between names and locations is called an "environment". When you create a top level variable in a program using `define', the name-location association for that variable is added to the "top level" environment. The "top level" environment also includes name-location associations for all the procedures that are supplied by standard Scheme. It is also possible to create environments other than the top level one, and to create variable bindings, or name-location associations, in those environments. This ability is a key ingredient in the concept of closure; the next subsection shows how it is done. 3.1.4.2 Local Variables and Environments ........................................ We have seen how to create top level variables using the `define' syntax (*note Definition::). It is often useful to create variables that are more limited in their scope, typically as part of a procedure body. In Scheme, this is done using the `let' syntax, or one of its modified forms `let*' and `letrec'. These syntaxes are described in full later in the manual (*note Local Bindings::). Here our purpose is to illustrate their use just enough that we can see how local variables work. For example, the following code uses a local variable `s' to simplify the computation of the area of a triangle given the lengths of its three sides. (define a 5.3) (define b 4.7) (define c 2.8) (define area (let ((s (/ (+ a b c) 2))) (sqrt (* s (- s a) (- s b) (- s c))))) The effect of the `let' expression is to create a new environment and, within this environment, an association between the name `s' and a new location whose initial value is obtained by evaluating `(/ (+ a b c) 2)'. The expressions in the body of the `let', namely `(sqrt (* s (- s a) (- s b) (- s c)))', are then evaluated in the context of the new environment, and the value of the last expression evaluated becomes the value of the whole `let' expression, and therefore the value of the variable `area'. 3.1.4.3 Environment Chaining ............................ In the example of the previous subsection, we glossed over an important point. The body of the `let' expression in that example refers not only to the local variable `s', but also to the top level variables `a', `b', `c' and `sqrt'. (`sqrt' is the standard Scheme procedure for calculating a square root.) If the body of the `let' expression is evaluated in the context of the _local_ `let' environment, how does the evaluation get at the values of these top level variables? The answer is that the local environment created by a `let' expression automatically has a reference to its containing environment -- in this case the top level environment -- and that the Scheme interpreter automatically looks for a variable binding in the containing environment if it doesn't find one in the local environment. More generally, every environment except for the top level one has a reference to its containing environment, and the interpreter keeps searching back up the chain of environments -- from most local to top level -- until it either finds a variable binding for the required identifier or exhausts the chain. This description also determines what happens when there is more than one variable binding with the same name. Suppose, continuing the example of the previous subsection, that there was also a pre-existing top level variable `s' created by the expression: (define s "Some beans, my lord!") Then both the top level environment and the local `let' environment would contain bindings for the name `s'. When evaluating code within the `let' body, the interpreter looks first in the local `let' environment, and so finds the binding for `s' created by the `let' syntax. Even though this environment has a reference to the top level environment, which also has a binding for `s', the interpreter doesn't get as far as looking there. When evaluating code outside the `let' body, the interpreter looks up variable names in the top level environment, so the name `s' refers to the top level variable. Within the `let' body, the binding for `s' in the local environment is said to "shadow" the binding for `s' in the top level environment. 3.1.4.4 Lexical Scope ..................... The rules that we have just been describing are the details of how Scheme implements "lexical scoping". This subsection takes a brief diversion to explain what lexical scope means in general and to present an example of non-lexical scoping. "Lexical scope" in general is the idea that * an identifier at a particular place in a program always refers to the same variable location -- where "always" means "every time that the containing expression is executed", and that * the variable location to which it refers can be determined by static examination of the source code context in which that identifier appears, without having to consider the flow of execution through the program as a whole. In practice, lexical scoping is the norm for most programming languages, and probably corresponds to what you would intuitively consider to be "normal". You may even be wondering how the situation could possibly -- and usefully -- be otherwise. To demonstrate that another kind of scoping is possible, therefore, and to compare it against lexical scoping, the following subsection presents an example of non-lexical scoping and examines in detail how its behavior differs from the corresponding lexically scoped code. An Example of Non-Lexical Scoping ................................. To demonstrate that non-lexical scoping does exist and can be useful, we present the following example from Emacs Lisp, which is a "dynamically scoped" language. (defvar currency-abbreviation "USD") (defun currency-string (units hundredths) (concat currency-abbreviation (number-to-string units) "." (number-to-string hundredths))) (defun french-currency-string (units hundredths) (let ((currency-abbreviation "FRF")) (currency-string units hundredths))) The question to focus on here is: what does the identifier `currency-abbreviation' refer to in the `currency-string' function? The answer, in Emacs Lisp, is that all variable bindings go onto a single stack, and that `currency-abbreviation' refers to the topmost binding from that stack which has the name "currency-abbreviation". The binding that is created by the `defvar' form, to the value `"USD"', is only relevant if none of the code that calls `currency-string' rebinds the name "currency-abbreviation" in the meanwhile. The second function `french-currency-string' works precisely by taking advantage of this behaviour. It creates a new binding for the name "currency-abbreviation" which overrides the one established by the `defvar' form. ;; Note! This is Emacs Lisp evaluation, not Scheme! (french-currency-string 33 44) => "FRF33.44" Now let's look at the corresponding, _lexically scoped_ Scheme code: (define currency-abbreviation "USD") (define (currency-string units hundredths) (string-append currency-abbreviation (number->string units) "." (number->string hundredths))) (define (french-currency-string units hundredths) (let ((currency-abbreviation "FRF")) (currency-string units hundredths))) According to the rules of lexical scoping, the `currency-abbreviation' in `currency-string' refers to the variable location in the innermost environment at that point in the code which has a binding for `currency-abbreviation', which is the variable location in the top level environment created by the preceding `(define currency-abbreviation ...)' expression. In Scheme, therefore, the `french-currency-string' procedure does not work as intended. The variable binding that it creates for "currency-abbreviation" is purely local to the code that forms the body of the `let' expression. Since this code doesn't directly use the name "currency-abbreviation" at all, the binding is pointless. (french-currency-string 33 44) => "USD33.44" This begs the question of how the Emacs Lisp behaviour can be implemented in Scheme. In general, this is a design question whose answer depends upon the problem that is being addressed. In this case, the best answer may be that `currency-string' should be redesigned so that it can take an optional third argument. This third argument, if supplied, is interpreted as a currency abbreviation that overrides the default. It is possible to change `french-currency-string' so that it mostly works without changing `currency-string', but the fix is inelegant, and susceptible to interrupts that could leave the `currency-abbreviation' variable in the wrong state: (define (french-currency-string units hundredths) (set! currency-abbreviation "FRF") (let ((result (currency-string units hundredths))) (set! currency-abbreviation "USD") result)) The key point here is that the code does not create any local binding for the identifier `currency-abbreviation', so all occurrences of this identifier refer to the top level variable. 3.1.4.5 Closure ............... Consider a `let' expression that doesn't contain any `lambda's: (let ((s (/ (+ a b c) 2))) (sqrt (* s (- s a) (- s b) (- s c)))) When the Scheme interpreter evaluates this, it * creates a new environment with a reference to the environment that was current when it encountered the `let' * creates a variable binding for `s' in the new environment, with value given by `(/ (+ a b c) 2)' * evaluates the expression in the body of the `let' in the context of the new local environment, and remembers the value `V' * forgets the local environment * continues evaluating the expression that contained the `let', using the value `V' as the value of the `let' expression, in the context of the containing environment. After the `let' expression has been evaluated, the local environment that was created is simply forgotten, and there is no longer any way to access the binding that was created in this environment. If the same code is evaluated again, it will follow the same steps again, creating a second new local environment that has no connection with the first, and then forgetting this one as well. If the `let' body contains a `lambda' expression, however, the local environment is _not_ forgotten. Instead, it becomes associated with the procedure that is created by the `lambda' expression, and is reinstated every time that that procedure is called. In detail, this works as follows. * When the Scheme interpreter evaluates a `lambda' expression, to create a procedure object, it stores the current environment as part of the procedure definition. * Then, whenever that procedure is called, the interpreter reinstates the environment that is stored in the procedure definition and evaluates the procedure body within the context of that environment. The result is that the procedure body is always evaluated in the context of the environment that was current when the procedure was created. This is what is meant by "closure". The next few subsections present examples that explore the usefulness of this concept. 3.1.4.6 Example 1: A Serial Number Generator ............................................ This example uses closure to create a procedure with a variable binding that is private to the procedure, like a local variable, but whose value persists between procedure calls. (define (make-serial-number-generator) (let ((current-serial-number 0)) (lambda () (set! current-serial-number (+ current-serial-number 1)) current-serial-number))) (define entry-sn-generator (make-serial-number-generator)) (entry-sn-generator) => 1 (entry-sn-generator) => 2 When `make-serial-number-generator' is called, it creates a local environment with a binding for `current-serial-number' whose initial value is 0, then, within this environment, creates a procedure. The local environment is stored within the created procedure object and so persists for the lifetime of the created procedure. Every time the created procedure is invoked, it increments the value of the `current-serial-number' binding in the captured environment and then returns the current value. Note that `make-serial-number-generator' can be called again to create a second serial number generator that is independent of the first. Every new invocation of `make-serial-number-generator' creates a new local `let' environment and returns a new procedure object with an association to this environment. 3.1.4.7 Example 2: A Shared Persistent Variable ............................................... This example uses closure to create two procedures, `get-balance' and `deposit', that both refer to the same captured local environment so that they can both access the `balance' variable binding inside that environment. The value of this variable binding persists between calls to either procedure. Note that the captured `balance' variable binding is private to these two procedures: it is not directly accessible to any other code. It can only be accessed indirectly via `get-balance' or `deposit', as illustrated by the `withdraw' procedure. (define get-balance #f) (define deposit #f) (let ((balance 0)) (set! get-balance (lambda () balance)) (set! deposit (lambda (amount) (set! balance (+ balance amount)) balance))) (define (withdraw amount) (deposit (- amount))) (get-balance) => 0 (deposit 50) => 50 (withdraw 75) => -25 An important detail here is that the `get-balance' and `deposit' variables must be set up by `define'ing them at top level and then `set!'ing their values inside the `let' body. Using `define' within the `let' body would not work: this would create variable bindings within the local `let' environment that would not be accessible at top level. 3.1.4.8 Example 3: The Callback Closure Problem ............................................... A frequently used programming model for library code is to allow an application to register a callback function for the library to call when some particular event occurs. It is often useful for the application to make several such registrations using the same callback function, for example if several similar library events can be handled using the same application code, but the need then arises to distinguish the callback function calls that are associated with one callback registration from those that are associated with different callback registrations. In languages without the ability to create functions dynamically, this problem is usually solved by passing a `user_data' parameter on the registration call, and including the value of this parameter as one of the parameters on the callback function. Here is an example of declarations using this solution in C: typedef void (event_handler_t) (int event_type, void *user_data); void register_callback (int event_type, event_handler_t *handler, void *user_data); In Scheme, closure can be used to achieve the same functionality without requiring the library code to store a `user-data' for each callback registration. ;; In the library: (define (register-callback event-type handler-proc) ...) ;; In the application: (define (make-handler event-type user-data) (lambda () ... ...)) (register-callback event-type (make-handler event-type ...)) As far as the library is concerned, `handler-proc' is a procedure with no arguments, and all the library has to do is call it when the appropriate event occurs. From the application's point of view, though, the handler procedure has used closure to capture an environment that includes all the context that the handler code needs -- `event-type' and `user-data' -- to handle the event correctly. 3.1.4.9 Example 4: Object Orientation ..................................... Closure is the capture of an environment, containing persistent variable bindings, within the definition of a procedure or a set of related procedures. This is rather similar to the idea in some object oriented languages of encapsulating a set of related data variables inside an "object", together with a set of "methods" that operate on the encapsulated data. The following example shows how closure can be used to emulate the ideas of objects, methods and encapsulation in Scheme. (define (make-account) (let ((balance 0)) (define (get-balance) balance) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (withdraw amount) (deposit (- amount))) (lambda args (apply (case (car args) ((get-balance) get-balance) ((deposit) deposit) ((withdraw) withdraw) (else (error "Invalid method!"))) (cdr args))))) Each call to `make-account' creates and returns a new procedure, created by the expression in the example code that begins "(lambda args". (define my-account (make-account)) my-account => # This procedure acts as an account object with methods `get-balance', `deposit' and `withdraw'. To apply one of the methods to the account, you call the procedure with a symbol indicating the required method as the first parameter, followed by any other parameters that are required by that method. (my-account 'get-balance) => 0 (my-account 'withdraw 5) => -5 (my-account 'deposit 396) => 391 (my-account 'get-balance) => 391 Note how, in this example, both the current balance and the helper procedures `get-balance', `deposit' and `withdraw', used to implement the guts of the account object's methods, are all stored in variable bindings within the private local environment captured by the `lambda' expression that creates the account object procedure. 3.2 Guile's Implementation of Scheme ==================================== Guile's core language is Scheme, which is specified and described in the series of reports known as "RnRS". "RnRS" is shorthand for the "Revised^n Report on the Algorithmic Language Scheme". The current latest revision of RnRS is version 5 (*note R5RS: (r5rs)Top.), and Guile 1.4 is fully compliant with the Scheme specification in this revision. But Guile, like most Scheme implementations, also goes beyond R5RS in many ways, because R5RS does not give specifications (or even recommendations) regarding many issues that are important in practical programming. Some of the areas where Guile extends R5RS are: * Guile's interactive documentation system * Guile's support for POSIX-compliant network programming * GOOPS - Guile's framework for object oriented programming. 3.3 Guile Scripting =================== 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. 3.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 R5RS, 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 *note The Meta Switch::. * 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. 3.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 *note Scripting Examples::. `-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 DIRECTORY' Add DIRECTORY to the front of Guile's module load path. The given directories are searched in the order given on the command line and before any directories in the GUILE_LOAD_PATH environment variable. Paths added here are _not_ in effect during execution of the user's `.guile' file. `-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. The FUNCTION is most often a simple symbol that names a function that is defined in the script. It can also be of the form `(@ MODULE-NAME SYMBOL)' and in that case, the symbol is looked up in the module named MODULE-NAME. For compatibility with some versions of Guile 1.4, you can also use the form `(symbol ...)' (that is, a list of only symbols that doesn't start with `@'), which is equivalent to `(@ (symbol ...) main)', or `(symbol ...) symbol' (that is, a list of only symbols followed by a symbol), which is equivalent to `(@ (symbol ...) symbol)'. We recommend to use the equivalent forms directly since they corresponf to the `(@ ...)' read syntax that can be used in normal code, *Note Using Guile Modules::. *Note Scripting Examples::. `-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 *note Scripting Examples::. `\' Read more command-line arguments, starting from the second line of the script file. *Note The Meta Switch::. `--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. `--use-srfi=LIST' The option `--use-srfi' expects a comma-separated list of numbers, each representing a SRFI number to be loaded into the interpreter before starting evaluating a script file or the REPL. Additionally, the feature identifier for the loaded SRFIs is recognized by `cond-expand' when using this option. guile --use-srfi=8,13 `--debug' Start with the debugging evaluator and enable backtraces. Using the debugging evaluator will give you better error messages but it will slow down execution. By default, the debugging evaluator is only used when entering an interactive session. When executing a script with `-s' or `-c', the normal, faster evaluator is used by default. `--no-debug' Do not use the debugging evaluator, even when entering an interactive session. `-h, --help' Display help on invoking Guile, and then exit. `-v, --version' Display the current version of Guile, and then exit. 3.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.3.4 Command Line Handling --------------------------- The ability to accept and handle command line arguments is very important when writing Guile scripts to solve particular problems, such as extracting information from text files or interfacing with existing command line applications. This chapter describes how Guile makes command line arguments available to a Guile script, and the utilities that Guile provides to help with the processing of command line arguments. When a Guile script is invoked, Guile makes the command line arguments accessible via the procedure `command-line', which returns the arguments as a list of strings. For example, if the script #! /usr/local/bin/guile -s !# (write (command-line)) (newline) is saved in a file `cmdline-test.scm' and invoked using the command line `./cmdline-test.scm bar.txt -o foo -frumple grob', the output is ("./cmdline-test.scm" "bar.txt" "-o" "foo" "-frumple" "grob") If the script invocation includes a `-e' option, specifying a procedure to call after loading the script, Guile will call that procedure with `(command-line)' as its argument. So a script that uses `-e' doesn't need to refer explicitly to `command-line' in its code. For example, the script above would have identical behaviour if it was written instead like this: #! /usr/local/bin/guile \ -e main -s !# (define (main args) (write args) (newline)) (Note the use of the meta switch `\' so that the script invocation can include more than one Guile option: *Note The Meta Switch::.) These scripts use the `#!' POSIX convention so that they can be executed using their own file names directly, as in the example command line `./cmdline-test.scm bar.txt -o foo -frumple grob'. But they can also be executed by typing out the implied Guile command line in full, as in: $ guile -s ./cmdline-test.scm bar.txt -o foo -frumple grob or $ guile -e main -s ./cmdline-test2.scm bar.txt -o foo -frumple grob Even when a script is invoked using this longer form, the arguments that the script receives are the same as if it had been invoked using the short form. Guile ensures that the `(command-line)' or `-e' arguments are independent of how the script is invoked, by stripping off the arguments that Guile itself processes. A script is free to parse and handle its command line arguments in any way that it chooses. Where the set of possible options and arguments is complex, however, it can get tricky to extract all the options, check the validity of given arguments, and so on. This task can be greatly simplified by taking advantage of the module `(ice-9 getopt-long)', which is distributed with Guile, *Note getopt-long::. 3.3.5 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 3.4 Using Guile Interactively ============================= When you start up Guile by typing just `guile', without a `-c' argument or the name of a script to execute, you get an interactive interpreter where you can enter Scheme expressions, and Guile will evaluate them and print the results for you. Here are some simple examples. guile> (+ 3 4 5) 12 guile> (display "Hello world!\n") Hello world! guile> (values 'a 'b) a b This mode of use is called a "REPL", which is short for "Read-Eval-Print Loop", because the Guile interpreter first reads the expression that you have typed, then evaluates it, and then prints the result. 3.4.1 Readline -------------- To make it easier for you to repeat and vary previously entered expressions, or to edit the expression that you're typing in, Guile can use the GNU Readline library. This is not enabled by default because of licensing reasons, but all you need to activate Readline is the following pair of lines. guile> (use-modules (ice-9 readline)) guile> (activate-readline) It's a good idea to put these two lines (without the "guile>" prompts) in your `.guile' file. Guile reads this file when it starts up interactively, so anything in this file has the same effect as if you type it in by hand at the "guile>" prompt. 3.4.2 Value History ------------------- Just as Readline helps you to reuse a previous input line, "value history" allows you to use the _result_ of a previous evaluation in a new expression. When value history is enabled, each evaluation result is automatically assigned to the next in the sequence of variables `$1', `$2', ..., and you can then use these variables in subsequent expressions. guile> (iota 10) $1 = (0 1 2 3 4 5 6 7 8 9) guile> (apply * (cdr $1)) $2 = 362880 guile> (sqrt $2) $3 = 602.3952191045344 guile> (cons $2 $1) $4 = (362880 0 1 2 3 4 5 6 7 8 9) To enable value history, type `(use-modules (ice-9 history))' at the Guile prompt, or add this to your `.guile' file. (It is not enabled by default, to avoid the possibility of conflicting with some other use you may have for the variables `$1', `$2', ..., and also because it prevents the stored evaluation results from being garbage collected, which some people may not want.) 3.4.3 Error Handling -------------------- When code being evaluated from the REPL hits an error, Guile remembers the execution context where the error occurred and can give you three levels of information about what the error was and exactly where it occurred. By default, Guile displays only the first level, which is the most immediate information about where and why the error occurred, for example: (make-string (* 4 (+ 3 #\s)) #\space) -| standard input:2:19: In procedure + in expression (+ 3 #\s): standard input:2:19: Wrong type argument: #\s ABORT: (wrong-type-arg) Type "(backtrace)" to get more information or "(debug)" to enter the debugger. However, as the message above says, you can obtain more information about the context of the error by typing `(backtrace)' or `(debug)'. `(backtrace)' displays the Scheme call stack at the point where the error occurred: (backtrace) -| Backtrace: In standard input: 2: 0* [make-string ... 2: 1* [* 4 ... 2: 2* [+ 3 #\s] Type "(debug-enable 'backtrace)" if you would like a backtrace automatically if an error occurs in the future. In a more complex scenario than this one, this can be extremely useful for understanding where and why the error occurred. You can make Guile show the backtrace automatically by adding `(debug-enable 'backtrace)' to your `.guile'. `(debug)' takes you into Guile's interactive debugger, which provides commands that allow you to * display the Scheme call stack at the point where the error occurred (the `backtrace' command -- see *note Display Backtrace::) * move up and down the call stack, to see in detail the expression being evaluated, or the procedure being applied, in each "frame" (the `up', `down', `frame', `position', `info args' and `info frame' commands -- see *note Frame Selection:: and *note Frame Information::) * examine the values of variables and expressions in the context of each frame (the `evaluate' command -- see *note Frame Evaluation::). The interactive debugger is documented further in the following section. 3.4.4 Using the Interactive Debugger ------------------------------------ Guile's interactive debugger is a command line application that accepts commands from you for examining the stack and, if stopped at a trap, for continuing program execution in various ways. Unlike in the normal Guile REPL, commands are typed mostly without parentheses. When you first enter the debugger, it introduces itself with a message like this: This is the Guile debugger -- for help, type `help'. There are 3 frames on the stack. Frame 2 at standard input:36:19 [+ 3 #\s] debug> "debug>" is the debugger's prompt, and a reminder that you are not in the normal Guile REPL. In case you find yourself in the debugger by mistake, the `quit' command will return you to the REPL. -- Debugger Command: quit Exit the debugger. The other available commands are described in the following subsections. 3.4.4.1 Display Backtrace ......................... The `backtrace' command, which can also be invoked as `bt' or `where', displays the call stack (aka backtrace) at the point where the debugger was entered: debug> bt In standard input: 36: 0* [make-string ... 36: 1* [* 4 ... 36: 2* [+ 3 #\s] -- Debugger Command: backtrace [count] -- Debugger Command: bt [count] -- Debugger Command: where [count] Print backtrace of all stack frames, or of the innermost COUNT frames. With a negative argument, print the outermost -COUNT frames. If the number of frames isn't explicitly given, the debug option `depth' determines the maximum number of frames printed. The format of the displayed backtrace is the same as for the `display-backtrace' procedure (*note Examining the Stack::). 3.4.4.2 Frame Selection ....................... A call stack consists of a sequence of stack "frames", with each frame describing one level of the nested evaluations and applications that the program was executing when it hit a breakpoint or an error. Frames are numbered such that frame 0 is the outermost -- i.e. the operation on the call stack that began least recently -- and frame N-1 the innermost (where N is the total number of frames on the stack). When you enter the debugger, the innermost frame is selected, which means that the commands for getting information about the "current" frame, or for evaluating expressions in the context of the current frame, will do so by default with respect to the innermost frame. To select a different frame, so that these operations will apply to it instead, use the `up', `down' and `frame' commands like this: debug> up Frame 1 at standard input:36:14 [* 4 ... debug> frame 0 Frame 0 at standard input:36:1 [make-string ... debug> down Frame 1 at standard input:36:14 [* 4 ... -- Debugger Command: up [n] Move N frames up the stack. For positive N, this advances toward the outermost frame, to lower frame numbers, to frames that have existed longer. N defaults to one. -- Debugger Command: down [n] Move N frames down the stack. For positive N, this advances toward the innermost frame, to higher frame numbers, to frames that were created more recently. N defaults to one. -- Debugger Command: frame [n] Select and print a stack frame. With no argument, print the selected stack frame. (See also "info frame".) An argument specifies the frame to select; it must be a stack-frame number. 3.4.4.3 Frame Information ......................... The following commands return detailed information about the currently selected frame. -- Debugger Command: info frame Display a verbose description of the selected frame. The information that this command provides is equivalent to what can be deduced from the one line summary for the frame that appears in a backtrace, but is presented and explained more clearly. -- Debugger Command: info args Display the argument variables of the current stack frame. Arguments can also be seen in the backtrace, but are presented more clearly by this command. -- Debugger Command: position Display the name of the source file that the current expression comes from, and the line and column number of the expression's opening parenthesis within that file. This information is only available when the `positions' read option is enabled (*note Reader options::). 3.4.4.4 Frame Evaluation ........................ The `evaluate' command is most useful for querying the value of a variable, either global or local, in the environment of the selected stack frame, but it can be used more generally to evaluate any expression. -- Debugger Command: evaluate expression Evaluate an expression in the environment of the selected stack frame. The expression must appear on the same line as the command, however it may be continued over multiple lines. 3.4.4.5 Single Stepping and Continuing Execution ................................................ The commands in this subsection all apply only when the stack is "continuable" -- in other words when it makes sense for the program that the stack comes from to continue running. Usually this means that the program stopped because of a trap or a breakpoint. -- Debugger Command: step [n] Tell the debugged program to do N more steps from its current position. One "step" means executing until the next frame entry or exit of any kind. N defaults to 1. -- Debugger Command: next [n] Tell the debugged program to do N more steps from its current position, but only counting frame entries and exits where the corresponding source code comes from the same file as the current stack frame. (See *note Step Traps:: for the details of how this works.) If the current stack frame has no source code, the effect of this command is the same as of `step'. N defaults to 1. -- Debugger Command: finish Tell the program being debugged to continue running until the completion of the current stack frame, and at that time to print the result and reenter the command line debugger. -- Debugger Command: continue Tell the program being debugged to continue running. (In fact this is the same as the `quit' command, because it exits the debugger command loop and so allows whatever code it was that invoked the debugger to continue.) 3.5 Using Guile in Emacs ======================== There are several options for working on Guile Scheme code in Emacs. The simplest are to use Emacs's standard `scheme-mode' for editing code, and to run the interpreter when you need it by typing "guile" at the prompt of a `*shell*' buffer, but there are Emacs libraries available which add various bells and whistles to this. The following diagram shows these libraries and how they relate to each other, with the arrows indicating "builds on" or "extends". For example, the Quack library builds on cmuscheme, which in turn builds on the standard scheme mode. scheme ^ | .-----+-----. | | cmuscheme xscheme ^ | .-----+-----. | | Quack GDS "scheme", written by Bill Rozas and Dave Love, is Emacs's standard mode for Scheme code files. It provides Scheme-sensitive syntax highlighting, parenthesis matching, indentation and so on. "cmuscheme", written by Olin Shivers, provides a comint-based Scheme interaction buffer, so that you can run an interpreter more directly than with the `*shell*' buffer approach by typing `M-x run-scheme'. It also extends `scheme-mode' so that there are key presses for sending selected bits of code from a Scheme buffer to this interpreter. This means that when you are writing some code and want to check what an expression evaluates to, you can easily select that code and send it to the interpreter for evaluation, then switch to the interpreter to see what the result is. cmuscheme is included in the standard Emacs distribution. "Quack", written by Neil Van Dyke, adds a number of incremental improvements to the scheme/cmuscheme combination: convenient menu entries for looking up Scheme-related references (such as the SRFIs); enhanced indentation rules that are customized for particular Scheme interpreters, including Guile; an enhanced version of the `run-scheme' command that knows the names of the common Scheme interpreters and remembers which one you used last time; and so on. Quack is available from `http://www.neilvandyke.org/quack'. "GDS", written by Neil Jerram, also builds on the scheme/cmuscheme combination, but with a change to the way that Scheme code fragments are sent to the interpreter for evaluation. cmuscheme and Quack send code fragments to the interpreter's standard input, on the assumption that the interpreter is expecting to read Scheme expressions there, and then monitor the interpreter's standard output to infer what the result of the evaluation is. GDS doesn't use standard input and output like this. Instead, it sets up a socket connection between the Scheme interpreter and Emacs, and sends and receives messages using a simple protocol through this socket. The messages include requests to evaluate Scheme code, and responses conveying the results of an evaluation, thus providing similar function to cmuscheme or Quack. They also include requests for stack exploration and debugging, which go beyond what cmuscheme or Quack can do. The price of this extra power, however, is that GDS is Guile-specific. GDS requires the Scheme interpreter to run some GDS-specific library code; currently this code is written as a Guile module and uses features that are specific to Guile. GDS is now included in the Guile distribution; for previous Guile releases (1.8.4 and earlier) it can be obtained as part of the `guile-debugging' package from `http://www.ossau.uklinux.net/guile'. Finally, "xscheme" is similar to cmuscheme -- in that it starts up a Scheme interaction process and sends commands to that process's standard input -- and to GDS -- in that it has support beyond cmuscheme or Quack for exploring the Scheme stack when an error has occurred -- but is implemented specifically for MIT/GNU Scheme. Hence it isn't really relevant to Guile work in Emacs, except as a reference for useful features that could be implemented in one of the other libraries mentioned here. In summary, the best current choice for working on Guile code in Emacs is either Quack or GDS, depending on which of these libraries' features you find most important. For more information on Quack, please see the website referenced above. GDS is documented further in the rest of this section. 3.5.1 GDS Introduction ---------------------- GDS aims to allow you to work on Guile Scheme code in the same kind of way that Emacs allows you to work on Emacs Lisp code: providing easy access to help, evaluating arbitrary fragments of code, a nice debugging interface, and so on. The thinking behind the GDS library is that you will usually be doing one of two things. 1. Writing or editing code. The code will be in a normal Emacs Scheme mode buffer, and GDS extends Scheme mode to add keystrokes and menu items for th