Christian Queinnec has written a masterpiece called LISP In Small Pieces, which features eleven Lisp Interpreters and two Lisp compilers.
When you go to download the code from the website here - it has the comment:
The programs of this book are available on the net.
These programs used to run with some Scheme systems around 1994.
Any idea:
(a) What Scheme systems these ran on at the time, and more importantly;
(b) What Scheme systems these would run on today?
There's a lot of programs in there. I did a few tests to see how well I could answer this without having to try them individually. There are 131 files in the tarball with extension ".scm". However there appear to be Scheme programs with other extensions such as .bgl. So I did a search for files containing 'L i S P' in the first five lines. That yields 173 files. I tried running all of these on my preferred Scheme implementation. 31 of these run without error. Almost all of these are in the "src" directory. So the language-specific programs really do seem language-specific. Let's look at one of the src/ files that failed, "chap9z.scm". It's choking on define-abbreviation. I don't know the origin of this symbol, but it's not defined anywhere in guile. But all of its uses could be performed by guile's syntax-rules.
Some Scheme implementations that existed in 1994 still are still around and maintained: Scheme 48, Chez Scheme, Gambit, Bigloo, MIT Scheme and SCM.
Probably the code from LiSP will run in other modern Scheme systems such as Guile or Larceny.
Personally, I would recommend using Racket. Most likely, much of the code will run in #lang racket with no changes, and there's no requirement to use [] (but your code may be easier to read :). Things that don't work are probably easy to fix, and you can also use the R5RS language implementation provided by Racket which will likely work for all of the code.
(a) What Scheme systems these ran on at the time
The Makefile in the source tarball from the author's website has targets for running the code under bigloo, elk, gambit, mit-scheme, scheme2c, and scm.
The Makefile mentions SCM 4e1 and Bigloo 1.9d as known working versions, though I haven't tested them myself. I didn't find any mention of specific versions for the other schemes.
(b) What Scheme systems these would run on today?
The code in this github repo has been updated so that almost all of the tests in the included test suite pass with current (as of 06/2014) versions of bigloo, gambit, and mit-scheme.
If you just want to be able to run the code and follow along with the book, one of those schemes should work for you.
[full disclosure: I'm the owner of the repo and I'm a Scheme noob. The code in the repo is WOMM certified, but your mileage may vary.]
If, on the other hand, you're not content to use bigloo / gambit / mit-scheme, it shouldn't be too hard to add support for guile / racket / insert-favorite-scheme-here. Use one of the book.* files as a starting point, e.g. gambit/book.scm or mitscheme/book.mit. If you can get a version of book.scm to load in your favorite scheme, then have a look at the test.interpreters make target, and finally the grand.test target to verify things are working as expected.
The included README file states:
These files were tested with a Scheme interpreter augmented with
a test-suite driver (tester.scm),
the define-syntax and define-abbreviation macros (using
Dybvig's syntax-case package),
and an object system: Meroonet (meroonet.scm).
Bigloo, Scheme->C, Gambit, Elk or SCM can be used. The first three are
better since a specialized interpreter may be built that contains a
compiled Meroonet and compiled hygienic macros.
Apparently Appleby has posted an updated version of the source code. Racket is missing though )=
See https://github.com/appleby/Lisp-In-Small-Pieces
Related
I work on computational music. I have found the ps13 pitch spelling algorithm implemented in Lisp in 2003, precisely "Digitool MCL 4.3". I would like to run this code, preferably on a Linux x86 machine, to compare its results with other similar codes.
I am new to Lisp, but so far my research led me to think that Digitool MCL is no longer available. I thought of two ways which may help me:
a virtual environment (Docker or else) which would emulate a machine from 2003…
a code translation tool which would transform the 2003 source code into something executable today
I have not succeeded in finding one of these two options, nor running it directly with sbcl (but, as a newbie, I may have missed a small modification to make it run easily).
May someone help me?
Summary
This code is very close to being portable CL: you won't need something emulating an antique Mac to run it. I ran it on three implementations (SBCL, LispWorks, CCL) within a few minutes. However if you're not a Lisp person (and don't want to become one) it will be somewhat more fiddly to do that.
However I can't just send you a fixed version, both because this isn't the right forum for that, and also because we'd need to get the author's permission to do so. I have asked him if he would be interested in a portabalised version, and if he is, I will send him one in due course. You could also get in touch and ask to be notified.
(Meta-summary: while I think the question is fine, any reasonable answer probably doesn't fit on SO.)
Details
One initial problem with this code is that the file uses old Mac line end conventions (I think: not Unix anyway): unless whatever Lisp you're using is smart enough to spot this (some are, SBCL seems not to be although I am sure there are options to tell it) you'll need to convert it.
Given that, the code that implements this algorithm is very, very close to being portable Common Lisp. It has four dependencies on non-standard things:
two global variables, *save-local-symbols* and *verbose-eval-selection*;
two functions: choose-file-dialog and choose-directory-dialog.
The global variables can probably be safely commented out as I think they are just controls for the compiler, probably. The functions have fairly obvious specifications: they're obviously meant to pop up file / directory choosers.
However you can just not use the bits of the code that use these functions, so you can compile it, get a few compiler warnings about undefined functions, and then it's fine.
But it gets better than that in fact: the latter-day descendant of MCL is Clozure CL: CCL is free, and open source. CCL has both choose-file-dialog and choose-directory-dialog already and both of the globals exist although one is no longer exported.
Unfortunately there are then some hidden portability problems to do with assumptions about what pathnames look like as strings: it's making some assumption about what things looked like on pre-OSX Macs I think. This kind of problem is easy but often a bit fiddly to fix (I think in this case it would be easy). So, again, the answer to that is just not call the things that are doing a lot of pathname munging:
> (ps13-test-from-file-list (directory "~/Downloads/d/*.opnd"))
[... much output ...]
Total number of errors = 81.
Total number of notes = 41544.
Percentage correct = 99.81%
nil
Note that the above output came from LispWorks, not CCL: CCL works just as well though, as will any CL probably.
SBCL has one additional problem: the CL-USER package in SBCL already uses a package which exports int which is defined in this code. So you need to compile it in some other package. But given that, it's fine in SBCL as well.
ctags is a simple source code tagging system, also integrated in vi (and its flavours nvi, vim, etc.). AFAIK, it builds a plain text file where all the elements (functions, macros, ...) of the source code are indexed. But this file may become too large and unmanageable when the source code tree is extremely huge: this is the case of a kernel (Linux, *BSD, or similar).
Is still ctags or exuberant-ctags suitable for a complex source tree like a kernel?
If not, what tools (with the same integration in vi as ctags) can replace it? This may become subjective, so if possible provide a list of suggested tools: any comments, and references to a guide with the keyboard shortcuts in vi, are welcome.
Supported languages should be at least C, C++, assembly. The tool should be usable through CLI. I would principally like to jump to the definition of functions, macros, struct and similar objects (with ctags, pressing Ctrl+] with the cursor over the item name), to their manpages if possible, and back to the code.
The only alternative tool I know so far is GNU global, with a pretty complex vi integration, which seems to be possible only through Perl (and I can't find the equivalent of Ctrl+]).
The answer to your first point is a resounding yes.
You can use ctags to generate a tags file for different subtrees, thus keeping the size of the generated file to a minimum. At this point, you need to have a mechanism in place for searching for these multiple tags files. Vim provides this, of course.
I have given some advice here, so you may want to check that out.
Of course, I use exuberant-ctags there, so keep that in mind.
I am currently trying to wrap my head around packages, systems & co.
I now have read Packages, systems, modules, libraries - WTF? a few times, and I think I'm still having difficulties to get it right.
If I simply want to split a Lisp source file into two files, where one shall "use" the other - how do I do that? Do I need to build a system for this? Should I use a module? …? I'm coming from a Node.js background, and there you can simply say
var foo = require('./foo');
to get a reference to what's exported in file foo.js. What is the closest equivalent to this in Lisp?
I understand that ASDF is for systems, and that it is bundled as part of Quicklisp, at least according to its documentation:
ASDF comes bundled with all recent releases of active Common Lisp implementations as well as with quicklisp […]
Okay, Quicklisp is for libraries, but what is their relationship? Is Quicklisp something such as a "package manager" in other languages? And if so, then what exactly does ASDF provide?
Sorry for these many questions, but I think it just shows the trouble I have to understand how to structure Lisp applications. Any help would be greatly appreciated :-)
System
For structuring large system use a system management tool. A 'free' one is ASDF.
You would need a system declaration, which lists the parts of you library or application. Typically it goes into an own file. Then you load a system or compile a system. There should be tutorials how to do that.
A simple Lisp system might have the following files:
a system file describing the system, its parts and whatever other stuff is needed (other systems)
a package file which describes the namespaces used
a basic tools file (for examples functions used by the macro)
a macro file which lists the macros (used so that they get compiled/loaded before the rest of the software)
one or more other files with functionality.
Quicklisp is independent of that. It's a software distribution tool.
Quick hack to compile and load files
But you can also compile and load files the old fashioned way without a system tool:
(defparameter *files*
'("/yourdir/foo.lisp" "/yourdir/bar.lisp"))
(defun compile-foobar ()
(mapc #'compile-file *files*))
(defun load-foobar ()
(mapc #'load *files*))
(defun compile-and-load ()
(mapc (lambda (file)
(load (compile-file file)))
*files*))
In reality there might be more to it, but often it's enough. It should be easy to write your own building tool. A typical system tool will provide many more features for building more complex software in a structured way. Many of the ideas for these tools reach back at least 35 years. See for example the Lisp Machine manual, here the edition from 1984, chapter Maintaining Large Systems.
The role of files
Note that in plain Common Lisp the role of files and its semantics are not very complex.
A file is not a namespace, it is not associated with a class/subclass or an object, it is not a module. You mix Lisp constructs in a file like you want. Files can be arbitrary large (for example one complex library has a version where it is delivered as single source file with 30000 lines). The only real place in the standard semantics where a file plays a role is when compiling a file. What side effects has compiling a file? What optimizations can a compiler do?
Other than that it is assumed that the development environment provides services like load and compiling groups of files aka systems, provide overviews of compilation errors, record source locations of definitions, can locate definitions and more. A tool like ASDF handles the system part.
There is a require function in Common Lisp, but it deprecated. If you simply want to split your code in one or more pieces, to use it interactively in the REPL, you can put the code in different files and then load each of them. If instead you want to write a full lisp project, I have found very useful the quickproject package, that provides a simple starting point for the creation of new packages.
I recently downloaded PLT Scheme and DrScheme. When I open DrScheme, I am told to choose a language. However, I'm not familiar with any of my options, and the help guides don't really break it down to help me easily choose which choice.
So, first - is DrScheme and PLT Scheme really the tools I need to learn Lisp and/or Scheme? If so, what are the different languages and which one(s) should I be using?
Just go for "Pretty Big". That will be all you need until you know what the rest are for. I find that R5RS is good, but it does lack the extensions that PLT has added to DrScheme.
edit: I just checked and I guess that both "Pretty Big" and "R5RS" are considered "legacy" in DrScheme 4 and the "Module" language is favored instead. Just make sure that all the files you use with the Module language start with
#lang scheme
Module is a way to specify the language used in the source file rather than globally by the DrScheme interpreter. This means that you can use different languages for different parts of your program by breaking it up into files and indicating in each file the language you're using. If you're just starting out, all you need to worry about is just keeping #lang scheme at the top of all the files you use.
A small note - this declaration is not official Scheme, and needs to be removed if you attempt to use the files in another Scheme interpreter.
Standard (R5RS) is the actual thing so that would be your best bet
i learnt it from http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/
used MIT Scheme while doing that
but otherwise i find plt a lot nicer to work with
I've been wanting to teach myself Lisp for a while. However, all the interpreters of which I've heard involve some flavor of emacs.
Are there any command line interpreters, such that I could type this into the command line:
lispinterpret sourcefile.lisp
just like I can run perl or python.
While I'd also like to become more familiar with Emacs (if only not to be frustrated when I work with somebody who uses Emacs), I'd rather decouple learning Emacs from learning Lisp.
Edit: I actually want to follow SICP which uses Scheme, so an answer about Scheme would be more useful. I'm just not that familiar with the differences.
You could also try DrScheme, which whilst not exactly a standalone interpreter, isn't emacs :)
It's basically a simple IDE that has an area to type in code that can be executed as a file, and then another area that is the running interpreter that you can interact with.
(Also, find the UC Berkeley CS61A podcasts and listen to them, as well as reading SICP)
It looks like Steel Bank Common Lisp (SBCL) also caters to what you want:
http://www.sbcl.org/manual/#Shebang-Scripts
SBCL is both top rate and open source.
Checkout CLISP wiki-link that ie. was used by Paul Graham
Direct link
I often write lisp shell scripts which start with this line:
#!/usr/bin/clisp
Then you don't even need to type "lispinterpret" on the command-line. Just mark the script executable and run it directly.
Most scheme interpreters that I am familiar with can be run from the command line. (Much of the list below is extracted from the comparative table at Alexey Radul's Scheme Implementation Choices page. There is a more extensive list at schemewiki but that page does not immediately provide command-line invocation syntax.)
Here's how you run a number of implementations at the command line:
Chez Scheme: scheme, petite
MIT Scheme: mit-scheme
Scheme 48: scheme48
RScheme: rs
Racket: racket (But I recommend trying the DrRacket IDE, especially for beginners.)
Guile: guile
Bigloo: bigloo
Chicken: csi
Gambit: gsi
Gauche: gosh
IronScheme: IronScheme.Console
Kawa: kawa, java kawa.repl
Larceny: larceny
SCM: scm
If you are looking for Scheme to work with the SICP, take a look at MIT/GNU Scheme
http://groups.csail.mit.edu/mac/projects/scheme/
http://www.gnu.org/software/mit-scheme/index.html
The most widely used IDE for Common Lisp, particularly in the free software subset of the community, is in fact SLIME, which runs on Emacs. You can use whatever CL compiler you prefer and invoke Lisp source files the way you describe, but if you do that, you won't be taking advantage of many of Lisps dynamic features that are so incredibly useful while developing your application.
I suggest you take a look at this SLIME demonstration video to see what I mean, even though it might be a bit outdated at this point.
If the problem is that you (think you) don't like Emacs, I seriously suggest you try to learn it. Seriously. No, really, I mean that. However, there are alternatives, such as the IDEs provided by commercial Lisp implementations such as Allegro and Lispworks (free trials available), or an Eclipse plug-in called Cusp.
Did you try Allegro CL from http://www.franz.com/?
#Nathan: I've upmodded the Common Lisp links, because you asked about Lisp (especially with reference to Emacs Lisp). However, Common Lisp is very different from Scheme. A program written for one is unlikely to run on the other.
As you mentioned, SICP is for learning Scheme, not Lisp (or at least, not Common Lisp and not Emacs Lisp). There are some overlap in principles, however you can't simply cut and paste code from SICP and expect it to run on any Common Lisp or Emacs Lisp system. :-)
No "interpreter" requires emacs.
Also, emacs can run elisp in a headless manner.
It seems like scheme shell is suitable for your purpose.
Take a look at http://www.scsh.net/index.html
Another good dialect of lisp is cmucl. They used to love to brag about being the "fastest" lisp.