[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Overview

Copyright © 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, animation, parallelism, and multimedia. For those, buy a commercial version.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Getter/Setter Variable 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.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Entering and Leaving Logo

The process to start Logo depends on your operating system:

Unix:

Type the word 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 top-level, 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 Classic

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.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 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 explicitly 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 normally delimiting character entered within vertical bars is EQUALP to the same character without the vertical bars, 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.)


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on December 27, 2019 using texi2html 5.0.