



	   ################################################
	   #                                              #
	   # ##   ## ###### ####### ##    ## ## ##     ## #
	   # ##   ## ##  ## ##      ###   ## ##  ##   ##  #
	   # ##   ## ##     ##      ####  ## ##   ## ##   #
	   # ##   ## ###### ######  ## ## ## ##    ###    #
	   # ##   ##     ## ##      ##  #### ##   ## ##   #
	   # ##   ## ##  ## ##      ##   ### ##  ##   ##  #
	   # ####### ###### ####### ##    ## ## ##     ## #
	   #                                              #
	   ################################################






 
 
 
	 The following paper was originally presented at the

		     Third Annual Tcl/Tk Workshop
		 Toronto, Ontario, Canada, July 1995

	   sponsored by Unisys, Inc. and USENIX Association



	    It was published by USENIX Association in the
		  1995 Tcl/Tk Workshop Proceedings.
 
 
 
 
        For more information about USENIX Association contact:
 
                   1. Phone:    510 528-8649
                   2. FAX:      510 548-5738
                   3. Email:    office@usenix.org
                   4. WWW URL:  http://www.usenix.org
 
 
 
 
 
^L

                          An Anatomy of Guile
                        The Interface to Tcl/Tk

                              Thomas Lord
                            lord@cygnus.com
                            Cygnus Support

                               Abstract

     Guile is an extension language library consisting of a virtual
     machine, run-time system, and front ends for multiple languages.
     Guile has been closely integrated with Tcl/Tk [Ousterhout] so that
     Tcl and Tk modules can be used by Guile programs, and Guile
     programs can be used to extend Tcl/Tk applications.

     This paper gives an overview of the structure and function of
     Guile, and includes some notes about how it is expected to evolve
     in the future.  The technical relation between Tcl/Tk and Guile is
     given special attention.

What is Guile?
==============

   Guile is the GNU project's *extension language library*.

   Libguile provides support for multiple, integrated extension
languages sharing a common object system, calling conventions, and
libraries of extension code.  The library is organized around a flexible
implementation of Scheme.  It is designed to mix unobtrusively with
ordinary C programs.

   Why build an extension language library that supports more than a
single extension language?  There are several reasons:

...so that users will have a choice of language.
     A user might prefer one language over another, or one language
     might be more appropriate to a situation than another.  For
     example, even though libguile is being derived from a Scheme
     interpreter, one goal of the project is to make Guile suitable for
     use in GNU Emacs.  There are many Emacs Lisp programmers and
     programs, and a considerable amount of documentation - so in
     addition to Scheme, full support for Emacs Lisp is very important.
     Another example: some users dislike Lisp dialects, and so a more
     C-like language is a good idea.

...so that extension writers can combine multiple bodies of code.
     For example, the GNU project's World Wide Web browser, TkWWW is
     currently written in a mixture of Scheme and Tcl. TkWWW was
     originally written in pure Tcl, and is now being extending drawing
     on code from the popular Scheme library slib.  Eventually, TkWWW
     will be able to run programs from the Emacs library as well.

...because it is better to optimize and port one multi-lingual interpreter than several monolingual interpreters.
     Under the hood, the implementations of many languages are quite
     similar.  There is a lot of duplicated effort in implementing them
     separately.

An Anatomy of Guile
===================

   If you could slice open a program built with Guile, you might see:

   whatis.eps

   A single virtual machine and run-time supports a variety of
languages.  The virtual machine is inter-operable with Tcl/Tk and
consequently, so are Tcl programs and programs interpreted by the
virtual machine.

   A particular application can define new additions to the built-in
run-time.  Other additions can be dynamicly loaded - including
additions which are extension language programs compiled to native code.

   In the next several sections, major features of Guile will be
individually described.

Core Functions and Types
------------------------

   `libguile' includes a core set of built-in types and procedures that
are accessible from extension languages.  Included are the core
procedures of standard Scheme, a Posix system call interface, a regular
expression package, an object system, and more.

   This section will describe (omitting many details) the representation
and interface to objects understood by the Guile virtual machine, and
the C calling conventions that apply to built-in functions.  Most of the
details of representation mentioned in this section are helpful for
understanding Guile, but are hidden by the public interfaces to
libguile.  This is a "behind the curtain" view.

   * Guile Objects

   All Guile objects are declared in C to be of the type `SCM'.  This
type is opaque and values of type `SCM' are manipulated almost entirely
by functions and macros.  There are two important exceptions: these
objects can be compared for equality (`eq?' in Scheme) using C's `=='
and `!='; these objects can be assigned to using C's `='.  The size of
an `SCM' object is guaranteed to be the same as a `void *' object.

   Internally to libguile, `SCM' values fall broadly into two classes:
immediates and non-immediates.  An immediate object fits entirely within
an `SCM' variable and represents an immutable value.  Some examples of
immediate values are character constants and small integers.  A
non-immediate object is one that is represented by a pointer into the
cons pair heap.  The pointer points to a cons pair.  The cons pair heap
is itself one or more large regions of memory allocated by `malloc',
carved up into individual pairs.

   A cons pair is heap memory containing two `SCM' values.  In keeping
with tradition, these values are called the CAR and CDR of the pair.  A
pair may be used in any of several ways.  It may be part of a
traditional lisp list in which case the CAR is the first element of the
list and the CDR is the remaining sub-list.  Or, a pair may hold some
other composite type, usually storing type and length information in
the CAR and type-specific data in the CDR.

   All values, immediate and non-immediate, are marked with their type.
Typically, type information is stored in the low order bits of immediate
values and the CAR of non-immediate values.

   pairs.eps

   Built-in non-immediate types include lists and arrays (Scheme
`pairs' and `vectors'), abstract streams (Scheme `ports'), arbitrary
precision integers, complex numbers, regular expressions, character
strings and more.

   Non-immediate objects are automaticly garbage collected.  There is
very little that programmers ever need to do to make the garbage
collector work correctly.  The garbage collector automaticly searches
the C stack (and also searches any other regions of memory explicitly
designated) for apparent pointers into the pair-cell heap.  All
non-immediates that appear to be referenced in that way are safe from
garbage collection.  Any object that is referenced directly or
indirectly by a saved object is itself saved.  Any remaining objects
are reclaimed and recycled because no legitimate manipulation of values
known to the program will again reference those objects.  Here is a
typical memory map of a Guile-based program:

   heap.eps

   Programmers using libguile can define new types of non-immediate
objects.  This is explained further in a later section.

   * Built-in Procedures

   Built-in procedures are available both to C programmers using
`libguile' and to programmers calling these procedures from an
extension language.  The built-in procedures are the basis set of
operations that can be performed on Guile objects.

   `libguile' includes a superset of the procedures required by
standard Scheme [Clinger].  Additional optional packages include an
advanced array package (volunteers are working on implementing a library
of APL-like array functions), an interface to Posix system calls and an
interface to the GNU regular expression library.

   For the most part, C functions implementing Guile procedures follow
normal C calling conventions.  For example, the procedure `cons', that
takes two values and constructs a new pair from them, can be declared
this way:

     extern SCM gscm_cons (SCM car, SCM cdr);

   Procedures that take a variable number of arguments generally expect
those arguments to be passed as a list (a linked list of cons pairs).
For example, the `apply' procedure applies an object that represents a
procedure to an arbitrary number of arguments.  To apply a procedure
object to three arguments, one might write:

     SCM result = gscm_apply (proc_object,
                              gscm_listify (a, b, c, GSCM_EOL_MARKER));

   `gscm_listify' is the sole `libguile' function that takes a variable
number of arguments in the usual C fashion.

   If an error occurs in a built-in function, a `libguile' exception is
thrown.  Usually this results in a `longjmp' past the caller to an
error handler, although an interface exists for preventing this by
posting an overriding exception handler.

The Virtual Machine
-------------------

   In order to provide support for an arbitrary number of extension
languages, `libguile' implements a virtual machine that interprets a
shared language to which extension languages can be translated ([Sah]).

   * The Graph Interpreter

   The primary Guile virtual machine interprets code stored in graphs of
cons pairs.  As it interprets, it rewrites parts of the graph for
efficiency.  For example, upon the first evaluation, a symbolic variable
reference is rewritten to a fast virtual instruction that uses the
resolved location of the named variable.  In this way, a variable lookup
is eliminated from subsequent executions of the same part of the code
graph.

   The virtual machine implements support for memoizing macros.  A
memoizing macro is a special kind of procedure that rewrites one
expression to form another.  When it occurs in code, the macro is
evaluated, and then its return value is itself evaluated.

   A memoizing macro is special because when a call to one is first
evaluated, the result is saved and that particular call is never
re-evaluated.  The return value of a memoizing macro will be evaluated
every time the interpreter passes through that region of the code graph
- but the macro itself, that generated that return value, will only be
evaluated once.  Essentially, memoizing macros are a mechanism for
incremental, demand-driven code generation.

   Interpreted Scheme is implemented for this virtual machine mostly by
a series of memoizing macros.  The Scheme macros macros transform cons
pair syntax-trees of Scheme source into cons pair trees of internal
virtual machine instructions.  The transformation is incremental and
demand driven: loading new source code into the system is very fast in
exchange for slower execution the first time through any particular
code-path.

   Other languages can be implemented for the `libguile' interpreter by
translating them to Scheme and interpreting that.  The memoizing macro
facility makes it possible to do much of the translation lazily -
perhaps from a cons pair syntax tree of the source language program.

   If a language L can be successfully translated to Scheme, the
implementor can avoid the harder task of writing a full implementation
of L.  By rendevouzing at (an extended) Scheme, various implementors
can make their languages inter-operable.  Once some L can be translated
to Scheme, it can be compiled to native code via a Scheme->C translator
(such as the Guile-compatible translator `hobbit' ([Tammet])) and a C
compiler.  ([Steele])

   * The Future Byte-Code Interpreter

   An extension to the Guile VM, a byte-code interpreter (something of a
misnomer in this case), is under construction and is likely to be in a
useful condition by the end of 1995. (Then again, GNU is a non-prophet
project [RMS], so who can say for sure.)  The byte-code interpreter and
the graph interpreter will interact smoothly - evaluation can
transparently be of a mix of byte-code and graphs.  An experimental
version of the byte-code interpreter is included with snapshots of
Guile.

   The byte-code interpreter executes one-word virtual instructions
stored along with operands in a contiguous, typically malloced, array.
It uses an instruction-set derived from the specification of the Java VM
[Sun] but not strictly identical.

   The byte-code interpreter is being built in order to provide:

a portable, fast-loading, compact representation for programs
a way to trade off time spent compiling extension programs for faster execution
an alternative target to Scheme for language implementors
a target for languages that use native-format (untagged) numbers and structures
   Other systems have already demonstrated the value of a byte-code
interpreter for its convenient code representation and good performance
([Emacs]).

   Because the byte-code and graph interpreters will work together,
language implementors will have a choice of targets.  For some
languages (for example, `ctax' which is described below), the byte-code
assembly language may be a more reasonable target language.

   The byte-code instruction-set includes instructions that operate on
intermediate values and structure fields stored not as `SCM' objects,
but in native format (for example: untagged, normal, integers).  This
is convenient for implementing, with excellent performance, extension
languages which are more like C or C++.

The Interface to Application Specific Functions and Types
---------------------------------------------------------

   Programmers using `libguile' can define new built-in procedures and
types for their application.  Built-in procedures are defined as
ordinary C functions, taking arguments and returning a result of type
`SCM'.  These functions are declared to the interpreter at any time
(usually during program initialization).

   New types may also be declared to the interpreter.  Programmers must
specify a name and size for the type.  Optionally they may specify a
print function for the type, an equivalence test (for Scheme `equal?'),
and a clean up function that is called when an object of the new type
is freed by the garbage collector.  Generally, new types are useless in
and of themselves but are made useful by also defining new procedures
to construct and manipulate them.

   Application-specific types are all non-immediate values.  They are
represented by a cons pair handle and a malloced block of data.  The
format of the malloced data is arbitrary and may contain fields of type
SCM.  The malloced data will be searched by the garbage collector -
programmer's do not need to write a "GC stub function" for a new type.

   newfn.eps

Guile Extension Languages
-------------------------

   The Guile virtual machine is a platform for multiple extension
languages.  This section will discuss what languages are available and
planned and briefly how they are implemented.

   * Modified and Standard Scheme

   Historicly, the bulk of the code in libguile was written as a Scheme
interpreter ([Jaffer]).  Scheme, because of its simplicity and
generality remains the language around which Guile is organized.  Scheme
serves as a systems programming language for the Guile virtual machine.

   A large body of Scheme code exists that Guile is able to run.  A
notable example is the popular Scheme library slib ([Jaffer2]).  Another
example is hobbit, a Guile-compatible Scheme->C compiler, capable of
producing dynamicly loadable object files ([Tammet]).

   The Guile version of Scheme differs from standard Scheme ([Clinger])
in two ways.  First, in Guile Scheme, symbols are case sensitive.
Second, in Guile Scheme, there is no distinction made between the empty
list and boolean false (between `'()' and `#f').

   Although large bodies of real-world Scheme code works without
modification in the Guile dialect, some picky Scheme code will not.
Therefore, support for running programs in strictly standard Scheme is
planned for a future version of Guile.

   As explained earlier, Scheme is implemented on top of the virtual
machine by means of memoizing macros that incrementally translate Scheme
source code (stored as lists) into internal code (also stored as lists).

   It is handy that the interpreter accepts source code as lists
because it means that extension language programs can generate and
evaluate Scheme expressions on-the-fly.  An example of such a program
is the `stand-alone-repl' (Read Eval Print Loop) that interactively
reads and evaluates Scheme expressions.

   * Ctax

   Guile also comes with an implementation of a language called ctax.
Ctax is Scheme, but with a C-like syntax.

   Here is an example of a ctax program and a Scheme program to which
it can be compared:

             /* Multiply all numbers between m and n */
             scm
             product (m, n)
             {
               scm answer;
               scm x;
     
               answer = 1;
               for (x = m; x <= n; ++x)
                 answer *= x;
               return answer;
             }
     
             ;; And again in Scheme:
             ;;
             (define (product m n)
               (let loop ((answer 1)
                          (x m))
                  (if (<= x n)
                      (loop (* answer x) (+ x 1))
                      answer)))

                     Comparing `ctax' and `Scheme'

   As this paper is being written, ctax is implemented by means of a
translation to Scheme.  A simple parser produces syntax trees as lists,
these are translated to Scheme and evaluated:

   ctax.eps

   In the future, ctax will be extended so that variables can be
declared to be of specific types (in addition to the universal type
`scm').  A `ctax->byte-code' translator is in the works that will take
advantage of the byte-code interpreter's native-format math
instructions.  Support for object oriented programming is in the works
as well.

   * Emacs Lisp

   Future releases of Guile will support another dialect of lisp: Emacs
Lisp.  This will allow `libguile.a' to be used in the implementation of
GNU Emacs and it will allow any program linked with Guile to execute
Emacs Lisp programs ([Krawitz]).

   Most of the low-level support for Emacs Lisp has already been built.
The remaining hard part is to add an efficient yet flexible
implementation of shallow binding - Emacs Lisp is an idiosyncraticly
dynamicly scoped language.  Once a reasonable dynamic binding mechanism
has been implemented, translation of Emacs Lisp to Guile Scheme will be
a straightforward syntactic transformation.

Combining Languages Via Modules
-------------------------------

   Extension language programs communicate with the run-time system and
with other extension language programs via shared global variables.
For example, an extension package that defines a new data structure
might publish global definitions for the constructors and accessors for
that data structure.

   Guile includes a user level module system that provides a fairly
conventional access-control interface for managing global bindings.
User level modules specify public and private definitions. Programs can
specify which modules' public namespaces are to be searched for globals.
An integrated autoloader loads definitions of requested modules
on-demand.

   The user level module system is built on a hook called the low level
module system.  Low level modules are a simple but powerful mechanism
that, as will be explained, play an important role in the interface
between Guile and Tcl.  Low level modules work as follows:

   Guile defines a single, special, global namespace called the
`symhash' table.  Some definitions in this namespace have special
meaning to the interpreter.  For example, extension-language signal
handlers can be specified by defining particular names in the symhash
namespace.

   One special name in the symhash namespace is the variable
`*top-level-lookup-thunk*' which may optionally be bound to a
procedure.  If it is bound, then that procedure is used to map variable
names to global variables.

   Storage cells for global variables are first-class anonymous objects
that may be explicitly created and manipulated.  When the interpreter is
interpreting a program, it may find an unresolved variable name that
needs to be looked up in the appropriate namespace.  If that happens,
then the procedure that was the value of `*top-level-lookup-thunk*' at
the time the code being evaluated was loaded is called, passing the
unresolved variable name as an argument.  The lookup-thunk may return
storage for a global, thereby resolving that name, or it may return
false to signal an error.  In short, the `linker' that resolves global
symbolic references in extension programs is entirely customizable.

   To illustrate the power of the `*top-level-lookup-thunk*', here is
some code that implements a simple kind of `safe execution' environment.
The goal of this code is to transform the interpreter into one in which
only the definitions in an approved list are available.  The list of
approved definitions would presumably omit dangerous functions such as
most system calls.  If Scheme code leaves you cold, don't sweat it -
the details of this example are not central to the paper.

     ;;; The list of approved definitions:
     ;;;
     (define safe-definitions '(list + - * / cons car cdr ... etc))
     
     
     ;;; Establish the rule for how global variables are looked
     ;;; up:
     ;;;
     (set! *top-level-lookup-thunk*
       (let ((definitions (make-table)))
         (lambda (name defining?)
            (or (aref definitions name)
                (let ((safe? (member name safe-definitions)))
                   (and (or safe? defining?)
                        (let ((answer (make-variable
                                        (and safe?
                                             (variable-ref
                                                (built-in-variable name))))))
                          (aset definitions name answer)
                          answer)))))))

                    Safe-Guile in 12 Lines of Code.

The Interface to Tcl
====================

   Tcl ([Ousterhout]) defines at one layer a scripting language in
which useful programs have been written, and at another layer, a C
call-out mechanism for which useful libraries of C code have been
written.

   The GNU project wants to adapt a substantial Tcl program, TkWWW
([Wang]), and Tcl library, libexpect ([Libes]).  So an early priority
for the Guile project has been a clean interface to Tcl at both the
scripting language and C call-out layers.

Tcl C Call-outs and Guile
-------------------------

   The low-level Guile interface to Tcl is based on the public C
interface to libtcl.  Most of the libtcl functions have been made
available to extension language programs as built-in procedures.  Thus,
one can write a Scheme program that creates any number of Tcl
interpreters, calls `Tcl_Global_Eval' and so forth.

   `Tcl_CreateCommand' is among the libtcl procedures that can be
called from extension programs.  For example, one can define a new Tcl
command to be not a C function, but a Scheme procedure.  By means of
this, Tcl programs can call Scheme procedures.

   Scheme procedures can call Tcl commands by way of `Tcl_Global_Eval',
but there is a better way.  Tcl commands are first-class Scheme objects
and can easily be converted to Scheme procedures.  When such a
procedure is invoked, the corresponding Tcl command is called with no
intervening pass through the Tcl string substitution/evaluation
mechanism.

     ;;; Creating an interpreter:
     ;;;
     (define interp (tcl-create-interp))
     
     ;;; Calling the Tcl evaluator (it returns both status and result):
     ;;;
     (tcl-global-eval interp "expr 5+7")    => (0 . "12")
     
     ;;; A tcl command can be converted to a Scheme procedure:
     ;;;
     (define expr (reify-tcl-command interp 'expr))
     
     (expr "5+7")    => 12
     
     ;;; Defining a new Tcl command as a Scheme procedure:
     ;;;
     (tcl-create-command interp 'string_smash
        (lambda (a b) (string-append a "<<<SMASH>>>" b)))
     
     (tcl-global-eval interp "string_smash hello world")
         => (0 . "hello<<<SMASH>>>world")

                Examples of The Low Level Tcl Interface

An Implicit Interpreter
-----------------------

   The low-level mechanisms just described provide an awkward way for
Scheme to call Tcl and Tcl, Scheme.  (Because Scheme is the rendez-vous
language for Guile, this means that other extension languages can call
and be called by Tcl as well.).

   Guile also provides a higher-level, specialized but more convenient
way for Scheme and Tcl to inter-operate.  The high-level mechanism is
based on the previously described low-level module system.  The
high-level Tcl interface uses the module system to transparently import
Tcl commands as Scheme procedures.  This works much like the earlier
`Safe-Guile' example combined with the low-level Tcl function
`reify-tcl-command', shown in the previous example.

   In addition, the high-level interface includes Scheme macros that
define a convenient syntax for defining new Tcl commands written in
Scheme.

     ;;; Switch-on the high-level tcl interface:
     ;;;
     (set! the-interpreter (tcl-create-interp))
     (use-default-tcl-commands)
     
     ;;; Now tcl commands are automaticly available as procedures
     ;;; ...no need to call reify-tcl-command.
     ;;;
     ;;; Note that set is the Tcl command, unrelated to Scheme set!.
     ;;;
     (set 'a 0)  => 0
     (incr 'a)   => 1
     (set 'a)    => 1
     
     ;;; The high-level syntax for defining new tcl commands
     ;;; includes a type declaration syntax for arguments.
     ;;; Declarations are used to automate the conversion of
     ;;; arguments from strings to other types.  For example:
     ;;;
     (proc average_of_3 ((number a) (number b) (number c))
       (/ (+ a b c) 3))
     
     (tcl-global-eval the-interpreter "average_of_3 1 2 3")
         => (0 . "2")

               Examples of the High-Level Tcl Interface

The Interface to Tk
===================

   The low-level Guile interface to Tk is, analogously to the low level
Tcl interface, a subset of the public C functions of libtk.  At this
time, the three functions exported to Guile extension languages are:
`tk-init-main-window', `tk-do-one-event', and `tk-num-main-windows'.

A small change to libtk: canonical commands
-------------------------------------------

   A number of Tk-related procedures deal with call-backs: several
widget configuration commands, `after', and `bind' at least.  It has
already been shown that Scheme (and consequently other Guile extension
languages) can define new Tcl commands - so obviously call-backs can be
defined in Scheme by explicitly defining new commands.  But there is a
better way.

   Scheme programmers are accustomed to dealing with anonymous
procedures.  Anonymous procedures are created on the fly and are
garbage collected when no-longer needed.  They are usually passed around
by value, kept in the arguments and local variables of other procedure
calls.  Sometimes they are stored in other data structures and are
garbage collected along with those structures.

   Anonymous procedures are ideal for call-backs.  They can encapsulate
an arbitrary amount of the state that is available at the time of their
creation and carry it through to the time the call-back is issued - an
effect traditionally achieved in C by storing a call-back as "function
pointer plus `void *'".

   It is extremely convenient that an anonymous procedure can be garbage
collected once it is no longer needed.  A named procedure does not have
the same benefit - once named, a procedure must persist until the name
is explicitly revoked for at any time the system can be asked to produce
the procedure given the name.  So, asking programmers to name call-backs
would impose the burden that programmers would have to remove those
names when the call-backs are no longer needed.

   The usefulness of anonymous procedures for writing call-backs is
considered sufficiently important that some small changes have been made
to libtk in support of them.  These changes add the concept of a
canonical command to Tk.

   A canonical command is a Tcl command related by an automatic naming
scheme to some earlier defined command.  The command name from which a
canonical command's name is derived is called the canonical command's
owner.  The owner of a canonical command controls it's lifetime - when
it is no longer needed by the owner, a canonical command is destroyed.

   A canonical command is created by passing a normal command, prefixed
by `"*"', as an argument in a position where a call-back is expected.
For example:

     # An example of canonical commands as seen from wish:
     # Start with a normal command:
     #
     % proc hw {} {puts "hello world"}
     % hw
     hello world
     
     # Note the asterisk in the command that follows. It means that
     # the command name should be canonicalized.  "hw" will be renamed.
     #
     % pack [.b -text howdy -command *hw]
     % hw
     invalid command name "hw"
     
     # but if you click the button instead:
     hello world
     
     # Which is because the name of the command
     # has been canonicalized:
     #
     % .b configure -command
     -command command Command {} {b.__-command }
     % b.__-command
     hello world
     
     # Since .b owns the canonical command, it
     # will go away when .b is done with it.  In this
     # case, by setting a new command, the old one is
     # made redundant and removed.
     #
     % .b configure -command {puts "so long, b-dot-underscore-und..."}
     % b.__-command
     invalid command name "b.__-command"
     
     # And if you click the button...
     so long, b-dot-underscore-und...

                 An Illustration of Canonical Commands

   The canonical command mechanism allows anonymous procedures to be
used as call-backs.  When an anonymous procedure is passed as an
argument to a Tcl command, a random command name is generated for the
procedure.  This command name, prefixed by "*", is passed in place of
the anonymous procedure.  A Tcl command is defined and given the random
name. The anonymous procedure is given as the definition of that Tcl
command.  Because of the "*", the random command is canonicalized.
Therefore, the Tcl name for the command is temporary - when the command
is no longer needed as a call-back, the name will be removed and the
anonymous procedure will be a candidate for garbage collection.

   As long as a Tcl command name exists for an otherwise anonymous
procedure, it is protected from garbage collection.  When the Tcl
command name is destroyed (for example a canonical command name that is
no longer needed), the anonymous procedure becomes unprotected and if no
other references exist, it will be garbage collected.

Gwish
-----

   Gwish is a Scheme program modeled loosely on the Scheme interpreter
STk ([Gallesio]).  It builds upon the implicit interpreter interface to
Tcl and the low level interface of Tk to present users with a wish-like
Scheme shell.

   Here some Gwish code for drawing a cheery face.  The symbols
prefixed by colons are keywords, a Guile extension to standard Scheme.
Have a nice day!

     (canvas '.c)
     (pack '.c :fill "both" :expand #t)
     (.c 'create 'oval  50 5 250 205 :fill 'yellow)
     (.c 'create 'oval  110 60 130 110 :fill 'black)
     (.c 'create 'oval  170 60 190 110 :fill 'black)
     (.c 'create 'polygon 100 125 125 170 150 180 175 170 200 125
                          200 120 175 165 150 175 125 165 100 120
                          :fill 'black :smooth 1)
     (bind '.c 'q (lambda () (destroy '.)))

The TkWWW Project
=================

   The GNU project is building a Free ([Stallman], [Stallman2]) web
browser using the Tcl/Tk web browser, TkWWW ([Wang]).  Volunteers are
need to help us quickly bring TkWWW up-to-date with the latest features
popular in browsers.

   To date, TkWWW has been minimally updated to Tk4 and it runs under
Gwish running under on an interpreter linked with the TkWWW ".o" files.
Thus, TkWWW is now a it is a Scheme-extensible, ctax-extensible,
Tcl-extensible web browser.

   The modifications needed to turn TkWWW from a pure Tcl program into a
program extensible in Scheme and ctax as well are less than 200 lines of
C code, most of which is `boilerplate' code copied from the sample
stand-alone interpreter in the Guile sources.  The change took only a
few hours to make.

   Planned features for TkWWW are in-lined images, an upgrade to a
multi-threaded client library, and support for down-loadable, safe
extensions.

Conclusions
===========

   Guile is a flexible multi-lingual extension language library
organized around Scheme and cleanly inter-operable with Tcl/Tk.  The
performance and generality of Guile can be used to add greater
extensibility of any program that already uses Tcl alone.  TkWWW is an
example of a Tcl program to which Guile has been added.

   Guile is organized as a virtual machine and uses Scheme as a "systems
programming language" for that machine.  A very customizable low-level
module system is central to how this vm can be used to run extensions in
more than a single extension language.

   In particular, a wish-style shell has been written for Guile that
provides a convenient interface for writing or extending Tk programs in
Scheme or other Guile extension languages.

Acknowledgments and Availability
================================

   Its hard to determine just who designed Guile.  A large share of the
credit surely belongs to Aubrey Jaffer whose excellent Scheme
interpreter, SCM, forms the core of the implementation.  The module
system was designed and built by Miles Bader.  Many of the goals of the
project were established by Richard Stallman.  The byte-code
interpreter was inspired by the specification of, and inherits many of
the desirable properties of the Java VM.  The architecture was
discussed and hacked on by many volunteers.  Perhaps it is more a
discovery of what we could do with available resources than it is a
self-consciously constructed strategy.

   For more information about Guile, you can join the Gnu extension
language mailing list by sending a subscribe message to
gel-request@cygnus.com, or you can contact the author directly.
Versions of Guile have been in free distribution since February.
Generally, snapshots can be found at the ftp location:
ftp.cygnus.com:pub/lord.

References
==========

[Clinger]
     William Clinger and Jonathan Rees (Eds.), "Revised^4 Report on the
     Algorithmic Language Scheme"
     ftp.cs.indiana.edu:/pub/scheme-repository, 1991

[Emacs]
     prep.ai.mit.edu:pub/gnu/emacs-19.28.tar.gz, the GNU Emacs editor,
     1995.

[Gallesio]
     Erick Gallesio, kaolin.unice.fr:pub/STk-2.1.6.tar.gz, the STk
     Scheme interpreter, 1995

[Jaffer]
     Aubrey Jaffer, ftp-swiss.ai.mit.edu:pub/scm/scm4e1.tar.gz, the SCM
     Scheme interpreter, 1995.

[Jaffer2]
     Aubrey Jaffer, ftp-swiss.ai.mit.edu:pub/scm/slib2a2.tar.gz, the
     slib Scheme library, 1995.

[Krawitz]
     Robert Krawitz et al., "The GNU Emacs Lisp Reference Manual", The
     Free Software Foundation, 1990

[Libes]
     Don Libes et al., "libexpect.tar.gz", the expect Tcl library, 1995.

[Ousterhout]
     John K. Ousterhout, "Tcl and the Tk Toolkit" Addison-Wesley, 1994

[RMS]
     RMS, personal communication.

[Sah]
     Adam Sah and Jon Blow,  "A New Architecture for the Implementation
     of Scripting Languages" USENIX Symp. on Very High Level Languages,
     1994.

[Stallman]
     Richard M. Stallman, ftp.prep.ai.mit.edu:pub/gnu/COPYING, the GNU
     Public License, 1991

[Stallman2]
     Richard M. Stallman, The GNU Manifesto, Free Software Foundation,
     Cambridge MA, USA, 1993.

[Steele]
     Guy L. Steele Jr., "Rabbit: A compiler for Scheme" S.M. thesis,
     Mass. Inst. of Technology, 1978

[Sun]
     "The Java Virtual Machine Specification", Sun Microsystems, 1995

[Tammet]
     Tanel Tammet, ftp.cs.chalmers.se:/pub/users/tammet/hobbit4a.tar.gz,
     source code for a Scheme->C compiler, 1995.

[Wang]
     Joe Wang et al., tkwww-0.12.tar.gz, the TkWWW web browser, 1994


