about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/usermanual
diff options
context:
space:
mode:
Diffstat (limited to 'js/games/nluqo.github.io/~bh/usermanual')
-rw-r--r--js/games/nluqo.github.io/~bh/usermanual4197
1 files changed, 4197 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/usermanual b/js/games/nluqo.github.io/~bh/usermanual
new file mode 100644
index 0000000..94e839a
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/usermanual
@@ -0,0 +1,4197 @@
+Berkeley Logo User Manual
+
+ *	Copyright (C) 1993 by the Regents of the University of California
+ *
+ *      This program is free software: you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation, either version 3 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+This is a program that is still being written.  Many things are missing,
+including adequate documentation.  This manual assumes that you already know
+how to program in Logo, and merely presents the details of this new
+implementation.  Read _Computer_Science_Logo_Style,_Volume_1:_
+_Symbolic_Computing_ by Brian Harvey (MIT Press, 1997) for a tutorial
+on Logo programming with emphasis on symbolic computation.
+
+Here are the special features of this dialect of Logo:
+
+	Source file compatible among Unix, DOS, Windows, and Mac platforms.
+
+	Random-access arrays.
+
+	Variable number of inputs to user-defined procedures.
+
+	Mutators for list structure (dangerous).
+
+	Pause on error, and other improvements to error handling.
+
+	Comments and continuation lines; formatting is preserved when
+	procedure definitions are saved or edited.
+
+	Terrapin-style tokenization (e.g., [2+3] is a list with one member)
+	but LCSI-style syntax (no special forms except TO).  The best of
+	both worlds.
+
+	First-class instruction and expression templates (see APPLY).
+
+	Macros.
+
+Features *not* found in Berkeley Logo include robotics, music, GUIs, animation,
+parallelism, and multimedia.  For those, buy a commercial version.
+
+
+GETTER/SETTER VARIBLE SYNTAX
+============================
+
+Logo distinguishes PROCEDURES from VARIABLES.  A procedure is a set of
+instructions to carry out some computation; a variable is a named
+container that holds a data value such as a number, word, list, or array.
+
+In traditional Logo syntax, a non-numeric word typed without punctuation
+represents a request to invoke the procedure named by that word.  A word
+typed with a preceding quotation mark represents the word itself.  For
+example, in the instruction
+	PRINT FIRST "WORD
+the procedures named FIRST and PRINT are invoked, but the procedure
+named WORD is not invoked; the word W-O-R-D is the input to FIRST.
+
+What about variables?  There are two things one can do with a variable:
+give it a value, and find out its value.  To give a variable a value,
+Logo provides the primitive procedure MAKE, which requires two inputs:
+the name of the variable and the new value to be assigned.  The first
+input, the name of the variable, is just a word, and if (as is almost
+always the case) the programmer wants to assign a value to a specific
+variable whose name is known in advance, that input is quoted, just
+as any known specific word would be:
+	MAKE "MY.VAR FIRST "WORD
+gives the variable named MY.VAR the value W (the first letter of WORD).
+
+To find the value of a variable, Logo provides the primitive procedure
+THING, which takes a variable name as its input, and outputs the value
+of the accessible variable with that name.  Thus
+	PRINT THING "MY.VAR
+will print W (supposing the MAKE above has been done).  Since finding
+the value of a specific, known variable name is such a common operation,
+Logo also provides an abbreviated notation that combines THING with quote:
+	PRINT :MY.VAR
+The colon (which Logo old-timers pronounce "dots") replaces THING and "
+in the earlier version of the instruction.
+
+Newcomers to Logo often complain about the need for all this punctuation.
+In particular, Logo programmers who learned about dots and quotes without
+also learning about THING wonder why an instruction such as
+	MAKE "NEW.VAR :OLD.VAR
+uses two different punctuation marks to identify the two variables.
+(Having read the paragraphs above, you will understand that actually
+both variable names are quoted, but the procedure THING is invoked to
+find the value of OLD.VAR, since it's that value, not OLD.VAR's name,
+that MAKE needs to know.  It wouldn't make sense to ask for THING of
+NEW.VAR, since we haven't given NEW.VAR a value yet.)
+
+Although Logo's punctuation rules make sense once understood, they
+do form a barrier to entry for the Logo beginner.  Why, then, couldn't
+Logo be designed so that an unpunctuated word would represent a
+procedure if there is a procedure by that name, or a variable if
+there is a variable by that name?  Then we could say
+	PRINT MY.VAR
+and Logo would realize that MY.VAR is the name of a variable, not
+of a procedure.  The traditional reason not to use this convention
+is that Logo allows the same word to name a procedure and a variable
+at the same time.  This is most often important for words that name
+data types, as in the following procedure:
+	TO PLURAL :WORD
+	OUTPUT WORD :WORD "S
+	END
+Here the name WORD is a natural choice for the input to PLURAL, since
+it describes the kind of input that PLURAL expects.  Within the procedure,
+we use WORD to represent Logo's primitive procedure that combines two
+input words to form a new, longer word; we use :WORD to represent the
+variable containing the input, whatever actual word is given when
+PLURAL is invoked.
+	? PRINT PLURAL "COMPUTER
+	COMPUTERS
+
+However, if a Logo instruction includes an unquoted word that is *not*
+the name of a procedure, Logo could look for a variable of that name
+instead.  This would allow a "punctuationless" Logo, ** PROVIDED THAT
+USERS WHO WANT TO WORK WITHOUT COLONS FOR VARIABLES CHOOSE VARIABLE
+NAMES THAT ARE NOT ALSO PROCEDURE NAMES. **
+
+What about assigning a value to a variable?  Could we do without
+the quotation mark on MAKE's first input?  Alas, no.  Although the
+first input to MAKE is *usually* a constant, known variable name,
+sometimes it isn't, as in this example:
+	TO INCREMENT :VAR
+	MAKE :VAR (THING :VAR)+1	; Note: it's not "VAR here!
+	END
+
+	? MAKE "X 5
+	? INCREMENT "X
+	? PRINT :X
+	6
+The procedure INCREMENT takes a variable name as its input and
+changes the value of that variable.  In this example there are
+two variables; the variable whose name is VAR, and whose value
+is the word X; and the variable whose name is X and whose value
+changes from 5 to 6.  Suppose we changed the behavior of MAKE so
+that it took the word after MAKE as the name of the variable to
+change; we would be unable to write INCREMENT:
+	TO INCREMENT :VAR	; nonworking!
+	MAKE VAR (THING VAR)+1
+	END
+This would assign a new value to VAR, not to X.
+
+What we can do is to allow an *alternative* to MAKE, a "setter"
+procedure for a particular variable.  The notation will be
+	? SETFOO 7
+	? PRINT FOO
+	7
+SETFOO is a "setter procedure" that takes one input (in this case
+the input 7) and assigns its value to the variable named FOO.
+
+Berkeley Logo allows users to choose either the traditional notation,
+in which case the same name can be used both for a procedure and for
+a variable, or the getter/setter notation, in which variable FOO is
+set with SETFOO and examined with FOO, but the same name can't be
+used for procedure and variable.
+
+Here is how this choice is allowed:  Berkeley Logo uses traditional notation,
+with procedures distinct from variables.  However, if there is a variable
+named AllowGetSet whose value is TRUE (which there is, by default, when
+Logo starts up), then if a Logo instruction refers to a *nonexistent*
+procedure (so that the error message "I don't know how to ..." would result),
+Logo tries the following two steps:
+
+	1.  If the name is at least four characters long, and the first three
+	characters are the letters SET (upper or lower case), and if the name
+	is followed in the instruction by another value, and if the name
+	without the SET is the name of a variable that already exists, then
+	Logo will invoke MAKE with its first input being the name without the
+	SET, and its second input being the following value.
+
+	2.  If step 1's conditions are not met, but the name is the name of an
+	accessible variable, then Logo will invoke THING with that name as
+	input, to find the variable's value.
+
+Step 1 requires that the variable already exist so that misspellings of names
+of SETxxx primitives (e.g., SETHEADING) will still be caught, instead of
+silently creating a new variable.  The command GLOBAL can be used to create
+a variable without giving it a value.
+
+One final point:  The TO command in Logo has always been a special
+case; the rest of the line starting with TO is not evaluated as
+ordinary Logo expressions are.  In particular, the colons used to
+mark the names of inputs to the procedure do not cause THING to be
+invoked.  They are merely mnemonic aids, reminding the Logo user
+that these words are names of variables.  (Arguably, this nonstantard
+behavior of TO adds to Logo beginners' confusion about colons.)
+To a programmer using colonless variable references, the colons in
+the TO line are unnecessary and meaningless.  Berkeley Logo therefore
+makes the colons optional:
+	TO FOO :IN1 :IN2
+and
+	TO FOO IN1 IN2
+are both allowed.
+
+
+ENTERING AND LEAVING LOGO
+=========================
+
+The process to start Logo depends on your operating system:
+
+Unix:	 Type the word {\tt logo} to the shell.  (The directory in which
+	 you've installed Logo must be in your path.)
+
+DOS:	 Change directories to the one containing Logo (probably
+	 C:\UCBLOGO).  Then type UCBLOGO for the large memory
+	 version, or BL for the 640K version.
+
+Mac:	 Double-click on the LOGO icon within the "UCB Logo" folder.
+
+Windows: Double-click on the UCBWLOGO icon in the UCBLOGO folder.
+
+To leave Logo, enter the command "bye".
+
+On startup, Logo looks for a file named "startup.lg" in the system Logo
+library and, if found, loads it.  Then it looks for "startup.lg" in the
+user's home directory, or the current directory, depending on the operating
+system, and loads that.  These startup files can be used to predefine
+procedures, e.g., to provide non-English names for primitive procedures.
+
+Under Unix, DOS, or Windows, if you include one or more filenames on the
+command line when starting Logo, those files will be loaded before the
+interpreter starts reading commands from your terminal.  If you load a file
+that executes some program that includes a "bye" command, Logo will run that
+program and exit.  You can therefore write standalone programs in Logo and run
+them with shell/batch scripts.  To support this technique, Logo does not print
+its usual welcoming and parting messages if you give file arguments to the
+logo command.
+
+If a command line argument is just a hyphen, then all command line arguments
+after the hyphen are not taken as filenames, but are instead collected in a
+list, one word per argument; the buried variable COMMAND.LINE contains that
+list of arguments, or the empty list if there are none.  On my Linux system,
+if the first line of an executable shell script is
+#!/usr/local/bin/logo -
+(note the hyphen) then the script can be given command line arguments and
+they all end up in :COMMAND.LINE along with the script's path.  Experiment.
+
+If you type your interrupt character (see table below) Logo will stop what
+it's doing and return to toplevel, as if you did THROW "TOPLEVEL.  If you
+type your quit character Logo will pause as if you did PAUSE.
+
+               wxWidgets       Unix        DOS/Windows          Mac
+
+toplevel         alt-S    usually ctrl-C     ctrl-Q      command-. (period)
+
+pause            alt-P    usually ctrl-\     ctrl-W      command-, (comma)
+
+If you have an environment variable called LOGOLIB whose value is the name of
+a directory, then Logo will use that directory instead of the default
+library.  If you invoke a procedure that has not been defined, Logo first
+looks for a file in the current directory named proc.lg where "proc" is the
+procedure name in lower case letters.  If such a file exists, Logo loads
+that file.  If the missing procedure is still undefined, or if there is no
+such file, Logo then looks in the library directory for a file named proc
+(no ".lg") and, if it exists, loads it.  If neither file contains a
+definition for the procedure, then Logo signals an error.  Several
+procedures that are primitive in most versions of Logo are included in the
+default library, so if you use a different library you may want to include
+some or all of the default library in it.
+
+
+TOKENIZATION
+============
+
+Names of procedures, variables, and property lists are case-insensitive.  So
+are the special words END, TRUE, and FALSE.  Case of letters is preserved
+in everything you type, however.
+
+Within square brackets, words are delimited only by spaces and square
+brackets.  [2+3] is a list containing one word.  Note, however, that the
+Logo primitives that interpret such a list as a Logo instruction or
+expression (RUN, IF, etc.) reparse the list as if it had not been typed
+inside brackets.
+
+After a quotation mark outside square brackets, a word is delimited by
+a space, a square bracket, or a parenthesis.
+
+A word not after a quotation mark or inside square brackets is delimited
+by a space, a bracket, a parenthesis, or an infix operator +-*/=<>.  Note
+that words following colons are in this category.  Note that quote and
+colon are not delimiters.  Each infix operator character is a word in
+itself, except that the two-character sequences <= >= and <> (the latter
+meaning not-equal) with no intervening space are recognized as a single
+word.
+
+A word consisting of a question mark followed by a number (e.g., ?37),
+when runparsed (i.e., where a procedure name is expected), is treated
+as if it were the sequence
+
+	( ? 37 )
+
+making the number an input to the ? procedure.  (See the discussion of
+templates, below.)  This special treatment does not apply to words read
+as data, to words with a non-number following the question mark, or if
+the question mark is backslashed.
+
+A line (an instruction line or one read by READLIST or READWORD) can be
+continued onto the following line if its last character is a tilde (~).
+READWORD preserves the tilde and the newline; READLIST does not.
+
+Lines read with READRAWLINE are never continued.
+
+An instruction line or a line read by READLIST (but not by READWORD)
+is automatically continued to the next line, as if ended with a tilde,
+if there are unmatched brackets, parentheses, braces, or vertical bars
+pending.  However, it's an error if the continuation line contains
+only the word END; this is to prevent runaway procedure definitions.
+Lines eplicitly continued with a tilde avoid this restriction.
+
+If a line being typed interactively on the keyboard is continued, either
+with a tilde or automatically, Logo will display a tilde as a prompt
+character for the continuation line.
+
+A semicolon begins a comment in an instruction line.  Logo ignores
+characters from the semicolon to the end of the line.  A tilde as the
+last character still indicates a continuation line, but not a continuation
+of the comment.  For example, typing the instruction
+
+	print "abc;comment ~
+	def
+
+will print the word abcdef.  Semicolon has no special meaning in data
+lines read by READWORD or READLIST, but such a line can later be reparsed
+using RUNPARSE and then comments will be recognized.
+
+The two-character sequence #! at the beginning of a line also starts a
+comment.  Unix users can therefore write a file containing Logo commands,
+starting with the line
+
+	#! /usr/local/bin/logo
+
+(or wherever your Logo executable lives) and the file will be executable
+directly from the shell.
+
+To include an otherwise delimiting character (including semicolon or tilde)
+in a word, precede it with backslash (\).  If the last character of a line
+is a backslash, then the newline character following the backslash will be
+part of the last word on the line, and the line continues onto the following
+line.  To include a backslash in a word, use \\.  If the combination
+backslash-newline is entered at the terminal, Logo will issue a backslash as
+a prompt character for the continuation line.  All of this applies to data
+lines read with READWORD or READLIST as well as to instruction lines.
+
+A line read with READRAWLINE has no special quoting mechanism; both
+backslash and vertical bar (described below) are just ordinary characters.
+
+An alternative notation to include otherwise delimiting characters in words is
+to enclose a group of characters in vertical bars.  All characters between
+vertical bars are treated as if they were letters.  In data read with READWORD
+the vertical bars are preserved in the resulting word.  In data read with
+READLIST (or resulting from a PARSE or RUNPARSE of a word) the vertical bars
+do not appear explicitly; all potentially delimiting characters (including
+spaces, brackets, parentheses, and infix operators) appear unmarked, but
+tokenized as though they were letters.  Within vertical bars, backslash may
+still be used; the only characters that must be backslashed in this context
+are backslash and vertical bar themselves.
+
+Characters entered between vertical bars are forever special, even if the
+word or list containing them is later reparsed with PARSE or RUNPARSE.
+Characters typed after a backslash are treated somewhat differently:  When a
+quoted word containing a backslashed character is runparsed, the backslashed
+character loses its special quality and acts thereafter as if typed normally.
+This distinction is important only if you are building a Logo expression out
+of parts, to be RUN later, and want to use parentheses.  For example,
+
+	PRINT RUN (SE "\( 2 "+ 3 "\))
+
+will print 5, but
+
+	RUN (SE "MAKE ""|(| 2)
+
+will create a variable whose name is open-parenthesis.  (Each example would
+fail if vertical bars and backslashes were interchanged.)
+
+A character entered with backslash is EQUALP to the same character without the
+backslash, but can be distinguished by the VBARREDP predicate.  (However,
+VBARREDP returns TRUE only for characters for which special treatment is
+necessary: whitespace, parentheses, brackets, infix operators, backslash,
+vertical bar, tilde, quote, question mark, colon, and semicolon.)
+
+
+DATA STRUCTURE PRIMITIVES
+=========================
+
+CONSTRUCTORS
+------------
+
+WORD word1 word2
+(WORD word1 word2 word3 ...)
+
+	outputs a word formed by concatenating its inputs.
+
+LIST thing1 thing2
+(LIST thing1 thing2 thing3 ...)
+
+	outputs a list whose members are its inputs, which can be any
+	Logo datum (word, list, or array).
+
+SENTENCE thing1 thing2
+SE thing1 thing2
+(SENTENCE thing1 thing2 thing3 ...)
+(SE thing1 thing2 thing3 ...)
+
+	outputs a list whose members are its inputs, if those inputs are
+	not lists, or the members of its inputs, if those inputs are lists.
+
+FPUT thing list
+
+	outputs a list equal to its second input with one extra member,
+	the first input, at the beginning.  If the second input is a word,
+	then the first input must be a one-letter word, and FPUT is
+	equivalent to WORD.
+
+LPUT thing list
+
+	outputs a list equal to its second input with one extra member,
+	the first input, at the end.  If the second input is a word,
+	then the first input must be a one-letter word, and LPUT is
+	equivalent to WORD with its inputs in the other order.
+
+ARRAY size
+(ARRAY size origin)
+
+	outputs an array of "size" members (must be a positive integer),
+	each of which initially is an empty list.  Array members can be
+	selected with ITEM and changed with SETITEM.  The first member of
+	the array is member number 1 unless an "origin" input (must be an
+	integer) is given, in which case the first member of the array has
+	that number as its index.  (Typically 0 is used as the origin if
+	anything.)  Arrays are printed by PRINT and friends, and can be
+	typed in, inside curly braces; indicate an origin with {a b c}@0.
+
+MDARRAY sizelist					(library procedure)
+(MDARRAY sizelist origin)
+
+	outputs a multi-dimensional array.  The first input must be a list
+	of one or more positive integers.  The second input, if present,
+	must be a single integer that applies to every dimension of the array.
+	Ex: (MDARRAY [3 5] 0) outputs a two-dimensional array whose members
+	range from [0 0] to [2 4].
+
+LISTTOARRAY list
+(LISTTOARRAY list origin)
+
+	outputs an array of the same size as the input list, whose members
+	are the members of the input list.
+
+ARRAYTOLIST array
+
+	outputs a list whose members are the members of the input array.
+	The first member of the output is the first member of the array,
+	regardless of the array's origin.
+
+COMBINE thing1 thing2					(library procedure)
+
+	if thing2 is a word, outputs WORD thing1 thing2.  If thing2 is a list,
+	outputs FPUT thing1 thing2.
+
+REVERSE list						(library procedure)
+
+	outputs a list whose members are the members of the input list, in
+	reverse order.
+
+GENSYM							(library procedure)
+
+	outputs a unique word each time it's invoked.  The words are of the
+	form G1, G2, etc.
+
+
+SELECTORS
+---------
+
+FIRST thing
+
+	if the input is a word, outputs the first character of the word.
+	If the input is a list, outputs the first member of the list.
+	If the input is an array, outputs the origin of the array (that
+	is, the INDEX OF the first member of the array).
+
+FIRSTS list
+
+	outputs a list containing the FIRST of each member of the input
+	list.  It is an error if any member of the input list is empty.
+	(The input itself may be empty, in which case the output is also
+	empty.)  This could be written as
+
+		to firsts :list
+		output map "first :list
+		end
+
+	but is provided as a primitive in order to speed up the iteration
+	tools MAP, MAP.SE, and FOREACH.
+ 
+		to transpose :matrix
+		if emptyp first :matrix [op []]
+		op fput firsts :matrix transpose bfs :matrix
+		end
+
+LAST wordorlist
+
+	if the input is a word, outputs the last character of the word.
+	If the input is a list, outputs the last member of the list.
+
+BUTFIRST wordorlist
+BF wordorlist
+
+	if the input is a word, outputs a word containing all but the first
+	character of the input.  If the input is a list, outputs a list
+	containing all but the first member of the input.
+
+BUTFIRSTS list
+BFS list
+
+	outputs a list containing the BUTFIRST of each member of the input
+	list.  It is an error if any member of the input list is empty or an
+	array.  (The input itself may be empty, in which case the output is
+	also empty.)  This could be written as
+
+		to butfirsts :list
+		output map "butfirst :list
+		end
+
+	but is provided as a primitive in order to speed up the iteration
+	tools MAP, MAP.SE, and FOREACH.
+
+BUTLAST wordorlist
+BL wordorlist
+
+	if the input is a word, outputs a word containing all but the last
+	character of the input.  If the input is a list, outputs a list
+	containing all but the last member of the input.
+
+ITEM index thing
+
+	if the "thing" is a word, outputs the "index"th character of the
+	word.  If the "thing" is a list, outputs the "index"th member of
+	the list.  If the "thing" is an array, outputs the "index"th
+	member of the array.  "Index" starts at 1 for words and lists;
+	the starting index of an array is specified when the array is
+	created.
+
+MDITEM indexlist array					(library procedure)
+
+	outputs the member of the multidimensional "array" selected by
+	the list of numbers "indexlist".
+
+PICK list						(library procedure)
+
+	outputs a randomly chosen member of the input list.
+
+REMOVE thing list					(library procedure)
+
+	outputs a copy of "list" with every member equal to "thing" removed.
+
+REMDUP list						(library procedure)
+
+	outputs a copy of "list" with duplicate members removed.  If two or
+	more members of the input are equal, the rightmost of those members
+	is the one that remains in the output.
+
+QUOTED thing						(library procedure)
+
+	outputs its input, if a list; outputs its input with a quotation
+	mark prepended, if a word.
+
+
+MUTATORS
+--------
+
+SETITEM index array value
+
+	command.  Replaces the "index"th member of "array" with the new
+	"value".  Ensures that the resulting array is not circular, i.e.,
+	"value" may not be a list or array that contains "array".
+
+MDSETITEM indexlist array value				(library procedure)
+
+	command.  Replaces the member of "array" chosen by "indexlist"
+	with the new "value".
+
+.SETFIRST list value
+
+	command.  Changes the first member of "list" to be "value".
+
+	WARNING:  Primitives whose names start with a period are DANGEROUS.
+	Their use by non-experts is not recommended.  The use of .SETFIRST can
+	lead to circular list structures, which will get some Logo primitives
+	into infinite loops, and to unexpected changes to other data
+	structures that share storage with the list being modified.
+
+.SETBF list value
+
+	command.  Changes the butfirst of "list" to be "value".
+
+	WARNING: Primitives whose names start with a period are DANGEROUS.
+	Their use by non-experts is not recommended.  The use of .SETBF can
+	lead to circular list structures, which will get some Logo primitives
+	into infinite loops; unexpected changes to other data structures that
+	share storage with the list being modified; or to Logo crashes and
+	coredumps if the butfirst of a list is not itself a list.
+
+.SETITEM index array value
+
+	command.  Changes the "index"th member of "array" to be "value",
+	like SETITEM, but without checking for circularity.
+
+	WARNING: Primitives whose names start with a period are DANGEROUS.
+	Their use by non-experts is not recommended.  The use of .SETITEM
+	can lead to circular arrays, which will get some Logo primitives into
+	infinite loops.
+
+PUSH stackname thing					(library procedure)
+
+	command.  Adds the "thing" to the stack that is the value of the
+	variable whose name is "stackname".  This variable must have a list
+	as its value; the initial value should be the empty list.  New
+	members are added at the front of the list.
+
+POP stackname						(library procedure)
+
+	outputs the most recently PUSHed member of the stack that is the
+	value of the variable whose name is "stackname" and removes that
+	member from the stack.
+
+QUEUE queuename thing					(library procedure)
+
+	command.  Adds the "thing" to the queue that is the value of the
+	variable whose name is "queuename".  This variable must have a list
+	as its value; the initial value should be the empty list.  New
+	members are added at the back of the list.
+
+DEQUEUE queuename					(library procedure)
+
+	outputs the least recently QUEUEd member of the queue that is the
+	value of the variable whose name is "queuename" and removes that
+	member from the queue.
+
+
+PREDICATES
+----------
+
+WORDP thing
+WORD? thing
+
+	outputs TRUE if the input is a word, FALSE otherwise.
+
+LISTP thing
+LIST? thing
+
+	outputs TRUE if the input is a list, FALSE otherwise.
+
+ARRAYP thing
+ARRAY? thing
+
+	outputs TRUE if the input is an array, FALSE otherwise.
+
+EMPTYP thing
+EMPTY? thing
+
+	outputs TRUE if the input is the empty word or the empty list,
+	FALSE otherwise.
+
+EQUALP thing1 thing2
+EQUAL? thing1 thing2
+thing1 = thing2
+
+	outputs TRUE if the inputs are equal, FALSE otherwise.  Two numbers
+	are equal if they have the same numeric value.  Two non-numeric words
+	are equal if they contain the same characters in the same order.  If
+	there is a variable named CASEIGNOREDP whose value is TRUE, then an
+	upper case letter is considered the same as the corresponding lower
+	case letter.  (This is the case by default.)  Two lists are equal if
+	their members are equal.  An array is only equal to itself; two
+	separately created arrays are never equal even if their members are
+	equal.  (It is important to be able to know if two expressions have
+	the same array as their value because arrays are mutable; if, for
+	example, two variables have the same array as their values then
+	performing SETITEM on one of them will also change the other.)
+
+NOTEQUALP thing1 thing2
+NOTEQUAL? thing1 thing2
+thing1 <> thing2
+
+	outputs FALSE if the inputs are equal, TRUE otherwise.  See EQUALP
+	for the meaning of equality for different data types.
+
+BEFOREP word1 word2
+BEFORE? word1 word2
+
+	outputs TRUE if word1 comes before word2 in ASCII collating sequence
+	(for words of letters, in alphabetical order).  Case-sensitivity is
+	determined by the value of CASEIGNOREDP.  Note that if the inputs are
+	numbers, the result may not be the same as with LESSP; for example,
+	BEFOREP 3 12 is false because 3 collates after 1.
+
+.EQ thing1 thing2
+
+	outputs TRUE if its two inputs are the same datum, so that applying a
+	mutator to one will change the other as well.  Outputs FALSE otherwise,
+	even if the inputs are equal in value.
+	WARNING: Primitives whose names start with a period are DANGEROUS.
+	Their use by non-experts is not recommended.  The use of mutators
+	can lead to circular data structures, infinite loops, or Logo crashes.
+
+MEMBERP thing1 thing2
+MEMBER? thing1 thing2
+
+	if "thing2" is a list or an array, outputs TRUE if "thing1" is EQUALP
+	to a member of "thing2", FALSE otherwise.  If "thing2" is
+	a word, outputs TRUE if "thing1" is a one-character word EQUALP to a
+	character of "thing2", FALSE otherwise.
+
+SUBSTRINGP thing1 thing2
+SUBSTRING? thing1 thing2
+
+	if "thing1" or "thing2" is a list or an array, outputs FALSE.  If
+	"thing2" is a word, outputs TRUE if "thing1" is EQUALP to a
+	substring of "thing2", FALSE otherwise.
+
+NUMBERP thing
+NUMBER? thing
+
+	outputs TRUE if the input is a number, FALSE otherwise.
+
+VBARREDP char
+VBARRED? char
+BACKSLASHEDP char                               (library procedure)
+BACKSLASHED? char                               (library procedure)
+
+	outputs TRUE if the input character was originally entered into Logo
+	within vertical bars (|) to prevent its usual special syntactic
+	meaning, FALSE otherwise.  (Outputs TRUE only if the character is a
+	backslashed space, tab, newline, or one of ()[]+-*/=<>":;\~?| )
+
+	The names BACKSLASHEDP and BACKSLASHED? are included in the Logo
+	library for backward compatibility with the former names of this
+	primitive, although it does *not* output TRUE for characters
+	originally entered with backslashes.
+
+
+QUERIES
+-------
+
+COUNT thing
+
+	outputs the number of characters in the input, if the input is a word;
+	outputs the number of members in the input, if it is a list
+	or an array.  (For an array, this may or may not be the index of the
+	last member, depending on the array's origin.)
+
+ASCII char
+
+	outputs the integer (between 0 and 255) that represents the input
+	character in the ASCII code.  Interprets control characters as
+	representing vbarred punctuation, and returns the character code
+	for the corresponding punctuation character without vertical bars.
+	(Compare RAWASCII.)
+
+RAWASCII char
+
+	outputs the integer (between 0 and 255) that represents the input
+	character in the ASCII code.  Interprets control characters as
+	representing themselves.  To find out the ASCII code of an arbitrary
+	keystroke, use RAWASCII RC.
+
+CHAR int
+
+	outputs the character represented in the ASCII code by the input,
+	which must be an integer between 0 and 255.
+
+MEMBER thing1 thing2
+
+	if "thing2" is a word or list and if MEMBERP with these inputs would
+	output TRUE, outputs the portion of "thing2" from the first instance
+	of "thing1" to the end.  If MEMBERP would output FALSE, outputs the
+	empty word or list according to the type of "thing2".  It is an error
+	for "thing2" to be an array.
+
+LOWERCASE word
+
+	outputs a copy of the input word, but with all uppercase letters
+	changed to the corresponding lowercase letter.
+
+UPPERCASE word
+
+	outputs a copy of the input word, but with all lowercase letters
+	changed to the corresponding uppercase letter.
+
+STANDOUT thing
+
+	outputs a word that, when printed, will appear like the input but
+	displayed in standout mode (boldface, reverse video, or whatever your
+	version does for standout).  The word contains machine-specific
+	magic characters at the beginning and end; in between is the printed
+	form (as if displayed using TYPE) of the input.  The output is always
+	a word, even if the input is of some other type, but it may include
+	spaces and other formatting characters.  Note: a word output by
+	STANDOUT while Logo is running on one machine will probably not have
+	the desired effect if printed on another type of machine.
+
+	In the Macintosh classic version, the way that standout works is
+	incompatible with the use of characters whose ASCII code is greater
+	than 127.  Therefore, you have a choice to make:  The instruction
+		CANINVERSE 0
+	disables standout, but enables the display of ASCII codes above 127,
+	and the instruction
+		CANINVERSE 1
+	restores the default situation in which standout is enabled and the
+	extra graphic characters cannot be printed.
+
+PARSE word
+
+	outputs the list that would result if the input word were entered
+	in response to a READLIST operation.  That is, PARSE READWORD has
+	the same value as READLIST for the same characters read.
+
+RUNPARSE wordorlist
+
+	outputs the list that would result if the input word or list were
+	entered as an instruction line; characters such as infix operators
+	and parentheses are separate members of the output.  Note that
+	sublists of a runparsed list are not themselves runparsed.
+
+
+COMMUNICATION
+=============
+
+TRANSMITTERS
+------------
+
+Note:  If there is a variable named PRINTDEPTHLIMIT with a nonnegative
+integer value, then complex list and array structures will be printed
+only to the allowed depth.  That is, members of members of... of members
+will be allowed only so far.  The members omitted because
+they are just past the depth limit are indicated by an ellipsis for each
+one, so a too-deep list of two members will print as [... ...].
+
+If there is a variable named PRINTWIDTHLIMIT with a nonnegative integer
+value, then only the first so many members of any array or
+list will be printed.  A single ellipsis replaces all missing data
+within the structure.  The width limit also applies to the number of
+characters printed in a word, except that a PRINTWIDTHLIMIT between 0 and 9
+will be treated as if it were 10 when applied to words.  This limit
+applies not only to the top-level printed datum but to any substructures
+within it.
+
+If there is a variable named FULLPRINTP whose value is TRUE, then words that
+were created using backslash or vertical bar (to include characters that
+would otherwise not be treated as part of a word) are printed with the
+backslashes or vertical bars shown, so that the printed result could be
+re-read by Logo to produce the same value.  If FULLPRINTP is TRUE then
+the empty word (however it was created) prints as ||.  (Otherwise it prints
+as nothing at all.)
+
+PRINT thing
+PR thing
+(PRINT thing1 thing2 ...)
+(PR thing1 thing2 ...)
+
+	command.  Prints the input or inputs to the current write stream
+	(initially the screen).  All the inputs are printed on a single
+	line, separated by spaces, ending with a newline.  If an input is a
+	list, square brackets are not printed around it, but brackets are
+	printed around sublists.  Braces are always printed around arrays.
+
+TYPE thing
+(TYPE thing1 thing2 ...)
+
+	command.  Prints the input or inputs like PRINT, except that no
+	newline character is printed at the end and multiple inputs are not
+	separated by spaces.  Note: printing to the terminal is ordinarily
+	"line buffered"; that is, the characters you print using TYPE will
+	not actually appear on the screen until either a newline character
+	is printed (for example, by PRINT or SHOW) or Logo tries to read
+	from the keyboard (either at the request of your program or after an
+	instruction prompt).  This buffering makes the program much faster
+	than it would be if each character appeared immediately, and in most
+	cases the effect is not disconcerting.  To accommodate programs that
+	do a lot of positioned text display using TYPE, Logo will force
+	printing whenever SETCURSOR is invoked.  This solves most buffering
+	problems.  Still, on occasion you may find it necessary to force the
+	buffered characters to be printed explicitly; this can be done using
+	the WAIT command.  WAIT 0 will force printing without actually
+	waiting.
+
+SHOW thing
+(SHOW thing1 thing2 ...)
+
+	command.  Prints the input or inputs like PRINT, except that
+	if an input is a list it is printed inside square brackets.
+
+
+RECEIVERS
+---------
+
+READLIST
+RL
+
+	reads a line from the read stream (initially the keyboard) and
+	outputs that line as a list.  The line is separated into members as
+	though it were typed in square brackets in an instruction.  If the
+	read stream is a file, and the end of file is reached, READLIST
+	outputs the empty word (not the empty list).  READLIST processes
+	backslash, vertical bar, and tilde characters in the read stream;
+	the output list will not contain these characters but they will have
+	had their usual effect.  READLIST does not, however, treat semicolon
+	as a comment character.
+
+READWORD
+RW
+
+	reads a line from the read stream and outputs that line as a word.
+	The output is a single word even if the line contains spaces,
+	brackets, etc.  If the read stream is a file, and the end of file is
+	reached, READWORD outputs the empty list (not the empty word).
+	READWORD processes backslash, vertical bar, and tilde characters in
+	the read stream.  In the case of a tilde used for line continuation,
+	the output word DOES include the tilde and the newline characters, so
+	that the user program can tell exactly what the user entered.
+	Vertical bars in the line are also preserved in the output.
+	Backslash characters are not preserved in the output.
+
+READRAWLINE
+
+	reads a line from the read stream and outputs that line as a word.
+	The output is a single word even if the line contains spaces,
+	brackets, etc.  If the read stream is a file, and the end of file is
+	reached, READRAWLINE outputs the empty list (not the empty word).
+	READRAWLINE outputs the exact string of characters as they appear
+	in the line, with no special meaning for backslash, vertical bar,
+	tilde, or any other formatting characters.
+
+READCHAR
+RC
+
+	reads a single character from the read stream and outputs that
+	character as a word.  If the read stream is a file, and the end of
+	file is reached, READCHAR outputs the empty list (not the empty
+	word).  If the read stream is the keyboard, echoing is turned off
+	when READCHAR is invoked, and remains off until READLIST or READWORD
+	is invoked or a Logo prompt is printed.  Backslash, vertical bar,
+	and tilde characters have no special meaning in this context.
+
+READCHARS num
+RCS num
+
+	reads "num" characters from the read stream and outputs those
+	characters as a word.  If the read stream is a file, and the end of
+	file is reached, READCHARS outputs the empty list (not the empty
+	word).  If the read stream is a terminal, echoing is turned off
+	when READCHARS is invoked, and remains off until READLIST or READWORD
+	is invoked or a Logo prompt is printed.  Backslash, vertical bar,
+	and tilde characters have no special meaning in this context.
+
+SHELL command
+(SHELL command wordflag)
+
+	Under Unix, outputs the result of running "command" as a shell
+	command.  (The command is sent to /bin/sh, not csh or other
+	alternatives.)  If the command is a literal list in the instruction
+	line, and if you want a backslash character sent to the shell, you
+	must use \\ to get the backslash through Logo's reader intact.  The
+	output is a list containing one member for each line generated by
+	the shell command.  Ordinarily each such line is represented by a
+	list in the output, as though the line were read using READLIST.  If
+	a second input is given, regardless of the value of the input, each
+	line is represented by a word in the output as though it were read
+	with READWORD.  Example:
+
+			to dayofweek
+			output first first shell [date]
+			end
+
+	This is "first first" to extract the first word of the first (and
+	only) line of the shell output.
+
+	Under MacOS X, SHELL works as under Unix.  SHELL is not available
+	under Mac Classic.
+
+	Under DOS, SHELL is a command, not an operation; it sends its
+	input to a DOS command processor but does not collect the result
+	of the command.
+
+	Under Windows, the wxWidgets version of Logo behaves as under Unix (except
+	that DOS-style commands are understood; use "dir" rather than "ls").
+	The non-wxWidgets version behaves like the DOS version.
+
+
+FILE ACCESS
+-----------
+
+SETPREFIX string
+
+	command.  Sets a prefix that will be used as the implicit beginning
+	of filenames in OPENREAD, OPENWRITE, OPENAPPEND, OPENUPDATE, LOAD,
+	and SAVE commands.  Logo will put the appropriate separator
+	character (slash for Unix, backslash for DOS/Windows, colon for
+	MacOS Classic) between the prefix and the filename entered by the user.
+	The input to SETPREFIX must be a word, unless it is the empty list,
+	to indicate that there should be no prefix.
+
+PREFIX
+
+	outputs the current file prefix, or [] if there is no prefix.
+	See SETPREFIX.
+
+OPENREAD filename
+
+	command.  Opens the named file for reading.  The read position is
+	initially at the beginning of the file.
+
+OPENWRITE filename
+
+	command.  Opens the named file for writing.  If the file already
+	existed, the old version is deleted and a new, empty file created.
+
+	OPENWRITE, but not the other OPEN variants, will accept as input
+	a two-element list, in which the first element must be a variable
+	name, and the second must be a positive integer.  A character
+	buffer of the specified size will be created.  When a SETWRITE is
+	done with this same list (in the sense of .EQ, not a copy, so
+	you must do something like
+		? make "buf [foo 100]
+		? openwrite :buf
+		? setwrite :buf
+		    [...]
+		? close :buf
+	and not just
+		? openwrite [foo 100]
+		? setwrite [foo 100]
+	and so on), the printed characters are stored in the buffer;
+	when a CLOSE is done with the same list as input, the characters
+	from the buffer (treated as one long word, even if spaces and
+	newlines are included) become the value of the specified variable.
+
+OPENAPPEND filename
+
+	command.  Opens the named file for writing.  If the file already
+	exists, the write position is initially set to the end of the old
+	file, so that newly written data will be appended to it.
+
+OPENUPDATE filename
+
+	command.  Opens the named file for reading and writing.  The read and
+	write position is initially set to the end of the old file, if any.
+	Note: each open file has only one position, for both reading and
+	writing.  If a file opened for update is both READER and WRITER at
+	the same time, then SETREADPOS will also affect WRITEPOS and vice
+	versa.  Also, if you alternate reading and writing the same file,
+	you must SETREADPOS between a write and a read, and SETWRITEPOS
+	between a read and a write.
+
+CLOSE filename
+
+	command.  Closes the named file.  If the file was currently the
+	reader or writer, then the reader or writer is changed to the
+	keyboard or screen, as if SETREAD [] or SETWRITE [] had been done.
+
+ALLOPEN
+
+	outputs a list whose members are the names of all files currently open.
+	This list does not include the dribble file, if any.
+
+CLOSEALL						(library procedure)
+
+	command.  Closes all open files.  Abbreviates
+	FOREACH ALLOPEN [CLOSE ?]
+
+ERASEFILE filename
+ERF filename
+
+	command.  Erases (deletes, removes) the named file, which should not
+	currently be open.
+
+DRIBBLE filename
+
+	command.  Creates a new file whose name is the input, like OPENWRITE,
+	and begins recording in that file everything that is read from the
+	keyboard or written to the terminal.  That is, this writing is in
+	addition to the writing to WRITER.  The intent is to create a
+	transcript of a Logo session, including things like prompt
+	characters and interactions.
+
+NODRIBBLE
+
+	command.  Stops copying information into the dribble file, and
+	closes the file.
+
+SETREAD filename
+
+	command.  Makes the named file the read stream, used for READLIST,
+	etc.  The file must already be open with OPENREAD or OPENUPDATE.  If
+	the input is the empty list, then the read stream becomes the
+	keyboard, as usual.  Changing the read stream does not close the
+	file that was previously the read stream, so it is possible to
+	alternate between files.
+
+SETWRITE filename
+
+	command.  Makes the named file the write stream, used for PRINT,
+	etc.  The file must already be open with OPENWRITE, OPENAPPEND, or
+	OPENUPDATE.  If the input is the empty list, then the write stream
+	becomes the screen, as usual.  Changing the write stream does
+	not close the file that was previously the write stream, so it is
+	possible to alternate between files.
+
+	If the input is a list, then its first element must be a variable
+	name, and its second and last element must be a positive integer; a
+	buffer of that many characters will be allocated, and will become the
+	writestream.  If the same list (same in the .EQ sense, not a copy)
+	has been used as input to OPENWRITE, then the already-allocated
+	buffer will be used, and the writer can be changed to and from this
+	buffer, with all the characters accumulated as in a file.  When the
+	same list is used as input to CLOSE, the contents of the buffer
+	(as an unparsed word, which may contain newline characters) will
+	become the value of the named variable.  For compatibility with
+	earlier versions, if the list has not been opened when the SETWRITE
+	is done, it will be opened implicitly, but the first SETWRITE after
+	this one will implicitly close it, setting the variable and freeing
+	the allocated buffer.
+
+READER
+
+	outputs the name of the current read stream file, or the empty list
+	if the read stream is the terminal.
+
+WRITER
+
+	outputs the name of the current write stream file, or the empty list
+	if the write stream is the screen.
+
+SETREADPOS charpos
+
+	command.  Sets the file pointer of the read stream file so that the
+	next READLIST, etc., will begin reading at the "charpos"th character
+	in the file, counting from 0.  (That is, SETREADPOS 0 will start
+	reading from the beginning of the file.)  Meaningless if the read
+	stream is the screen.
+
+SETWRITEPOS charpos
+
+	command.  Sets the file pointer of the write stream file so that the
+	next PRINT, etc., will begin writing at the "charpos"th character
+	in the file, counting from 0.  (That is, SETWRITEPOS 0 will start
+	writing from the beginning of the file.)  Meaningless if the write
+	stream is the screen.
+
+READPOS
+
+	outputs the file position of the current read stream file.
+
+WRITEPOS
+
+	outputs the file position of the current write stream file.
+
+EOFP
+EOF?
+
+	predicate, outputs TRUE if there are no more characters to be
+	read in the read stream file, FALSE otherwise.
+
+FILEP filename
+FILE? filename						(library procedure)
+
+	predicate, outputs TRUE if a file of the specified name exists
+	and can be read, FALSE otherwise.
+
+
+TERMINAL ACCESS
+---------------
+
+KEYP
+KEY?
+
+	predicate, outputs TRUE if there are characters waiting to be
+	read from the read stream.  If the read stream is a file, this
+	is equivalent to NOT EOFP.  If the read stream is the terminal,
+	then echoing is turned off and the terminal is set to CBREAK
+	(character at a time instead of line at a time) mode.  It
+	remains in this mode until some line-mode reading is requested
+	(e.g., READLIST).  The Unix operating system forgets about any
+	pending characters when it switches modes, so the first KEYP
+	invocation will always output FALSE.
+
+CLEARTEXT
+CT
+
+	command.  Clears the text window.
+
+SETCURSOR vector
+
+	command.  The input is a list of two numbers, the x and y
+	coordinates of a text window position (origin in the upper left
+	corner, positive direction is southeast).  The text cursor
+	is moved to the requested position.  This command also forces
+	the immediate printing of any buffered characters.
+
+CURSOR
+
+	outputs a list containing the current x and y coordinates of
+	the text cursor.  Logo may get confused about the current
+	cursor position if, e.g., you type in a long line that wraps
+	around or your program prints escape codes that affect the
+	screen strangely.
+
+SETMARGINS vector
+
+	command.  The input must be a list of two numbers, as for
+	SETCURSOR.  The effect is to clear the screen and then arrange for
+	all further printing to be shifted down and to the right according
+	to the indicated margins.  Specifically, every time a newline
+	character is printed (explicitly or implicitly) Logo will type
+	x_margin spaces, and on every invocation of SETCURSOR the margins
+	will be added to the input x and y coordinates.  (CURSOR will report
+	the cursor position relative to the margins, so that this shift will
+	be invisible to Logo programs.)  The purpose of this command is to
+	accommodate the display of terminal screens in lecture halls with
+	inadequate TV monitors that miss the top and left edges of the
+	screen.
+
+SETTEXTCOLOR foreground background
+SETTC foreground background
+
+	command (wxWidgets only).  The inputs are color numbers, or RGB color
+	lists, as for turtle graphics.  The foreground and background colors
+	for the textscreen/splitscreen text window are changed to the given
+	values.  The change affects text already printed as well as future
+	text printing; there is only one text color for the entire window.
+
+	command (non-wxWidgets Windows and DOS extended only).  The inputs are
+	color numbers, as for turtle graphics.  Future printing to the text
+	window will use the specified colors for foreground (the characters
+	printed) and background (the space under those characters).  Using
+	STANDOUT will revert to the default text window colors.  In the DOS
+	extended (ucblogo.exe) version, colors in textscreen mode are limited
+	to numbers 0-7, and the coloring applies only to text printed by the
+	program, not to the echoing of text typed by the user.  Neither
+	limitation applies to the text portion of splitscreen mode, which is
+	actually drawn as graphics internally.
+
+INCREASEFONT
+DECREASEFONT
+
+	command (wxWidgets only).  Increase or decrease the size of the font
+	used in the text and edit windows to the next larger or smaller
+	available size.
+
+SETTEXTSIZE height
+
+	command (wxWidgets only).  Set the "point size" of the font used in
+	the text and edit windows to the given integer input.  The desired
+	size may not be available, in which case the nearest available size
+	will be used.  Note: There is only a slight correlation between these
+	integers and pixel sizes.  Our rough estimate is that the number of
+	pixels of height is about 1.5 times the point size, but it varies for
+	different fonts.  See SETLABELHEIGHT for a different approach used for
+	the graphics window.
+
+TEXTSIZE
+
+	(wxWidgets only) outputs the "point size" of the font used in the text
+	and edit windows.  See SETTEXTSIZE for a discussion of font sizing.
+	See LABELSIZE for a different approach used for the graphics window.
+
+SETFONT fontname
+
+	command (wxWidgets only).  Set the font family used in all windows
+	to the one named by the input.  Try 'Courier' or 'Monospace' as likely
+	possibilities.  Not all computers have the same fonts installed.  It's
+	a good idea to stick with monospace fonts (ones in which all
+	characters have the same width).
+
+SETTEXTFONT fontname
+
+	command (wxWidgets only).  Set the font family used in the text window
+	to the one named by the input.  Try 'Courier' or 'Monospace' as likely
+	possibilities.  Not all computers have the same fonts installed.  It's
+	a good idea to stick with monospace fonts (ones in which all
+	characters have the same width).
+
+
+FONT
+
+	(wxWidgets only) outputs the name of the font family used in all
+	windows.
+
+
+ARITHMETIC
+==========
+
+NUMERIC OPERATIONS
+------------------
+
+SUM num1 num2
+(SUM num1 num2 num3 ...)
+num1 + num2
+
+	outputs the sum of its inputs.
+
+DIFFERENCE num1 num2
+num1 - num2
+
+	outputs the difference of its inputs.  Minus sign means infix
+	difference in ambiguous contexts (when preceded by a complete
+	expression), unless it is preceded by a space and followed
+	by a nonspace.  (See also MINUS.)
+
+MINUS num
+- num
+
+	outputs the negative of its input.  Minus sign means unary minus if
+	the previous token is an infix operator or open parenthesis, or it is
+	preceded by a space and followed by a nonspace.  There is a difference
+	in binding strength between the two forms:
+
+		MINUS 3 + 4	means	-(3+4)
+		- 3 + 4		means	(-3)+4
+
+PRODUCT num1 num2
+(PRODUCT num1 num2 num3 ...)
+num1 * num2
+
+	outputs the product of its inputs.
+
+QUOTIENT num1 num2
+(QUOTIENT num)
+num1 / num2
+
+	outputs the quotient of its inputs.  The quotient of two integers
+	is an integer if and only if the dividend is a multiple of the divisor.
+	(In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is
+	2, not 2.0 -- it does the right thing.)  With a single input,
+	QUOTIENT outputs the reciprocal of the input.
+
+REMAINDER num1 num2
+
+	outputs the remainder on dividing "num1" by "num2"; both must be
+	integers and the result is an integer with the same sign as num1.
+
+MODULO num1 num2
+
+	outputs the remainder on dividing "num1" by "num2"; both must be
+	integers and the result is an integer with the same sign as num2.
+
+INT num
+
+	outputs its input with fractional part removed, i.e., an integer
+	with the same sign as the input, whose absolute value is the
+	largest integer less than or equal to the absolute value of
+	the input.
+
+ROUND num
+
+	outputs the nearest integer to the input.
+
+SQRT num
+
+	outputs the square root of the input, which must be nonnegative.
+
+POWER num1 num2
+
+	outputs "num1" to the "num2" power.  If num1 is negative, then
+	num2 must be an integer.
+
+EXP num
+
+	outputs e (2.718281828+) to the input power.
+
+LOG10 num
+
+	outputs the common logarithm of the input.
+
+LN num
+
+	outputs the natural logarithm of the input.
+
+SIN degrees
+
+	outputs the sine of its input, which is taken in degrees.
+
+RADSIN radians
+
+	outputs the sine of its input, which is taken in radians.
+
+COS degrees
+
+	outputs the cosine of its input, which is taken in degrees.
+
+RADCOS radians
+
+	outputs the cosine of its input, which is taken in radians.
+
+ARCTAN num
+(ARCTAN x y)
+
+	outputs the arctangent, in degrees, of its input.  With two
+	inputs, outputs the arctangent of y/x, if x is nonzero, or
+	90 or -90 depending on the sign of y, if x is zero.
+
+RADARCTAN num
+(RADARCTAN x y)
+
+	outputs the arctangent, in radians, of its input.  With two
+	inputs, outputs the arctangent of y/x, if x is nonzero, or
+	pi/2 or -pi/2 depending on the sign of y, if x is zero.
+
+	The expression 2*(RADARCTAN 0 1) can be used to get the
+	value of pi.
+
+ISEQ from to						(library procedure)
+
+	outputs a list of the integers from FROM to TO, inclusive.
+
+		? show iseq 3 7
+		[3 4 5 6 7]
+		? show iseq 7 3
+		[7 6 5 4 3]
+
+RSEQ from to count					(library procedure)
+
+	outputs a list of COUNT equally spaced rational numbers
+	between FROM and TO, inclusive.
+
+		? show rseq 3 5 9
+		[3 3.25 3.5 3.75 4 4.25 4.5 4.75 5]
+		? show rseq 3 5 5
+		[3 3.5 4 4.5 5]
+
+
+PREDICATES
+----------
+
+LESSP num1 num2
+LESS? num1 num2
+num1 < num2
+
+	outputs TRUE if its first input is strictly less than its second.
+
+GREATERP num1 num2
+GREATER? num1 num2
+num1 > num2
+
+	outputs TRUE if its first input is strictly greater than its second.
+
+LESSEQUALP num1 num2
+LESSEQUAL? num1 num2
+num1 <= num2
+
+	outputs TRUE if its first input is less than or equal to its second.
+
+GREATEREQUALP num1 num2
+GREATEREQUAL? num1 num2
+num1 >= num2
+
+	outputs TRUE if its first input is greater than or equal to its second.
+
+
+RANDOM NUMBERS
+--------------
+RANDOM num
+(RANDOM start end)
+
+	with one input, outputs a random nonnegative integer less than its
+	input, which must be a positive integer.
+
+	With two inputs, RANDOM outputs a random integer greater than or
+	equal to the first input, and less than or equal to the second
+	input.  Both inputs must be integers, and the first must be less
+	than the second.  (RANDOM 0 9) is equivalent to RANDOM 10;
+	(RANDOM 3 8) is equivalent to (RANDOM 6)+3.
+
+RERANDOM
+(RERANDOM seed)
+
+	command.  Makes the results of RANDOM reproducible.  Ordinarily
+	the sequence of random numbers is different each time Logo is
+	used.  If you need the same sequence of pseudo-random numbers
+	repeatedly, e.g. to debug a program, say RERANDOM before the
+	first invocation of RANDOM.  If you need more than one repeatable
+	sequence, you can give RERANDOM an integer input; each possible
+	input selects a unique sequence of numbers.
+
+
+PRINT FORMATTING
+----------------
+
+FORM num width precision
+
+	outputs a word containing a printable representation of "num",
+	possibly preceded by spaces (and therefore not a number for
+	purposes of performing arithmetic operations), with at least
+	"width" characters, including exactly "precision" digits after
+	the decimal point.  (If "precision" is 0 then there will be no
+	decimal point in the output.)
+
+	As a debugging feature, (FORM num -1 format) will print the
+	floating point "num" according to the C printf "format", to allow
+
+		to hex :num
+		op form :num -1 "|%08X %08X|
+		end
+
+	to allow finding out the exact result of floating point operations.
+	The precise format needed may be machine-dependent.
+
+
+BITWISE OPERATIONS
+------------------
+
+BITAND num1 num2
+(BITAND num1 num2 num3 ...)
+
+	outputs the bitwise AND of its inputs, which must be integers.
+
+BITOR num1 num2
+(BITOR num1 num2 num3 ...)
+
+	outputs the bitwise OR of its inputs, which must be integers.
+
+BITXOR num1 num2
+(BITXOR num1 num2 num3 ...)
+
+	outputs the bitwise EXCLUSIVE OR of its inputs, which must be
+	integers.
+
+BITNOT num
+
+	outputs the bitwise NOT of its input, which must be an integer.
+
+ASHIFT num1 num2
+
+	outputs "num1" arithmetic-shifted to the left by "num2" bits.
+	If num2 is negative, the shift is to the right with sign
+	extension.  The inputs must be integers.
+
+LSHIFT num1 num2
+
+	outputs "num1" logical-shifted to the left by "num2" bits.
+	If num2 is negative, the shift is to the right with zero fill.
+	The inputs must be integers.
+
+
+LOGICAL OPERATIONS
+==================
+
+AND tf1 tf2
+(AND tf1 tf2 tf3 ...)
+
+	outputs TRUE if all inputs are TRUE, otherwise FALSE.  All inputs
+	must be TRUE or FALSE.  (Comparison is case-insensitive regardless
+	of the value of CASEIGNOREDP.  That is, "true" or "True" or "TRUE"
+	are all the same.)  An input can be a list, in which case it is
+	taken as an expression to run; that expression must produce a TRUE
+	or FALSE value.  List expressions are evaluated from left to right;
+	as soon as a FALSE value is found, the remaining inputs are not
+	examined.  Example:
+		MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5]
+	to avoid the division by zero if the first part is false.
+
+OR tf1 tf2
+(OR tf1 tf2 tf3 ...)
+
+	outputs TRUE if any input is TRUE, otherwise FALSE.  All inputs
+	must be TRUE or FALSE.  (Comparison is case-insensitive regardless
+	of the value of CASEIGNOREDP.  That is, "true" or "True" or "TRUE"
+	are all the same.)  An input can be a list, in which case it is
+	taken as an expression to run; that expression must produce a TRUE
+	or FALSE value.  List expressions are evaluated from left to right;
+	as soon as a TRUE value is found, the remaining inputs are not
+	examined.  Example:
+		IF OR :X=0 [some.long.computation] [...]
+	to avoid the long computation if the first condition is met.
+
+NOT tf
+
+	outputs TRUE if the input is FALSE, and vice versa.  The input can be
+	a list, in which case it is taken as an expression to run; that
+	expression must produce a TRUE or FALSE value.
+
+
+GRAPHICS
+========
+
+Berkeley Logo provides traditional Logo turtle graphics with one turtle.
+Multiple turtles, dynamic turtles, and collision detection are not supported.
+This is the most hardware-dependent part of Logo; some features may exist
+on some machines but not others.  Nevertheless, the goal has been to make
+Logo programs as portable as possible, rather than to take fullest advantage
+of the capabilities of each machine.  In particular, Logo attempts to scale
+the screen so that turtle coordinates [-100 -100] and [100 100] fit on the
+graphics window, and so that the aspect ratio is 1:1.
+
+The center of the graphics window (which may or may not be the entire
+screen, depending on the machine used) is turtle location [0 0].  Positive
+X is to the right; positive Y is up.  Headings (angles) are measured in
+degrees clockwise from the positive Y axis.  (This differs from the common
+mathematical convention of measuring angles counterclockwise from the
+positive X axis.)  The turtle is represented as an isoceles triangle; the
+actual turtle position is at the midpoint of the base (the short side).
+However, the turtle is drawn one step behind its actual position, so that
+the display of the base of the turtle's triangle does not obscure a line
+drawn perpendicular to it (as would happen after drawing a square).
+
+Colors are, of course, hardware-dependent.  However, Logo provides partial
+hardware independence by interpreting color numbers 0 through 7 uniformly
+on all computers:
+
+	0  black	1  blue		2  green	3  cyan
+	4  red		5  magenta	6  yellow	7 white
+
+Where possible, Logo provides additional user-settable colors; how many
+are available depends on the hardware and operating system environment.
+If at least 16 colors are available, Logo tries to provide uniform
+initial settings for the colors 8-15:
+
+	 8  brown	 9  tan		10  forest	11  aqua
+	12  salmon	13  purple	14  orange	15  grey
+
+Logo begins with a black background and white pen.
+
+
+TURTLE MOTION
+-------------
+
+FORWARD dist
+FD dist
+
+	moves the turtle forward, in the direction that it's facing, by
+	the specified distance (measured in turtle steps).
+
+BACK dist
+BK dist
+
+	moves the turtle backward, i.e., exactly opposite to the direction
+	that it's facing, by the specified distance.  (The heading of the
+	turtle does not change.)
+
+LEFT degrees
+LT degrees
+
+	turns the turtle counterclockwise by the specified angle, measured
+	in degrees (1/360 of a circle).
+
+RIGHT degrees
+RT degrees
+
+	turns the turtle clockwise by the specified angle, measured in
+	degrees (1/360 of a circle).
+
+SETPOS pos
+
+	moves the turtle to an absolute position in the graphics window.  The
+	input is a list of two numbers, the X and Y coordinates.
+
+SETXY xcor ycor
+
+	moves the turtle to an absolute position in the graphics window.  The
+	two inputs are numbers, the X and Y coordinates.
+
+SETX xcor
+
+	moves the turtle horizontally from its old position to a new
+	absolute horizontal coordinate.  The input is the new X
+	coordinate.
+
+SETY ycor
+
+	moves the turtle vertically from its old position to a new
+	absolute vertical coordinate.  The input is the new Y
+	coordinate.
+
+SETHEADING degrees
+SETH degrees
+
+	turns the turtle to a new absolute heading.  The input is
+	a number, the heading in degrees clockwise from the positive
+	Y axis.
+
+HOME
+
+	moves the turtle to the center of the screen.  Equivalent to
+	SETPOS [0 0] SETHEADING 0.
+
+ARC angle radius
+
+	draws an arc of a circle, with the turtle at the center, with the
+	specified radius, starting at the turtle's heading and extending
+	clockwise through the specified angle.  The turtle does not move.
+
+TURTLE MOTION QUERIES
+---------------------
+
+POS
+
+	outputs the turtle's current position, as a list of two
+	numbers, the X and Y coordinates.
+
+XCOR							(library procedure)
+
+	outputs a number, the turtle's X coordinate.
+
+YCOR							(library procedure)
+
+	outputs a number, the turtle's Y coordinate.
+
+HEADING
+
+	outputs a number, the turtle's heading in degrees.
+
+TOWARDS pos
+
+	outputs a number, the heading at which the turtle should be
+	facing so that it would point from its current position to
+	the position given as the input.
+
+SCRUNCH
+
+	outputs a list containing two numbers, the X and Y scrunch
+	factors, as used by SETSCRUNCH.  (But note that SETSCRUNCH
+	takes two numbers as inputs, not one list of numbers.)
+
+
+TURTLE AND WINDOW CONTROL
+-------------------------
+
+SHOWTURTLE
+ST
+
+	makes the turtle visible.
+
+HIDETURTLE
+HT
+
+	makes the turtle invisible.  It's a good idea to do this while
+	you're in the middle of a complicated drawing, because hiding
+	the turtle speeds up the drawing substantially.
+
+CLEAN
+
+	erases all lines that the turtle has drawn on the graphics window.
+	The turtle's state (position, heading, pen mode, etc.) is not
+	changed.
+
+CLEARSCREEN
+CS
+
+	erases the graphics window and sends the turtle to its initial
+	position and heading.  Like HOME and CLEAN together.
+
+WRAP
+
+	tells the turtle to enter wrap mode:  From now on, if the turtle
+	is asked to move past the boundary of the graphics window, it
+	will "wrap around" and reappear at the opposite edge of the
+	window.  The top edge wraps to the bottom edge, while the left
+	edge wraps to the right edge.  (So the window is topologically
+	equivalent to a torus.)  This is the turtle's initial mode.
+	Compare WINDOW and FENCE.
+
+WINDOW
+
+	tells the turtle to enter window mode:  From now on, if the turtle
+	is asked to move past the boundary of the graphics window, it
+	will move offscreen.  The visible graphics window is considered
+	as just part of an infinite graphics plane; the turtle can be
+	anywhere on the plane.  (If you lose the turtle, HOME will bring
+	it back to the center of the window.)  Compare WRAP and FENCE.
+
+FENCE
+
+	tells the turtle to enter fence mode:  From now on, if the turtle
+	is asked to move past the boundary of the graphics window, it
+	will move as far as it can and then stop at the edge with an
+	"out of bounds" error message.  Compare WRAP and WINDOW.
+
+FILL
+
+	fills in a region of the graphics window containing the turtle
+	and bounded by lines that have been drawn earlier.  This is not
+	portable; it doesn't work for all machines, and may not work
+	exactly the same way on different machines.
+
+FILLED color instructions
+
+	runs the instructions, remembering all points visited by turtle
+	motion commands, starting *and ending* with the turtle's initial
+	position.  Then draws (ignoring penmode) the resulting polygon,
+	in the current pen color, filling the polygon with the given color,
+	which can be a color number or an RGB list.  The instruction list
+	cannot include another FILLED invocation.
+
+LABEL text
+
+	takes a word or list as input, and prints the input on the
+	graphics window, starting at the turtle's position.
+
+SETLABELHEIGHT height
+
+	command (wxWidgets only).  Takes a positive integer argument and tries
+	to set the font size so that the character height (including
+	descenders) is that many turtle steps.  This will be different from
+	the number of screen pixels if SETSCRUNCH has been used.  Also, note
+	that SETSCRUNCH changes the font size to try to preserve this height
+	in turtle steps.  Note that the query operation corresponding to this
+	command is LABELSIZE, not LABELHEIGHT, because it tells you the width
+	as well as the height of characters in the current font.
+
+TEXTSCREEN
+TS
+
+	rearranges the size and position of windows to maximize the
+	space available in the text window (the window used for
+	interaction with Logo).  The details differ among machines.
+	Compare SPLITSCREEN and FULLSCREEN.
+
+FULLSCREEN
+FS
+
+	rearranges the size and position of windows to maximize the space
+	available in the graphics window.  The details differ among machines.
+	Compare SPLITSCREEN and TEXTSCREEN.
+
+	Since there must be a text window to allow printing (including the
+	printing of the Logo prompt), Logo automatically switches from
+	fullscreen to splitscreen whenever anything is printed.
+
+	In the DOS version, switching from fullscreen to splitscreen loses the
+	part of the picture that's hidden by the text window.  [This design
+	decision follows from the scarcity of memory, so that the extra memory
+	to remember an invisible part of a drawing seems too expensive.]
+
+SPLITSCREEN
+SS
+
+	rearranges the size and position of windows to allow some room for
+	text interaction while also keeping most of the graphics window
+	visible.  The details differ among machines.  Compare TEXTSCREEN
+	and FULLSCREEN.
+
+SETSCRUNCH xscale yscale
+
+	adjusts the aspect ratio and scaling of the graphics display.
+	After this command is used, all further turtle motion will be
+	adjusted by multiplying the horizontal and vertical extent of
+	the motion by the two numbers given as inputs.  For example,
+	after the instruction "SETSCRUNCH 2 1" motion at a heading of
+	45 degrees will move twice as far horizontally as vertically.
+	If your squares don't come out square, try this.  (Alternatively,
+	you can deliberately misadjust the aspect ratio to draw an ellipse.)
+
+	In wxWidgets only, SETSCRUNCH also changes the size of the text font
+	used for the LABEL command to try to keep the height of characters
+	scaled with the vertical turtle step size.
+
+	For all modern computers For DOS machines, the scale factors are
+	initially set according to what the hardware claims the aspect ratio
+	is, but the hardware sometimes lies.  For DOS, the values set by
+	SETSCRUNCH are remembered in a file (called SCRUNCH.DAT) and are
+	automatically put into effect when a Logo session begins.
+
+REFRESH
+
+	(command) tells Logo to remember the turtle's motions so that they
+	can be used for high-resolution printing (wxWidgets) or to refresh
+	the graphics window if it is moved, resized, or overlayed
+	(non-wxWidgets).  This is the default.
+
+NOREFRESH
+
+	(command) tells Logo not to remember the turtle's motions, which may
+	be useful to save time and memory if your program is interactive or
+	animated, rather than drawing a static picture you'll want to print
+	later (wxWidgets).  In non-wxWidgets versions, using NOREFRESH may
+	prevent Logo from restoring the graphics image after the window is
+	moved, resized, or overlayed.
+
+
+TURTLE AND WINDOW QUERIES
+-------------------------
+
+SHOWNP
+SHOWN?
+
+	outputs TRUE if the turtle is shown (visible), FALSE if the
+	turtle is hidden.  See SHOWTURTLE and HIDETURTLE.
+
+SCREENMODE
+
+	outputs the word TEXTSCREEN, SPLITSCREEN, or FULLSCREEN depending
+	on the current screen mode.
+
+TURTLEMODE
+
+	outputs the word WRAP, FENCE, or WINDOW depending on the current
+	turtle mode.
+
+LABELSIZE
+
+	(wxWidgets only) outputs a list of two positive integers, the width
+	and height of characters displayed by LABEL measured in turtle steps
+	(which will be different from screen pixels if SETSCRUNCH has been
+	used).  There is no SETLABELSIZE because the width and height of a
+	font are not separately controllable, so the inverse of this operation
+	is SETLABELHEIGHT, which takes just one number for the desired height.
+
+
+PEN AND BACKGROUND CONTROL
+--------------------------
+
+The turtle carries a pen that can draw pictures.  At any time the pen
+can be UP (in which case moving the turtle does not change what's on the
+graphics screen) or DOWN (in which case the turtle leaves a trace).
+If the pen is down, it can operate in one of three modes: PAINT (so that it
+draws lines when the turtle moves), ERASE (so that it erases any lines
+that might have been drawn on or through that path earlier), or REVERSE
+(so that it inverts the status of each point along the turtle's path).
+
+PENDOWN
+PD
+
+	sets the pen's position to DOWN, without changing its mode.
+
+PENUP
+PU
+
+	sets the pen's position to UP, without changing its mode.
+
+PENPAINT
+PPT
+
+	sets the pen's position to DOWN and mode to PAINT.
+
+PENERASE
+PE
+
+	sets the pen's position to DOWN and mode to ERASE.
+
+PENREVERSE
+PX
+
+	sets the pen's position to DOWN and mode to REVERSE.
+	(This may interact in system-dependent ways with use of color.)
+
+SETPENCOLOR colornumber.or.rgblist
+SETPC colornumber.or.rgblist
+
+	sets the pen color to the given number, which must be a nonnegative
+	integer.  There are initial assignments for the first 16 colors:
+
+	 0  black	 1  blue	 2  green	 3  cyan
+	 4  red		 5  magenta	 6  yellow	 7 white
+	 8  brown	 9  tan		10  forest	11  aqua
+	12  salmon	13  purple	14  orange	15  grey
+
+	but other colors can be assigned to numbers by the PALETTE command.
+	Alternatively, sets the pen color to the given RGB values (a list of
+	three nonnegative numbers less than 100 specifying the percent
+	saturation of red, green, and blue in the desired color).
+
+SETPALETTE colornumber rgblist
+
+	sets the actual color corresponding to a given number, if allowed by
+	the hardware and operating system.  Colornumber must be an integer
+	greater than or equal to 8.  (Logo tries to keep the first 8 colors
+	constant.)  The second input is a list of three nonnegative numbers
+	less than 100 specifying the percent saturation of red, green, and
+	blue in the desired color.
+
+SETPENSIZE size
+
+	sets the thickness of the pen.  The input is either a single positive
+	integer or a list of two positive integers (for horizontal and
+	vertical thickness).  Some versions pay no attention to the second
+	number, but always have a square pen.
+
+SETPENPATTERN pattern
+
+	sets hardware-dependent pen characteristics.  This command is
+	not guaranteed compatible between implementations on different
+	machines.
+
+SETPEN list						(library procedure)
+
+	sets the pen's position, mode, thickness, and hardware-dependent
+	characteristics according to the information in the input list, which
+	should be taken from an earlier invocation of PEN.
+
+SETBACKGROUND colornumber.or.rgblist
+SETBG colornumber.or.rgblist
+
+	set the screen background color by slot number or RGB values.
+	See SETPENCOLOR for details.
+
+
+PEN QUERIES
+-----------
+
+PENDOWNP
+PENDOWN?
+
+	outputs TRUE if the pen is down, FALSE if it's up.
+
+PENMODE
+
+	outputs one of the words PAINT, ERASE, or REVERSE according to
+	the current pen mode.
+
+PENCOLOR
+PC
+
+	outputs a color number, a nonnegative integer that is associated with
+	a particular color, or a list of RGB values if such a list was used as
+	the most recent input to SETPENCOLOR.  There are initial assignments
+	for the first 16 colors:
+
+	 0  black	 1  blue	 2  green	 3  cyan
+	 4  red		 5  magenta	 6  yellow	 7 white
+	 8  brown	 9  tan		10  forest	11  aqua
+	12  salmon	13  purple	14  orange	15  grey
+
+	but other colors can be assigned to numbers by the PALETTE command.
+
+PALETTE colornumber
+
+	outputs a list of three nonnegative numbers less than 100 specifying
+	the percent saturation of red, green, and blue in the color associated
+	with the given number.
+
+PENSIZE
+
+
+	outputs a list of two positive integers, specifying the horizontal
+	and vertical thickness of the turtle pen.  (In some implementations,
+	including wxWidgets, the two numbers are always equal.)
+
+PENPATTERN
+
+	outputs system-specific pen information.
+
+PEN							(library procedure)
+
+	outputs a list containing the pen's position, mode, thickness, and
+	hardware-specific characteristics, for use by SETPEN.
+
+BACKGROUND
+BG
+
+	outputs the graphics background color, either as a slot number or
+	as an RGB list, whichever way it was set.  (See PENCOLOR.)
+
+
+SAVING AND LOADING PICTURES
+---------------------------
+
+SAVEPICT filename
+
+	command.  Writes a file with the specified name containing the
+	state of the graphics window, including any nonstandard color
+	palette settings, in Logo's internal format.  This picture can
+	be restored to the screen using LOADPICT.  The format is not
+	portable between platforms, nor is it readable by other programs.
+	See EPSPICT to export Logo graphics for other programs.
+
+LOADPICT filename
+
+	command.  Reads the specified file, which must have been
+	written by a SAVEPICT command, and restores the graphics
+	window and color palette settings to the values stored in
+	the file.  Any drawing previously on the screen is cleared.
+
+EPSPICT filename
+
+	command.  Writes a file with the specified name, containing
+	an Encapsulated Postscript (EPS) representation of the state
+	of the graphics window.  This file can be imported into other
+	programs that understand EPS format.  Restrictions: the
+	drawing cannot use FILL, PENERASE, or PENREVERSE; any
+	such instructions will be ignored in the translation to
+	Postscript form.
+
+
+MOUSE QUERIES
+-------------
+
+
+MOUSEPOS
+
+	outputs the coordinates of the mouse, provided that it's within the
+	graphics window, in turtle coordinates.  If the mouse is outside the
+	graphics window, then the last position within the window is returned.
+	Exception:  If a mouse button is pressed within the graphics window
+	and held while the mouse is dragged outside the window, the mouse's
+	position is returned as if the window were big enough to include it.
+
+CLICKPOS
+
+	outputs the coordinates that the mouse was at when a mouse button
+	was most recently pushed, provided that that position was within the
+	graphics window, in turtle coordinates.  (wxWidgets only)
+
+BUTTONP
+BUTTON?
+
+	outputs TRUE if a mouse button is down and the mouse is over the
+	graphics window.  Once the button is down, BUTTONP remains true until
+	the button is released, even if the mouse is dragged out of the
+	graphics window.
+
+BUTTON
+
+	outputs 0 if no mouse button has been pushed inside the Logo window
+	since the last call to BUTTON.  Otherwise, it outputs an integer
+	between 1 and 3 indicating which button was most recently pressed.
+	Ordinarily 1 means left, 2 means right, and 3 means center, but
+	operating systems may reconfigure these.
+
+
+
+WORKSPACE MANAGEMENT
+====================
+
+PROCEDURE DEFINITION
+--------------------
+
+TO procname :input1 :input2 ...				(special form)
+
+	command.  Prepares Logo to accept a procedure definition.  The
+	procedure will be named "procname" and there must not already
+	be a procedure by that name.  The inputs will be called "input1"
+	etc.  Any number of inputs are allowed, including none.  Names
+	of procedures and inputs are case-insensitive.
+
+	Unlike every other Logo procedure, TO takes as its inputs the
+	actual words typed in the instruction line, as if they were
+	all quoted, rather than the results of evaluating expressions
+	to provide the inputs.  (That's what "special form" means.)
+
+	This version of Logo allows variable numbers of inputs to a
+	procedure.  After the procedure name come four kinds of
+	things, *in this order*:
+
+	    1.   0 or more REQUIRED inputs    :FOO :FROBOZZ
+	    2.   0 or more OPTIONAL inputs    [:BAZ 87] [:THINGO 5+9]
+	    3.   0 or 1 REST input            [:GARPLY]
+	    4.   0 or 1 DEFAULT number        5
+
+	Every procedure has a MINIMUM, DEFAULT, and MAXIMUM
+	number of inputs.  (The latter can be infinite.)
+
+	The MINIMUM number of inputs is the number of required inputs,
+	which must come first.  A required input is indicated by the
+
+			:inputname
+
+	notation.
+
+	After all the required inputs can be zero or more optional inputs,
+	each of which is represented by the following notation:
+
+			[:inputname default.value.expression]
+
+	When the procedure is invoked, if actual inputs are not supplied
+	for these optional inputs, the default value expressions are
+	evaluated to set values for the corresponding input names.  The
+	inputs are processed from left to right, so a default value
+	expression can be based on earlier inputs.  Example:
+
+			to proc :inlist [:startvalue first :inlist]
+
+	If the procedure is invoked by saying
+
+			proc [a b c]
+
+	then the variable INLIST will have the value [A B C] and the
+	variable STARTVALUE will have the value A.  If the procedure
+	is invoked by saying
+
+			(proc [a b c] "x)
+
+	then INLIST will have the value [A B C] and STARTVALUE will
+	have the value X.
+
+	After all the required and optional input can come a single "rest"
+	input, represented by the following notation:
+
+			[:inputname]
+
+	This is a rest input rather than an optional input because there
+	is no default value expression.  There can be at most one rest
+	input.  When the procedure is invoked, the value of this inputname
+	will be a list containing all of the actual inputs provided that
+	were not used for required or optional inputs.  Example:
+
+			to proc :in1 [:in2 "foo] [:in3 "baz] [:in4]
+
+	If this procedure is invoked by saying
+
+			proc "x
+
+	then IN1 has the value X, IN2 has the value FOO, IN3 has the value
+	BAZ, and IN4 has the value [] (the empty list).  If it's invoked
+	by saying
+
+			(proc "a "b "c "d "e)
+
+	then IN1 has the value A, IN2 has the value B, IN3 has the value C,
+	and IN4 has the value [D E].
+
+	The MAXIMUM number of inputs for a procedure is infinite if a
+	rest input is given; otherwise, it is the number of required
+	inputs plus the number of optional inputs.
+
+	The DEFAULT number of inputs for a procedure, which is the number
+	of inputs that it will accept if its invocation is not enclosed
+	in parentheses, is ordinarily equal to the minimum number.  If
+	you want a different default number you can indicate that by
+	putting the desired default number as the last thing on the
+	TO line.  example:
+
+			to proc :in1 [:in2 "foo] [:in3] 3
+
+	This procedure has a minimum of one input, a default of three
+	inputs, and an infinite maximum.
+
+	Logo responds to the TO command by entering procedure definition
+	mode.  The prompt character changes from "?" to ">" and whatever
+	instructions you type become part of the definition until you
+	type a line containing only the word END.
+
+DEFINE procname text
+
+	command.  Defines a procedure with name "procname" and text "text".
+	If there is already a procedure with the same name, the new
+	definition replaces the old one.  The text input must be a list
+	whose members are lists.  The first member is a list of inputs;
+	it looks like a TO line but without the word TO, without the
+	procedure name, and without the colons before input names.  In
+	other words, the members of this first sublist are words for
+	the names of required inputs and lists for the names of optional
+	or rest inputs.  The remaining sublists of the text input make
+	up the body of the procedure, with one sublist for each instruction
+	line of the body.  (There is no END line in the text input.)
+	It is an error to redefine a primitive procedure unless the variable
+	REDEFP has the value TRUE.
+
+TEXT procname
+
+	outputs the text of the procedure named "procname" in the form
+	expected by DEFINE: a list of lists, the first of which describes
+	the inputs to the procedure and the rest of which are the lines of
+	its body.  The text does not reflect formatting information used
+	when the procedure was defined, such as continuation lines and
+	extra spaces.
+
+FULLTEXT procname
+
+	outputs a representation of the procedure "procname" in which
+	formatting information is preserved.  If the procedure was defined
+	with TO, EDIT, or LOAD, then the output is a list of words.  Each
+	word represents one entire line of the definition in the form
+	output by READWORD, including extra spaces and continuation lines.
+	The last member of the output represents the END line.  If the
+	procedure was defined with DEFINE, then the output is a list of
+	lists.  If these lists are printed, one per line, the result will
+	look like a definition using TO.  Note: the output from FULLTEXT
+	is not suitable for use as input to DEFINE!
+
+COPYDEF newname oldname
+
+	command.  Makes "newname" a procedure identical to "oldname".
+	The latter may be a primitive.  If "newname" was already defined,
+	its previous definition is lost.  If "newname" was already a
+	primitive, the redefinition is not permitted unless the variable
+	REDEFP has the value TRUE.
+
+	Note: dialects of Logo differ as to the order of inputs to COPYDEF.
+	This dialect uses "MAKE order," not "NAME order."
+
+
+VARIABLE DEFINITION
+-------------------
+
+MAKE varname value
+
+	command.  Assigns the value "value" to the variable named "varname",
+	which must be a word.  Variable names are case-insensitive.  If a
+	variable with the same name already exists, the value of that
+	variable is changed.  If not, a new global variable is created.
+
+NAME value varname					(library procedure)
+
+	command.  Same as MAKE but with the inputs in reverse order.
+
+LOCAL varname
+LOCAL varnamelist
+(LOCAL varname1 varname2 ...)
+
+	command.  Accepts as inputs one or more words, or a list of
+	words.  A variable is created for each of these words, with
+	that word as its name.  The variables are local to the
+	currently running procedure.  Logo variables follow dynamic
+	scope rules; a variable that is local to a procedure is
+	available to any subprocedure invoked by that procedure.
+	The variables created by LOCAL have no initial value; they
+	must be assigned a value (e.g., with MAKE) before the procedure
+	attempts to read their value.
+
+LOCALMAKE varname value				(library procedure)
+
+	command.  Makes the named variable local, like LOCAL, and
+	assigns it the given value, like MAKE.
+
+THING varname
+:quoted.varname
+
+	outputs the value of the variable whose name is the input.
+	If there is more than one such variable, the innermost local
+	variable of that name is chosen.  The colon notation is an
+	abbreviation not for THING but for the combination
+
+				thing "
+
+	so that :FOO means THING "FOO.
+
+GLOBAL varname
+GLOBAL varnamelist
+(GLOBAL varname1 varname2 ...)
+
+	command.  Accepts as inputs one or more words, or a list of
+	words.  A global variable is created for each of these words, with
+	that word as its name.  The only reason this is necessary is that
+	you might want to use the "setter" notation SETXYZ for a variable
+	XYZ that does not already have a value; GLOBAL "XYZ makes that legal.
+	Note: If there is currently a local variable of the same name, this
+	command does *not* make Logo use the global value instead of the
+	local one.
+
+
+PROPERTY LISTS
+--------------
+
+Note: Names of property lists are always case-insensitive.  Names of
+individual properties are case-sensitive or case-insensitive depending
+on the value of CASEIGNOREDP, which is TRUE by default.
+
+In principle, every possible name is the name of a property list, which
+is initially empty.  So Logo never gives a "no such property list" error,
+as it would for undefined procedure or variable names.  But the primitive
+procedures that deal with "all" property lists (CONTENTS, PLISTS, etc.)
+list only nonempty ones.  To "erase" a property list (see ERASE below)
+means to make it empty, removing all properties from it.
+
+PPROP plistname propname value
+
+	command.  Adds a property to the "plistname" property list
+	with name "propname" and value "value".
+
+GPROP plistname propname
+
+	outputs the value of the "propname" property in the "plistname"
+	property list, or the empty list if there is no such property.
+
+REMPROP plistname propname
+
+	command.  Removes the property named "propname" from the
+	property list named "plistname".
+
+PLIST plistname
+
+	outputs a list whose odd-numbered members are the names, and
+	whose even-numbered members are the values, of the properties
+	in the property list named "plistname".  The output is a copy
+	of the actual property list; changing properties later will not
+	magically change a list output earlier by PLIST.
+
+
+PREDICATES
+----------
+
+PROCEDUREP name
+PROCEDURE? name
+
+	outputs TRUE if the input is the name of a procedure.
+
+PRIMITIVEP name
+PRIMITIVE? name
+
+	outputs TRUE if the input is the name of a primitive procedure
+	(one built into Logo).  Note that some of the procedures
+	described in this document are library procedures, not primitives.
+
+DEFINEDP name
+DEFINED? name
+
+	outputs TRUE if the input is the name of a user-defined procedure,
+	including a library procedure.
+
+NAMEP name
+NAME? name
+
+	outputs TRUE if the input is the name of a variable.
+
+PLISTP name
+PLIST? name
+
+	outputs TRUE if the input is the name of a *nonempty* property list.
+	(In principle every word is the name of a property list; if you haven't
+	put any properties in it, PLIST of that name outputs an empty list,
+	rather than giving an error message.)
+
+
+QUERIES
+-------
+
+Note:  All procedures whose input is indicated as "contentslist" will
+accept a single word (taken as a procedure name), a list of words (taken
+as names of procedures), or a list of three lists as described under
+the CONTENTS command above.
+
+CONTENTS
+
+	outputs a "contents list," i.e., a list of three lists containing
+	names of defined procedures, variables, and property lists
+	respectively.  This list includes all unburied named items in
+	the workspace.
+
+BURIED
+
+	outputs a contents list including all buried named items in
+	the workspace.
+
+TRACED
+
+	outputs a contents list including all traced named items in
+	the workspace.
+
+STEPPED
+
+	outputs a contents list including all stepped named items in
+	the workspace.
+
+PROCEDURES
+
+	outputs a list of the names of all unburied user-defined procedures
+	in the workspace.  Note that this is a list of names, not a
+	contents list.  (However, procedures that require a contents list
+	as input will accept this list.)
+
+PRIMITIVES
+
+	outputs a list of the names of all primitive procedures
+	in the workspace.  Note that this is a list of names, not a
+	contents list.  (However, procedures that require a contents list
+	as input will accept this list.)
+
+NAMES
+
+	outputs a contents list consisting of an empty list (indicating
+	no procedure names) followed by a list of all unburied variable
+	names in the workspace.
+
+PLISTS
+
+	outputs a contents list consisting of two empty lists (indicating
+	no procedures or variables) followed by a list of all unburied
+	nonempty property lists in the workspace.
+
+NAMELIST varname					(library procedure)
+NAMELIST varnamelist
+
+	outputs a contents list consisting of an empty list followed by
+	a list of the name or names given as input.  This is useful in
+	conjunction with workspace control procedures that require a contents
+	list as input.
+
+PLLIST plname						(library procedure)
+PLLIST plnamelist
+
+	outputs a contents list consisting of two empty lists followed by
+	a list of the name or names given as input.  This is useful in
+	conjunction with workspace control procedures that require a contents
+	list as input.
+
+ARITY procedurename
+
+	outputs a list of three numbers: the minimum, default, and maximum
+	number of inputs for the procedure whose name is the input.  It is an
+	error if there is no such procedure.  A maximum of -1 means that the
+	number of inputs is unlimited.
+
+NODES
+
+	outputs a list of two numbers.  The first represents the number of
+	nodes of memory currently in use.  The second shows the maximum
+	number of nodes that have been in use at any time since the last
+	invocation of NODES.  (A node is a small block of computer memory
+	as used by Logo.  Each number uses one node.  Each non-numeric
+	word uses one node, plus some non-node memory for the characters
+	in the word.  Each array takes one node, plus some non-node
+	memory, as well as the memory required by its elements.  Each
+	list requires one node per element, as well as the memory within
+	the elements.)  If you want to track the memory use of an
+	algorithm, it is best if you invoke GC at the beginning of each
+	iteration, since otherwise the maximum will include storage that
+	is unused but not yet collected.
+
+
+INSPECTION
+----------
+
+PRINTOUT contentslist
+PO contentslist
+
+	command.  Prints to the write stream the definitions of all
+	procedures, variables, and property lists named in the input
+	contents list.
+
+POALL							(library procedure)
+
+	command.  Prints all unburied definitions in the workspace.
+	Abbreviates PO CONTENTS.
+
+POPS							(library procedure)
+
+	command.  Prints the definitions of all unburied procedures in
+	the workspace.  Abbreviates PO PROCEDURES.
+
+PONS							(library procedure)
+
+	command.  Prints the definitions of all unburied variables in
+	the workspace.  Abbreviates PO NAMES.
+
+POPLS							(library procedure)
+
+	command.  Prints the contents of all unburied nonempty property
+	lists in the workspace.  Abbreviates PO PLISTS.
+
+PON varname						(library procedure)
+PON varnamelist
+
+	command.  Prints the definitions of the named variable(s).
+	Abbreviates PO NAMELIST varname(list).
+
+POPL plname						(library procedure)
+POPL plnamelist
+
+	command.  Prints the definitions of the named property list(s).
+	Abbreviates PO PLLIST plname(list).
+
+POT contentslist
+
+	command.  Prints the title lines of the named procedures and
+	the definitions of the named variables and property lists.
+	For property lists, the entire list is shown on one line
+	instead of as a series of PPROP instructions as in PO.
+
+POTS							(library procedure)
+
+	command.  Prints the title lines of all unburied procedures
+	in the workspace.  Abbreviates POT PROCEDURES.
+
+
+WORKSPACE CONTROL
+-----------------
+
+ERASE contentslist
+ER contentslist
+
+	command.  Erases from the workspace the procedures, variables,
+	and property lists named in the input.  Primitive procedures may
+	not be erased unless the variable REDEFP has the value TRUE.
+
+ERALL
+
+	command.  Erases all unburied procedures, variables, and property
+	lists from the workspace.  Abbreviates ERASE CONTENTS.
+
+ERPS
+
+	command.  Erases all unburied procedures from the workspace.
+	Abbreviates ERASE PROCEDURES.
+
+ERNS
+
+	command.  Erases all unburied variables from the workspace.
+	Abbreviates ERASE NAMES.
+
+ERPLS
+
+	command.  Erases all unburied property lists from the workspace.
+	Abbreviates ERASE PLISTS.
+
+ERN varname						(library procedure)
+ERN varnamelist
+
+	command.  Erases from the workspace the variable(s) named in the
+	input.  Abbreviates ERASE NAMELIST varname(list).
+
+ERPL plname						(library procedure)
+ERPL plnamelist
+
+	command.  Erases from the workspace the property list(s) named in the
+	input.  Abbreviates ERASE PLLIST plname(list).
+
+BURY contentslist
+
+	command.  Buries the procedures, variables, and property lists
+	named in the input.  A buried item is not included in the lists
+	output by CONTENTS, PROCEDURES, VARIABLES, and PLISTS, but is
+	included in the list output by BURIED.  By implication, buried
+	things are not printed by POALL or saved by SAVE.
+
+BURYALL							(library procedure)
+
+	command.  Abbreviates BURY CONTENTS.
+
+BURYNAME varname					(library procedure)
+BURYNAME varnamelist
+
+	command.  Abbreviates BURY NAMELIST varname(list).
+
+UNBURY contentslist
+
+	command.  Unburies the procedures, variables, and property lists
+	named in the input.  That is, the named items will be returned to
+	view in CONTENTS, etc.
+
+UNBURYALL						(library procedure)
+
+	command.  Abbreviates UNBURY BURIED.
+
+UNBURYNAME varname					(library procedure)
+UNBURYNAME varnamelist
+
+	command.  Abbreviates UNBURY NAMELIST varname(list).
+
+BURIEDP contentslist
+BURIED? contentslist
+
+	outputs TRUE if the first procedure, variable, or property list named
+	in the contents list is buried, FALSE if not.  Only the first thing in
+	the list is tested; the most common use will be with a word as input,
+	naming a procedure, but a contents list is allowed so that you can
+	BURIEDP [[] [VARIABLE]] or BURIEDP [[] [] [PROPLIST]].
+
+TRACE contentslist
+
+	command.  Marks the named items for tracing.  A message is printed
+	whenever a traced procedure is invoked, giving the actual input
+	values, and whenever a traced procedure STOPs or OUTPUTs.  A
+	message is printed whenever a new value is assigned to a traced
+	variable using MAKE.  A message is printed whenever a new property
+	is given to a traced property list using PPROP.
+
+UNTRACE contentslist
+
+	command.  Turns off tracing for the named items.
+
+TRACEDP contentslist
+TRACED? contentslist
+
+	outputs TRUE if the first procedure, variable, or property list named
+	in the contents list is traced, FALSE if not.  Only the first thing in
+	the list is tested; the most common use will be with a word as input,
+	naming a procedure, but a contents list is allowed so that you can
+	TRACEDP [[] [VARIABLE]] or TRACEDP [[] [] [PROPLIST]].
+
+STEP contentslist
+
+	command.  Marks the named items for stepping.  Whenever a stepped
+	procedure is invoked, each instruction line in the procedure body
+	is printed before being executed, and Logo waits for the user to
+	type a newline at the terminal.  A message is printed whenever a
+	stepped variable name is "shadowed" because a local variable of
+	the same name is created either as a procedure input or by the
+	LOCAL command.
+
+UNSTEP contentslist
+
+	command.  Turns off stepping for the named items.
+
+STEPPEDP contentslist
+STEPPED? contentslist
+
+	outputs TRUE if the first procedure, variable, or property list named
+	in the contents list is stepped, FALSE if not.  Only the first thing
+	in the list is tested; the most common use will be with a word as
+	input, naming a procedure, but a contents list is allowed so that you
+	can STEPPEDP [[] [VARIABLE]] or STEPPEDP [[] [] [PROPLIST]].
+
+EDIT contentslist
+ED contentslist
+(EDIT)
+(ED)
+
+	command.  If invoked with an input, EDIT writes the definitions
+	of the named items into a temporary file and edits that file, using
+	an editor that depends on the platform you're using.  In wxWidgets,
+	and in the MacOS Classic version, there is an editor built into Logo.
+	In the non-wxWidgets versions for Unix, MacOS X, Windows, and DOS,
+	Logo uses your favorite editor as determined by the EDITOR environment
+	variable.  If you don't have an EDITOR variable, edits the
+	definitions using jove.  If invoked without an input, EDIT edits
+	the same file left over from a previous EDIT or EDITFILE instruction.
+	When you leave the editor, Logo reads the revised definitions and
+	modifies the workspace accordingly.  It is not an error if the
+	input includes names for which there is no previous definition.
+
+	If there is a variable LOADNOISILY whose value is TRUE, then, after
+	leaving the editor, TO commands in the temporary file print "PROCNAME
+	defined" (where PROCNAME is the name of the procedure being defined);
+	if LOADNOISILY is FALSE or undefined, TO commands in the file are
+	carried out silently.
+
+	If there is an environment variable called TEMP, then Logo uses
+	its value as the directory in which to write the temporary file
+	used for editing.
+
+	Exceptionally, the EDIT command can be used without its default
+	input and without parentheses provided that nothing follows it on
+	the instruction line.
+
+EDITFILE filename
+
+	command.  Starts the Logo editor, like EDIT, but instead of editing
+	a temporary file it edits the file specified by the input.  When you
+	leave the editor, Logo reads the revised file, as for EDIT.
+	EDITFILE also remembers the filename, so that a subsequent EDIT
+	command with no input will re-edit the same file.
+
+	EDITFILE is intended as an alternative to LOAD and SAVE.  You can
+	maintain a workspace file yourself, controlling the order in which
+	definitions appear, maintaining comments in the file, and so on.
+
+EDALL							(library procedure)
+
+	command.  Abbreviates EDIT CONTENTS.
+
+EDPS							(library procedure)
+
+	command.  Abbreviates EDIT PROCEDURES.
+
+EDNS							(library procedure)
+
+	command.  Abbreviates EDIT NAMES.
+
+EDPLS							(library procedure)
+
+	command.  Abbreviates EDIT PLISTS.
+
+EDN varname						(library procedure)
+EDN varnamelist
+
+	command.  Abbreviates EDIT NAMELIST varname(list).
+
+EDPL plname						(library procedure)
+EDPL plnamelist
+
+	command.  Abbreviates EDIT PLLIST plname(list).
+
+SAVE filename
+
+	command.  Saves the definitions of all unburied procedures,
+	variables, and nonempty property lists in the named file.
+	Equivalent to
+
+			to save :filename
+			local "oldwriter
+			make "oldwriter writer
+			openwrite :filename
+			setwrite :filename
+			poall
+			setwrite :oldwriter
+			close :filename
+			end
+
+	Exceptionally, SAVE can be used with no input and without parentheses
+	if it is the last thing on the command line.  In this case, the
+	filename from the most recent LOAD or SAVE command will be used.  (It
+	is an error if there has been no previous LOAD or SAVE.)
+
+SAVEL contentslist filename				(library procedure)
+
+	command.  Saves the definitions of the procedures, variables, and
+	property lists specified by "contentslist" to the file named
+	"filename".
+
+LOAD filename
+
+	command.  Reads instructions from the named file and executes
+	them.  The file can include procedure definitions with TO, and
+	these are accepted even if a procedure by the same name already
+	exists.  If the file assigns a list value to a variable named
+	STARTUP, then that list is run as an instructionlist after the
+	file is loaded.  If there is a variable LOADNOISILY whose value
+	is TRUE, then TO commands in the file print "PROCNAME defined"
+	(where PROCNAME is the name of the procedure being defined); if
+	LOADNOISILY is FALSE or undefined, TO commands in the file are
+	carried out silently.
+
+CSLSLOAD name
+
+	command.  Loads the named file, like LOAD, but from the directory
+	containing the Computer Science Logo Style programs instead of the
+	current user's directory.
+
+HELP name
+(HELP)
+
+	command.  Prints information from the reference manual about
+	the primitive procedure named by the input.  With no input,
+	lists all the primitives about which help is available.
+	If there is an environment variable LOGOHELP, then its value
+	is taken as the directory in which to look for help files,
+	instead of the default help directory.
+
+	If HELP is called with the name of a defined procedure for which there
+	is no help file, it will print the title line of the procedure
+	followed by lines from the procedure body that start with semicolon,
+	stopping when a non-semicolon line is seen.
+
+	Exceptionally, the HELP command can be used without its default
+	input and without parentheses provided that nothing follows it on
+	the instruction line.
+
+SETEDITOR path
+
+	command.  Tells Logo to use the specified program as its editor
+	instead of the default editor.  The format of a path depends on your
+	operating system.
+
+SETLIBLOC path
+
+	command.  Tells Logo to use the specified directory as its library
+	instead of the default.  (Note that many Logo "primitive" procedures
+	are actually found in the library, so they may become unavailable if
+	your new library does not include them!)  The format of a path depends
+	on your operating system.
+
+SETHELPLOC path
+
+	command.  Tells Logo to look in the specified directory for the
+	information provided by the HELP command, instead of the default
+	directory.  The format of a path depends on your operating system.
+
+SETCSLSLOC path
+
+	command.  Tells Logo to use the specified directory for the CSLSLOAD
+	command, instead of the default directory.  The format of a path
+	depends on your operating system.
+
+SETTEMPLOC path
+
+	command.  Tells Logo to write editor temporary files in the specified
+	directory rather than in the default directory.  You must have write
+	permission for this directory.  The format of a path depends on your
+	operating system.
+
+GC
+(GC anything)
+
+	command.  Runs the garbage collector, reclaiming unused nodes.  Logo
+	does this when necessary anyway, but you may want to use this
+	command to control exactly when Logo does it.  In particular, the
+	numbers output by the NODES operation will not be very meaningful
+	unless garbage has been collected.  Another reason to use GC is that
+	a garbage collection takes a noticeable fraction of a second, and you
+	may want to schedule collections for times before or after some
+	time-critical animation.  If invoked with an input (of any value),
+	GC runs a full garbage collection, including GCTWA (Garbage Collect
+	Truly Worthless Atoms, which means that it removes from Logo's
+	memory words that used to be procedure or variable names but aren't
+	any more); without an input, GC does a generational garbage
+	collection, which means that only recently created nodes are
+	examined.  (The latter is usually good enough.)
+
+.SETSEGMENTSIZE num
+
+	command.  Sets the number of nodes that Logo allocates from the
+	operating system at once to num, which must be a positive integer.
+	The name is dotted because bad things will happen if you use a
+	number that's too small or too large for your computer.  The
+	initial value is 16,000 for most systems, but is smaller for
+	68000-based Macs.  Making it larger will speed up computations
+	(by reducing the number of garbage collections) at the cost of
+	allocating more memory than necessary.
+
+
+CONTROL STRUCTURES
+==================
+
+Note: in the following descriptions, an "instructionlist" can be a list
+or a word.  In the latter case, the word is parsed into list form before
+it is run.  Thus, RUN READWORD or RUN READLIST will work.  The former is
+slightly preferable because it allows for a continued line (with ~) that
+includes a comment (with ;) on the first line.
+
+A "tf" input must be the word TRUE, the word FALSE, or a list.  If it's a
+list, then it must be a Logo expression, which will be evaluated to produce
+a value that must be TRUE or FALSE.  The comparisons with TRUE and FALSE
+are always case-insensitive.
+
+A runlist can consist of either a single expression (that produces a value)
+or zero or more instructions (that do something, rather than output a value),
+depending on the context:
+
+	PRINT IFELSE :X<0 ["NEGATIVE] ["POSITIVE]  ; one value in each case
+	REPEAT 4 [PRINT "A PRINT "B]  ; two instructions
+
+
+RUN instructionlist
+
+	command or operation.  Runs the Logo instructions in the input
+	list; outputs if the list contains an expression that outputs.
+
+RUNRESULT instructionlist
+
+	runs the instructions in the input; outputs an empty list if
+	those instructions produce no output, or a list whose only
+	member is the output from running the input instructionlist.
+	Useful for inventing command-or-operation control structures:
+
+		local "result
+		make "result runresult [something]
+		if emptyp :result [stop]
+		output first :result
+
+REPEAT num instructionlist
+
+	command.  Runs the "instructionlist" repeatedly, "num" times.
+
+FOREVER instructionlist
+
+	command.  Runs the "instructionlist" repeatedly, until something
+	inside the instructionlist (such as STOP or THROW) makes it stop.
+
+REPCOUNT
+
+	outputs the repetition count of the innermost current REPEAT or
+	FOREVER, starting from 1.  If no REPEAT or FOREVER is active,
+	outputs -1.
+
+	The abbreviation # can be used for REPCOUNT unless the REPEAT is
+	inside the template input to a higher order procedure such as
+	FOREACH, in which case # has a different meaning.
+
+IF tf instructionlist
+(IF tf instructionlist1 instructionlist2)
+
+	command.  If the first input has the value TRUE, then IF runs
+	the second input.  If the first input has the value FALSE, then
+	IF does nothing.  (If given a third input, IF acts like IFELSE,
+	as described below.)  It is an error if the first input is not
+	either TRUE or FALSE.
+
+	For compatibility with earlier versions of Logo, if an IF
+	instruction is not enclosed in parentheses, but the first thing
+	on the instruction line after the second input expression is a
+	literal list (i.e., a list in square brackets), the IF is
+	treated as if it were IFELSE, but a warning message is given.
+	If this aberrant IF appears in a procedure body, the warning is
+	given only the first time the procedure is invoked in each Logo
+	session.
+
+IFELSE tf instructionlist1 instructionlist2
+
+	command or operation.  If the first input has the value TRUE, then
+	IFELSE runs the second input.  If the first input has the value FALSE,
+	then IFELSE runs the third input.  IFELSE outputs a value if the
+	instructionlist contains an expression that outputs a value.
+
+TEST tf
+
+	command.  Remembers its input, which must be TRUE or FALSE, for use
+	by later IFTRUE or IFFALSE instructions.  The effect of TEST is local
+	to the procedure in which it is used; any corresponding IFTRUE or
+	IFFALSE must be in the same procedure or a subprocedure.
+
+IFTRUE instructionlist
+IFT instructionlist
+
+	command.  Runs its input if the most recent TEST instruction had
+	a TRUE input.  The TEST must have been in the same procedure or a
+	superprocedure.
+
+IFFALSE instructionlist
+IFF instructionlist
+
+	command.  Runs its input if the most recent TEST instruction had
+	a FALSE input.  The TEST must have been in the same procedure or a
+	superprocedure.
+
+STOP
+
+	command.  Ends the running of the procedure in which it appears.
+	Control is returned to the context in which that procedure was
+	invoked.  The stopped procedure does not output a value.
+
+OUTPUT value
+OP value
+
+	command.  Ends the running of the procedure in which it appears.
+	That procedure outputs the value "value" to the context in which
+	it was invoked.  Don't be confused: OUTPUT itself is a command,
+	but the procedure that invokes OUTPUT is an operation.
+
+CATCH tag instructionlist
+
+	command or operation.  Runs its second input.  Outputs if that
+	instructionlist outputs.  If, while running the instructionlist,
+	a THROW instruction is executed with a tag equal to the first
+	input (case-insensitive comparison), then the running of the
+	instructionlist is terminated immediately.  In this case the CATCH
+	outputs if a value input is given to THROW.  The tag must be a word.
+
+	If the tag is the word ERROR, then any error condition that arises
+	during the running of the instructionlist has the effect of THROW
+	"ERROR instead of printing an error message and returning to
+	toplevel.  The CATCH does not output if an error is caught.  Also,
+	during the running of the instructionlist, the variable ERRACT is
+	temporarily unbound.  (If there is an error while ERRACT has a
+	value, that value is taken as an instructionlist to be run after
+	printing the error message.  Typically the value of ERRACT, if any,
+	is the list [PAUSE].)
+
+THROW tag
+(THROW tag value)
+
+	command.  Must be used within the scope of a CATCH with an equal
+	tag.  Ends the running of the instructionlist of the CATCH.  If
+	THROW is used with only one input, the corresponding CATCH does
+	not output a value.  If THROW is used with two inputs, the second
+	provides an output for the CATCH.
+
+	THROW "TOPLEVEL can be used to terminate all running procedures and
+	interactive pauses, and return to the toplevel instruction prompt.
+	Typing the system interrupt character (alt-S for wxWidgets; otherwise
+	normally control-C for Unix, control-Q for DOS, or command-period for
+	Mac) has the same effect.
+
+	THROW "ERROR can be used to generate an error condition.  If the
+	error is not caught, it prints a message (THROW "ERROR) with the
+	usual indication of where the error (in this case the THROW)
+	occurred.  If a second input is used along with a tag of ERROR,
+	that second input is used as the text of the error message
+	instead of the standard message.  Also, in this case, the location
+	indicated for the error will be, not the location of the THROW,
+	but the location where the procedure containing the THROW was
+	invoked.  This allows user-defined procedures to generate error
+	messages as if they were primitives.  Note: in this case the
+	corresponding CATCH "ERROR, if any, does not output, since the second
+	input to THROW is not considered a return value.
+
+	THROW "SYSTEM immediately leaves Logo, returning to the operating
+	system, without printing the usual parting message and without
+	deleting any editor temporary file written by EDIT.
+
+ERROR
+
+	outputs a list describing the error just caught, if any.  If there was
+	not an error caught since the last use of ERROR, the empty list will
+	be output.  The error list contains four members: an integer code
+	corresponding to the type of error, the text of the error message (as
+	a single word including spaces), the name of the procedure in which
+	the error occurred, and the instruction line on which the error
+	occurred.
+
+PAUSE
+
+	command or operation.  Enters an interactive pause.  The user is
+	prompted for instructions, as at toplevel, but with a prompt that
+	includes the name of the procedure in which PAUSE was invoked.
+	Local variables of that procedure are available during the pause.
+	PAUSE outputs if the pause is ended by a CONTINUE with an input.
+
+	If the variable ERRACT exists, and an error condition occurs, the
+	contents of that variable are run as an instructionlist.  Typically
+	ERRACT is given the value [PAUSE] so that an interactive pause will
+	be entered in the event of an error.  This allows the user to check
+	values of local variables at the time of the error.
+
+	Typing the system quit character (alt-S for wxWidgets; otherwise
+	normally control-\ for Unix, control-W for DOS, or command-comma for
+	Mac) will also enter a pause.
+
+CONTINUE value
+CO value
+(CONTINUE)
+(CO)
+
+	command.  Ends the current interactive pause, returning to the
+	context of the PAUSE invocation that began it.  If CONTINUE is
+	given an input, that value is used as the output from the PAUSE.
+	If not, the PAUSE does not output.
+
+	Exceptionally, the CONTINUE command can be used without its default
+	input and without parentheses provided that nothing follows it on
+	the instruction line.
+
+WAIT time
+
+	command.  Delays further execution for "time" 60ths of a second.
+	Also causes any buffered characters destined for the terminal to
+	be printed immediately.  WAIT 0 can be used to achieve this
+	buffer flushing without actually waiting.
+
+BYE
+
+	command.  Exits from Logo; returns to the operating system.
+
+.MAYBEOUTPUT value					(special form)
+
+	works like OUTPUT except that the expression that provides the
+	input value might not, in fact, output a value, in which case
+	the effect is like STOP.  This is intended for use in control
+	structure definitions, for cases in which you don't know whether
+	or not some expression produces a value.  Example:
+
+		to invoke :function [:inputs] 2
+		.maybeoutput apply :function :inputs
+		end
+
+		? (invoke "print "a "b "c)
+		a b c
+		? print (invoke "word "a "b "c)
+		abc
+
+	This is an alternative to RUNRESULT.  It's fast and easy to use,
+	at the cost of being an exception to Logo's evaluation rules.
+	(Ordinarily, it should be an error if the expression that's
+	supposed to provide an input to something doesn't have a value.)
+
+GOTO word
+
+	command.  Looks for a TAG command with the same input in the same
+	procedure, and continues running the procedure from the location of
+	that TAG.  It is meaningless to use GOTO outside of a procedure.
+
+TAG quoted.word
+
+	command.  Does nothing.  The input must be a literal word following
+	a quotation mark ("), not the result of a computation.  Tags are
+	used by the GOTO command.
+
+IGNORE value						(library procedure)
+
+	command.  Does nothing.  Used when an expression is evaluated for
+	a side effect and its actual value is unimportant.
+
+` list							(library procedure)
+
+	outputs a list equal to its input but with certain substitutions.
+	If a member of the input list is the word "," (comma) then the
+	following member should be an instructionlist that produces an
+	output when run.  That output value replaces the comma and the
+	instructionlist.  If a member of the input list is the word ",@"
+	(comma atsign) then the following member should be an instructionlist
+	that outputs a list when run.  The members of that list replace the
+	,@ and the instructionlist.  Example:
+
+		show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]]
+
+	will print
+
+		[foo baz [b c] garply b c]
+
+	A word starting with , or ,@ is treated as if the rest of the word
+	were a one-word list, e.g., ,:FOO is equivalent to ,[:FOO].
+
+	A word starting with ", (quote comma) or :, (colon comma) becomes a
+	word starting with " or : but with the result of running the
+	substitution (or its first word, if the result is a list) replacing
+	what comes after the comma.
+
+	Backquotes can be nested.  Substitution is done only for commas at
+	the same depth as the backquote in which they are found:
+
+		? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f]
+		[a ` [b , [1+2] , [foo 4 d] e] f]
+
+		?make "name1 "x
+		?make "name2 "y
+		? show `[a `[b ,:,:name1 ,",:name2 d] e]
+		[a ` [b , [:x] , ["y] d] e]
+
+FOR forcontrol instructionlist				(library procedure)
+
+	command.  The first input must be a list containing three or four
+	members: (1) a word, which will be used as the name of a local
+	variable; (2) a word or list that will be evaluated as by RUN to
+	determine a number, the starting value of the variable; (3) a word
+	or list that will be evaluated to determine a number, the limit value
+	of the variable; (4) an optional word or list that will be evaluated
+	to determine the step size.  If the fourth member is missing, the
+	step size will be 1 or -1 depending on whether the limit value is
+	greater than or less than the starting value, respectively.
+
+	The second input is an instructionlist.  The effect of FOR is to run
+	that instructionlist repeatedly, assigning a new value to the control
+	variable (the one named by the first member of the forcontrol list)
+	each time.  First the starting value is assigned to the control
+	variable.  Then the value is compared to the limit value.  FOR is
+	complete when the sign of (current - limit) is the same as the sign
+	of the step size.  (If no explicit step size is provided, the
+	instructionlist is always run at least once.  An explicit step size
+	can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...)  Otherwise, the
+	instructionlist is run, then the step is added to the current value
+	of the control variable and FOR returns to the comparison step.
+
+		? for [i 2 7 1.5] [print :i]
+		2
+		3.5
+		5
+		6.5
+		?
+
+DO.WHILE instructionlist tfexpression			(library procedure)
+
+	command.  Repeatedly evaluates the "instructionlist" as long as the
+	evaluated "tfexpression" remains TRUE.  Evaluates the first input
+	first, so the "instructionlist" is always run at least once.  The
+	"tfexpression" must be an expressionlist whose value when evaluated
+	is TRUE or FALSE.
+
+WHILE tfexpression instructionlist			(library procedure)
+
+	command.  Repeatedly evaluates the "instructionlist" as long as the
+	evaluated "tfexpression" remains TRUE.  Evaluates the first input
+	first, so the "instructionlist" may never be run at all.  The
+	"tfexpression" must be an expressionlist whose value when evaluated
+	is TRUE or FALSE.
+
+DO.UNTIL instructionlist tfexpression			(library procedure)
+
+	command.  Repeatedly evaluates the "instructionlist" as long as the
+	evaluated "tfexpression" remains FALSE.  Evaluates the first input
+	first, so the "instructionlist" is always run at least once.  The
+	"tfexpression" must be an expressionlist whose value when evaluated
+	is TRUE or FALSE.
+
+UNTIL tfexpression instructionlist			(library procedure)
+
+	command.  Repeatedly evaluates the "instructionlist" as long as the
+	evaluated "tfexpression" remains FALSE.  Evaluates the first input
+	first, so the "instructionlist" may never be run at all.  The
+	"tfexpression" must be an expressionlist whose value when evaluated
+	is TRUE or FALSE.
+
+CASE value clauses					(library procedure)
+
+	command or operation.  The second input is a list of lists (clauses);
+	each clause is a list whose first element is either a list of values
+	or the word ELSE and whose butfirst is a Logo expression or
+	instruction.  CASE examines the clauses in order.  If a clause begins
+	with the word ELSE (upper or lower case), then the butfirst of that
+	clause is evaluated and CASE outputs its value, if any.  If the first
+	input to CASE is a member of the first element of a clause, then the
+	butfirst of that clause is evaluated and CASE outputs its value, if
+	any.  If neither of these conditions is met, then CASE goes on to the
+	next clause.  If no clause is satisfied, CASE does nothing.  Example:
+
+		to vowelp :letter
+		output case :letter [ [[a e i o u] "true] [else "false] ]
+		end
+
+COND clauses						(library procedure)
+
+	command or operation.  The input is a list of lists (clauses); each
+	clause is a list whose first element is either an expression whose
+	value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo
+	expression or instruction.  COND examines the clauses in order.  If a
+	clause begins with the word ELSE (upper or lower case), then the
+	butfirst of that clause is evaluated and CASE outputs its value, if
+	any.  Otherwise, the first element of the clause is evaluated; the
+	resulting value must be TRUE or FALSE.  If it's TRUE, then the
+	butfirst of that clause is evaluated and COND outputs its value, if
+	any.  If the value is FALSE, then COND goes on to the next clause.  If
+	no clause is satisfied, COND does nothing.  Example:
+
+		to evens :numbers	; select even numbers from a list
+		op cond [ [[emptyp :numbers] []]
+		          [[evenp first :numbers]  ; assuming EVENP is defined
+		           fput first :numbers evens butfirst :numbers]
+		          [else evens butfirst :numbers] ]
+		end
+
+
+TEMPLATE-BASED ITERATION
+------------------------
+
+The procedures in this section are iteration tools based on the idea of a
+"template."  This is a generalization of an instruction list or an
+expression list in which "slots" are provided for the tool to insert varying
+data.  Four different forms of template can be used.
+
+The most commonly used form for a template is "explicit-slot" form, or
+"question mark" form.  Example:
+
+	? show map [? * ?] [2 3 4 5]
+	[4 9 16 25]
+	?
+
+In this example, the MAP tool evaluated the template [? * ?] repeatedly,
+with each of the members of the data list [2 3 4 5] substituted in turn
+for the question marks.  The same value was used for every question mark
+in a given evaluation.  Some tools allow for more than one datum to be
+substituted in parallel; in these cases the slots are indicated by ?1 for
+the first datum, ?2 for the second, and so on:
+
+	? show (map [(word ?1 ?2 ?1)] [a b c] [d e f])
+	[ada beb cfc]
+	?
+
+If the template wishes to compute the datum number, the form (? 1) is
+equivalent to ?1, so (? ?1) means the datum whose number is given in
+datum number 1.  Some tools allow additional slot designations, as shown
+in the individual descriptions.
+
+The second form of template is the "named-procedure" form.  If the template
+is a word rather than a list, it is taken as the name of a procedure.  That
+procedure must accept a number of inputs equal to the number of parallel
+data slots provided by the tool; the procedure is applied to all of the
+available data in order.  That is, if data ?1 through ?3 are available,
+the template "PROC is equivalent to [PROC ?1 ?2 ?3].
+
+	? show (map "word [a b c] [d e f])
+	[ad be cf]
+	?
+
+	to dotprod :a :b	; vector dot product
+	op apply "sum (map "product :a :b)
+	end
+
+The third form of template is "named-slot" or "lambda" form.  This form is
+indicated by a template list containing more than one member, whose first
+member is itself a list.  The first member is taken as a list of names;
+local variables are created with those names and given the available data
+in order as their values.  The number of names must equal the number of
+available data.  This form is needed primarily when one iteration tool must
+be used within the template list of another, and the ? notation would be
+ambiguous in the inner template.  Example:
+
+	to matmul :m1 :m2 [:tm2 transpose :m2]	; multiply two matrices
+	output map [[row] map [[col] dotprod :row :col] :tm2] :m1
+	end
+
+The fourth form is "procedure text" form, a variant of lambda form.  In this
+form, the template list contains at least two members, all of which are
+lists.  This is the form used by the DEFINE and TEXT primitives, and APPLY
+accepts it so that the text of a defined procedure can be used as a template.
+
+Note:  The fourth form of template is interpreted differently from the
+others, in that Logo considers it to be an independent defined procedure
+for the purposes of OUTPUT and STOP.  For example, the following two
+instructions are identical:
+
+	? print apply [[x] :x+3] [5]
+	8
+	? print apply [[x] [output :x+3]] [5]
+	8
+
+although the first instruction is in named-slot form and the second is
+in procedure-text form.  The named-slot form can be understood as telling
+Logo to evaluate the expression :x+3 in place of the entire invocation of
+apply, with the variable x temporarily given the value 5.  The procedure-text
+form can be understood as invoking the procedure
+
+	to foo :x
+	output :x+3
+	end
+
+with input 5, but without actually giving the procedure a name.  If
+the use of OUTPUT were interchanged in these two examples, we'd get errors:
+
+	? print apply [[x] output :x+3] [5]
+	Can only use output inside a procedure
+	? print apply [[x] [:x+3]] [5]
+	You don't say what to do with 8
+
+The named-slot form can be used with STOP or OUTPUT inside a procedure,
+to stop the enclosing procedure.
+
+
+The following iteration tools are extended versions of the ones in Appendix
+B of the book _Computer_Science_Logo_Style,_Volume_3:_Advanced_Topics_ by
+Brian Harvey [MIT Press, 1987].  The extensions are primarily to allow for
+variable numbers of inputs.
+
+
+APPLY template inputlist
+
+	command or operation.  Runs the "template," filling its slots with
+	the members of "inputlist."  The number of members in "inputlist"
+	must be an acceptable number of slots for "template."  It is
+	illegal to apply the primitive TO as a template, but anything else
+	is okay.  APPLY outputs what "template" outputs, if anything.
+
+INVOKE template input					(library procedure)
+(INVOKE template input1 input2 ...)
+
+	command or operation.  Exactly like APPLY except that the inputs
+	are provided as separate expressions rather than in a list.
+
+FOREACH data template					(library procedure)
+(FOREACH data1 data2 ... template)
+
+	command.  Evaluates the template list repeatedly, once for each
+	member of the data list.  If more than one data list are given,
+	each of them must be the same length.  (The data inputs can be
+	words, in which case the template is evaluated once for each
+	character.)
+
+	In a template, the symbol ?REST represents the portion of the
+	data input to the right of the member currently being used as
+	the ? slot-filler.  That is, if the data input is [A B C D E]
+	and the template is being evaluated with ? replaced by B, then
+	?REST would be replaced by [C D E].  If multiple parallel slots
+	are used, then (?REST 1) goes with ?1, etc.
+
+	In a template, the symbol # represents the position in the data
+	input of the member currently being used as the ? slot-filler.
+	That is, if the data input is [A B C D E] and the template is
+	being evaluated with ? replaced by B, then # would be replaced
+	by 2.
+
+MAP template data					(library procedure)
+(MAP template data1 data2 ...)
+
+	outputs a word or list, depending on the type of the data input,
+	of the same length as that data input.  (If more than one data
+	input are given, the output is of the same type as data1.)  Each
+	member of the output is the result of evaluating the template
+	list, filling the slots with the corresponding member(s) of the
+	data input(s).  (All data inputs must be the same length.)  In the
+	case of a word output, the results of the template evaluation must
+	be words, and they are concatenated with WORD.
+
+	In a template, the symbol ?REST represents the portion of the
+	data input to the right of the member currently being used as
+	the ? slot-filler.  That is, if the data input is [A B C D E]
+	and the template is being evaluated with ? replaced by B, then
+	?REST would be replaced by [C D E].  If multiple parallel slots
+	are used, then (?REST 1) goes with ?1, etc.
+
+	In a template, the symbol # represents the position in the data
+	input of the member currently being used as the ? slot-filler.
+	That is, if the data input is [A B C D E] and the template is
+	being evaluated with ? replaced by B, then # would be replaced
+	by 2.
+
+MAP.SE template data					(library procedure)
+(MAP.SE template data1 data2 ...)
+
+	outputs a list formed by evaluating the template list repeatedly
+	and concatenating the results using SENTENCE.  That is, the
+	members of the output are the members of the results of the
+	evaluations.  The output list might, therefore, be of a different
+	length from that of the data input(s).  (If the result of an
+	evaluation is the empty list, it contributes nothing to the final
+	output.)  The data inputs may be words or lists.
+
+	In a template, the symbol ?REST represents the portion of the
+	data input to the right of the member currently being used as
+	the ? slot-filler.  That is, if the data input is [A B C D E]
+	and the template is being evaluated with ? replaced by B, then
+	?REST would be replaced by [C D E].  If multiple parallel slots
+	are used, then (?REST 1) goes with ?1, etc.
+
+	In a template, the symbol # represents the position in the data
+	input of the member currently being used as the ? slot-filler.
+	That is, if the data input is [A B C D E] and the template is
+	being evaluated with ? replaced by B, then # would be replaced
+	by 2.
+
+FILTER tftemplate data					(library procedure)
+
+	outputs a word or list, depending on the type of the data input,
+	containing a subset of the members (for a list) or characters (for
+	a word) of the input.  The template is evaluated once for each
+	member or character of the data, and it must produce a TRUE or
+	FALSE value.  If the value is TRUE, then the corresponding input
+	constituent is included in the output.
+
+		? print filter "vowelp "elephant
+		eea
+		?
+
+	In a template, the symbol ?REST represents the portion of the
+	data input to the right of the member currently being used as
+	the ? slot-filler.  That is, if the data input is [A B C D E]
+	and the template is being evaluated with ? replaced by B, then
+	?REST would be replaced by [C D E].
+
+	In a template, the symbol # represents the position in the data
+	input of the member currently being used as the ? slot-filler.
+	That is, if the data input is [A B C D E] and the template is
+	being evaluated with ? replaced by B, then # would be replaced
+	by 2.
+
+FIND tftemplate data					(library procedure)
+
+	outputs the first constituent of the data input (the first member
+	of a list, or the first character of a word) for which the value
+	produced by evaluating the template with that consituent in its
+	slot is TRUE.  If there is no such constituent, the empty list
+	is output.
+
+	In a template, the symbol ?REST represents the portion of the
+	data input to the right of the member currently being used as
+	the ? slot-filler.  That is, if the data input is [A B C D E]
+	and the template is being evaluated with ? replaced by B, then
+	?REST would be replaced by [C D E].
+
+	In a template, the symbol # represents the position in the data
+	input of the member currently being used as the ? slot-filler.
+	That is, if the data input is [A B C D E] and the template is
+	being evaluated with ? replaced by B, then # would be replaced
+	by 2.
+
+REDUCE template data					(library procedure)
+
+	outputs the result of applying the template to accumulate the
+	members of the data input.  The template must be a two-slot
+	function.  Typically it is an associative function name like SUM.
+	If the data input has only one constituent (member in a list or
+	character in a word), the output is that consituent.  Otherwise,
+	the template is first applied with ?1 filled with the next-to-last
+	consitient and ?2 with the last constituent.  Then, if there are
+	more constituents, the template is applied with ?1 filled with the
+	next constituent to the left and ?2 with the result from the
+	previous evaluation.  This process continues until all constituents
+	have been used.  The data input may not be empty.
+
+	Note: If the template is, like SUM, the name of a procedure that is
+	capable of accepting arbitrarily many inputs, it is more efficient
+	to use APPLY instead of REDUCE.  The latter is good for associative
+	procedures that have been written to accept exactly two inputs:
+
+		to max :a :b
+		output ifelse :a > :b [:a] [:b]
+		end
+
+		print reduce "max [...]
+
+	Alternatively, REDUCE can be used to write MAX as a procedure
+	that accepts any number of inputs, as SUM does:
+
+		to max [:inputs] 2
+		if emptyp :inputs ~
+		   [(throw "error [not enough inputs to max])]
+		output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs
+		end
+
+CROSSMAP template listlist				(library procedure)
+(CROSSMAP template data1 data2 ...)
+
+	outputs a list containing the results of template evaluations.
+	Each data list contributes to a slot in the template; the number
+	of slots is equal to the number of data list inputs.  As a special
+	case, if only one data list input is given, that list is taken as
+	a list of data lists, and each of its members contributes values
+	to a slot.  CROSSMAP differs from MAP in that instead of taking
+	members from the data inputs in parallel, it takes all possible
+	combinations of members of data inputs, which need not be the same
+	length.
+
+		? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4])
+		[a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4]
+		?
+
+	For compatibility with the version in the first edition of CSLS,
+	CROSSMAP templates may use the notation :1 instead of ?1 to indicate
+	slots.
+
+CASCADE endtest template startvalue			(library procedure)
+(CASCADE endtest tmp1 sv1 tmp2 sv2 ...)
+(CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate)
+
+	outputs the result of applying a template (or several templates,
+	as explained below) repeatedly, with a given value filling the
+	slot the first time, and the result of each application filling
+	the slot for the following application.
+
+	In the simplest case, CASCADE has three inputs.  The second input
+	is a one-slot expression template.  That template is evaluated
+	some number of times (perhaps zero).  On the first evaluation,
+	the slot is filled with the third input; on subsequent evaluations,
+	the slot is filled with the result of the previous evaluation.
+	The number of evaluations is determined by the first input.  This
+	can be either a nonnegative integer, in which case the template is
+	evaluated that many times, or a predicate expression template, in
+	which case it is evaluated (with the same slot filler that will be
+	used for the evaluation of the second input) repeatedly, and the
+	CASCADE evaluation continues as long as the predicate value is
+	FALSE.  (In other words, the predicate template indicates the
+	condition for stopping.)
+
+	If the template is evaluated zero times, the output from CASCADE
+	is the third (startvalue) input.  Otherwise, the output is the
+	value produced by the last template evaluation.
+
+	CASCADE templates may include the symbol # to represent the number
+	of times the template has been evaluated.  This slot is filled with
+	1 for the first evaluation, 2 for the second, and so on.
+
+		? show cascade 5 [lput # ?] []
+		[1 2 3 4 5]
+		? show cascade [vowelp first ?] [bf ?] "spring
+		ing
+		? show cascade 5 [# * ?] 1
+		120
+		?
+
+	Several cascaded results can be computed in parallel by providing
+	additional template-startvalue pairs as inputs to CASCADE.  In this
+	case, all templates (including the endtest template, if used) are
+	multi-slot, with the number of slots equal to the number of pairs of
+	inputs.  In each round of evaluations, ?2, for example, represents the
+	result of evaluating the second template in the previous round.  If
+	the total number of inputs (including the first endtest input) is odd,
+	then the output from CASCADE is the final value of the first template.
+	If the total number of inputs is even, then the last input is a
+	template that is evaluated once, after the end test is satisfied, to
+	determine the output from CASCADE.
+
+		to fibonacci :n
+		output (cascade :n [?1 + ?2] 1 [?1] 0)
+		end
+
+		to piglatin :word
+		output (cascade [vowelp first ?] ~
+				[word bf ? first ?] ~
+				:word ~
+				[word ? "ay])
+		end
+
+CASCADE.2 endtest temp1 startval1 temp2 startval2	(library procedure)
+
+	outputs the result of invoking CASCADE with the same inputs.
+	The only difference is that the default number of inputs is
+	five instead of three.
+
+TRANSFER endtest template inbasket			(library procedure)
+
+	outputs the result of repeated evaluation of the template.
+	The template is evaluated once for each member of the list
+	"inbasket."  TRANSFER maintains an "outbasket" that is
+	initially the empty list.  After each evaluation of the
+	template, the resulting value becomes the new outbasket.
+
+	In the template, the symbol ?IN represents the current member
+	from the inbasket; the symbol ?OUT represents the entire
+	current outbasket.  Other slot symbols should not be used.
+
+	If the first (endtest) input is an empty list, evaluation
+	continues until all inbasket members have been used.  If not,
+	the first input must be a predicate expression template, and
+	evaluation continues until either that template's value is TRUE
+	or the inbasket is used up.
+
+
+MACROS
+======
+
+.MACRO procname :input1 :input2 ...				(special form)
+.DEFMACRO procname text
+
+	A macro is a special kind of procedure whose output is evaluated
+	as Logo instructions in the context of the macro's caller.
+	.MACRO is exactly like TO except that the new procedure becomes
+	a macro; .DEFMACRO is exactly like DEFINE with the same exception.
+
+	Macros are useful for inventing new control structures comparable
+	to REPEAT, IF, and so on.  Such control structures can almost, but
+	not quite, be duplicated by ordinary Logo procedures.  For example,
+	here is an ordinary procedure version of REPEAT:
+
+		to my.repeat :num :instructions
+		if :num=0 [stop]
+		run :instructions
+		my.repeat :num-1 :instructions
+		end
+
+	This version works fine for most purposes, e.g.,
+
+		my.repeat 5 [print "hello]
+
+	But it doesn't work if the instructions to be carried out include
+	OUTPUT, STOP, or LOCAL.  For example, consider this procedure:
+
+		to example
+		print [Guess my secret word.  You get three guesses.]
+		repeat 3 [type "|?? | ~
+			  if readword = "secret [pr "Right! stop]]
+		print [Sorry, the word was "secret"!]
+		end
+
+	This procedure works as written, but if MY.REPEAT is used instead
+	of REPEAT, it won't work because the STOP will stop MY.REPEAT
+	instead of stopping EXAMPLE as desired.
+
+	The solution is to make MY.REPEAT a macro.  Instead of actually
+	carrying out the computation, a macro must return a list containing
+	Logo instructions.  The contents of that list are evaluated as if
+	they appeared in place of the call to the macro.  Here's a macro
+	version of REPEAT:
+
+		.macro my.repeat :num :instructions
+		if :num=0 [output []]
+		output sentence :instructions ~
+				(list "my.repeat :num-1 :instructions)
+		end
+
+	Every macro is an operation -- it must always output something.
+	Even in the base case, MY.REPEAT outputs an empty instruction
+	list.  To show how MY.REPEAT works, let's take the example
+
+		my.repeat 5 [print "hello]
+
+	For this example, MY.REPEAT will output the instruction list
+
+		[print "hello my.repeat 4 [print "hello]]
+
+	Logo then executes these instructions in place of the original
+	invocation of MY.REPEAT; this prints "hello" once and invokes
+	another repetition.
+
+	The technique just shown, although fairly easy to understand,
+	has the defect of slowness because each repetition has to
+	construct an instruction list for evaluation.  Another approach
+	is to make MY.REPEAT a macro that works just like the non-macro
+	version unless the instructions to be repeated include OUTPUT
+	or STOP:
+
+		.macro my.repeat :num :instructions
+		catch "repeat.catchtag ~
+		      [op repeat.done runresult [repeat1 :num :instructions]]
+		op []
+		end
+
+		to repeat1 :num :instructions
+		if :num=0 [throw "repeat.catchtag]
+		run :instructions
+		.maybeoutput repeat1 :num-1 :instructions
+		end
+
+		to repeat.done :repeat.result
+		if emptyp :repeat.result [op [stop]]
+		op list "output quoted first :repeat.result
+		end
+
+	If the instructions do not include STOP or OUTPUT, then REPEAT1 will
+	reach its base case and invoke THROW.  As a result, MY.REPEAT's last
+	instruction line will output an empty list, so the evaluation of the
+	macro result by the caller will do nothing.  But if a STOP or OUTPUT
+	happens, then REPEAT.DONE will output a STOP or OUTPUT instruction
+	that will be executed in the caller's context.
+
+	The macro-defining commands have names starting with a dot because
+	macros are an advanced feature of Logo; it's easy to get in trouble
+	by defining a macro that doesn't terminate, or by failing to
+	construct the instruction list properly.
+
+	Lisp users should note that Logo macros are NOT special forms.
+	That is, the inputs to the macro are evaluated normally, as they
+	would be for any other Logo procedure.  It's only the output from
+	the macro that's handled unusually.
+
+	Here's another example:
+
+		.macro localmake :name :value
+		output (list "local		~
+			     word "" :name	~
+			     "apply		~
+			     ""make		~
+			     (list :name :value))
+		end
+
+	It's used this way:
+
+		to try
+		localmake "garply "hello
+		print :garply
+		end
+
+	LOCALMAKE outputs the list
+
+		[local "garply apply "make [garply hello]]
+
+	The reason for the use of APPLY is to avoid having to decide
+	whether or not the second input to MAKE requires a quotation
+	mark before it.  (In this case it would -- MAKE "GARPLY "HELLO --
+	but the quotation mark would be wrong if the value were a list.)
+
+	It's often convenient to use the ` function to construct the
+	instruction list:
+
+		.macro localmake :name :value
+		op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]]
+		end
+
+	On the other hand, ` is pretty slow, since it's tree recursive and
+	written in Logo.
+
+MACROP name
+MACRO? name
+
+	outputs TRUE if its input is the name of a macro.
+
+MACROEXPAND expr					(library procedure)
+
+	takes as its input a Logo expression that invokes a macro (that is,
+	one that begins with the name of a macro) and outputs the the Logo
+	expression into which the macro would translate the input expression.
+
+
+		.macro localmake :name :value
+		op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]]
+		end
+
+		? show macroexpand [localmake "pi 3.14159]
+		[local "pi apply "make [pi 3.14159]]
+
+
+ERROR PROCESSING
+================
+
+If an error occurs, Logo takes the following steps.  First, if there is
+an available variable named ERRACT, Logo takes its value as an instructionlist
+and runs the instructions.  The operation ERROR may be used within the
+instructions (once) to examine the error condition.  If the instructionlist
+invokes PAUSE, the error message is printed before the pause happens.
+Certain errors are "recoverable"; for one of those errors, if the
+instructionlist outputs a value, that value is used in place of the
+expression that caused the error.  (If ERRACT invokes PAUSE and the user then
+invokes CONTINUE with an input, that input becomes the output from PAUSE and
+therefore the output from the ERRACT instructionlist.)
+
+It is possible for an ERRACT instructionlist to produce an inappropriate value
+or no value where one is needed.  As a result, the same error condition could
+recur forever because of this mechanism.  To avoid that danger, if the same
+error condition occurs twice in a row from an ERRACT instructionlist without
+user interaction, the message "Erract loop" is printed and control returns
+to toplevel.  "Without user interaction" means that if ERRACT invokes PAUSE and
+the user provides an incorrect value, this loop prevention mechanism does not
+take effect and the user gets to try again.
+
+During the running of the ERRACT instructionlist, ERRACT is locally unbound,
+so an error in the ERRACT instructions themselves will not cause a loop.  In
+particular, an error during a pause will not cause a pause-within-a-pause
+unless the user reassigns the value [PAUSE] to ERRACT during the pause.  But
+such an error will not return to toplevel; it will remain within the original
+pause loop.
+
+If there is no available ERRACT value, Logo handles the error by generating
+an internal THROW "ERROR.  (A user program can also generate an error
+condition deliberately by invoking THROW.)  If this throw is not caught by
+a CATCH "ERROR in the user program, it is eventually caught either by the
+toplevel instruction loop or by a pause loop, which prints the error message.
+An invocation of CATCH "ERROR in a user program locally unbinds ERRACT, so
+the effect is that whichever of ERRACT and CATCH "ERROR is more local will
+take precedence.
+
+If a floating point overflow occurs during an arithmetic operation, or a
+two-input mathematical function (like POWER) is invoked with an illegal
+combination of inputs, the "doesn't like" message refers to the second
+operand, but should be taken as meaning the combination.
+
+
+ERROR CODES
+-----------
+
+Here are the numeric codes that appear as the first member of the list
+output by ERROR when an error is caught, with the corresponding messages.
+Some messages may have two different codes depending on whether or not
+the error is recoverable (that is, a substitute value can be provided
+through the ERRACT mechanism) in the specific context.  Some messages are
+warnings rather than errors; these will not be caught.  Errors 0 and 32 are
+so bad that Logo exits immediately.
+
+  0	Fatal internal error (can't be caught)
+  1	Out of memory
+  2	Stack overflow
+  3	Turtle out of bounds
+  4	PROC doesn't like DATUM as input (not recoverable)
+  5	PROC didn't output to PROC
+  6	Not enough inputs to PROC
+  7	PROC doesn't like DATUM as input (recoverable)
+  8	Too much inside ()'s
+  9	You don't say what to do with DATUM
+ 10	')' not found
+ 11	VAR has no value
+ 12	Unexpected ')'
+ 13	I don't know how to PROC (recoverable)
+ 14	Can't find catch tag for THROWTAG
+ 15	PROC is already defined
+ 16	Stopped
+ 17	Already dribbling
+ 18	File system error
+ 19	Assuming you mean IFELSE, not IF (warning only)
+ 20	VAR shadowed by local in procedure call (warning only)
+ 21	Throw "Error
+ 22	PROC is a primitive
+ 23	Can't use TO inside a procedure
+ 24	I don't know how to PROC (not recoverable)
+ 25	IFTRUE/IFFALSE without TEST
+ 26	Unexpected ']'
+ 27	Unexpected '}'
+ 28	Couldn't initialize graphics
+ 29	Macro returned VALUE instead of a list
+ 30	You don't say what to do with VALUE
+ 31	Can only use STOP or OUTPUT inside a procedure
+ 32	APPLY doesn't like BADTHING as input
+ 33	END inside multi-line instruction
+ 34	Really out of memory (can't be caught)
+ 35	user-generated error message (THROW "ERROR [message])
+ 36	END inside multi-line instruction
+ 37	Bad default expression for optional input: EXPR
+ 38	Can't use OUTPUT or STOP inside RUNRESULT
+ 39 	Assuming you meant 'FD 100', not FD100 (or similar)
+ 40	I can't open file FILENAME
+ 41	File FILENAME already open
+ 42	File FILENAME not open
+ 43	Runlist [EXPR EXPR] has more than one expression.
+
+
+SPECIAL VARIABLES
+=================
+
+Logo takes special action if any of the following variable names exists.
+They follow the normal scoping rules, so a procedure can locally set one of
+them to limit the scope of its effect.  Initially, no variables exist except
+for ALLOWGETSET, CASEIGNOREDP, and UNBURYONEDIT, which are TRUE and buried.
+
+ALLOWGETSET						(variable)
+
+	if TRUE, indicates that an attempt to use a procedure that doesn't
+	exist should be taken as an implicit getter or setter procedure
+	(setter if the first three letters of the name are SET) for a variable
+	of the same name (without the SET if appropriate).
+
+BUTTONACT						(variable)
+
+	if nonempty, should be an instruction list that will be evaluated
+	whenever a mouse button is pressed.  Note that the user may have
+	released the button before the instructions are evaluated.  BUTTON
+	will still output which button was most recently pressed.  CLICKPOS
+	will output the position of the mouse cursor at the moment the
+	button was pressed; this may be different from MOUSEPOS if the
+	user moves the mouse after clicking.
+
+	Note that it's possible for the user to press a button during the
+	evaluation of the instruction list.  If this would confuse your
+	program, prevent it by temporarily setting BUTTONACT to the empty
+	list.  One easy way to do that is the following:
+
+		make "buttonact [button.action]
+
+		to button.action [:buttonact []]
+		... ; whatever you want the button to do
+		end
+
+CASEIGNOREDP						(variable)
+
+	if TRUE, indicates that lower case and upper case letters should be
+	considered equal by EQUALP, BEFOREP, MEMBERP, etc.  Logo initially
+	makes this variable TRUE, and buries it.
+
+COMMANDLINE						(variable)
+
+	contains any text appearing after a hyphen on the command line
+	used to start Logo.
+
+ERRACT							(variable)
+
+	an instructionlist that will be run in the event of an error.
+	Typically has the value [PAUSE] to allow interactive debugging.
+
+FULLPRINTP						(variable)
+
+	if TRUE, then words that were created using backslash or vertical bar
+	(to include characters that would otherwise not be treated as part of
+	a word) are printed with the backslashes or vertical bars shown, so
+	that the printed result could be re-read by Logo to produce the same
+	value.  If FULLPRINTP is TRUE then the empty word (however it was
+	created) prints as ||.  (Otherwise it prints as nothing at all.)
+
+KEYACT							(variable)
+
+	if nonempty, should be an instruction list that will be evaluated
+	whenever a key is pressed on the keyboard.  The instruction list
+	can use READCHAR to find out what key was pressed.  Note that only
+	keys that produce characters qualify; pressing SHIFT or CONTROL
+	alone will not cause KEYACT to be evaluated.
+
+	Note that it's possible for the user to press a key during the
+	evaluation of the instruction list.  If this would confuse your
+	program, prevent it by temporarily setting KEYACT to the empty
+	list.  One easy way to do that is the following:
+
+		make "keyact [key.action]
+
+		to key.action [:keyact []]
+		... ; whatever you want the key to do
+		end
+
+LOADNOISILY						(variable)
+
+	if TRUE, prints the names of procedures defined when loading
+	from a file (including the temporary file made by EDIT).
+
+PRINTDEPTHLIMIT						(variable)
+
+	if a nonnegative integer, indicates the maximum depth of sublist
+	structure that will be printed by PRINT, etc.
+
+PRINTWIDTHLIMIT						(variable)
+
+	if a nonnegative integer, indicates the maximum number of members
+	in any one list that will be printed by PRINT, etc.
+
+REDEFP							(variable)
+
+	if TRUE, allows primitives to be erased (ERASE) or redefined (COPYDEF).
+
+STARTUP							(variable)
+
+	if assigned a list value in a file loaded by LOAD, that value is
+	run as an instructionlist after the loading.
+
+UNBURYONEDIT						(variable)
+
+	if TRUE, causes any procedure defined during EDIT or LOAD to be
+	unburied, so that it will be saved by a later SAVE.  Files that
+	want to define and bury procedures must do it in that order.
+
+USEALTERNATENAMES					(variable)
+
+	if TRUE, causes Logo to generate non-English words (from the
+	Messages file) instead of TRUE, FALSE, END, etc.
+
+
+Logo provides the following buried variables that can be used by programs:
+
+LOGOVERSION						(variable)
+
+	a real number indicating the Logo version number, e.g., 5.5
+
+LOGOPLATFORM						(variable)
+
+	one of the following words: wxWidgets, X11, Windows, or
+	Unix-Nographics.
+
+
+
+INTERNATIONALIZATION
+====================
+
+Berkeley Logo has limited support for non-English-speaking users.
+Alas, there is no Unicode support, and high-bit-on ASCII codes work in
+some contexts but not others.
+
+If you want to translate Berkeley Logo for use with another language,
+there are three main things you have to do:
+	1. Primitive names
+	2. Error (and other) messages
+	3. Documentation
+
+For primitive names, the easiest thing is to provide a startup file that
+defines aliases for the English primitive names, using COPYDEF:
+	COPYDEF "AVANT "FORWARD
+This should take care of it, unless your language's name for one primitive
+is spelled like the English name of a different primitive.  In that case
+you have to turn REDEFP on and be sure to copy the non-conflicting name
+before overwriting the conflicting one!
+
+"Primitives" that are actually in the Logo library, of course, can just
+be replaced or augmented with native-language-named Logo procedures and
+filenames.
+
+Of course Logo programs will still not look like your native language if
+the word order is dramatically different, especially if you don't put
+verbs before their objects.
+
+For error messages, there is a file named Messages in the logolib directory
+with texts of messages, one per line.  You can replace this with a file for
+your own language.  Do not add, delete, or reorder lines; Logo finds messages
+by line number.  The sequences %p, %s, and %t in these messages represent
+variable parts of the message and should not be translated.  (%p PRINTs
+the variable part, while %s SHOWs it -- that is, the difference is about
+whether or not brackets are shown surrounding a list.  %t means that the
+variable part is a C text string rather than a Logo object.)  If you want to
+change the order of two variable parts (no reorderable message has more than
+two), you would for example replace the line
+	%p doesn't like %s as input
+with
+	%+s is a lousy input to %p
+The plus sign tells the message printer to reverse the order; you must
+reverse the order of %p and %s, if both are used, to match.  The plus
+sign goes just after the first percent sign in the message, which might
+not be at the beginning of the line.  The sequence \n in a message
+represents a newline; don't be fooled into thinking that the "n" is part
+of the following word.
+
+Some messages appear twice in the file; this isn't a mistake.  The two
+spaces before "to" in "I don't know how  to" aren't a mistake either.
+The message containing just "%p" is for user-provided error messages
+in THROW "ERROR.  The message "  in %s\n%s" is the part of all error
+messages that indicates where the error occurred if it was inside a
+procedure; you might want to change the word "in" to your language.
+"%s defined\n" is what LOAD prints for each procedure defined if
+the variable LOADNOISILY is TRUE.  "to %p\nend\n\n" is what EDIT puts in the
+temporary file if you ask to edit a procedure that isn't already defined.
+
+Also in the Messages file are lines containing only one word each; the
+first of these is the word "true".  Some of these words are recognized by
+Logo in user input; some are generated by Logo; some are both.  For example,
+the words TRUE and FALSE are recognized as Boolean values by IF and IFELSE,
+and are also generated by Logo as outputs from the primitive predicates
+such as EQUALP.  The word END is recognized as the end of a procedure
+definition, and may be generated when Logo reconstructs a procedure body
+for PO or EDIT.  I've used capital letters in this paragraph for easier
+reading, but the words in the Messages file should be in lower case.
+
+If you replace these with non-English words, Logo will *recognize* both the
+English names and your alternate names.  For example, if you replace the
+word "true" with "vrai" then Logo will understand both of these:
+	IF "TRUE [PRINT "YES]
+	IF "VRAI [PRINT "YES]
+
+The variable UseAlternateNames determines whether Logo will *generate*
+other-language names -- for example, whether predicate functions return
+the other-language alternates for TRUE and FALSE.  This variable is FALSE by
+default, meaning that the English words will be generated.
+
+You might wish to have English-named predicate functions generate English TRUE
+and FALSE, while other-language-named predicates generate the alternate
+words.  This can be done by leaving UseAlternateNames false, and instead of
+defining the other-language predicates with COPYDEF, do it this way:
+
+	to french.boolean :bool
+	if equalp :bool "true [output "vrai]
+	if equalp :bool "false [output "faux]
+	output :bool	; shouldn't happen
+	end
+
+	to make.french.predicate :french :english :arity
+	define :french `[[[inputs] ,[:arity]]
+	                 [output french.boolean
+				    apply ,[word "" :english] :inputs]]
+	end
+
+	? make.french.predicate "egal? "equal? 2
+	? pr egal? 3 4
+	faux
+	? pr egal? 4 4
+	vrai
+	? pr equal? 3 4
+	false
+	? pr equal? 4 4
+	true
+
+The third input to make.french.predicate is the number of inputs that the
+predicate expects.  This solution isn't quite perfect because the infix
+predicates (=, <, >) will still output in English.  If you want them to
+generate alternate-language words, set UseAlternateNames to TRUE instead.
+
+Some of the words in this section of the Messages file are names of Logo
+primitives (OUTPUT, STOP, GOTO, TAG, IF, IFELSE, TO, .MACRO).  To translate
+these names, you must use COPYDEF as described earlier, in addition to
+changing the names in Messages.  You should be consistent in these two steps.
+Don't forget the period in ".macro"!
+
+For documentation, there are two kinds: this manual and the help files.
+The latter are generated automatically from this manual if you have a
+Unix system, so in that case you need only translate this manual,
+maintaining the format.  (The automatic helpfile generator notices
+things like capital letters, tabs, hyphens, and equal signs at the
+beginnings of lines.)  The program makehelp.c may require modification
+because a few of the primitive names are special cases (e.g., LOG10 is
+the only name with digits included).
+
+If you don't have Unix tools, you can just translate each helpfile
+individually.  A period in a primitive name is represented as a D in
+the filename; there are no files for question marks because the HELP
+command looks for the file named after the corresponding primitive
+that ends in P.