This is Unlambda.  Welcome.

If you are trying to learn what Unlambda is, you should start with the
file doc/unlambda.html (the latest version of which can be found at
http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/ ).

If you are puzzled over the fact that there is no Makefile, search for
``how do I install all this'' later in this document.


This file refers to version 2.0.0 of the Unlambda distribution.


----------------------------------------------------------------------

The contents of the subdirectories are as follows:

CUAN/ contains a mirror of the Comprehensive Unlambda Archive Network,
that (presumably) contains (nearly) all Unlambda programs written so
far (as you can see, there aren't too many of those).

c/ contains an Unlambda interpreter written in C.  It is made to be
used with the Hans Boehm conservative C/C++ garbage collector, which
you can find on http://www.hpl.hp.com/personal/Hans_Boehm/gc/ (or on
http://reality.sgi.com/boehm/gc.html if the former doesn't work).  Two
compiled versions are included in the directory: one for
i686-gnu-linux with glibc 2.1.1 at least and one for
sparc-sun-solaris2.5 (has been tested on Solaris 2.5, 2.6 and 7).
They are statically linked with the garbage collector.

c-refcnt/ contains a modified version of the previous interpreter that
replaces the Boehm garbage collector by a reference-counting system.
So this is completely self-contained.

caml/ contains an Unlambda interpreter written in CAML (an ML variant
developped at the INRIA, http://www.inria.fr/ ).  See
http://caml.inria.fr/ for more information about CAML.  It is thought
that any version of CAML (or, at any rate, of OCAML) will compile
this, but the INRIA is not very keen on upward compatibility (to say
the least): this has been tested with OCAML version 2.02 (see
http://pauillac.inria.fr/ocaml/ for downloading OCAML; since version
2.03, OCAML is - presumably - free software).

doc/ contains the Unlambda documentation, that is, the file
doc/unlambda.html which is a mirror of
http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/

java/ contains an Unlamba interpreter written in Java.  This is
presumably the most pedagogical one, and it is *very* lengthily
commented, so you should probably start by reading it if you want to
know how an Unlambda interpreter is to be written.  This directory
also contains the compiled Java classes for this interpreter (to run
it, put them in a directory called unlambda/ below your classpath, and
run the Execute.main method).

perl/ contains an Unlambda debugger written in Perl.  This can be used
as an interpreter (although it is rather slow), but it is most useful
for understanding the step-by-step details of Unlambda evaluation.

scheme/ contains an Unlambda interpreter written in Scheme.  As of
Unlambda version 1, this was the only Unlambda interpreter.  It also
contains the unlambdaify program.  The interpreter was compiled using
bigloo (a free Scheme compiler which you can get from
ftp://kaolin.unice.fr/pub/Bigloo/ ).  Two compiled versions, one for
i686-gnu-linux with glibc 2.1.1 at least and one for
sparc-sun-solaris2.5 (has been tested on Solaris 2.5, 2.6 and 7) are
also included (they are statically compiled with the bigloo
libraries).

smlnj/ contains an Unlambda interpreter written in SML/NJ.  You can
get SML/NJ from http://cm.bell-labs.com/cm/cs/what/smlnj/ (SML/NJ is
free software).

tools/ contains various tools for writing Unlambda programs.


----------------------------------------------------------------------

The contents of the directories c/, c-refcnt/, doc/, java/ and scheme/
are distributed under the terms of the GNU General Public License (see
the accompanying file COPYING), version 2.0, or, at your option, any
later version.

The files of the smlnj/ and caml/ directories are distributed under
the terms the more relaxed GNU Lesser General Public License (see the
accompanying file COPYING.LESSER), version 2.1, or, at your option,
any later version.

The perl/ directory (copyright by Jean Marot) can be copied under the
same terms as Perl itself: that is, at your option, either under the
GNU General Public License (version 2.0 or later at your option) or
under the Artistic License (see the accompanying file
COPYING.Artistic).

The files in the CUAN/ directory are copyright of their respective
authors, and it is hoped that they won't be nasty enough to fuss about
the way they are distributed.

The files in the tools/ directory are hereby put in the public domain.

As a whole, the distribution is made available under the terms of the
GNU General Public License.


----------------------------------------------------------------------

If you are wondering ``how do I install all this'', there is no
definite answer: you don't need to install _all_ the Unlambda
interpreters, you merely need to install _one_.  So make your choice,
and consult the README file in the appropriate directory.  There is no
global Makefile because that would be pointless (as I just said, you
have to choose which interpreter you will use).  And there is no
Makefile in any subdirectory either, because the build process is
generally either trivial, or too system-dependent.

If you are wondering which interpreter to install, read the next
section.


----------------------------------------------------------------------

Let me say a few words about the pros and cons of the various
interpreters here.

The Scheme interpreter used to be the only version.  Initially, it was
fairly clearly written but now it's a mess.  It's hard to say anything
about its speed, though, because that depends wildly on the Scheme
system you use.  With bigloo, it's pretty fast, but it has the problem
that it's not properly tail-recursive in all cases (memory use may
explode for no adequately explained reason).  With guile, you'll have
severe limitations on size (guile is a scripting language, not a true
Scheme implementation).  I haven't tried it with other schemes such as
MIT-Scheme.  One of the major problems of the Scheme language is that
its library is soooo poor.  It doesn't even have the most basic
functions to read the command line, or to terminate program execution!
This is why I have a special bigloo version of the interpreter, which
uses bigloo extensions to do that sort of things.  Note that the
``unlambdaify'' program (which performs abstraction elimination) has
been written only in Scheme so far.

The Java version of the interpreter is mainly useful if you want to
learn about how to write an Unlambda interpreter, or to make sure you
understand the Unlambda specifications.  It is mostly useless in
practice because it is soooo slow.  It might be fun to have a web page
that uses a script in Java to run Unlambda programs (entered in a
dialog box); but my knowledge of Java is insufficient for this: I
would be grateful if someone did this for me.

The Perl interpreter is even slower than the Java version.  It is not
meant to be used as an interpreter, but mainly as a debugger, to
perform step-by-step evaluation of an Unlambda program (this is very
useful for understanding programs like "``r`ci`.*`ci").  There seem to
be some problems with the way c and d interact (I haven't had the time
to look in detail).

The SML/NJ interpreter is very simple because SML/NJ has all that is
required to make the writing of an Unlambda interpreter trivial.  It
hasn't been very much tested, though.

The Caml interpreter is an adaptation of the SML/NJ interpreter
(essentially, a rewriting of it in CPS).  It seems rather fast and
robust, but it hasn't been very much tested, either.  (I just wrote it
in a haste to make a point about the practicality of implementing
continuations in a language that doesn't have them, but has
first-class functions.)

The C interpreter is the smallest and the most robust.  I recommend
using it.  You may be surprised to learn, however, that it is
distinctly slower than the Scheme version when the latter is compiled
using bigloo.  This is because it was derived from the Java version,
which was designed for elegance rather than efficiency.  Contrary to
the bigloo-compiled Scheme version, the C interpreter is properly
tail-recursive in all cases.  As for the choice between the version
that uses the Boehm GC and that which uses reference counting, well,
the reference counting version is hardly more efficient, but it is
more portable; however, it has been less thoroughly tested (and it is
much easier to make a mistake in a reference counting memory
allocation scheme than a GC'ed system).

If you are looking for the most portable interpreter, the
reference-counting one written in C my best guess.  If you are looking
for the most efficient one in all cases, the one written in Caml is
probably a safe choice.


There is another Unlambda interpreter which I would very much have
liked to include in this distribution, but that was not possible for
license reasons.  It was written by Jacob L. Mandelson <jlm@ghs.com>,
it is in C, it uses reference counting (as opposed to full garbage
collection), and it is *much* more efficient than any other
interpreter included here.  You can get it from

  ftp://quatramaran.ens.fr/pub/madore/unlambda/contrib/mandelson-unlambda.c



          -- David A. Madore <david.madore@ens.fr>
             Orsay, France, 1999/12/20
