The Wraith Scheme software and its related documentation are provided AS IS, and without warranty of any kind. Jay Reynolds Freeman expressly disclaims all other warranties, expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose.
Wraith Scheme is shareware: You are welcome to use Wraith Scheme for free, forever, and to pass out free copies of it to anybody else. If you would like to make a shareware donation for it, that's fine, and there is information in the program about how to go about it, but in no sense do I request, insist, or expect that you do so. Furthermore, Wraith Scheme is intended to be complete and fully functional as downloaded. There is nothing to buy, there are no activation codes required, and there are no annoying reminders about shareware donations.
If you can't find what you are looking for in the table of contents, use the "Find" command -- in either the Apple Help Viewer or your HTML browser, whichever you are using to view this file -- to locate words and phrases.
Introduction
Getting Started
System Requirements
Installation
Security
Starting Wraith Scheme
Wraith Scheme Startup Actions
Changing the Startup Defaults
Changing How it Looks
Interacting with Wraith Scheme
The Wraith Scheme Window
The Input Panel
The Main Display Panel
The Message Panel
The Dialog Panel
The Basic Buttons Drawer
The Wraith Scheme Instrument Panel
Menu Items
The Wraith Scheme Menu
The "Preferences..." Menu Item
The Interpreter Menu
The Edit Menu
The Font Menu
The Window Menu
The Help Menu
Another View of Interacting with Wraith Scheme
Error Handling
Controlling Wraith Scheme
Differences from R5 Scheme
R5 Section 1
R5 Section 2
R5 Section 3
R5 Section 4
R5 Section 5
R5 Section 6
Internal Representations of Numbers
Exactness
#\tab and #\return
Slashification
R5 Section 7
Optional Features Omitted
Enhancements
Compiler
Debugger
Lambda Expression "Names"
Logic Programming
Procedures and Forms
Bit Operations
Evaluation
Files and Directories
Infinities and Nans
Inspecting Scheme Objects
Macros -- An Alternate Implementation
Miscellaneous Predicates
Miscellaneous Procedures
Multiple-Values Objects and Operations
Numeric Formatting
Permanence
Print Length and Depth
Random Numbers
State Flags
Storage Management
System Information
Top-Level Control
World Saves and Loads
Quarantined Short Flonums
Top-Level Loop Variables
Kittens -- Parallel Processing in Wraith Scheme
Warning
Introduction to Wraith Scheme Parallel Processing
Background, Philosophy and Intent
Keeping Track of Things
Interprocess Communication
Locks and Critical Sections
Aids to Debugging
Auxiliary Files
A Final Word of Caution
Easter Eggs
Bugs, Flaws, Limitations, and Dealing with Them
Known Bugs and Flaws
Limitations
Common Problems and Solutions
Elementary Debugging
Development Testing
Timeline
What's New
What Used to be New
What Might be New in the Future
Miscellaneous Information
Numbers Revisited
Technical Details About Wraith Scheme
Scheme References
Lisp References
Other References
Whimsy
On Dialectic and History
Excuses
Infrequently Asked Questions
Thanks To
Welcome to the help file for Wraith Scheme, an implementation of the Scheme programming language for the Apple Macintosh™. Wraith Scheme was written by me, Jay Reynolds Freeman. By all means Email me about it if you wish.
I believe Wraith Scheme is a complete implementation of the "R5" dialect of Scheme (major Revision 5 of Scheme). There is one caveat to the word "complete": The R5 report (citation in next paragraph) describes a number of optional Scheme features, using language like "some implementations support ...", or something similar. Wraith Scheme does not support all of these optional features. A list of optional features that are missing is here.
This document is not a complete Scheme language description or programming manual. For a complete and authoritative manual, I strongly recommend that you obtain and peruse a copy of the 1998 Revised5 report on the Algorithmic Language Scheme, edited by Richard Kelsey, William Clinger and Jonathan Rees. That report is available on several Internet sites, such as http://www.schemers.org.
You might also consider reading some of the Scheme References and Lisp References listed later herein.
Wraith Scheme is shareware: You are welcome to use Wraith Scheme for free, forever, and to pass out free copies of it to anybody else. If you should at some time wish to make a shareware donation for Wraith Scheme, use my PayPal&trade account or send a check by regular mail to
PayPal will need my EMail address:
How much to donate is your choice.
Wraith Scheme was named after my late, lamented, scruffy gray cat, "Wraith". If you don't think that makes sense, remember that it runs on a computer named after a raincoat. Wraith Scheme is a direct descendent of Pixie Scheme (another cat), which I wrote in the late 1980s for early versions of the Apple Macintosh™.
By all means, read through this material and the next section or two following it, but you might also want to look at the section, Common Problems and Solutions.
Wraith Scheme is a stand-alone application for the Apple Macintosh&trade. It is universal binary, and thus should run on any Macintosh with either an Intel microprocessor such as the Core Duo&trade, or one of the older PowerPC&trade microprocessors. Wraith Scheme requires the Apple OS X operating system, version 10.4 or later. Its memory and disc requirements are minimal: The program occupies less than 4 Megabytes of space on disk, requires about 30 MBytes of memory to run with its default "preferences" settings, and can run usefully while using less than 10 Megabytes of memory.
Technical Note: I developed Wraith Scheme on a 2006-model Apple Macbook&trade (Macbook version 1,1 -- a flat-black model with an 13-inch diagonal screen, a 2 GHz Intel Core Duo&trade processor, and 1 GByte of memory), running Mac OS X versions no earlier than 10.4.8. The present release was created on that platform, running Mac OS 10.4.11 and XCode&trade 2.4.1.
I have tested Wraith Scheme under both "Tiger" (Mac OS 10.4) and "Leopard" (Mac OS 10.5). I also tested it on an old Macintosh G3 portable, using the PowerPC architecture, also running OS X 10.4.8 and later, and through the courtesy of friends and acquaintances I have tested it briefly on a few other Macintoshes. Thus there is reasonable cause to believe that Wraith Scheme is indeed a universal binary application, but I must in honesty advise you that I do not have a back room full of Macintoshes in hundreds of different configurations, on which to test my work. (Don't laugh, some large software companies do have that much equipment.)
The program is minuscule by today's standards -- less than 5 MByte on disc -- but just after startup it requests memory from the operating system as storage space for Scheme objects. The default main memory size of 10 MByte, in the "Preferences" panel, results in Wraith Scheme requesting about 22 MByte of memory from the operating system -- that's two main memories plus some other stuff. You may change the setting to be smaller or larger if you wish. I have run Wraith Scheme using more than two GByte of memory -- that's "Gigabytes"!
The lower limit for the Wraith Scheme main memory size required for Scheme objects is about 1 MByte, in which case the total memory that Wraith Scheme will request is about 2.2 MByte. That lower limit, plus the size of the program itself, defines Wraith Scheme's minimum memory requirement.
It is possible that Wraith Scheme will run on versions of OS X that are earlier than 10.4; possibly as early as 10.2. Unfortunately, I have not tested the program with earlier versions of OS X.
An installation of Wraith Scheme comprises just the "Wraith Scheme" application itself -- there are no extra files. The Wraith Scheme application contains some extra items embedded within it, such as HTML help files (including this one), a "README" file, and some examples of Scheme source code, so that all you really need is the application. (By the way, in case you obtained this help file as a separate download, the "Wraith Scheme Help" menu item, in Wraith Scheme's "Help" menu, will call up this same file from within the program -- you don't need a separate copy.)
"Installation" is simply the act of putting the application wherever you like. Possibly it should end up in your "Applications" folder, but that choice is up to you.
Technical note: One installation of Wraith Scheme should be sufficient for all the users who have accounts on your Macintosh, provided that you put the Wraith Scheme application in a place where they all can get at it, such as in the "Applications" folder. Furthermore, if you have enabled "fast user switching" on your Macintosh, so that many users' activities may continue at the same time, you will find that different users will be able to run Wraith Scheme simultaneously, without interfering with one another.
Wraith Scheme is what might be called "classic shareware": It depends solely on your generosity for support, with no strings attached. In particular, there is nothing to register, there are no activation codes required, and there are no enhanced versions available for a price. The shareware product, "Wraith Scheme", is all there is. Furthermore, Wraith Scheme will not emit annoying reminders to send me a shareware donation.
You are welcome to make as many backup copies of Wraith Scheme as you wish, and to give free copies of it to anyone.
Most people consider it ill-advised to run an unknown application -- like Wraith Scheme -- without special precautions, because it might contain code to do something malicious. If I had deliberately written a malicious program, I certainly wouldn't tell you, at least, not until it was way too late. What's more, if you are a suspicious type -- and in today's Internet and computing environment, you should be! -- there is nothing I can do or say to convince you that I have not put some ill-intended code into Wraith Scheme. Actually, I suppose it might help if I told you where I live, but I myself am a suspicious type, so I am not going to do that.
Besides, my house is a mess.
It might be useful to remember that Apple's OS X operating system is based on Unix: If you have moderate Unix experience, you might know that Unix is pretty good about keeping one user from messing with other users' data. Thus you might create a special, "dummy", user account, just for testing Wraith Scheme, with access to nothing other than Wraith Scheme and any files of Scheme code you may be using. If you know how to do that, good. If not, perhaps you should seek advice from a Unix-knowledgeable and trustworthy friend. (You shouldn't rely on me to provide the details; for all you know I am a computer criminal who might deliberately tell you something that didn't work and thereby set you up for disaster.)
Furthermore, one thing I worry about -- something every software developer worries about -- is that some third party will modify my code to be malicious, or create a malicious program with the same name and appearance as mine, and produce nefarious results thereby. I have no way to avoid this problem; nobody does.
Just click on the Wraith Scheme icon, and away you go. The program will open up a window that looks like this:
The Wraith Scheme Main Window, at reduced size.
In case you can't read the image on your browser, the messages shown at startup will be something like:
Wraith Scheme -- an implementation of the Scheme programming language.
Written by Jay Reynolds Freeman (Jay_Reynolds_Freeman@mac.com).
(Personal Web Site: http://web.mac.com/Jay_Reynolds_Freeman)
This version compiled on Jan 6 2007, at 18:04:06.
Allocated two main memories, each 10485760 bytes long.
Top-level loop...
The "Top-level loop..." message means that Wraith Scheme has completed initialization and started doing what a Scheme interpreter does -- running an endless loop of reading Scheme code that you type in, processing (more precisely, "evaluating") what it read, and printing out the results.
Wraith Scheme Startup Actions:
On startup, Wraith Scheme
Note that it may take a long time to initialize large Wraith Scheme main memories. The exact time required depends on what kind of Macintosh you have, how much physical memory (RAM) is installed, and what other applications are running. As a rule of thumb, if the main memory size that you have requested is more than a quarter the size of the physical memory installed in your Macintosh, initialization delays may be vexing.
If you wish to run Wraith Scheme with a large main memory, I recommend that you start with a small main memory and increase its size in modest increments -- setting the memory size via Wraith Scheme's "preferences" and relaunching Wraith Scheme -- in order to become familiar with the initialization times involved.
If Wraith Scheme were started up without loading such a world file, you would get a rather disfunctional version of Scheme: Not all of the language is "built in" to the Wraith Scheme program itself. What is there is a rather minimal subset of Scheme features, which are enough so that the rest of Scheme can be written using them. I make the start-up world file by running the minimal version of the program, loading some files of Scheme code that create the rest of Scheme from the built-in features, and saving the world that is thereby built.
Commands to load and save worlds are described later herein.
Changing the Startup Defaults:
All of Wraith Scheme's preferences take effect at startup, so as you learn later herein what those preferences are, remember that you can change Wraith Scheme's startup behavior by changing them.
In particular, you might write your own file to be loaded on initialization, and set the preferences to load it. Such a file might contain text like:
(define my-favorite-constant 42) (load "MyFavoriteSchemeCode.s") (load "../SomeOtherDirectory/SomeOtherSchemeCode.s") (begin (newline) (display "Hi, good looking!") (newline))
(By the way, Scheme source files do not have to end in ".s". That is merely a personal convention of my own.)
Alternatively, the file could load a Wraith Scheme world that you had previously saved.
Perhaps you would not like to have any file loaded at all at startup -- maybe you are sick of seeing the demonstration program run. In that case, delete the text in the "Load This Source File After Startup" field in the preferences window, so that it looks like this:
If you don't like the way the Wraith Scheme main window looks, there are plenty of ways to change its appearance. There is all the usual Macintosh stuff for customizing the user interface, and in particular:
The Font Menu, full size.
The Window Menu, full size.
Pull here.
While you are reading this section, remember that there is also a section called Common Problems and Solutions.
Wraith Scheme provides one main window, a few buttons, and a generous handful of menu items. The main part of the Wraith Scheme Window is where you do almost everything with the Wraith Scheme program -- things like entering Scheme source code, running it, and looking at the results. The buttons, menu items, and a few accessory panels -- Apple calls them "drawers" -- that slide out from the main window allow you to do things to the Wraith Scheme program -- things like setting options and taking control of Scheme programs that are misbehaving. They also allow you to keep track of what Wraith Scheme is doing.
There is one other way of interacting with Wraith Scheme that may be particularly useful: Wraith Scheme makes considerable use of "tooltips" -- the brief text descriptions that pop up when the cursor is positioned over particular areas of the screen. You can learn something about almost any visible feature of Wraith Scheme by moving the cursor over it and waiting for a tooltip to appear.
Note that Wraith Scheme requires ASCII characters for everything it does. (ASCII characters are pretty much the letters of the English alphabet and the standard punctuation marks -- what you could get from the keyboard of an old-fashioned typewriter.) That requirement includes the names of files and folders that Wraith Scheme might have to deal with, and in the case of files, it means that Wraith Scheme will complain if the folder containing the file has a name containing non-ASCII characters, or if the folder containing that folder does, and so on.
Technical note: The requirement to use ASCII characters stems from the R5 report, which uses the ASCII character set to define what constitutes a "letter". It might be possible to interpret the R5 report as allowing non-ASCII characters in strings, and it would certainly have been possible to create a Scheme implementation that allowed all the fancy characters that the Macintosh can create. I chose to restrict the character set to ASCII to facilitate creating Scheme programs which can easily be adapted to run on other implementations of Scheme, that might not allow fancy Macintosh characters.
Let's discuss the window, buttons, and menu items in more detail:
The Wraith Scheme Main Window, at reduced size.
Mostly, you type Wraith Scheme commands into the Wraith Scheme window, and look there to see what happened.
The left end of the Input Panel, full size.
You type into the panel at the bottom of the window that is one line tall and almost as wide as the whole window. That panel is surrounded by black lines. Input to Wraith Scheme is line-at-a-time. Wraith Scheme will process an entire line when you press the "return" key. If you are typing a Scheme expression that takes several lines and notice a mistake after you have already pressed the "return" key for that line, you can press the "Discard Input" button, or use the corresponding menu item in the Interpreter Menu, to start over.
You do not need to have the cursor at the right end of the line when you press the "return" key. Wraith Scheme will get to process the entire line when you press "return", no matter where the cursor is positioned in the line.
The one-line panel where you type provides standard Apple text-editing capability, including cut-and-paste and drag-and-drop. It is in fact a scrolling window, though there is no scroll bar to tell you so, and only one line of its text will be visible at any given time. You may use the up-arrow and down-arrow keys to scroll back and forth among lines of text that you have previously typed. For convenience, there are buttons labeled "Previous Command" and "Subsequent Command" that also scroll this window.
If you type a single line -- with no "return" -- that is longer than the Input Panel is wide, the line will "wrap", and you will only see the last part of it in the Input Panel. Don't worry. It's all there, and you can use the keys to move back and forth in a line to get to the first part of it, if necessary. Wraith Scheme will finally "see" the entire line, and start to process it, when you get around to pressing the "return" key.
When you have scrolled to a line that you previously typed, and have the cursor on that line, you may press "return" to send that line of text to Wraith Scheme again. You can re-enter a Scheme expression that spanned more than one line, one line at a time: Use the scroll commands to retrieve the first line of the expression, press "return", use the arrow keys to retrieve the second line of the expression, press "return", and so on.
The Macintosh's "cut-and-paste" and "drag-and-drop" mechanisms are very useful for entering Scheme expressions.
Although you can only edit one line of text in the Wraith Scheme window, Scheme commands may span more than one line. For example if you type (with a final "return")
( + 2 2 )
the effect is the same as if you had typed (again with a final return)
(+ 2 2)
That is, Wraith Scheme prints out
4
The Main Display Panel, at reduced size.
The Main Display Panel is the big panel that covers most of the Wraith Scheme window. It shows copies of the text that you have submitted to Wraith Scheme, interspersed with whatever Wraith Scheme has printed out in response. You cannot edit that text, but you can select it for cut-and-paste or drag-and-drop to some other location, such as the Wraith Scheme Input Panel. The Main Display Panel scrolls too, using the scroll bar at the right edge of the main window.
Both the input window and the main display window can store essentially unlimited amounts of scrolled-back text, but if for some reason you want to reduce the amount of scroll-back, there is a "Trim Scrollback" menu item in the Interpreter Menu, that does so. Every time you use it, it trims off the oldest half of scrolled text in each window, down to 20,000 characters. That is, this command will never reduce the amount of scrolled-back text in either window to less than 20,000 characters.
The Message Panel is the top line of the Wraith Scheme window. Wraith Scheme will occasionally print messages there, that tell something about what the Wraith Scheme program is doing. One message that you will probably see a lot is "Garbage collection completed." Any message printed will go away after about ten seconds.
The Message and Dialog Panels, slightly reduced.
The dialog panel consists of the second and third lines from the top of the Wraith Scheme window, which are isolated from the rest of the window by a horizontal line beneath them. Wraith Scheme will start a dialog with you by printing a prompt message in the first line of the panel, and will then move the cursor to the start of the second line of the panel and wait for you to enter your reply -- one line only. Type the line, using the same line-editing commands as for the main window, and type a final "return" when you are done.
As a visual cue that a dialog is in progress, the prompt message will display in colored text, cycling through several colors, to draw your attention to the fact that Wraith Scheme is waiting for you to do something.
You don't actually need to type a response: You may use cut-and-paste or drag-and-drop to make your response, so long as it's just one line long.
To remind you of what has been going on, Wraith Scheme will leave the text of the last dialog visible in the dialog panel, with the prompt message in the normal color, until the next dialog begins.
In a typical dialog, Wraith Scheme might ask you the name of a file to load.
Technical note: I decided to use a text-based panel for these interactions, rather than use more conventional Macintosh-style browsers and dialog boxes, because the standard Macintosh mechanisms are for you to use. I thought the program should stick to its own turf, so to speak, rather than do mysterious things with features you are used to manipulating personally.
Thus the idea is that when you open a file, for example, perhaps by a menu command, you get the standard kind of Macintosh browser window, but when a Scheme program does so, it uses the dialog box.
The Basic Buttons Drawer, full size.
The Basic Buttons Drawer slides out from the left side of the Wraith Scheme window. You make the drawer open and close with the "Show Basic Buttons" menu item in the Window Menu, or you can drag the left edge of the drawer with the mouse to slide it in and out. Its buttons do the following things:
The Load Last File button, full size.
If you need to know the full path to the file in question -- not just the name -- move the cursor over the button, and the full path will pop up in a "tooltip".
The When Updated button, full size.
This button might be particularly useful when you are working on a file of Scheme code in a text editor: Load the file once, press the "When Updated" button, and then every time you save a new batch of changes to the file, Wraith Scheme will load them in for you to test, or whatever.
The "When Updated" button only works when a file has been successfully loaded; Wraith Scheme won't worry about files that it couldn't locate or couldn't open, for example. Reloads will not occur when Wraith Scheme is executing other code. When Wraith Scheme is not busy, it tests for updates approximately every two seconds.
Letting Wraith Scheme load files this way allows you to create and edit Scheme source-code files using the editor you prefer, instead of using some built-in editor that I happened to like.
The Discard Input button, full size.
"Discard Input" only works when you have not yet completed the expression. Once Wraith Scheme has received the final right parenthesis, or whatever it is that marks the end of the expression, Wraith Scheme will start processing it.
Technical Note: What "Discard Input" actually does is tell Wraith Scheme to stop any processing it may be doing, and return to the top-level loop to await further input. (What that loop does is an endless cycle of read from the keyboard, evaluate what was read, and print the result.) Yet the "Discard Input" button is not really a complete "reset" command, because it is disabled whenever Wraith Scheme has begun evaluating the input it has received. I thought it would be risky, having a big reset button out where you might click on it by mistake in the middle of a lengthy calculation, and lose the work that had been done. Wraith Scheme does have a complete reset command, in the Interpreter Menu, but it uses a key combination that you are unlikely to type by mistake.
The Previous Command and Subsequent Command buttons, full size.
The up and down arrow keys do the same thing, provided that you have the typing cursor -- the narrow vertical line -- in the input panel to begin with.
The Basic Buttons drawer contains one more useful item, but it is not a button. Near the bottom edge of the drawer, close to the left end of the Input Panel, is a small text field that is normally invisible because it contains no text. When you are entering a Scheme expression that takes more than one line, this field will contain text to remind you of how many right parentheses you need to complete the expression, if any, or if you are in the process of typing a text string that spans more than one line, it will remind you that you need a quotation mark (") to complete the string. I put this feature in because many times I have sat bewildered in front of a Lisp or Scheme interpreter, wondering why the command I had just typed wasn't doing anything, without realizing that I had to type something else to finish it.
Thus if you type the following line into the input panel -- note the unbalanced parentheses -- followed by "return":
(+ 2 2
The little field at the bottom of the Basic Buttons drawer will remind you:
Expect )
Here are some images that show this field in operation:
Wraith Scheme will remind you when what you have typed has unbalanced parentheses or a missing quotation mark. (Images shown full size.)
The basic buttons drawer is set up so that if you close it part way, the edges of the buttons remain visible, and the little reminder field at the bottom also remains visible. Thus, once you have enough experience with Wraith Scheme to know which button is which without reading the label on it, you can save space on your display by closing the basic buttons drawer most of the way, and still use all of its features.
The Wraith Scheme Instrument Panel, slightly reduced.
The Wraith Scheme Instrument Panel is a drawer that slides out from the bottom of the Wraith Scheme window. You make the drawer open and close with the "Show Instrument Panel" menu item in the Window Menu, or you can drag the bottom of the drawer with the mouse to slide it in and out.
The instrument panel contains no buttons or other controls; all it does is display some information about what Wraith Scheme is up to and what it has been doing. Many of the items displayed are self-explanatory; the meanings of the others are described elsewhere herein. Don't forget to move the cursor over items to read the tooltips associated with them.
In particular, the instrument panel shows the names of the last world file loaded, and of the last file of Scheme source code loaded. To see the complete path for either of these items, move the cursor over the file name, and the full path will pop up as a tooltip.
Several of the items displayed in the instrument panel are "status lights", that go on and off when the item whose status they monitor changes. If you don't think these are useful, I at least hope you think they are cute. Every computer ought to have status lights, preferably ones that blink a lot ...
When Wraith Scheme is busy, the instrument panel display will lag behind what Wraith Scheme is doing, but it will catch up when it gets the chance.
The instrument panel is set up so that if you close it part way, the items at the bottom of the panel are covered up, and the items at the top of the panel remain visible. I have put what I believe are the most important items in the instrument panel at the top. Thus, if you want to save space on your display, you can close the instrument panel most of the way and still see the most useful information that it contains.
When the Basic Buttons Drawer and Instrument Panel are both partially closed, the Wraith Scheme Main Window might look like the image that follows. Note that there is still enough of the buttons visible to click on them:
The Wraith Scheme Main Window, with Basic Buttons Drawer and Instrument Panel partially closed, at reduced size.
When the Basic Buttons Drawer and Instrument Panel are both closed, the Wraith Scheme Main Window looks like this:
The Wraith Scheme Main Window, with Basic Buttons Drawer and Instrument Panel completely closed, at reduced size.
Wraith Scheme's complete menu bar, full size.
The Wraith Scheme Menu, full size.
The items in the Wraith Scheme menu are pretty much Apple standards. Only three require special discussion for Wraith Scheme:
The preferences window actually contains two different displays, one for general preferences, and one for preferences for Wraith Scheme's parallel processing capabilities. You toggle back and forth between the two displays by pressing on the "General" and "Kittens" tabs at the top of the window.
The General Preferences Window, full size, showing the default values of Wraith Scheme's preferences that do not have to do with parallel processing.
The Kittens Preferences Window, full size, showing the default values of Wraith Scheme's preferences that have to do with parallel processing.
Why do these items not take effect immediately? Why wait till the next time? Changes in a few items could in principle make something happen immediately, but it seemed more consistent, and easier to keep track of, if they all took effect at the same time. So the preferences are only used when Wraith Scheme starts running.
Note that if you get a fatal-error message advising you to try using a smaller main memory size, you can open the Wraith Scheme preferences window then and there, before Wraith Scheme exits from the fatal error, to change the amount of memory Wraith Scheme asks for next time it runs.
There is a limit to how much memory Wraith Scheme can handle, too, and that limit is reflected as a limit on how big a memory-size preference you can set in the preferences window.
The default setting for this item is a file contained within the Wraith Scheme application, that runs a short Scheme demonstration as an introduction to the language.
Wraith Scheme's Quit Panel, full size.
In Wraith Scheme parallel processing, the MomCat is essential: Thus when you terminate the MomCat by the "Quit" command or by any other means, Wraith Scheme will also terminate all other Wraith Scheme processes -- all the kittens -- that are running.
The Interpreter Menu items have to do with your interactions with Wraith Scheme in the Wraith Scheme window.
The Interpreter Menu, full size.
The downside of any kind of "reset" command is the risk of using it by mistake, part way into a long calculation, and thereby losing lots of work and lots of time. For that reason, I did not provide a button for this menu item (if you have never pressed the wrong button of a computer application by mistake, you are a much better person than I am, or at least a much luckier one), and I chose a keyboard equivalent -- Control-Option-Command-Delete -- that you are not likely to type accidentally.
There are three circumstances in which "Reset to Top-Level Loop" will not take effect: First, if Wraith Scheme is garbage-collecting, the reset will not take effect until garbage collection has finished. Second, if Wraith Scheme is sleeping, the reset will not take effect until it has waked up. There are blinking lights in the Wraith Scheme Instrument Panel to indicate when these things are happening. Third, a reset will not take effect while Wraith Scheme is starting up, because there isn't anything there to reset until startup is complete.
If Wraith Scheme is garbage-collecting or asleep when you use the "Reset to Top-Level Loop" command, the command will take effect eventually. If you use that command while Wraith Scheme is initializing, the command will simply be ignored: You will have to try again.
"Discard Input" only works when you have not yet completed the expression. Once Wraith Scheme has received the final right parenthesis, or whatever it is that marks the end of the expression, Wraith Scheme will start processing it, and it is too late to think about starting over.
Technical Note: "Discard Input" is actually "Reset to Top-Level Loop" by another name, but disabled whenever Wraith Scheme has begun evaluating the input it has received, so you can't ruin a long calculation by pressing it accidentally.
The "Disable Window Output" menu item causes Wraith Scheme to stop printing output into the Wraith Scheme Main Display Panel. Output that would have been printed there will be lost for good. Output to files, including transcript files, is not affected.
When this menu item is used, a panel drops down from the top of the Wraith Scheme window, reminding you that output is disabled, and providing a button you may press to re-enable it.
The reason for this menu item is that output to the main display panel is slow. If your Scheme program prints lots of things you don't need to see, you might disable output to speed things up. If you do so, however, make sure that any program results you want to preserve are either written to a file or bound to a variable that you can evaluate later, after re-enabling output.
It is up to you to make sure that the file you select for loading contains something that Wraith Scheme can understand; Wraith Scheme will report an error if it does not.
This menu item will only be enabled when Wraith Scheme is not busy with other processing; it doesn't usually make much sense to load a file at some random time while a Scheme program is executing.
This menu item will only be enabled when Wraith Scheme is not busy with other processing, and when there has been at least one file loaded since Wraith Scheme started.
To learn what the file is, move the cursor over the menu item, and the full path will pop up in a "tooltip".
The name of the last file loaded is also displayed in the Wraith Scheme Instrument Panel.
This menu item will only be enabled when Wraith Scheme is not busy with other processing, and when there have been at least two files loaded since Wraith Scheme started.
To learn what the file is, move the cursor over the menu item, and the full path will pop up in a "tooltip".
Remember, laziness is the mother of invention. I could demonstrate to you that I am a very lazy person, but it would be a whole lot of trouble, so I won't bother.
This submenu remembers the names of files that you have loaded in previous sessions of Wraith Scheme, as well as files that you have loaded in the current session. Just because a file is named in the menu, doesn't mean that the code it contains is in Wraith Scheme at present: All the submenu does is relieve you of the task of remembering the names and paths to files that you have recently loaded, and might want to load again.
The submenu can hold the names of up to a dozen different files. It also has a menu item to clear out all the file names, in case you are tired of looking at them. That menu item only removes the file names from the submenu; it doesn't do anything to the files themselves.
This menu item will only be enabled when Wraith Scheme is not busy with other processing, and when there are actually some file names on it.
The name of the last file that Wraith Scheme loaded in the current session of Wraith Scheme is also displayed in the Wraith Scheme Instrument Panel.
This menu item might be particularly useful when you are working on a file of Scheme code in a text editor: Load the file once, check the "Load Last File When Updated" menu item, and then every time you save a new batch of changes to the file, Wraith Scheme will load them in for you to test, or whatever.
This menu item is only enabled when a file has been successfully opened for loading since Wraith Scheme was last started. Attempts to load a file that did not exist, or that could not be opened for loading, do not count. Reloads will not occur when Wraith Scheme is executing other code. When Wraith Scheme is not busy, it tests for updates approximately every two seconds.
Letting Wraith Scheme load files this way allows you to create and edit Scheme source-code files using the editor you prefer, instead of using some built-in editor that I happened to like.
CAUTION!! Loading a world overwrites everything in Wraith Scheme's memory!
Using the "Load World" menu item and then selecting a file which is not a saved world may cause Wraith Scheme to throw up its paws and quit: Wraith Scheme will try to make sure that any file you provide as a world to load really is a saved world, but you should not count on its ability to do so. (By the way, the way you create "saved worlds" is by using Wraith Scheme itself. We'll see how later herein.)
The name of the last world file loaded is displayed in the Wraith Scheme Instrument Panel.
This menu item will only be enabled when Wraith Scheme is not busy with other processing; it rarely makes any sense to load a world at some random time while a Scheme program is executing.
You may give a saved world any name you wish. I sometimes use names that end in ".world", to make such files easy to recognize, but that is only a personal convention.
Saved worlds can be loaded only into the release of Wraith Scheme from which they were originally saved, but it doesn't matter whether that version is running on a Macintosh with an Intel processor or on one with a PowerPC processor. You can use a world saved on either kind of Macintosh, in either kind of Macintosh.
This menu item will only be enabled when Wraith Scheme is not busy with other processing; it rarely makes any sense to save a world at some random time while a Scheme program is executing.
This menu item toggles between the "number->string" mechanism and a simpler output format, in which floating-point numbers are displayed with at most seven decimal digits, and explicit exact and inexact prefixes ("#e" and "#i") are not used. This toggling applies only to the procedures "display" and "write", and to output at top level in the Wraith Scheme window. The strings returned by "number->string" itself remain unchanged. The internal representations of numbers remain unchanged.
I put in this feature because some people use a Scheme interpreter as a very fancy calculator, and they might get tired of looking at numbers in unnecessarily long formats. Furthermore, the use of the full precision of "number->string" sometimes produces counterintuitive least-significant digits. Thus if you are using the full precision and type in
1/3
Wraith Scheme will print
0.33333333333333331
which is correct in terms of "number->string" -- that is, that number is the best approximation to 1/3 that the system can provide -- but that final "1" might look suspicious if you were expecting "3"s to infinity, and beyond.
The Edit Menu, full size.
The Font Menu, full size.
The font menu allows you to increase ("Bigger") or decrease ("Smaller") the font size in the Wraith Scheme window, within limits. The smallest font available is 9 point, and the largest is 36 point. When you use these menu items, the size of all text in the Wraith Scheme window changes all at once -- they aren't "mark and click" style menu items.
The "Change Text Color..." menu item opens up a small window that allows you to change the text color Wraith Scheme uses. That small window contains a standard Macintosh "color well" that you may use to select a color. Once you have done so, use the "Preview" button to see how the color looks in the Wraith Scheme window. When you have a color you like, use the "Done" button to make the small window close. Alternatively, use the "Cancel" button to leave the background color the way it was when the small window first opened.
The Change Text Color Window, full size.
When you use the "Change Text Color..." menu item to pick a new text color, and press the "Done" button, Wraith Scheme will ask if you want to make the new color a preference, so that it will automatically be used the next time Wraith Scheme starts up. If you reply "Yes", Wraith Scheme will put the new color into the "Preferences" window on your behalf.
The "Change Background Color..." menu item opens up a small window that allows you to change the background color of areas where Wraith Scheme displays text. That small window contains a standard Macintosh "color well" that you may use to select a color. Once you have done so, use the "Preview" button to see how the color looks in the Wraith Scheme window. When you have a color you like, use the "Done" button to make the small window close. Alternatively, use the "Cancel" button to leave the background color the way it was when the small window first opened.
The Change Background Color Window, full size.
When you use the "Change Background Color..." menu item to pick a new background color, and press the "Done" button, Wraith Scheme will ask if you want to make the new color a preference, so that it will automatically be used the next time Wraith Scheme starts up. If you reply "Yes", Wraith Scheme will put the new color into the "Preferences" window on your behalf.
The Window Menu, full size.
Many of the contents of the Window Menu are standard Apple menu items. but four are not:
The Help Menu, full size.
The Help Menu provides access to some rather lengthy HTML files that tell how to use Wraith Scheme.
This file opens in the standard Apple "Help Viewer" application.
This file opens in Safari; if Safari is not installed, or is somehow not available, Wraith Scheme will not be able to open the file for you. Later in this section is a description of another way to open the file.
These files open in Safari; if Safari is not installed, or is somehow not available, Wraith Scheme will not be able to open the files for you. Later in this section is a description of another way to open these files.
This file opens in Safari; if Safari is not installed, or is somehow not available, Wraith Scheme will not be able to open the file for you. In that case, keep reading ...
If for some reason you would like to access these files by some means other than using the menu items, there's a way. The files themselves are buried deep within the Wraith Scheme application. To find them:
There is another way to think about how you may interact with Wraith Scheme:
There are five ways for Wraith Scheme to provide information to you:
There are four ways for you to provide information to Wraith Scheme:
When Wraith Scheme encounters an error from which it can recover, its general strategy is to print an error message -- I hope a useful one -- in the Main Display Panel, then abort whatever Scheme processing is going on and return control to you at "top level" in the Wraith Scheme window. For example, suppose you tried to divide by zero. You might type (with a final "return")
(/ 42 0)
whereupon Wraith Scheme would print
42 Problem: Attempt to divide this number by zero. (Resetting) Top-level loop...
A similar error message, and a similar return to the "top level" of control of Wraith Scheme, would occur even if the attempt to divide by zero occurred deep in some elaborate Scheme procedure.
Wraith Scheme may also encounter errors from which no recovery is possible, in which case its general strategy is to open a special panel with an error message and then exit. If you should ever see a fatal error message whose cause is not obviously due to some system limitation (such as not having enough memory), I would like to hear about it: Send bug reports to Jay_Reynolds_Freeman@mac.com.
(e::exit)
and then type "return". (That Scheme command is one of the
Enhancements provided by Wraith Scheme.)
This procedure causes an immediate exit: Wraith Scheme will not
ask you to confirm that you really do want to quit. (That omission
provides a way to run a Scheme program that can exit automatically
when it is done.)
This way to quit only works if the Wraith Scheme window is accepting
commands, which it won't be, for example, if a long Scheme procedure
is running; you might have to use the "Reset to Top-Level Loop" menu
item or command -- described a few paragraphs above -- first.
In
Wraith Scheme parallel processing,
the
MomCat
is essential: Thus when you terminate the MomCat by any of these means,
Wraith Scheme will also terminate all other Wraith Scheme processes -- all the
kittens --
that are running.
Herein I describe how Wraith Scheme differs from "R5" Scheme by going through the Revised5 Report on the Algorithmic Language Scheme, section by section, and listing differences between Wraith Scheme and that standard. It is my intention that any essential or non-essential feature of Scheme, as described in the R5 report, is either provided as described, or mentioned here with an indication of how Wraith Scheme differs from the R5 report.
One major difference is that Wraith Scheme provides numerous enhancements and special features, in great part in the form of extra built-in procedures and constants whose identifiers generally begin with "e::" or "c::". I mention some of these features in passing in this section, keeping the descriptions brief for clarity of presentation. I have described them in more detail in a separate Enhancements section.
I have summarized the R5 features that Wraith Scheme lacks, in the Optional Features Omitted section. Each missing feature is also mentioned separately in the discussion of the appropriate section of the R5 report, below.
1.3.1:
Unless otherwise stated, Wraith Scheme supports all features of Scheme, including optional ones, that are described in the R5 report.
1.3.2:
Wraith Scheme attempts to print sensible error messages for errors indicated in the R5 report, even when the R5 report does not require that an error be signaled. In general, Wraith Scheme will print an error message and then return control to the top level of the Scheme interpreter. If the error occurred within a user-defined function, Wraith Scheme may provide some rudimentary debugging information, such as the names of functions on the call stack when the error occurred.
Some errors are fatal: For them, Wraith Scheme will in general display an error message in a special panel, and then exit.
Where R5 states that the value of an expression is unspecified, Wraith Scheme generally returns #t.
1.3.5:
Wraith Scheme provides numerous functions and variables as enhancements to R5 Scheme, and distinguishes them by naming conventions. In particular, Wraith Scheme uses symbols which begin with the characters "e::" for enhancements that in my opinion will probably be of broad interest to users, and "c::" for more specialized enhancements that will probably be less generally useful. For example,
e::exit
names a function of no arguments which may be called to exit from Wraith Scheme.
The syntax of these naming conventions was inspired by various "package" and "namespace" mechanisms used in other Lisp implementations, but there is no such mechanism in Wraith Scheme; "e::" and "c::" are just some of the characters in the identifier.
2.1:
Identifiers in Wraith Scheme are independent of alphabetic case. Thus for example, Wraith Scheme considers "define", "DEFINE", "Define", and "dEfiNE" all to be the same identifier.
Wraith Scheme prints identifiers with lower-case letters. Thus
'dEfiNE
returns
define
There is a well-known "gotcha" in the specification of identifiers in the R5 report: The language of that report allows identifiers to begin with the character '@', but the use of such identifiers creates syntactic confusion with the symbol ",@" that Scheme uses as shorthand for "unquote-splicing". Thus, consider the Scheme expression
`(a b ,@c)
Is that to be understood as
(quasiquote (a b (unquote @c)))
or as
(quasiquote (a b (unquote-splicing c)))
Given the possibility that identifiers begin with '@', Scheme has no way to distinguish between the two interpretations.
Therefore, in Wraith Scheme, identifiers may not begin with '@': '@' may occurs within an identifier only in positions other than the first letter.
All identifiers that are syntactic keywords, all identifiers associated with procedures defined in R5, and all identifiers for enhancements provided by Wraith Scheme, are bound to the code that executes those procedures, in a manner difficult to change. You must undo these "permanent" bindings in order to perform such interesting operations as "(set! cons ...)". Wraith Scheme uses an internal flag for each binding to indicate whether it is "permanent", and provides the functions "e::permanent?", "e::set-permanent!" and "e::clear-permanent!" -- each taking an identifier as argument -- for your own use, at your own risk. For example
(e::permanent? 'define)
returns #t.
Wraith Scheme does not uniformly allow syntactic keywords to be used as variables, though the mechanisms used to implement hygienic macros will sometimes allow you to get away with doing so.
2.2:
Wraith Scheme recognizes tabs, carriage returns, newlines and blank spaces, as whitespace.
No comments.
4.3:
In addition to the hygienic macro implementation described in this section of the R5 report, Wraith Scheme has an additional, low-level macro implementation, described in Macros -- An Alternate Implementation.
5.2:
Wraith Scheme will not always report an error if internal definitions are used incorrectly within what the R5 report calls a "<body>"; that is, at locations in the <body> other than at the beginning. Internal definitions at locations within a <body> other than at the beginning bind and assign within the top-level environment, not locally. Internal definitions at the beginning of a <body> act within the local environment of that <body>.
That is not to say that you should put definitions in such places.
In Wraith Scheme, "define" recursively searches the expression being bound or assigned for macro "calls", and expands any that it finds.
Wraith Scheme allows optional automatic compilation of top-level defines, by means of the "compile defines" item in the Interpreter Menu. Any such compilation takes place after macro expansion, and only for procedures defined using the procedure-defining syntax that involves parentheses around the name and formal parameters.
Wraith Scheme does not support complex numbers with nonzero imaginary part, does not support irrational real numbers, and does not support rational numbers in which the numerator and denominator are both present as separate values.
Wraith Scheme supports only three internal representations for numbers: 32-bit signed fixnums, and IEEE 32-bit and 64-bit flonums. A number stored in any such format is necessarily either an integer or a rational. Therefore, the procedures "rational?", "real?" and "complex?" will always return #t when applied to any finite number stored by Wraith Scheme (but not when applied to IEEE floating-point infinities and nans).
6.2.2:
When Wraith Scheme performs flonum arithmetic, it uses the underlying floating-point hardware mechanisms of the Macintosh processor, notably relying on the floating-point exception bits to detect inexact results. This mechanism allows Wraith Scheme to extend the usable domain of exact integer arithmetic well beyond that usually associated with 32-bit fixnums, because the IEEE 64-bit flonum format can represent exact integers of absolute value up to 2**52.
Wraith Scheme attempts to preserve maximum accuracy and precision when doing arithmetic. Thus in general, operations yield a result with at least as much precision as the most precise of their operands. Furthermore, operations may return a result in a more precise form than any of the inputs if the operation overflowed the limits of representation of the types of the operands given; for example, the multiplication of 200000000 by 20000000, when both operands happen to be stored as 32-bit fixnums, will return a result of 4000000000000000 stored as an IEEE 64-bit flonum. This result will be exact if the operands were.
The IEEE floating-point standard provides representations to indicate when floating-point overflow has taken place, and to indicate when an operation cannot produce a numeric result. These representations are called "infinities" and "nans". ("Nan" stands for "not a number".) Wraith Scheme handles these representations so as to facilitate calculations: Procedures that both accept and return numeric values generally accept infinities and nans without balking, and return whatever value is appropriate. However, procedures which perform an explicit or implicit ordering of numeric values report an error when called with a nan as argument. Those procedures are:
= < > <= >= max min positive? negative?
Furthermore, the procedures
= < > <= >= max minreport an error when asked to compare two infinities of the same sign.
The type-checking procedures
number? real? rational? integer?
return #f when called with either an infinity or a nan as an argument.
Infinities and nans are always inexact.
Wraith Scheme has some procedures to tell whether Scheme objects are infinities or nans. These procedures are enhancements.
Wraith Scheme prints all nans as "nan", and all infinities as "inf"". The printed representations of infinities make no distinction between positive and negative infinities, though the internal representations are in fact signed, and their signs can be determined by such procedures as "positive?" and "negative?".
Wraith Scheme will report an error and reset itself to top-level if it detects an attempt to divide by zero.
6.2.4:
The syntax of Wraith Scheme's numeric constants is insensitive to alphabetic case. #E works as well as #e, #Xfeed is just as good a hexadecimal representation of 65261 as is #xFeeD, 2.0E0 represents the same number as 2.0e0, and so on.
Wraith Scheme allows numeric constants to be written as fractions -- such as 22/7 -- but has no means to store numerator and denominator separately; instead, it performs the division and returns the result. Informally, Wraith Scheme "reads fractions", but remembers only their numeric value.
Wraith Scheme will not override a user's use of an explicit exact prefix ("#e") with a number if the number contains too many digits to be stored exactly.
Wraith Scheme will report an error when a string used to represent a numeric constant contains both an explicit "exact" prefix ("#e") and one or more sharps in places where digits might be expected. Thus the text string
#e12##
-- which might conceivably be intended as a number with value somewhere near 1200 -- is not recognized as a number by Wraith Scheme.
Wraith Scheme will report an error when characters are used in the written representation of a number that are inappropriate for the implicit or explicit radix. Thus if you enter
12a3
or
#d12a3
Wraith Scheme will report an error, whereas
#x12a3
will evaluate to
4771
Internal Representations of Numbers:
Wraith Scheme stores numbers in three forms: 32-bit fixnums, IEEE 32-bit flonums, and IEEE 64-bit flonums; however, the manner of use of IEEE 32-bit flonums is an enhancement over the R5 Scheme specification, discussed separately in detail under Quarantined Short Flonums.
Wraith Scheme generally uses 32-bit fixnums to store signed integers from -2,147,483,647 through 2,147,483,647, and uses IEEE 64-bit flonums to store numbers outside that range. Notwithstanding, it is possible that an integer in the range -2,147,483,647 through 2,147,483,647 will be stored as an IEEE 64-bit flonum: That storage form has more than enough bits to store such integers without loss of precision.
Wraith Scheme generally observes "flonum contagion", in that when at least one of the operands of a mathematical operation is an IEEE 64-bit flonum, the result will usually be an IEEE 64-bit flonum.
When converting from an external representation of a number to an internal representation, Wraith Scheme will take the presence of any of the normal Scheme exponent markers -- "d", "e", "f", "l", and "s" -- as reason to store the number in question as an IEEE 64-bit flonum. Furthermore, if the external representation does not include an exponent marker, but is an integer too large to store as a 32-bit fixnum, Wraith Scheme will store it as an IEEE 64-bit flonum.
Details of Wraith Scheme's use of IEEE 32-bit flonums are described in Quarantined Short Flonums, but in summary, if you do not use the enhancements provided to create IEEE 32-bit flonums, Wraith Scheme will not create any for you. Thus if you do not wish to use IEEE 32-bit flonums, you may use Scheme as described in the R5 report, and you will not encounter any.
6.2.5:
The procedures "=", "<", ">", "<=" and ">=" each take two or more arguments. The procedure "=" returns #t if and only if its arguments are all equal. The procedure "<" returns #t if and only if its arguments form a sequence that is strictly increasing; that is, if and only if each of its arguments is greater than its neighbor to the left (if any) and less than its neighbor to the right (if any). The other procedures have similar semantics.
The procedures "quotient", "remainder", "modulo", "gcd" and "lcm" are implemented only for integer arguments whose absolute value is less than 4503599627370496. (This value, which is 2 to the 52nd power, stems from the fact that IEEE 64-bit floating-point numbers can represent integers with no more than about 52 bits without loss of accuracy.)
The error messages for out-of-range arguments will state that the argument is of improper type, but will not specifically mention that the problem is one of range. These messages may be confusing if you have not noted the range limit just given.
Furthermore, if the algorithm for "lcm" requires a temporary value outside this range, Wraith Scheme will be unable to finish without loss of precision, and will report an error. Furthermore, if "lcm" is called with arguments that are all 32-bit fixnums, Wraith Scheme will attempt to perform the algorithm solely with fixnum arithmetic, and to return a 32-bit fixnum result. It will report an error if unable to do so; it will NOT promote arguments or result to flonum.
"Gcd" and "lcm" return IEEE 64-bit flonums when one or more of their arguments are IEEE 64-bit flonums.
Since Wraith Scheme does not support complex numbers, and does not separately remember the numerators and denominators of numbers provided as fractions, Wraith Scheme does not provide the following procedures:
rationalize numerator denominator make-rectangular make-polar real-part imag-part magnitude angle
6.2.6
Although "string->number" recognizes numbers written in fraction notation, the best that Wraith Scheme can do with them is store a single number whose value is the numerator divided by the denominator. Thus "number->string" will never print a number as a fraction.
Let me summarize how Wraith Scheme's implementations of string->number and number->string deal with exactness. I believe that Wraith Scheme handles these matters correctly, but this section of the R5 report is a bit obscure, and does allow implementors some leeway. The following rules tell how the external representation of a number -- what you type, and what Wraith Scheme prints -- corresponds to the exactness of Wraith Scheme's internal representation of that number.
The idea is that numbers input to Wraith Scheme are considered exact unless some feature of the external representation -- typically one or more embedded "#"s or an explicit inexact prefix ("#i") -- indicates otherwise.
There is a complication with numbers that are expressed in base 10. The problem is, that there are additional means of indicating exactness available to external representations of those numbers: Base 10 is the only base in which the external representations of numbers are allowed to have decimal points or exponents. These act as indicators of inexactness, but "weakly", in that their indications may be overridden by explicit exact prefixes.
In a little more detail:
#e1## #e1##. #e1.##e2 #e#xff##
Thus, examples of numbers which both you and Wraith Scheme should consider inexact are:
100. 1e2 1.37e2 -100. -1e2 -1.37e2
And examples of numbers which both you and Wraith Scheme should consider exact are:
#e100. #e1e2 #e1.37e2 -#e100. -#e1e2 -#e1.37e2
Thus, examples of numbers which both you and Wraith Scheme should consider inexact are:
#i100 10# -#i100 -10#
And examples of numbers which both you and Wraith Scheme should consider exact are:
100 -100
Thus, examples of numbers which both you and Wraith Scheme should consider inexact are:
#i#b1110 #i#o16 #i#xe -#i#b1110 -#i#o16 -#i#xe
And examples of numbers which both you and Wraith Scheme should consider exact are:
#b1110 #o16 #xe -#b1110 -#o16 -#xe
Exact prefixes and the like notwithstanding, Wraith Scheme cannot necessarily store a number that is mathematically identical to a given external representation. For example, Wraith Scheme stores #e1.3 as a number that is certainly not 1.3, but that differs from it by a few digits a long way to the right of the decimal point. Furthermore, if you type in a long string of digits, with no decimal point or exponent, Wraith Scheme will interpret what you have typed as an integer and will do the best it can to store it, but if you have typed too many digits, the ones farthest to the right will have no effect on the value stored.
In Wraith Scheme, the empty list counts as true in conditional expressions.
In Wraith Scheme, the empty list is not equivalent (eqv?) to #f.
Wraith Scheme does not provide "t" and "nil". (You can easily define them yourself.)
Wraith Scheme provides two specialized "logic constants", "#u" and "#s", for use in logic programming. (See Friedman, Byrd and Kiselyov, 2005). Wraith Scheme does not include any software based on this work; that's copyrighted, but you couldn't even get Wraith Scheme to read these identifiers unless I built them in, because R5 identifiers are not generally allowed to start with '#'. So here they are, for anyone who wishes to use them.
Each of "#u" and "#s" evaluates to itself.
Wraith Scheme has no uninterned symbols; in particular, those returned by "string->symbol" are already interned. Of course, not every symbol is necessarily associated with a value. Wraith Scheme will report an error when it tries to evaluate such an unbound symbol.
The boolean procedures that compare characters all take precisely two arguments. Those procedures are:
char=? char-ci=? char<? char-ci<? char>? char-ci>? char<=? char-ci<=? char>=? char-ci>=?
Wraith Scheme uses the ASCII ordering of characters, and does not accept non-ASCII characters for any purpose.
The procedure "integer->char" is capable of producing any ASCII character, even ones that the Wraith Scheme interpreter does not accept as typed input. Wraith Scheme displays some of these characters strangely.
Wraith Scheme uses text names for two additional characters beyond the R5 Scheme standards of #\newline and #\space. The external representations of these characters are #\tab and #\return; they stand for the ASCII characters whose values as decimal integers are respectively 9 and 13. Wraith Scheme's character-handling procedures handle them in a manner analogous to #\space and #\newline. Also see Slashification.
6.3.5:
The boolean procedures that compare strings all take precisely two arguments. Those procedures are:
string=? string-ci=? string<? string-ci<? string>? string-ci>? string<=? string-ci<=? string>=? string-ci>=?
Wraith Scheme uses the ASCII ordering of characters, and does not accept non-ASCII characters for any purpose.
Wraith Scheme allows the "backslash" character, '\', to serve as a slightly more general "escape" than is required by the R5 report: Section 6.3.5 of that report reads in part
A doublequote can be written inside a string only by escaping it with a backslash (\), as in
"The word \"recursion\" has many meanings."
A backslash can be written inside a string only by escaping it with another backslash. Scheme does not specify the effect of a backslash in a string that is not followed by a doublequote or backslash.
Wraith Scheme takes advantage of the freedom implicit in the last quoted sentence in the following way:
"abcdefg\ hijklmn"
results in a string which contains an ASCII newline character after the 'g'. On the other hand, an attempt to input
"abcdefg hijklmn"
-- without the '\' -- would result in an error message.
Also see #\tab and #\return.
Wraith Scheme implements "dynamic-wind" along the lines of the implementation given by Rees (1992). That implementation involves modifying "call-with-current-continuation". The unmodified version of "call-with-current-continuation" is available as an enhancement, "e::original-cwcc".
The Wraith Scheme procedures "e::reset" and "e::exit", which are enhancements described in the section "Top-Level Control", will leave a call of "dynamic-wind" without invoking the "after" procedure that was part of that call. So will the corresponding commands to the Wraith Scheme interpreter, which are performed via buttons, menu items. or their keyboard equivalents.
Wraith Scheme recognizes only the exact integer 5 as a valid value of the "version" argument for "scheme-report-environment" and for "null-environment".
The null environment contains bindings for three symbols that are not defined in the R5 report; namely "c::begin", "c::if" and "c::lambda". These names follow the naming convention for specialized enhancements outlined in the "Enhancements" section herein.
There is a possible ambiguity in the meaning of "interaction environment". The R5 report describes it as "the environment in which the implementation would calculate expressions dynamically typed by the user"; the only circumstance in which a Wraith Scheme user can type expressions for evaluation is when Wraith Scheme is reading at the top-level loop. I therefore made the interaction environment be the same as the top-level loop environment. Thus, e.g., typing at top-level:
(define a 'top-level) ==> a a ==> top-level (let ((a 'local)) a) ==> local
but
(let ((a 'local)) (eval 'a (interaction-environment))) ==> top-level ;; Not "local"
Input and output procedures such as "open-input-file", that take a string argument that names a file, will ask you to type in a file name when called without the string argument. These procedures will use the Wraith Scheme Dialog Panel for that purpose.
For example,
(open-input-file "foo")
opens an input file named "foo" -- or at least tries to -- whereas
(open-input-file)
will ask you to type in a file name. Similarly,
(call-with-input-file "foo" my-procedure)
calls "my-procedure" with the port obtained by opening "foo", whereas
(call-with-input-file my-procedure)
asks you to type in a file name. The full list of standard Scheme procedures that work this way is:
load call-with-input-file call-with-output-file with-input-from-file with-output-from-file open-input-file open-output-file transcript-on
Several non-standard procedures, described in the "Enhancements" section, also work this way.
There are other, system-dependent I/O features. See the "Enhancements" section.
The procedure "input-port?" returns #f when called with an input port that has been closed. The procedure "output-port?" returns #f when called with an output port that has been closed.
Procedures that open a port for output always create a new file as the destination, destroying any previous file of the same name that may already exist.
Each Wraith Scheme process allows a maximum of eight input ports and eight output ports to be open at once. (The picky wording about "each Wraith Scheme process" is because of Wraith Scheme's enhancement for parallel processing.) The port for a transcript file does not count as one of the eight output ports.
6.6.3:
Wraith Scheme "slashifies" the characters "newline", "return", and "tab", in the procedure "write", but not in the procedure "display": That is, "write" prints "newline" as "\n", "return" as "\r", and "tab" as "\t". "Display" prints these characters literally: A "newline" moves the printing to the start of the next line, and so on.
This treatment matches the escaping of those characters within string constants.
6.6.4:
Wraith Scheme allows only one transcript file to be open at a time. If "transcript-on" is called twice without an intervening call to "transcript-off", the second call closes the first file opened.
In the section-by-section discussions above, of how Wraith Scheme differs from the R5 standard, I have listed the optional R5 features that Wraith Scheme lacks. These features are "optional" in that the R5 report mentions them, perhaps with such language as "some implementations support ...". Here they are once again, all in one place, in summary:
rationalize numerator denominator make-rectangular make-polar real-part imag-part magnitude angle
This section describes Wraith Scheme's non-standard features, procedures and syntax. Many are rather conventional: Most implementations of Scheme will have them in some form, but they are sufficiently dependent on the particular computer and operating system in use that the R5 report cannot specify them. Others deal with matters of controversy in the Scheme community. Possibly some version of them will be incorporated into the standard at a future date. Meanwhile, I have provided what seems best to me.
There are a moderate number of enhancements that are specific to the look and feel of the Apple Macintosh, or that allow you to access special features of the Macintosh itself. And finally, there are some enhancements that allow you to inspect or modify parts of Wraith Scheme at a rather low level. Some of these may be useful in debugging programs, or in satisfying your curiosity about what's going on. Others are there because I needed them for some purpose related to developing Wraith Scheme.
Some of these enhancements are identified by naming conventions. In particular, Wraith Scheme uses symbols which begin with the characters "e::" for enhancements that in my opinion will probably be of broad interest to users, and "c::" for more specialized enhancements that will probably be less generally useful.
By and large, enhancements whose names begin with "e::" will be reasonably well-documented and will have reasonable handling of errors. They should be no risker to use -- with "risk" in the sense of unexpected crashes and mysterious behaviors -- than standard Scheme procedures, special forms, and macros. Furthermore, these enhancements are more likely to continue to exist in the same form in future releases of Wraith Scheme, or at the very least, I will make a big to-do in documentation if there are changes.
Enhancements whose names begin with "c::" will be less-well documented, riskier, and more likely to change in future releases. Most of the "c::" enhancements are provided for my own use in developing Wraith Scheme, or are auxiliaries used by standard Scheme procedures or by "e::" enhancements. I have left them in the release and documented some of them.
You might remember the distinction this way:
e:: for enhancement, c:: for caution
A cynic might have said:
e:: for enhancement, c:: for catastrophe
Wraith Scheme contains a simple compiler: What it produces is not native code for the Macintosh microprocessor, but merely a somewhat more optimized form of Scheme, which the interpreter can evaluate more quickly.
Wraith Scheme has an internal "compile defines" flag that causes each "define" automatically to compile the quantity being defined, provided that "define" is used with the syntax
(define (<name> <argument ...>) ... )
that is, with parentheses around the function name and argument list.
That flag is turned on and off by checking and unchecking the "compile defines" item of the interpreter menu, or by using the procedures described in the Enhancements section under State Flags. With the flag on,
(define (inc x) (+ x 1))
will create a compiled procedure called "inc", that adds one to its argument.
The idea of compilation is to do as much of the work of a program as possible just once, at compile-time, instead of many times, every time the program is run. Thus the compiler ...
Precalculates the positions within the environment of variables (including the arguments) referenced by compiled procedures,
Inserts the actual values of variables that are "permanent", within the bodies of compiled procedures.
Code that has had these things done runs much faster than code that has not.
Even if the "compile defines" menu item is not checked, the compiler will expand macros in procedures that are "define"d using the syntax
(define (<name> <argument ...>) ... )
If the "compile defines" menu item is not checked, there is still a way to compile things, using the procedure "e::compile-form":
(e::compile-form <form>)
in which <form> evaluates to what you want to compile. "<Form>" will typically be either a lambda expression or a symbol to which a lambda expression is bound. You will probably wish to bind the value returned by "e::compile-form" to a symbol, for subsequent use. For example, you might first enter
(define inc (lambda ( x) (+ x 1)))
or
(define (inc x) (+ x 1))
followed by
(define inc (e::compile-form inc))
The result in either case would be a compiled procedure called "inc", that adds one to its argument.
The compiler attempts to do something sensible with every <form>, but compilation has no effect on <form>s which do not evaluate to lambda expressions: Thus for example
(e::compile-form '(1 2 3)) ;; ==> (1 2 3).
If you define a lambda expression with "compile defines" flag off, then turn it on, you can compile the expression easily, as shown here:
With "compile defines" off:
(define foo (lambda ...)).
Then, after turning "compile defines" on:
(define foo (e::compile-form foo))
The compiler includes some other procedures of interest:
(e::define-no-compile <symbol> <form>) (e::define-no-compile (<symbol> ... ) <form> ... )
"e::define-no-compile" acts as "define" does when the "compile defines" flag is unchecked: That is, even if "compile defines" is checked, and even if quantity being defined evaluates to a lambda expression, nevertheless "e::define-no-compile" will merely bind the evaluated quantity to the <symbol>, without compiling it. Use "e::define-no-compile" to make sure something never gets compiled.
"e::define-no-compile" recursively searches its second argument for macro "calls", and expands any that it finds, before binding the result to the <symbol>.
Effective use of the compiler requires understanding how it uses the "permanence" mechanism. To make a symbol permanent is to make a promise to the compiler, that whatever value is associated with the symbol at compile-time will continue to be associated with it at run-time. Thus the compiler can substitute the value for the symbol once and for all in compiled code, and save the time required to look up the symbol time after time, at run-time. The down side of permanence is that if you ever decide to make a permanent symbol un-permanent, and change its value, you will have to recompile all the procedures that use it, that were compiled while it had the first permanent value. Otherwise, those procedures will continue to use the old value.
The typical symbols you will probably wish to make permanent are the names of procedures, and there is a special procedure to help a bunch of compiled, permanent procedures all know that they are all permanent. That function is "e::substitute-new-permanent-symbols"; you use it on a procedure that has already been compiled, to let that procedure know about symbols that it contains, that have been made permanent after it was compiled:
(e::substitute-new-permanent-symbols <form>)
Note that you do not have to bind the result of "e::substitute-new-permanent-symbols" to anything; that procedure modifies its argument: It looks through the function body for symbols that have become permanent, and substitutes in their values.
Here is some boiler-plate for how to use the "permanence" mechanism effectively in compiled code. Suppose that the "compile defines" menu item is checked, and that you wish to compile three functions, "foo", "bar" and "baz", that call each other, or that call themselves recursively, or both. The idea is to define them all first, then make them all permanent, then apply "e::substitute-new-permanent-symbols" to all of them. You do all this with the "compile defines" flag set:
(define my-function-names '(foo bar baz) (define (foo ...) ...) (define (bar ...) ...) (define (baz ...) ...) (map e::set-permanent! my-function-names) (map e::substitute-new-permanent-symbols my-function-names)
The debugging mechanism provided with Wraith Scheme is very incomplete, though there is a hook for making it better. Wraith Scheme's mechanism for handling recoverable errors -- the kind that eventually return control to top level --knows to look for a symbol called "e::debug". If that symbol is bound to a procedure, the error-handling message will call it with a single argument. Thus you may create a debugger merely by defining "e::debug", like this:
(define e::debug (lambda (x) ...))Wraith Scheme will then call "e::debug" as part of its error handling, after the error message has been printed, instead of returning control to the top-level environment.
The argument to "e::debug" will be a non-empty list of all the environments in the lexical scope of the place where the error happened. The last member of that list will be the top-level environment: It will be a vector, each of whose elements is a list of symbols. Every symbol bound in the top-level environment will appear in exactly one vector element. If the list that is passed to "e::debug" has more members, its first member will be a list of the symbols bound in the lexical scope most local to the error, its second will be a list of the symbols bound in the next lexical scope outward, and so on till the top level. Only the last member will be a vector; all the others will be lists.
You may have your "e::debug" do whatever you like with this information. You might display the symbols. It will be hard to obtain their values, because the environment list passed to "e::debug" as an argument is not the one Wraith Scheme searches automatically from within "e::debug", when looki