
LAST
UPDATE: 10/22/98
This Learning Module is currently under construction!
This
is the most current version of Learning Module III; however, the study
guide needs to be written (for the independent learner) and
some
of the content sections, links, and assessment tools need to be fine-tuned.
(Nothing is wrong, just imperfect!)
Note
that the blinking text designates things that I need to work on; the material
is not wrong, but can be improved.
(Don't
worry, I don't like blinking text, either, so there will not be any in
the finished product!)
LOGO, AN APPLICATIVE
LANGUAGE WITH IMPERATIVE ADDITIONS
This learning module introduces the declarative programming paradigm
via the applicative (functional) programming langauge Logo. Logo
is used instead of the classic applicative langauge Lisp becasue the Logo
syntax is much more illustrative and the Logo environment makes investigating
language structures much easier. (See the handout Learn
Logo Before Lisp.) Students
will work with Logo in three
labs that
compliment this learning module and illustrate the declarative language
structures. However, this module (and thus the whole declarative
language part of this course) is introduced via an interactive, in-class
presentation using the handout DO-IT-YOURSELF
INTRODUCTION TO STRUCTURED PROGRAMMING VIA LOGO. If
you are an independent learner (not enrolled in the current class COSC450
at FSU), then, before proceeding, consult the study guide for this module.
The
sequence of presentations, in this Learning Module, is:
-
OVERVIEW
OF LOGO
-
DATA
TYPES AND OPERATIONS ON THESE TYPES:
-
VARIABLES
-
THE
ASSIGNMENT STATEMENT, AN IMPERATIVE ADD-ON FOR EASE OF USE
-
ARITHMETIC
EXPRESSIONS
-
LOGICAL
EXPRESSIONS (PREDICATES)
-
FUNCTION
AND PROCEDURES (ANOTHER IMPERATIVE ADDITION FOR UTILITY)
-
CONTROL
STRUCTURES
-
INPUT AND
OUTPUT IN LOGO
-
DATA
STRUCTURES ARE BASED ON THE LIST CONSTRUCT
-
TURTLE
GRAPHICS, A VIRTUE AND AN ACHILLES HEEL
-
ANALYSIS
OF THE LOGO LANGUAGE ENVIRONMENT
Logo has been described as both a computer language and a philosophy
of learning. The central theme of this philosophy is to learn by
experimentation. It is "a complete learning environment" in
which one explores and discovers by trial and error, an environment in
which the learner is never made to feel bad about being wrong. It
was developed from Lisp in the late 1960s by Seymore Papert and
associates at M.I.T. Papert, a long-time collaborator with the late Swiss
child psychologist Jean Piaget, added "turtle graphics" to the list
processing facilities of Lisp in order to provide a friendly environment
in which children can explore math concepts and programming constructs.
The "turtle" is actually a small triangular image on the monitor that can
be moved by Logo commands to create lines and shapes. This allows beginners
to enter the world of computer programming with immediate visual feedback
from the instructions typed. However Logo is far more than a children's
language; for example, the powerful features dealing with words and lists
of words (sentences) facilitates the writing of artificial intelligence
programs. Logo is said to have "no threshold and no ceiling" because
it is easy to learn but is extensible, i.e., new language elements
can be built from primitives and previously defined procedures in a never
ending cycle. Thus, it is sophisticated enough for the most challenging
projects.
SAQ:
Give a precise, concise definition of Logo from a PLS viewpoint. (NOTE:
this answer should evolve as you learn Logo!)
NOTE:
Unfortunately various implementations of the Logo Language have varying
elements. The following presentation is based on "minimal Logo", i.e. those
elements that are common to all versions of Logo; some nonstandard features
of Terrapin Logo will be given.
1.
OVERVIEW OF LOGO:
1.1 Logo is interpreted and, thus,
interactive by design.
-
Logo is an interpreted
language; therefore, its commands can be executed directly, outside of
any program. For example, typingPRINT "HIat the keyboard will cause
HI
to appear on the screen immediately after striking enter.
-
In interpreted languages (as
opposed to compiled languages) is essentially interactive in that
it provides instant feedback. This makes it is easy to explore programming
concepts.
1.2 Logo is moduler.
-
The built-in key words from
which all Logo statements are built are called primitives.
-
Logo procedures are modules
consisting of a self-contained block of statements that can stand alone
or be invoked by another procedure. A Logo procedure is invoked by typing
its name followed by any required parameters.
-
A Logo procedure is defined
by typing the primitive TO followed by the procedure name,
its input parameters and, on subsequent lines, the statements
making up the procedure; the procedure is terminated by typing the primitive
END. In some versions of Logo (e.g. Terrapin), typing TO followed by
the <return> (or enter) key invokes the Logo Editor, in which
a procedure can be easily written. In Terrapin Logo one chooses Open
Edit Window from the File menu.
-
There is no distinction between
procedures and functions (subprogram modules that return a value
via its name) in Logo, but a distinction will be in the following presentation.
-
Procedures (and/or functions)
can be thought of as modules from which larger units (programs,
procedures, or functions) can be built.
-
There is no clear distinction
between a Logo program and a Logo procedure. The same module can serve
both as an independent program and as a procedure called by a program or
another procedure.
-
In theory a program is
a module that is invoked by the user; a procedure is a module
invoked by a program or another procedure.
-
In practice, it is impossible
to distinguish between programs and procedures by looking at a given workspace.
The
distinction is only made by context, i.e. one would have to read each
module to identify those that must be called by a user and those that are
called by other modules. The term procedure will therefore be used in
this chapter to refer to both Logo programs and Logo procedures.
1.3 Logo is extensible.
-
An "extensible" language has
the same syntax for both its built-in commands and the user-defined
commands created by procedures or functions.
-
Logo's user-defined procedures
and functions can be formatted so that they can be used exactly like primitives.
For example, Logo does not have a built-in while loop; however, a while
loop command can be created from Logo primitives! (See section 8.5.B.)
-
The extensibility feature can
be used to rename any primitive or procedure. This makes it easy
to replace some Logo primitives with a single character making the language
useable by children who can not even spell, much less type. On the other
end of the scale, one can rename primitives so that Logo programs would
look like another language. This makes it easy to write "interpreters"
for other languages or create languages of your own! For example, Logo
can be made to perform like Lisp because their syntax is identical, only
their primitives differ.
-
This powerful
extensibility of Logo makes it a virtually unlimited language.
SAQ
1: Compare the exxtensibility of Logo and Pascal.
1.4 Logo is recursive.
-
Since recursion is theprimary
means of indefinite repetition, recursion is more easily learned and
understood with Logo than with imperative languages like Pascal.
-
Recursion is a feature that
facilitates developing Artificial Intelligence applications; it
is also the primary repetition control structure of Lisp the dominant A.
I. language.
1.5 Logo utilizes complex data structures.
-
The built-in data types (numbers,
words, and lists) can be used to create any complex data structure.
Making lists of lists is a very efficient, powerful way of implementing
linked data structures such as stacks, queues, rings, trees, graphs, etc.
-
Logo can utilize words, lists,
lists of lists, and functions as input to procedures or functions.
1.6 Logo programs can "learn", an essential
feature of A.I.
-
Since both data and programs
are, in fact, only lists off words, characters, and numbers, Logo procedures
can create and/or modify programs, procedures, or data!
-
Since Logo procedures can modify
procedures, a program (or procedure) can modify the procedures it calls.
Thus a Logo program can modify itself. In other words a Logo program
can learn! This is an essential feature of Artificial Intelligence.
1.7 Logo has other features that make
it user-friendly.
-
Nontyped variables: There
are no type declarations in Logo.
-
A variable can have any type
of value assigned to it. (One must be careful of GIGO!)
-
Automatic dynamic memory
allocation makes it unnecessary to reserve RAM for different data structures
so there is no need to declare the size of lists or words.
-
Dynamic scoping: When
a variable is accessed, Logo first looks for a local variable, which must
be identified within a procedure, of that name; if none is found it will
look for a global variable .
-
Helpful, friendly error messages:
Logo
error messages explain, in a friendly way, what caused the error
and where the error occurs.
-
Turtle graphics: Turtle
graphics, objects drawn by "turtles" (cursors), provides a means to give
a novice programmer instant visual feedback as to the results of
a command or procedure. This is highly motivating and not only helps the
learner master the language's syntax, but also helps develop the skill
of structured programming.
1.8 Logo has a simple syntax, a functional
format.
-
Every statement in Logo has
one of the following two (functional)forms:
PRIMITIVE + INPUT(S) or
PROCEDURE + INPUT(S)
NOTE: Remember that "procedure"
stands for both procedures and functions (this is unfortunate because
Logo is an applicative (i.e. "functional") language; actually Logo's procedural
facilities were additions to the functional facilities addapted from Lisp,
which is a purely functional language.
-
Primitives and procedures
can be categorized in one of two kinds:
-
Commands (analagous to
Pascal ___________(1)) which perform an action, e.g.FORWARD 50 moves
the turtle forward 50 "turtle steps"
-
Operations (analagous
to Pascal ___________(2)) output (or return) a value, e.g. ROUND 3.4 outputs
3 which becomes the input to whatever precedes ROUND
SAQ
2: Syntactically, what is the difference between Logo and Pascal?
-
Similarly, inputs can be
categorized in one of five kinds:
-
Numbers, e.g. 1991,
3.14, 1.86E5, -10.5, etc.
-
Words, which are the
primary data elements in Logo, have two designations:
-
Quoted words, which are
identified by leading quotes, represent string constants, e.g. "HI.
(NOTE: variable identifiers (i.e. memory locations)
are also designated by leading quotes, e.g. "X or "ID; see dotted words,
below.)
-
"Dotted" words,
which are identified by a leading colon, specify the value of a variable,
e.g.: X designates the value of the variable named "X. For example,
MAKE "LENGTH 100FORWARD :LENGTH
assigns 100 to the variable
named ____________(3) whose value _____________(4) is, in turn, used as
input to the primitive _______________(5).
-
Lists, which are identified
by surrounding brackets, e.g.
[A E I O U],
[1 [2.2 2.5] 3],
[THIS IS A SENTENCE AS WELL AS A LIST.], etc.
The List is the primary
data structure in Logo.
-
Operations (functions)
which output a value that must be used as an input, e.g.
FORWARD SUM 10 20 or
PRINT ROUND 3.4.
-
Actually, all inputs to primitives
and procedures must be numbers, string constants, or lists. Thus ________________(6)
must eventually return values that are numbers, string constants, or lists
and ________________(7) must eventually output values that are numbers,
string constants, or lists.
-
Whenever the Logo interpreter
encounters a word that is neither quoted nor dotted, it assumes the word
is either a primitive, a procedure, or a function.
This is an important point to remember when trying to interpret Logo error
messages.
TPQ
1: Words in Logo programs are one of five kinds. What are they?
SAQ
3: What is the difference between words and strings in Logo?
1.9 Logo Utilizes the "Workspace"
Rather Than Files:
Logo does not provide standard
facilities for the reading and writing of disk files from within programs.
As in most languages, Input/Output is implementation dependent.
However, accessing disk files is not as important in Logo as in other languages
because Logo relies on the concept of a workspace..
-
A "workspace" consists
of all procedures and values of variables that were defined during
a given programming session. The workspace is saved to disk as a
unit and read back in from disk as a unit.
-
The workspace concept is characteristic
of Logo and Lisp and, unusual among programming languages. The procedures
exist more or less independently in a workspace.
-
Subject to space limitations,
any number or Logo procedures can be in a workspace, whether or not they
are related.
-
Informative documentation
is essential in any "workspace" environment! Because there is no syntactic
distinction of a "main procedure", external documentation is needed
to indicate which procedure(s) should be called first by the user. (Obviously,
a workspace will be capable of providing more than one "tool" to the user,
so all such procedures will be available (at "top level") when the workspace
file is loaded.) Internal documentation is needed to explain each
procedure because lack of nesting makes it impossible to determine the
reason for the procedure's existance and origin of invocation. Thus, there
is no way, from the syntax, to determine the hierarchy of invocations within
a workspace! Therefore, the software developer is responsible for explaining
this in external documentation. (NOTE: all of this is also true in Lisp!)
SAQ
4: Explain the statement, "In a way, the workspace itself is like the "program"
of Pascal or the "main" of C++".
-
If a Logo program needs to
maintain a set of data from one session to the next, it does not need
to create a separate disk file. It can instead store the data in free variables
within the workspace. Then, when the workspace is saved, the free variables
are saved along with any procedures that happen to be in the workspace.
-
The command to (a) save and
(b) read a workspace are as follows:
-
SAVE "<WSNAME>
-
LOAD "<WSNAME>;
where <WSNAME> is the desired
name for the workspace.
-
Manipulation of external
files is implementation dependent so the reader is referred
to the appropriate Logo reference manuals.(See the "Streams" handout
for Terrapin.)
SAQ
5: What is the primary (a) similarity and (b) difference between
(1) a workspace and a file and (2) a workspace and a program?
2. DATA
TYPES AND OPERATIONS ON THESE TYPES:
The primitive data types in Logo are numbers, words, and lists. (There
is a nonstandard string type in some versions of Logo, e.g.Terrapin Logo.)
Each type is presented, in the following sections along with operations
associated with them. There are no type declarations in Logo so the user
is not required to make any special acknowledgment of types.
2.1 Numbers:
Logo numbers can be integers
or floating point numbers, but numbers are weakly typed,
i.e. there is no strong distinction between integers and floating point
numbers. They may be used more or less interchangeably within the appropriate
ranges. Logo converts freely between integer and floating point numbers
as necessary in arithmetic expressions.
-
Integers can range between
approximately plus 2 billion and minus 2 billion.
-
Floating point numbers
can range in magnitude from approximately ten to the minus 38th power to
ten to the plus 38th power. Floating point numbers are accurate to about
7 digits. Floating point constants can be written with or without an exponent,
for example:
3.14159
-2.3E2 = -230
2.5N1 = 0.25
-
The first two numbers are written
as they are in most other languages. The E indicates a positive power of
10. The N in the third number indicates a negative power of 10.
2.2
Lists,
the Primitive Data Structure of Logo (and all Declarative Languages):
-
A list is a sequence of elements,
separated by blanks and delimited by square brackets, e.g.[This is a list
of 7 words.]
-
While a word is manipulated
___________-by-____________(8), a list is manipulated __________-by-__________(9).
-
Quotation marks are not needed
for the words in a list.
-
A list may include
-
numbers.
-
another list, e.g. [[a list]
within a list] is a list which has _________(10) elements.
-
The empty list is written as
"[]"
-
There is only one space between
the words in a list; if you try to put multiple spaces between the words
in a list, most systems will eliminate the extra blanks. Multiple spaces
must be embedded within a word, as discussed in section 2.2.G.
-
The list is the fundamental
built-in data structure which can be used to build more complex data structures.
This will be discussed in more detail in the section on data structures.
-
Individual elements in a list
can be manipulated by the FIRST, BUTFIRST, LAST, and
BUTLAST
commands. When used with lists, these commands operate on the elements
of the list, which are ________ or __________(11).
-
FIRST is a function
that returns the first element of a list.
-
Similarly, LAST
returns the _________________________________(12).
-
BUTFIRST returns
the new _______(13) consisting of all but the _________________(14) of
the list that is its argument.
-
Similarly, BUTLAST
returns the__________________________________(15).
-
For example:
-
FIRST [This is easy!]
returns _________(16),
-
FIRST [[ AN INTERIOR LIST] WITHIN A LIST]
returns ________________(17).
-
LAST [ This is easy!]
returns ___________(18).
-
BUTFIRST [[ AN INTERIOR LIST] WITHIN A LIST]
returns ____________________(19).
-
BUTLAST [[ AN INTERIOR LIST] WITHIN A LIST]
returns _____________________(20).
-
Procedures for manipulating
the interior list elements are discussed in the next sections.
SAQ
6: What is the difference between the types of the values returned
by FIRST and BUTFIRST when operating on lists?
SAQ
7: FIRST BUTFIRST BUTLAST [one two three four] returns what?
SAQ
8: What is the difference between the primitive "List" operations in Logo
and those taught in our Data Structures courses (virtually all texts, as
well!)?
2.3 Words, special cases of the List:
-
A word (or a string
constant or a string value) in Logo is a string of characters.
Actually, a word is a List of characters, but, in Logo, it has a meaning
distinct from the list.
-
A word is written with a leading
quotation mark, e.g. "HI is a word.
-
A word is terminated by a
space or a square bracket; no final quotation mark is required. Thus
the statement PRINT "HI" would produce _________(21) on the screen.
-
Logo commands that allow
manipulation
of the individual characters of a word are the same as those for lists.:
-
FIRST is a function
that returns the ____________________________(22).
-
Similarly, LAST
returns the _________________________________(23).
-
BUTFIRST returns
the new _______ consisting of all but the _________________(24)of the word
that is its argument.
-
Similarly, BUTLAST
returns the__________________________________(25).
-
EXAMPLES:
-
PRINT FIRST "LOGO will print ___________(26).
-
PRINT LAST "LOGO will print ___________(27).
-
PRINT BUTFIRST "LOGO will print __________(28)
(See the SAQs after section 2.3.)
-
PRINT BUTLAST "LOGO will print __________(29).
(See the SAQs after section 2.3.)
SAQ
9: What is the difference between the types of the values returned
by FIRST and BUTFIRST when operating on words?
SAQ
10: In Logo there is no character data type as there is in Pascal.
Why is there no need for one? Could the same be true for Pascal?
-
There are no primitives for
accessing interior letters of a word; the are accessed indirectly
using sequences of _____ and ________(30) or _____ and _______(31). Methods
for doing so will be discussed later .
-
It is important to note that
a
number is a word, but a word is not necessarily a number. A number
can be used anywhere a word can be used. The commands that are used to
manipulate words will also manipulate numbers in the same way. Obviously,
however, arithmetic operations cannot be performed on words that are not
numbers.
-
The words "TRUE and "FALSE
have
special meaning, as will be discussed in the section on logical expressions.
-
The empty word is indicated
by a quotation mark alone, i.e.
PRINT "
will print___________(32). The
utility of the empty word will not be evident until we begin writing recursive
procedures manipulating words and lists.
-
The backslash key is
used for special formatting of text output in Terrapin Logo that
tells Logo to print the following character exactly as it is, e.g.
-
the following characters must
be backslashed if you want them to be part of a word:
-
all math and comparison symbols:
+ - * / < > =,
-
spaces and <return>,
-
brackets and parentheses: [
] ( ),
-
semicolon: ;,
-
backslash itself (use two: \\),
and
-
lowercase characters (e.g. PR
"h\i would print Hi.)
-
Blanks, since they are
the delimiters of Logo words are a nuisance to insert in output text. In
Terrapin Logo a blank can be inserted is a list or sentence by using the
backslash character, i.e. PRINT [1\ 2] would print 1 and 2 separated by
one blank; PRINT [1 \ 2] would print 1 and 2 separated by ___________.
2.4 Other Word and List Operations:
-
The WORD command takes
two or more words as inputs and combines them into a single word, e.g.
WORD "out "put
returns ______________(33).
Parentheses
must be used with more than two inputs. The parentheses must contain
the command as well as its arguments, e.g.
(WORD "OUT "PUT "S )
returns _____________(34).
-
The LIST command receives
two or more words and/or lists and returns a single list. If an input is
a list, that list will remain intact as an element of the new list e.g.
(LIST "one [ two three ] 4)
returns [ONE [ TWO THREE] 4]
SAQ
11: Note that PRINT (LIST "one [ two three ] 4) writes ONE [ TWO THREE]
4 not [ONE [ TWO THREE] 4] on the screen! Why?
-
The SENTENCE command
is similar to LIST, but it removes one level of brackets from arguments
that are lists, e.g.
(SENTENCE "one [ two three] 4)
returns [ ONE TWO THREE 4].
SAQ
12: PRINT (SENTENCE [ This ] [is] [[ a sentence ] containing a list.] )
produces what on the screen?
-
The FPUT command receives
two inputs (only) and returns a list with the first input concatenated
to the beginning of the second input. The first input of FPUT may be a
word or a list, but the second input must be a list.
-
The LPUT command is similar
to FPUT but the first input is concatenated to the ______(35) of the second
input.
SAQ
13: Think up a good SAQ that checks one's understanding of FPUT and LPUT?
-
SUMMARY (by example):
-
LIST [AB] [C] [[AB] [C]]
yields ________________(36)
-
SENTENCE [AB] [C] [AB C] yields
________________(37)
-
FPUT [AB] [C] [[AB] C]
yields ________________(38)
-
LIST [AB] "C [[AB] C]
yields ________________(39)
-
SENTENCE [AB] "C [AB C]
yields ________________(40)
-
FPUT [AB] "C yields
error
-
LIST [[A]] [B] [[[A]] [B]]
yields ________________(41)
-
SENTENCE [[A]] [B] [[ A] B]
yields ________________(42)
-
FPUT [[A]] [B] [[[ A]] B]
yields ________________(43)
SAQ
14: Why did FPUT [AB] "C give an error?
SAQ
15: What is the difference in LIST and SENTENCE when their inputs are words
instead of lists?
3.
VARIABLES:
-
Variables in Logo can have values
that are numbers, words, or lists.
-
There are no explicit variable
declarations in Logo.
-
A variable name can be
any legitimate Logo word.
-
The variable name is designated
by a leading quotation mark, e.g. "X is a variable identifier.
-
The value of a variable
can be obtained in two different ways. Assume the variable "X has the value
2.
-
The Logo function THING can
be used to get at this value, e.g. THING "X will return the number
2.
-
Because this is such a common
operation, there is another, abbreviated, way to accomplish the same thing:
PRINT
:X The colon is usually called dots in Logo.
NOTE: There are occasions where
the dots abbreviation can not be used. For example, in the Call by
Binding technique of parameter passing, the parameters are passed as variable
names (quoted words), so THING must be used inside such procedures to access
the value of these parameters. (See section
7.3, below, its link to Call by
Binding, and Lab 6.)
SAQ
16: What would PRINT "X produce on the screen?
-
Logo variables may be local
to a particular procedure, or they may be global.
-
Local variable have meaning
only within the procedure where they are declared; this is done by using
the primitive LOCAL followed by each variable to be designated as local.
-
Global variables in Logo
are called free variables. A free variable exists on its own
in a workspace and is accessible from within any Logo procedure
in that workspace. It keeps its value from one execution of a procedure
to the next. When a workspace is saved, the values of all free variables
are saved with it.
-
Parameters are not distinguished
as such in Logo. They are simply referred to as arguments or inputs
to primitives or procedures.
4.
THE ASSIGNMENT STATEMENT, AN IMPERATIVE ADD-ON:
-
The MAKE command in Logo associates
a variable name with a specific value. Thus, the first argument required
by MAKE is a variable name (designated by a leading quotation mark), and
the second argument must be the value to be assigned, e.g.
MAKE "X 2
MAKE "Y "HI
MAKE "Z [Ho Hum]
MAKE "W :X
-
The value may be a number,
a word, a list, or the value of another variable. Recall that to obtain
the value of that other variable, you must precede its name with "dots".
-
To print out the value of the
four variables above, we could write
PRINT :X which
would produce ____________(44) on the screen.
PRINT :Y which
would produce ____________(45) on the screen.
PRINT :Z which
would produce ____________(46) on the screen.
PRINT :W which
would produce ____________(47) on the screen.
-
Typing MAKE
"X 2 outside of a procedure
in Logo creates X as a global variable.
5.
ARITHMETIC EXPRESSIONS:
-
Most arithmetic expressions
in Logo use conventional infix notation. The arithmetic operators provided
are +, -, *, and/.
-
The division operator (/) produces
real results, that is PRINT 5/2
will print 2.5.
-
Integer division is accomplished
using the primitives (functions) QUOTIENT
and REMAINDER
which accept two arguments.
-
To find the integer quotient
of 5 and 2, one would type PRINT QUOTIENT 5 2;
the result would be_______(48).
-
Similarly, to find the remainder
of this division, one would type PRINT
___________(49);they result would be _____(50).
-
Parentheses are necessary, as
in all languages that use infix notation, to insure the arithmetic operations
are conducted in the proper order.
SAQ
17: If the variable RADIUS has a value, how would one write the Logo statement
that calculates the area of the associated circle and assigns that value
to the variable to CIRCLEAREA?
-
Random numbers can be generated
by the primitive function RANDOM
which requires one argument. PRINT RANDOM 5
will print a random integer between 0 and 4. Other ways of treating random
numbers are implementation dependent so consult the associated manual.
6.
LOGICAL EXPRESSIONS (PREDICATES):
-
In Logo logical expressions
are called predicates. The result of a predicate in Logo is either
"TRUE or "FALSE, e.g. PRINT 2 > 1
would print TRUE,
and PRINT 2 < 1
would print _________(51).
-
The basic logical
operators in Logo are <, >, =, and NOT which have
the usual meanings.
-
Additional logical operators,
each of which use prefix notation, include the following (in MSW Logo):
-
NUMBERP which returns
"TRUE
if its argument is a number,
-
WORDP which returns "TRUE
if its argument is a _________(52),
-
LISTP which returns "TRUE
if its argument is a _________(53), and
-
THING which returns "TRUE
if its argument is a variable that has some value associated with it.
SAQ
18: The fact that there are no <= or >= operations in Logo is a pain!
How would one perform operations that require these conditionals?
7.
FUNCTION AND PROCEDURES (ANOTHER IMPERATIVE ADDITION FOR UTILITY):
7.1 Functions, the Essential
Modularity Construct of Applicative Languages:
SAQ
19: In general, what is the fundamental difference between a procedure
and a function in any language?
SAQ
20: Functions have one big advantage over procedures in that their use
within a program can make coding more efficient. What is this advantage?
-
In Logo there is no overt distinction
between functions and procedures, i.e. there is nothing that distinguishes
a function from a procedure; there are only procedures and nothing else.
However, there are procedures that behave like functions in other languages
in that they return a single result via the "procedure" name. Such procedures
will be referred to as functions in this presentation.
-
Logo provides the usual built-in
functions such as SQRT, which returns the square root of its argument.
A description of these functions can be found in the separate handout,
LOGO
COMMAND SUMMARY.
-
User-defined functions contain
the OUTPUT primitive which causes the result of an operation to be associated
with the function name. The operation is usually an expression which forms
the argument of the function, e.g.
TO DOUBLE :X
OUTPUT 2 * :X
END
is a mathematical function which
returns , via the name DOUBLE,
the result of the mathematical expression 2 * :X.
-
If the user types DOUBLE
2, Logo will respond RESULT:4.
-
However, function outputs are
usually used as inputs to procedures or other functions, e.g. PRINT
DOUBLE 2
-
The OUTPUT
statement causes an immediate exit from the function, regardless of its
position within the function itself. (Such premature exits are not allowed
in Pascal.)
-
EXAMPLE: The function
equivalent of the preceding procedure FIND.TRIANGLE.AREA
is
TO "TRIANGLE.AREA :Base :Height
OUTPUT (1/2) * :Base :Height
END
The invoking statement TRIANGLE.AREA
5 2 will cause __________(54)
to be printed on the screen.
7.2 Procedures, another Imperative Ease-of-use
add-on that makes Logo an "impure" applicative language:
-
There is no distinction between
Logo procedures and Logo programs; henceforth we will refer only to
Logo procedures.
-
Logo procedures are defined
by typing:
-
the primitive TO followed
by the name of the procedure and an optional list of "formal
arguments" (formal parameters),
-
the instructions of the procedure,
and
-
the primitive END which
terminates the procedure definition, e.g.
TO FIND.TRIANGLE..AREA :Base :Height
MAKE "Triangle.Area (1/2) * :Base :Height
END
The variable Triangle.Area is
a _____(55) variable, i.e. it will have the assigned value anywhere in
the workspace.
-
Note that Logo has arguments
(input parameters) but no explicitly designated output parameters
as in imperative languages. Output is either via global variables (which
encourages harmful "side effects") or via the function name. However,
the
equivalent to pass by reference can be implemented by using "Call by Binding".
(See section 7.2.E and its references.)
-
The invoking statement
FIND.TRIANGLE.AREA 5 10
would result in :Triangle.Area
being _________(56) throughout the workspace.
SAQ
21: Most versions of Logo do not facilitate indentation within a procedure.
However, using Logo's extensibility feature, Logo may be "taught "to indent.
How can this be done?
-
In Logo the formal arguments
(formal parameters) are simply dotted words written after the name of the
procedure, separated by blanks. "Actual arguments" (actual parameters)
are supplied in the calling statement of Logo procedures; these may be
numbers, words, or lists. (Note that if an actual argument is
a word ("quoted identifier") this implements "Call by Binding", an
impure imperative construct that is operationally equivalent of pass by
reference in imperative languages. See section 7.3, below.)
-
As in any language, Tony encourages
programmers to use verbs for _____________(57a) names and
nouns
for _____________(57b) names. Why?
7.3 Parameters
(arguments):
-
Formal parameters (formal
arguments) are always declared by typing them, as dotted words, on the
same line as the procedure or function name.
-
Actual
parameters in purely functional languages, behave as value parameters,
i.e. they are function arguments used only for "pass by value".
-
Therefore, normally, Logo
functions and procedures are called using actual arguments that are either
constants or variable values (dotted words).
-
However, "call by binding"
(the practical equivalent of "pass by reference" of imperative languages)
is a rarely used, but useful, imperative construct made possible by Logo's
versatile syntax. To accomplish this, no distinction is made in the
formal parameter declarations (as done in imperative languages using
pass by reference); however, a quoted word is used in the calling statement,
e.g.
-
Example: The calling
statement
MAKE "X POP "STACK
; (Note the quote mark on "STACK.) This is part of the assignment
in Lab 6.
The name of the variable
STACK (i.e. "STACK) is passed to the function POP rather than a value
(:STACK). This is effectively the same as pass by reference or passing
a pointer to the address of the variable STACK.
-
Although call by binding is
NOT a functional construct, this is a useful "impurity" that avoids
the need to use global variables when a function or procedure needs
to change two or more things. Functions, by definition, return only
one result, via the function name. If call by binding is not used
any other thing modified in the function would have to be a global variable,
with their inherent danger of side effects. (
See
the separate discussion, CALL BY BINDING
IN LOGO and its application in Lab
6.)
-
In some versions of Logo, e.g.
MSW Logo, "call by binding" is operationally equivalent to pass by reference.
See the separate document, Call
by Binding in Logo.
7.4 Local variables:
-
The function LOCAL
inputs a variable name or a list of names and makes it local to the current
procedure or function. Thus the variable(s) has ____________________(58)
outside the procedure. If assignments are made to a local variable, variables
with the same name outside the procedure are ______________________(59).
-
Local variables are similar
to parameters in that they are specifically defined to be processed
by the procedure, but unlike parameters they are assigned values with
MAKE
instead of when the procedure is called.
-
The syntax of the function
LOCAL
is
LOCAL VarName
(LOCAL VarName1 VarName2...)
e.g. (LOCAL"Name
"Height "Age).
SAQ
22: How would one make the variable Triangle.Area local in the procedure
in section 7.1.B? What effect would this have? Would it make sense to do
this?
8.
CONTROL STRUCTURES:
Compared to imperative languages like Pascal C, Logo has relatively few
control structures. Its primary selection mechanism is the indespensible
If-then-else;
there is no case statement in minimal Logo. The most widely-used control
structure for repetition in Logo is recursion. It has definite (count-controlled)
loop, REPEAT which
is an ___________
add-on to the language. It is more limited than a typical FOR loop in other
languages. Surprisingly (to those unused to functional languages), there
is no conditional (while) loop. However, one of Logo's powerful features
is that, if a control structure is needed that is not availlable as
a primitive, it can be created as a user-defined control structure. (See
section
8.4, below).
8.1 Simple Selection: the IF-THEN-ELSE
Statement:
-
The syntax for the standard
IF-THEN-ELSE statement, in MSW Logo, is as follows:
IF predicate L1
; If-then
IFELSE predicate L1 L2 ; If-then-else
-
The predicate
in Logo is called a ________ or__________
expression in other languages.
-
The symbols L1 and L2 each stand
for one statement or a list of statements. L2 is optional
-
If the predicate is true, L1
is executed; if the predicate is false, L2 is executed.
-
Other versions of Logo have
a syntax:
IF predicate L1 L2 ;Terrapin Logo
IF predicate THEN L1 ELSE L2
where L1 and L2 (optional) are
single statements or groups of statements.
-
EXAMPLE of a standard IF-THEN-ELSE
statement in MSW Logo:
IFELSE :Hours > 40 [PAY.OVERTIME] [PAY.REGULAR.RATE];
If-then-else
IF :Hours < 0 [PRINT [
What?! Hours worked less than zero?!]] ;If-then
SAQ
23: How would one write an IF-THEN-ELSE that only does something if the
predicate is false?
-
The major problem with IF-THEN-ELSE
structure is that the entire statement must be typed as one line, as in
most versions of BASIC. (It may wrap around to the next line.)
-
This restriction, combined with
the lack of indentation in most version of Logo, tends to make the IF-THEN-ELSE
hard to read, especially compared to the equivalent statements in Pascal
or C.
-
Because of this problem, some
versions of Logo offer the TEST statement, another way to achieve the same
result. We will ignor this here because . . .
-
allows instruction formatting via use of the <tab>
key. When editing a Logo procedure, the <return> key terminates an instruction
(the <enter> key causes execution of an instruction). Thus and instruction
like IF predicate L1 L2 must be written on one line (the logo editor will
automatically wrap if the line is too long) unless the <tab> key is
used, e.g.
IFELSE predicate <tab key>
L1 <tab key>
L2 <return key>
will cause the more readable
formatting.
8.2 Definite Loops, an Imperative Add-On
for Ease of Use:
-
The only type of iteration built
into Logo is the REPEAT statement, a very limited form of a definite loop.
The syntax is:
REPEAT :N [statement(s)]
-
The :N
may be either a variable or a constant.
-
The statement or statements
within the square brackets are repeated the appropriate number of times.
-
There is no automatic incrementing
of a counter variable as in the FOR statement of BASIC
or Pascal, nor is there any conditional testing as in a while statement.
However, such constructs can be simulated using user-defined control structures;
see section 8.4.
-
SIMPLE EXAMPLE:. The
following procedures prints, on the screen, the integers from 1 to a value
input as a parameter of the procedure.
TO COUNT :I
; this prints the integers from one to :I on
the screen.
______________(61)
________________________________(62)
END
8.3
Recursion, Logo's only built-in indefinite repetition construct:
-
A procedure or function is recursive
if it calls (or invokes) itself.
-
Recursion is the primary
method of repetition in Logo (as it is in Lisp), because recursion
is a powerful technique for the processing of lists, the primary
data structure in Logo.
-
EXAMPLE OF A RECURSIVE PROCEDURE:
A
recursive procedure can also be used in much the same way as a conditional
loop would be in another language. Consider, for example, a procedure to
counts from one input value to another.
TO R.COUNT.I.TO.N :I :N
;a recursive procedure that counts from :I to :N
IF :I > :N [STOP]
PRINT :I
R.COUNT.I.TO.N :I + 1 :N
END
SAQ
24: Rewrite COUNT of section 8.2B as a recursive procedure.
SAQ
25: Rewrite R.COUNT.I.TO.N using an IF-THEN-ELSE rather than an IF.
-
EXAMPLE OF A RECURSIVE FUNCTION:
The factorial of a positive integer is a mathematical function that
is defined recursively. The factorial of zero is defined as one. The factorial
of a positive integer N is defined as N times the factorial of N-1. This
definition is recursive because it is defined in terms of itself. A recursive
implementation of the factorial function is:
TO FACTORIAL :N
;recursively computes the factorial of :N
IF :N = 0 [OUTPUT 1]
OUTPUT :N * FACTORIAL :N - 1
END
SAQ
26: Rewrite FACTORIAL using an If-then-else construct rather than an if-then.
-
EXAMPLES OF RECURSION IN
LIST-PROCESSING:
-
The following recursive procedure
is self explanatory.
TO LIST.LIST :List
;this lists the element of List vertically
IF EMPTY? :List [STOP]
PRINT FIRST :List
LIST.LIST BUTFIRST :List
END
NOTE: EMPTY? returns
true if its argument is an empty list or empty word, otherwise it returns
false
SAQ
27: Rewrite LIST.LIST without using EMPTY?.
-
The following recursive function
sums
a list of numbers when it is not known in advance how many numbers there
are in the list.
TO SUM :List
; this sums a list of numbers
IF BUTFIRST :List = [ ] [OUTPUT FIRST :List]
OUTPUT ( FIRST :List ) + SUM BUTFIRST :List
END
-
Getting accustomed to using
recursion as a matter of routine often takes some time for programmers
who first learned to program with a nonrecursive language. In Logo recursion
is natural, so most will find that it is well worth the effort.
8.4
User-defined Control Structures:
The absence of control structures like the while loop or case statement
in Logo is of no significance. As indicated above, recursion can accomplish
anything that otherwise would require an indefinite loop and nested if-then-elses
behave like a case statement. On the other hand, any control structure
can be created using the Logo RUN command, so should one want to use
a control structure not available as a primitive in Logo, it can be simulated.
This very powerful feature of Logo leads to its extensibility and customizability;
it also makes it easy to write interpreters in Logo.
-
The RUN command runs
an input list (its argument) as if each instruction were typed in directly.
The syntax is:
RUN List
-
If List is a function, then
RUN outputs whatever List outputs.
-
EXAMPLE:
TO CALCULATE
PR RUN READLIST
PR []
CALCULATE
END
If one types CALCULATE,
followed by 2 + 3, 5 will appear on the screen. The program can be terminated
from the keyboard.
-
SIMULATED WHILE LOOP: The
following procedure runs a list of instructions while a specified condition
is true.
TO WHILE :Condition :LoopBody
IFELSE RUN :Condition
[RUN :LoopBody WHILE :Condition :LoopBody]
[STOP]
END
SAQ
28: Write a simulated REPEAT UNTIL loop. (This is part of Lab 5.)
SAQ
29: Write a simulated FOR loop that increments its loop control variable
by one each time the loop repeats.
(This
is part of Lab 5.)
SAQ
30: What error traps are needed for this while construct? (Hint:
they must detect ________ errors.) How are they implemented?
9. INPUT AND
OUTPUT IN LOGO:
Input/Output in Logo, as
in many languages, is implementation dependent. In the following
sections the standard primitives of minimal Logo are discussed; nonstandard
I/O are designated as such or are given as outside references.
9.1 Output In Logo Is Rather Simplistic:
-
Output limitations include:
-
a lack of built-in procedures
for formatting text or numbers,
-
the interpreter and editor ignoring
blanks, thus not allowing formatting of sentences or lists (Terrapin Logo
has minimal indentation facility of using <tab> instead of <return>
in a sequence of statements>), and
-
output is only in upper-case
in most versions of Logo.
-
The PRINT
command (abbreviated PR)
normally takes one argument, whether it be a number, word, or list. It
can take multiple arguments when the command and its arguments are enclosed
by parentheses, e.g. he following two PRINT
statements will produce identical results:
PRINT [THIS IS A TEST]
(PRINT "THIS "IS "A "TEST )
-
Note, that in the former statement,
PRINT
has but one argument, which is a ______(). In the latter statement, PRINT
has four arguments, each of which is a ______().
-
In some limited versions of
Logo (not Terrapin) the placement of parentheses is critical. In such versions
the last parenthesis must be separated from the preceding word by a space;
otherwise Logo would think that the word was TEST) and wouldn't be able
to find the closing parentheses.
-
The PRINT
statement always causes a carriage return and line feed to be output after
its arguments.
-
In some versions of Logo (e.g.
Terrapin) the PRINT1
statement outputs its argument(s) without the carriage return and line
feed; in Apple Logo II the same effect is accomplished with the TYPE statement.
With multiple arguments, it does not output spaces between each argument.
This is useful for labeling output, as in the following example:
PRINT1 [THE ANSWER IS] PRINT :X which
causes the prompt and the value of X both to appear on the same line of
the display.
SAQ:
What Pascal instructions are equivalent to (a) PRINT and (b) PRINT1?
-
Output can be redirected from
the screen to a printer. Unfortunately, the technique for doing so is implementation-dependent.
-
For Terrapin Logo for the Macintosh,
the command that redirects output isSETWRITE OPENW "PRINTER::
All
subsequent output (except error messages) will sent to the selected printer.
CLOSE
WRITER cancels the SETWRITE
"PRINTER:: instruction.
-
WRITER outputs the
current file or device that is open for writing.
-
EXAMPLE: The following
procedure prints a hardcopy listing of the contents of the workspace:
TO PAPER.POALL
SETWRITE OPENW "PRINTER::
POALL
CLOSE WRITER
END
9.2 Input In Logo Is Sophisticated but
Implementation Dependent:
-
Logo provides several primitives
for input from the keyboard. There are two standard input primitives.
-
The function READLIST (RL)
reads an input line (terminated by a return) and returns the result as
a list.
-
The function READCHAR (Apple
Logo II) or READCHARACTER (Terrapin Logo) (RC) reads a single
character and returns it as a word, e.g.
MAKE "X RC
waits for input. If 3 were typed,
it would not appear on the screen but would be assigned to the variable
"X.
SAQ:
What would happen if HI were typed as input to RC?
-
READER outputs the current
file opened for reading.
-
Nonstandard Input primitives
in Apple Logo II:
-
READCHARS (RCS) outputs
a specified number of characters read from the current file or device (The
default is the keyboard.). The number is specified by a parameter, e.g.READCHARS
5 selects the next 5 characters encountered.
-
READPOS outputs the
file position of the current file being read.
-
READWORD (RW) outputs
the line read by the current device (default is the keyboard) after a carriage
return.
-
Nonstandard I/O in Terrapin
Logo for the Macintosh (windows and streams) is given in separate references.
-
EXAMPLE USING READLIST: A
common
error in Logo is to fail to recognize the form of the input. If a number
is desired as an input, a list must be read and the number extracted from
the list. This process is illustrated in the following example program.
TO FIND.CIRCLE.AREA
; illustration of input/output
and the use of READLIST
; the primitive PRINT1 is
available in Terrapin Logo but not Apple Logo II
PRINT [ ]
PRINT [ENTER RADIUS: ]
MAKE "RADIUS FIRST READLIST
MAKE "A 3.14159 * :RADIUS
* :RADIUS
PRINT [ ]
PRINT1 [THE AREA OF A CIRCLE]
(PRINT [WITH RADIUS ] :RADIUS
[IS ] :A)
PRINT [ ]
END
This program calculates
the area of a circle; it prompts the user to input the radius from the
keyboard. The command READLIST returns a list from the keyboard, and FIRST
READLIST extracts the first word from that list, which happens to be a
number. The MAKE command assigns the value of this number to the variable
RADIUS. This form of input takes some getting used to by programmers
with experience in more conventional languages such as Pascal.
E. EXAMPLE USING READCHAR:
TO TYPER
; an electronic typewriter
in Apple Logo II using a GO statement in an infinite loop
; DRIBBLE 1 is an Apple Logo
II primitive that sends subsequent output to a printer.
PRINT [ENTER YOUR TEXT, FOLLOWED
BY <CONTROL-C.>]
DRIBBLE 1
LOOP: MAKE "C READCHAR
IF :C = CHAR 3 [TYPE [ ]
NODRIBBLE STOP]
TYPE :C
GO "LOOP
END
a. Because Logo does not
support lowercase, neither does this electronic typewriter.
b. Depending on the printer,
it may not output anything until a carriage return is typed; then it will
print the whole line.
c. Notice that TYPER has
no provision for stopping itself. Terrapin Logo programs can be stopped
by choosing STOP or PAUSE from the Debug Menu or using their key equivalents,
<command>-S and <command>-P. STOP returns control to top-level; PAUSE
suspends execution; the procedure may be continued by typing CONTINUE or
CO. It is therefore common to deliberately include infinite loops in Logo
programs; it makes a the program simpler. However, such a practice should
be used with care.
SAQ: Rewrite TYPER
for Terrapin Logo for the Macintosh. (HINT: Consider the procedure PAPER.POALL
given previously.
SAQ: Rewrite TYPER
using recursion instead of the GO statement. Two procedures will be needed.
Why?
10.
DATA STRUCTURES ARE BASED ON THE LIST CONSTRUCT:
The basic minimal Logo data
types (numbers, words, and lists) support the construction of some very
sophisticated data structures. All user-defined data structures are
constructed from lists. It is simple to implement , , rings,
etc. because of their close kinship to the list. The key to creating multidimensional
data structures is that a list can include other lists as members. This
allows the creation of , , and Graphs as lists of lists. Some data
structures such as arrays and records are very awkward when implemented
with lists; therefore, a special type of list called a property list
is provided, and in some versions of Logo (including Terrapin Logo)
arrays are available
10.1
Linked Lists, the Fundamental Data Structure of Logo:
A. In imperative languages
linked lists must be created using built-in data structures such as arrays
or records with pointers. Because the list is a built-in data structure
in Logo, it is simple and natural to use linked lists.
It is not necessary to deal directly with the links or an end-of-list indicator,
as these are taken care of by the language itself, invisible to the user.
B. The creation of a list
in Logo can be accomplished by
a. using the assignment
statement, e.g.
MAKE "NAME.LIST [TONY TOM
DICK HARRY]
b. inputting via READLIST,
and
c. using the function
LIST which outputs a list consisting of its arguments, which may be
any Logo data type.
C. The primary primitives
for moving through lists are _______, ____________, _________, and
_______________. Notice that, true to the characteristics of lists, only
the first and last elements can be directly accessed whereas in arrays
and records every element can be directly accessed. This is not strictly
true, however, because ITEM (See below.) does allow outputting any specified
element.
D. List Manipulators
(in addition to those above) are:
a. FPUT obj
list outputs a list formed by putting its first input in front
of List.
b. LPUT obj
list outputs a list formed by putting its first input at the end
of List.
c. ITEM n list outputs
the nth element of list.
E. List Interrogators, which
get information from lists, are:
a. COUNTlist outputsthe
number of elements in list.
b. EMPTY? obj outputs
TRUE if obj is an empty list (or empty word).
c. EQUAL? obj1 obj2
outputs
TRUE if its arguments are equal.
d. LIST? obj outputs
TRUE if obj is a list.
e. MEMBER? obj1
obj2 outputs TRUE if its first argument is an element of its second
argument.
NOTE: The list manipulators
and interrogators can be used with any Logo data object, not just lists.
F. Other procedures for handling
lists need to be built from the above primitives, for example INSERT and
DELETE are defined on the following page
TO INSERT :NAME
:L
; to insert an element, :NAME,
into a list, :L
IF :L = [] [OUTPUT LIST :NAME
:L]
IF LTEQ :NAME FIRST
:L [OUTPUT FPUT :NAME :L]
OUTPUT (SE FIRST :L INSERT
:NAME BUTFIRST :L)
END
TO LTEQ :A :B
; Boolean function outputs
TRUE if :A <= :B. This procedure is discussed in section
; 10.1.F.c, below.
; Note: this is a useful
function because Logo can not handle <= or >=
IF ASCII FIRST :A < ASCII
FIRST :B [OUTPUT "TRUE]
IF ASCII FIRST :A > ASCII
FIRST :B [OUTPUT "FALSE]
IF BUTFIRST :A = " [OUTPUT
"TRUE]
IF BUTFIRST :B = " [OUTPUT
"FALSE]
OUTPUT LTEQ BUTFIRST
:A BUTFIRST :B
END
TO DELETE :NAME :L
; to delete a specific element
from a list
END
SAQ: Write a Boolean
function GTEQ, analogous to LTEQ above, that returns true if the first
argument is greater than or equal to the second argument.
SAQ: Fill in the three
blank lines of the function DELETE above.
a. Using the INSERT procedure
you could add Bill to the list as follows:
MAKE "L INSERT "BILL :L
b. Tony could be deleted
from the list by typing the following:
__________________
c. Logo does not provide
directly for the comparison of characters or words. The < and
> operators work only with numbers. (The = works with numbers and words).
The INSERT procedure requires word comparison so that the name can be inserted
into its proper position alphabetically, so a new procedure, LTEQ,
had to be written to carry out this comparison.
(1) The procedure LTEQ
compares its two inputs and determines whether or not its first input is
less than or equal to its second input (alphabetically). The comparison
is done a letter at a time and uses the ASCII function to convert the letter
to its numeric representation.
(2)The procedure first attempts
to make the comparison based on the first letters of each word. If the
first letters are equal, it first checks to see whether one of the words
has no more letters. (This would distinguish B from BE, for example.) If
not, the procedure is called recursively to deal with the remaining letters
of each word.
D. The logic of the INSERT
and DELETE procedures may take some study to understand. Neither is
very long, however, so they are easy to trace. Short, easily traceable,
procedures such as this should be used as building blocks for longer, more
complicated procedures.
10.2 Property Lists: a
Built-In Extension of the List:
A. A property list consists
of an even number of elements. Each pair of elements consists of a property
and its value; values can be any Logo object. A property list has the
format:
[property1 value1 propery2
value2 property3 value3 . . .]
i.e. __________ are the odd
numbered members and the _______ are the even numbered members.
B One manipulates property
lists using a special set of primitives designed specially for them.
In
Terrapin Logo the commands are:
a. GETPROP name property
which
returns the value of a specified property from the property list
name,
b. PLIST word which
returns the property list associated with the specified word,
c. PUTPROP name property
value which, if the property is not already present, adds it
to the list and assigns it the value specified (Property lists are
built by assigning property-value pairs using the PUTPROP primitive), and
d. REMPROP name property
which
removes property and its associated value from the property list
name.
C. NAME and MAKE can not
be used with property lists and property lists can not be accessed
as normal variables.
D. Property lists are beyond
the scope of this course so they will not be treated further. Anyone wish
to use property lists should refer to the Terrapin Logo Reference Manual.
10.3 Arrays, an (Impure)
Imperative Data Structure Added for Ease of Use:
A. Some versions of Logo
have the array as a built-in data structure (e.g. Terrapin Logo for
the Macintosh). Others require that the array be simulated by using
the list or property list; see section 10.4 below.
B. Logo arrays, like those
of Pascal, are random access and mutable (elements are selectively
changable), but, unlike arrays in Pascal, they are heterogeneous,
i.e. they _______________________________________________________. .
C. Arrays in Terrapin Logo
are similar to those in Pascal so they will not be covered in this presentation
which concentrates on the differences between Logo and imperative languages.
Anyone wishing to use Logo arrays should refer to the Terrapin Logo
Reference Manual.
10.4 User-Defined Data
Structures:
User-defined data structures are exactly the opposite from those of Imperative
languages. In Imperative languages all data structures are constructed
from the two built-in primative data structures __________() and ___________
(linked with ___________()); in declarative language the _______() is the
primative and all linking is therefore transparent. In the following
section, we investigate how the imperative data structure primatives are
constructed in Logo. In Lab
6 the student will see how easy it is to construct stacks, queues,
and ordered lists.
-
User-Defined Arrays:
-
Minimal Logo does not support
the array. . It is straightforward to use a list or, even better, a property
list as if it were an array. However, some array operations not represented
by Logo primitives would have to be written; some of these can be complicated.
-
Retrieving an array element:
to
retrieve a particular element from a list, as if that list were an array,
one could utilize the primitive ITEM:
TO ELEMENT :Index :Array
_________________
END
In order
to assign the third element of [A B C D] to the variable Letter, one would
have to write ____________________.
-
Assignment to an array element:
Lists
in minimal Logo are not "mutable", i.e. a list element can not be
changed in place; the entire list has to be recopied. Therefore, it is
not a trivial exercise to write a Logo procedure to assign a value to an
array.
-
The COUNT primitive makes it
easy to determine the size of an array.
-
User-Defined Data Structure:
Records:
-
Logo does not require the
advance declaration of data structures; therefore, there is no syntax
for declaring a record as there is in Pascal, for example. To implement
a record data structure, one would (1) create a list of lists (The
"file" or "database" would be the outermost list; each record would be
a list nested within the outermost list; and the fields would be lists
nested within each record.) or (2) utilize a property lista (a more
efficient approach).
-
Because there is no specific
syntax to illustrate a generic record structure, a minimal Logo implementation
of a record using a list is illustrated by a simple example: a file of
records containing the names of students and their scores on up to 20 tests.
One can represent the field "Name" by a list, and the field "test scores"
by another list. Because lists are used (instead of arrays), one need not
specify in advance how many test scores there might be.
-
File Creation : A file
containing the records of two students is created by typing, on one line:
MAKE 'CLASS [[[JOHN DOE] [95 87 100 93]] [[MARY
SMITH] [98 85 95 88]]]
-
Logo procedures for manipulating
the records of the File "Class": (Notice that each procedure is quite
short.)
-
To print out all the student
names:
TO ROSTER :CLASS
PRINT FIRST FIRST :CLASS
IF NOT BUTFIRST :CLASS = [ ] [ROSTER
BUTFIRST :CLASS]
END
-
To retrieve the Ith record in
the list:
TO GET.RECORD :I :A
IF :I = 1 [OUTPUT FIRST :A]
OUTPUT GET.RECORD ( :I - 1 ) BUTFIRST
:A
END
-
To retrieve the record that
matches a given student name
TO GETNAME :NAME :CLASS
; return the record of :NAME
IF :CLASS = [ ] [PRINT [NOT FOUND] OUTPUT
[ ] STOP]
IF :NAME = FIRST FIRST :CLASS [OUTPUT FIRST
:CLASS]
OUTPUT GETNAME :NAME BUTFIRST :CLASS
END
-
To retrieve the scores from
a given record (as a list)
TO GETSCORES :NAME :CLASS
IF :CLASS = [ ] [PRINT [NOT FOUND] OUTPUT
[ ] STOP]
IF :NAME = FIRST FIRST :CLASS [ OUTPUT FIRST
BUTFIRST FIRST :CLASS]
OUTPUT GETSCORES :NAME BUTFIRST :CLASS
END
-
To retrieve the Ith test score
from a list of scores
TO GETTEST :I :RECORD
; function that returns the ith test score
IF :I = 1 [OUTPUT FIRST :RECORD]
IF BUTFIRST :RECORD = [ ] [PRINT [NOT THAT
MANY TESTS] OUTPUT [ ] STOP]
OUTPUT GETTEST ( : I - 1 ) BUTFIRST
:RECORD
END
-
To print out the entire file:
TO PRINT.CLASSBOOK :CLASS
PRINT FIRST :CLASS
IF NOT BUTFIRST :CLASS = [ ] [PRINT.CLASSBOOK
BUTFIRST :CLASS]
END
-
The preceding procedures canhandle
most requirements for record retrieval (used singly or in combination).
Another
set of procedures would have be written to handle update requirements.
-
EXAMPLES of the use of
the preceding procedures:
-
To print out all the names,
that is, a class roster type _____________________.
-
To print out the name and scores
of the second student, type ___________________.
-
To print out the record of John
Doe, type ____________________________.
-
The scores are separated from
the rest of the record using GETSCORES.
Individual test scores are retrieved from a list of scores using GETTEST.
For example, to print the score received by John Doe on the third test,
type
PRINT GETTEST 3 GETNAME [JOHN DOE]
:CLASS
This illustrates how Logo
functions can be combined, with the output of one function becoming the
input to another procedure.
-
Obviously it is more difficult
and tedious to handle records in Logo than in languages where records are
a built-in data type, e.g. Pascal. This is the reason that Logo would
not be the language of choice for "data processing" applications involving
records.
-
Every operation that is built
into record handling languages (e.g. simple assignment of a value to field
variable) would have to have a corresponding Logo procedure written for
it.
-
However, it is straight-forward
(if not simple) to write procedures to handle any specific collection
of records; to write a set of procedures that can handle a file of arbitrary
records is much more difficult.
10.5 Comparison of Logo Data Structures
with Those of Other Languages:
See a separate
Handout
Logo's
Underlying Data Structures
11.
TURTLE GRAPHICS, A VIRTUE AND AN ACHILLES HEEL:
Logo is best known for its turtle graphics capabilities. In fact, this
could
be the "achilles heel" of Logo because turtle graphics are so successful
at introducing children to the Logo language, many people, including teachers,
consentrate on the turtle graphics facilities to the extent that they are
unaware of its other powerful features. The primary reason for introducing
turtle graphics this late in the this presentation is that it emphasizes
the fact that turtle graphics is only one small part of a very powerful,
general computer language. (In Terrapin Logo, which has sophisticated turtle
graphics, only 61 of a total of 292 primitives are turtle graphics commands.)
-
Turtle graphics in Logo is very
similar to the graphics package of the same name provided as part of the
Turbo Pascal. The main difference is that in Logo (because it is an interpreter),
unlike Pascal, graphics commands can be interactively executed directly
from the keyboard.
-
The central metaphor of Turtle
Graphics is the turtle. The turtle is an imaginary creature that
can be moved about the screen. (In most Logo implementations the turtle
is represented on the screen by an isoceles triangle, the point of which
indicates the direction the turtle is heading.) He carries with him a pen,
which can be "down" so that it leaves a trail, or "up" so that it does
not leave a trail. The pen can write with different colors of ink, depending
on the capabilities of the computer and video monitor.
-
The turtle can be moved forward
or backward a given number of "turtle steps" by the primitive commands
FORWARD
and BACK, or he can be turned
to the right or left (RIGHT
or LEFT commands)a specified
number of degrees. Using combinations of these primitives, the turtle can
be made to draw any shape.
-
The details
of turtle graphics are implementation dependent. Some versions
allow for the turtle to take on diffenent shapes via the STAMP command.
Some versions (e.g. Terrapin Logo for the Macintosh and Sprite Logo) also
facilitate multiple turtle on the screen at once; combined with the STAMP
command this facilitates simple animated graphics. Creating a Pacman game
is a straightforward exercise.
-
Examples of turtle graphics
are given in the handout, DO-IT-YOURSELF INTRO
TO PROGRAMMING VIA LOGO, and elsewhere. A few of the essential
characterristics of turtle graphics are illustrated in the classic Logo
procedure DRAW.SQUARE:
TO DRAW.SQUARE :Size
SHOWTURTLE
PENDOWN
REPEAT 4 [ FORWARD :SIZE RIGHT 90]
HIDETURTLE
PENUP
END
In case the turtle had been
hidden and its pen been raised from the paper (it which case it will not
draw while moving), the primitives SHOWTURTLE
and PENDOWN initialize the
procedure. After the variably sized square is drawn by the REPEAT
loop, the turtle is hidden from view and its pen raised in anticipation
of other subsequent operations by the primitives HIDETURTLE
and PENUP.
-
One of the fascinating things
about turtle graphics in Logo is that a few short procedures can be
used to create a variety of designs. Given a few short procedures,
a child (or even an adult!) can create variation upon variation on the
basic theme, based on the symmetry of the the procedures.
12.
ANALYSIS OF THE LOGO LANGUAGE ENVIRONMENT:
12.1 Advantages of Logo:
-
Logo is virtually unique
as a learning environment.
-
The primary advantages of Logo
over other languages are its ease of learning and ease of use.
-
Young children can learn to
program in Logo, almost as soon as they can learn to read. Logo is designed
for interactive users with the user seated at the keyboard. This facilitates
a learning by discovery approach that is fun and user-friendly.
What attracts children to Logo is the graphics. What keeps their interest
is the friendly, interactive environment. Advanced features such as lists
and recursion will be discovered via natural curiosity.
-
Logo facilitates the learning
of structured programming skills because it is very modular and does
not encourage the use of the GOTO (GO in Logo).
-
Logo, with its Turtle Graphics
capabilities, facilitates learning concepts especially geometry,
but in programming, the immediate graphic feedback is useful in illustrating
the effects of language structures.
-
Logo, an descendent of Lisp,
inherits a facility for implementing artificial intelligence algorithms.
Logo easily supports data structures of many kinds, including lists, queues,
and trees which are well-suited for the organization of knowledge. The
function-based syntax, and recursion oriented control structures are well
suited for manipulating these data structures. The result is a language
that can accommodate the development of programs that rely upon accumulated
knowledge and upon decision making based on that knowledge. Since procedures
are lists of instructions and Logo can manipulate lists, Logo can write
or modify programs; therefore, a Logo program can modify itself, the
essential feature of machine learning.
-
Logo, like Lisp, is best
suited for tasks involving linked lists, stacks, queues, trees, etc.
Its list processing facilities make it unusually powerful in manipulating
text although its limitation to upper-case
and lack of formatting utilities reduce its usefulness in this area.
-
Logo can handle symbols as well
as numbers. It is excellent for those sorts of tasks that require the manipulation
of words, characters, and other symbols. One such potential application
would be symbolic differential calculus.
-
One of Logo's principal strengths
is in graphics. Complex graphic images are easily created in Logo using
Turtle
Graphics.
-
Logo procedures can be developed
and defined separately, and then can be used together. This means that
when a single procedure is modified, the other procedures in the program
do not have to be redefined. This greatly speeds the development of complex
programs.
12.2 Disadvantages of Logo:
-
Logo programs are not easy
to read.
-
To accommodate nesting of constructs
(either control or data) brackets are necessary. When combined with minimal
Logo's inability to indent, the numerous enclosed brackets can be very
confusing. (However this problem is not as acute as the infamous parentheses
of Lisp!)
-
Logo commands are typically
based on functions. Therefore many operations that humans are familiar
with in their infix notations look strange in their prefix format.
For example, (A < B) AND (A < C) is easier to read than AND (A <
B) (A < C).
-
Logo does not have the relational
operators <= and >=; therefore, the simple infix relation A <=
B has to be written AND (:A < :B) (:A = :B) which is considerably harder
to read, particularly when the relational expressions are complicated.
-
Because Logo is based on recursion,
Logo
programs take up a great deal of memory space (more than analogous
programs in an imperative language).
-
Because Logo is an interpretive
language, Logo programs are relatively slow in execution.
-
Although Logo can handle simple
calculations, numeric computation is not its main strength. It lacks many
mathematical operations (although these can easily be defined), and without
arrays many mathematical algorithms are tedious to implement in minimal
Logo.
-
As a string processing language,
the list processing power of minimal Logo is somewhat negated
by its lack of formatting features and the restriction to upper-case output.
-
Logo is not a strongly typed
language and thus allows bugs that would normally be identified by type
checking.