The DrScheme system is a development environment -- a collection of tools to assist programmers. It is built around a Scheme processor named MzScheme, which is the component that actually evaluates your expressions and executes your programs.
When someone wants to execute a fully developed Scheme program, she can
invoke the MzScheme processor directly, without bothering to call up the
rest of the DrScheme environment. For instance, consider the following
Scheme program, reminiscent of the square-root-computer
procedure from the reading on input and
output procedures, but offering the user the possibility of recovering
from incorrect input:
;;; Square root program
;;; John David Stone
;;; Department of Mathematics and Computer Science
;;; Grinnell College
;;; stone@cs.grinnell.edu
;;; created March 5, 2000
;;; last revised August 22, 2001
;;; The PROMPT procedure takes the text of a prompt as its
;;; argument, displays it, and collects and returns the user's
;;; reply.
;;; Given:
;;; PROMPT-TEXT, a string.
;;; Results:
;;; LECT, a value.
;;; Preconditions:
;;; None.
;;; Postconditions:
;;; (1) PROMPT-TEXT has been written out to the terminal
;;; window.
;;; (2) If the user has responded by typing in the
;;; representation of some Scheme value, LECT is that
;;; value.
(define prompt
(lambda (prompt-text)
(display prompt-text)
(read)))
;;; The PROMPT-FOR-NUMBER procedure prompts the user for a
;;; number, which it returns. If the user supplies something
;;; that is not a number, PROMPT-FOR-NUMBER displays an
;;; advisory message and repeats the prompt.
;;; Givens:
;;; None.
;;; Result:
;;; LECT, a number.
;;; Preconditions:
;;; None.
;;; Postconditions:
;;; (1) The program user has been prompted at least once for
;;; a number.
;;; (2) The program user's reply has been read in.
;;; (3) If the program user's reply is the Scheme
;;; representation of a number, LECT is that number.
(define prompt-for-number
(lambda ()
(let ((candidate (prompt "Number: ")))
(if (number? candidate)
candidate
(begin
(display "The value ")
(write candidate)
(display " is not a number.")
(newline)
(display "Please supply a number.")
(newline)
(prompt-for-number))))))
;;; The REPORT-SQUARE-ROOT procedure takes a number as its
;;; argument and displays the square root of that number as
;;; part of an English sentence that describes it.
;;; Given:
;;; NUMBER, a number.
;;; Results:
;;; None.
;;; Preconditions:
;;; None.
;;; Postconditions:
;;; An English sentence has been written out to the
;;; terminal, identifying NUMBER and reporting its square
;;; root, or at least a value which, when multiplied by
;;; itself, is approximately equal to NUMBER.
(define report-square-root
(lambda (number)
(display "The square root of ")
(display number)
(display " is ")
(display (sqrt number))
(display ".")
(newline)))
;;; So much for definitions. The executable part of the
;;; program begins here.
;;; Explain to the user what the program does.
(display "Give me a number, and I'll compute its square root.")
(newline)
;;; Get a number from the user and report its square root.
(report-square-root (prompt-for-number))
The file /home/stone/courses/scheme/examples/square-root-program.ss contains a copy of this program. You can ask MzScheme to run it by creating a terminal-emulator window and giving the command
mzscheme -r /home/stone/courses/scheme/examples/square-root-program.ss
at the shell prompt. MzScheme learns the three definitions at the top of the program and then evaluates the procedure calls that follow, much as if they had been typed into a DrScheme interactions window. Instead of drawing an interaction box around the program's input and output, however, MzScheme simply displays it in the terminal-emulator window:
bourbaki$ mzscheme -r /home/stone/courses/scheme/examples/square-root-program.ss Give me a number, and I'll compute its square root. Number: 9604 The square root of 9604 is 98.
When it reaches the end of the program, MzScheme shuts itself down, returning control of the terminal-emulator window to the shell.
When you're running a program under MzScheme rather than DrScheme, there is no Break button to interrupt a runaway recursion. However, pressing <Control/C> in the terminal-emulator window has the same effect.
There are many Scheme processors besides MzScheme, and often there are good reasons to use them. Some are faster; some, perhaps, are more readily extensible; some are smaller and can be incorporated into other software more easily. Kawa translates Scheme programs into instructions for the Java Virtual Machine, so that Scheme programs can be distributed over the World Wide Web and executed by any Java-speaking browser. Stalin is a compiler that translates Scheme programs into files that load and run much more quickly.
Ideally, submitting a Scheme program to several different Scheme processors should yield the same results. However, even among the processors that provide an interactive interface like MzScheme's, there are minor variations and differences, many of them related to input and output. For instance, here are the results of running the square-root program under several Scheme processors that are available on MathLAN:
bourbaki$ scheme /home/stone/courses/scheme/examples/square-root-program.ss Chez Scheme Version 6.1 Copyright (c) 1998 Cadence Research Systems Give me a number, and I'll compute its square root. Number: 9604 The square root of 9604 is 98. >
Chez Scheme prints its version and copyright header at the beginning of
every interactive session, even when it is reading the program in from a
file. Also, Chez Scheme doesn't shut itself down when it reaches the end
of the program; instead, it enters interactive mode, issuing a prompt at
which the user can type in another command or definition. (We could add
the command (exit) at the end of the program to instruct Chez
Scheme to shut itself down.)
bourbaki$ scheme48
Welcome to Scheme 48 0.57 (made by root on Mon Aug 20 09:18:50 CDT 2001).
Copyright (c) 1993-2001 by Richard Kelsey and Jonathan Rees.
Please report bugs to scheme-48-bugs@martigny.ai.mit.edu.
Type ,? (comma question-mark) for help.
> (load "/home/stone/courses/scheme/examples/square-root-program.ss")
/home/stone/courses/scheme/examples/square-root-program.ss
Give me a number, and I'll compute its square root.
Number: 9604
The square root of 9604 is 98.
#{Unspecific}
> >
Scheme 48 does not allow the user to specify a file name on the command
line that starts it; instead, one must invoke the load
procedure to execute the file.
`#{Unspecific}' is Scheme 48's name for the value returned by
the newline procedure (which is also the value returned by the
report-square-root procedure in the program above). Since we
call newline for its side effect, we don't really care what
the value of the procedure call is, and most Scheme processors
simply discard it instead of trying to make it visible to the user; but
Scheme 48 wants to report it.
After completing the program, Scheme 48 returns to interactive mode and
issues another prompt. (Putting `(exit)' at the bottom of the
program wouldn't help this time; Scheme 48 would interpret it as an attempt
to call a procedure that it has never heard of.) In fact, it issues
two prompts, because when it reads the number that the user types
in, it leaves behind the newline character that the user generated by
pressing the <Enter> key, and then later mistakes that
character for the user's response to the first prompt.
bourbaki$ elk-scheme > (load "/home/stone/courses/scheme/examples/square-root-program.ss") Give me a number, and I'll compute its square root. Number: 9604 The square root of 9604 is 98.0. >
Again, Elk Scheme requires the user to invoke the load
procedure to execute the file and returns to an interactive mode afterwards
However, Elk Scheme does know the exit command.
Elk Scheme's sqrt procedure returns an inexact number, even
when it receives an exact integer that is a perfect square -- hence the
decimal point in the output.
bourbaki$ scm /home/stone/courses/scheme/examples/square-root-program.ss Give me a number, and I'll compute its square root. Number: 9604 The square root of 9604 is 98.0. >
SCM enters interactive mode after executing the program, but it does
recognize the exit command. Like Elk Scheme, it computes all
square roots as inexact numbers.
bourbaki$ guile -s /home/stone/courses/scheme/examples/square-root-program.ss Give me a number, and I'll compute its square root. 9604 Number: The square root of 9604 is 98.0.
Guile computes all square roots as inexact numbers.
Notice that, under Guile, the user of the program has to supply the number
before the prompt is printed! The explanation is that Guile's
write procedure does not output directly to the terminal
window, but rather to an internal buffer in the computer's memory.
This buffer is copied to the terminal window only when a complete line has
been accumulated -- in this program, not until the newline
procedure is invoked at the end.
The programmer can insist that the contents of the buffer be copied to the
terminal window immediately by invoking a procedure called
force-output:
(define prompt
(lambda (prompt-text)
(display prompt-text)
(force-output)
(read)))
With this change, the Guile program makes the prompt visible before the
user has to type anything. However, the force-output
procedure exists only in Guile, so if you modify the program by adding the
call to force-output, the other Scheme processors choke on
it.
The differences of detail here are less important than the general lesson about running a program under different Scheme processors: Although the core of the language remains the same, there are likely to be a few differences in the mechanics of starting up the program and shutting it down, as well as in the way values are represented in the output.
Almost all Scheme implementations provide many more primitive procedures than the Scheme standard actually requires, and it is sometimes prudent to use them instead of trying to define everything using only the standard procedures. But in doing so, you generally sacrifice your program's portability.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~stone/courses/scheme/readings/outside-drscheme.xhtml
created March 5, 2000
last revised December 4, 2001
John David Stone (stone@cs.grinnell.edu) and Ben Gum (gum@cs.grinnell.edu)