Turtle Tracks documentation
Turtle Tracks documentation
Turtle Tracks documentation
Copyright ©1997-1998 Daniel Azuma. All rights reserved worldwide.
This is the current working draft of the documentation for Turtle Tracks. It is intended as a reference manual, and not an introduction to Logo or a primer for first-time programmers.
Note: Significant sections of this document are not yet completed.
Table of contents
About Turtle Tracks 4
Running Turtle Tracks 4
Running the graphical environment 7
The Turtle Tracks implementation of Logo 7
Language concepts 7
Parsing, operators and precedence 12
Key features 12
Runtime environment 12
Standard Commands 14
Data structures 14
Constructors 14
Selectors 17
Queries 19
String Manipulation 21
Flow Control 22
Executor Structures 23
Mapping Structures 26
Conditional Structures 28
Loop Structures 29
Threads 32
Error Handling 37
Jump Commands 39
Input/output 41
Reading and writing 41
Opening streams 44
Stream Management 46
File system management 49
Mathematical Operations 50
Logical operations 51
Bitwise operations 52
Comparison operations 54
Numeric operations 56
Trigonometric operations 60
Workspace Management 64
General workspace control 65
Procedure operations 67
Variable operations 72
Property list operations 75
Advanced operations 78
Turtle Graphics Commands 81
Window Management 81
Turtle Motion 84
Turtle Position Queries 86
Turtle State 87
Color palette operations 90
Appendix 92
Differences between Turtle Tracks and UCBLogo 92
Daniel Azuma (dazuma@)
Last updated 3 February 1999
About Turtle Tracks
Turtle Tracks is a modern Logo interpreter and runtime environment written entirely in Java. It is not a direct port of an existing interpreter, but written from the ground up specifically for Java, and designed to take advantage of the strengths of Java as a language and environment. Turtle Tracks is platform-independent and Internet-ready, and supports numerous advanced features such as multithreading and networking. Unlike similar projects such as Bongo, Turtle Tracks is true Logo and supports the same Logo syntax and the same primitives as other Logo implementations. It also supports plug-in primitive sets and should, in the future, allow integration with outside Java code as a scripting language.
Note: this section of the manual not yet completed.
Daniel Azuma (dazuma@)
Last updated 25 July 1997
Running Turtle Tracks
Turtle Tracks can be run in several different forms: with a text-based command line interface, a graphical window interface, or a custom-built interface; with or without turtle graphics, or with or without other extensions to the primitive set. These forms are chosen by selecting a plug-in interface class, and a set of plug-in primitive groups. Shortcuts are provided for some of the more common configurations
Installation
The Turtle Tracks distribution includes a Java zip file called "turtletracks.zip". This zip file contains the entire Turtle Tracks program, including the language engine, the standard primitive group plug-ins, user interface plug-ins for a command line interface and a graphical window-based interface, and several tools for running the application.
This zip file should be installed in your classpath. Normally, it should not be expanded, but should instead be installed directly as a zip file. Consult the documentation for your Java runtime environment for details on how to set up your class path.
Command line interface quick start
Once the zip file has been installed, you can initiate a Logo session using the operating system's command line by invoking the helper class "virtuoso.logo.app.Cli". Under some operating systems and Java runtime environments, you accomplish this by typing the command:
java virtuoso.logo.app.Cli
Consult your Java documentation for details specific to your Java implementation.
The virtuoso.logo.app.Cli helper class launches Turtle Tracks using a standard command line based user interface, and including all the standard primitive groups. However, it does not automatically include the turtle graphics primitive group, because command line based systems sometimes do not provide windowing capability. If you wish, you can manually load the turtle graphics system by issuing the Logo command:
LOADPRIMITIVES "virtuoso.logo.lib.TurtlePrimitives
The command line system also does not support an editor window. Any attempts to invoke the EDIT command will result in an error.
Mac OS Runtime for Java 2.0 currently does not support command line input. Do not attempt to run virtuoso.logo.app.Cli under Mac OS Runtime for Java 2.0.
Graphical interface quick start
You can initiate a Logo session using a graphical window-based interface by invoking the helper class "virtuoso.logo.app.Gui". Under some operating systems and Java runtime environments, you accomplish this by typing the command:
java virtuoso.logo.app.Gui
Consult your Java documentation for details specific to your Java implementation.
The virtuoso.logo.app.Gui helper class launches Turtle Tracks using a graphical window-based interface, and including all the standard primitive groups, plus the turtle graphics primitives. The graphical interface also supports editing through the EDIT command, or through menu commands. See Using the graphical environment for more details on running the graphical version of Turtle Tracks.
If you are running Mac OS Runtime for Java, you can also download a standalone double-clickable application that automatically runs the graphical interface. This installation requires no classpath modification, because all the Java code for the program is embedded within the application itself.
Using virtuoso.logo.app.Run
Turtle Tracks also provides a general tool for specifying custom-built sets of primitives, custom plug-in user interfaces, and other advanced options. This tool can be used by invoking the class virtuoso.logo.app.Run. The general form for this is as follows:
java virtuoso.logo.app.Run [switches]
Using the switches, you can specify exactly which plug-ins to use. For example, to run the command-line interface with only the core standard primitives and classloading primitives (but no networking, files, threads, or the like), you could invoke:
java virtuoso.logo.app.Run -c virtuoso.logo.app.CliConsole -p virtuoso.logo.lib.StandardPrimitives virutoso.logo.lib.LoaderPrimitives
Here is a list of the different switches that can be used:
1. -c consoleclass
Specifies a console (user interface) class to use. The -c switch should be followed immediately by a fully-qualified class name. If no -c switch is present, Run chooses virtuoso.logo.app.CliConsole by default. If multiple -c switches are used, Run chooses the last console specified.
2. -p primitiveclass [primitiveclass2...]
Specifies a primitive group class to use. The -p switch should be followed immediately by any number of fully-qualified class names. All primitive groups specified are added to the interpreter's primitive set.
3. -std
Specifies all the standard primitive classes: virtuoso.logo.lib.StandardPrimitives, virtuoso.logo.lib.FilePrimitives, virtuoso.logo.workPrimitives, virtuoso.logo.lib.ThreadPrimitives, virtuoso.logo.lib.ShellPrimitives, virtuoso.logo.lib.LoaderPrimitives and virtuoso.logo.lib.LibraryPrimitives
-std is essentially shorthand for invoking -p followed by all the above class names.
The virtuoso.logo.app.Cli and virtuoso.logo.app.Gui classes described above are shortcuts for some common configurations. Cli is exactly the same as:
java virtuoso.logo.app.Run -c virtuoso.logo.app.CliConsole -std
Gui is exactly the same as:
java virtuoso.logo.app.Run -c virtuoso.logo.app.GuiConsole -std -p virtuoso.logo.lib.TurtlePrimitives
Daniel Azuma (dazuma@)
Last updated 11 December 1997
Running the graphical environment
See also: Running Turtle Tracks
Note: this section of the manual not yet completed.
Daniel Azuma (dazuma@)
Last updated 11 December 1997
The Turtle Tracks implementation of Logo
• Language concepts
• Parsing, operators and precedence
• Key features
• Runtime environment
Turtle Tracks is a unique implementation of Logo, built entirely using the Java language and platform. This chapter describes the Logo language specification and key language concepts, and the details of the Turtle Tracks implementation of Logo, including tokenizing and parsing, command semantics, and the runtime model.
|Language concepts |
Lisp background
Logo is a derivative and distant cousin of the Lisp programming language. Like Lisp, it employs no static type checking., and its data structures consist of string atoms and typeless lists. Logo programs are structured as collections of functions which interact with call-by-value semantics. State is represented in the form of symbols that can be bound to functions, immutable data, and several other elements of the environment. All data is referenced through pointer semantics, and a garbage collector reclaims unused space.
Unlike most languages in the Lisp family, however, Logo uses dynamic scoping, and Logo functions are not first-class. Because of this, Logo is often considered a hybrid functional/imperative language. Logo also includes a large library of primitive functions, including more powerful list-manipulation functions than are typically offered by implementations of Common Lisp or Scheme. In addition, Logo syntax differs from most variants of Lisp in several key areas. First, list boundaries are denoted by square brackets instead of parens, and do not delimit separate function calls. Also, Logo syntax supports several infix operators for use in mathematical expressions. Some implementations of Logo, including Turtle Tracks, add additional features such as exception handling, threads, streams, and property lists.
Data structures
Two types of logo data structures exist: words and lists. A word, analogous to an atom in other Lisp derivatives, is represented by a single string. A list is an ordered collection of other Logo data structures, which can include words and other lists. Primitive functions exist for list manipulation, including accessing the elements on both ends of a list.
A Logo word is represented by a string, delimited by white space or by square brackets. Delimiting characters or certain escape characters may be represented using backslashes. In addition, a special character, the vertical bar, may be used to escape an entire sequence of characters. Here are a few examples of Logo words:
1. MAKE
2. "Hello!!!
3. This\ is| a long string...|\|| |
(represents the string "This is a long string...| ") what is then the meaning of the back and the vertical slashes?
A Logo list is a collection of data, separated by white space, and enclosed in square brackets. Here are a few examples of lists
4. [Hello world]
(represents a list of two elements)
5. [[This is a list] within a list]
(represents a list of four elements, the first of which is another list)
6. [|This list| |has only two elements|]
(represents a list of two elements, both of which are words)
7. []
(represents the empty list)
Names
A name is a triple consisting of an identifying word, a value (which may be a word or a list), and a scope. Names may be bound and unbound using primitives in the Logo language. The scope of a name is defined by the syntactic manner in which it is bound, and the runtime environment in which it is bound. The value corresponding to a name may be retrieved using Logo primitives.
Scope in Logo is dynamic. That is, a stack is kept at runtime, each element of which contains one level of scope. When a name is bound, unbound, or accessed, its identifier is searched for starting from the top scope in the stack, and working down towards the bottom scope in the stack, which is called the global scope. The first instance of the identifier found in this manner is used. The global scope is always present; higher scopes, called local scopes, are added and removed by function invocations.
Functions
A function is a mapping from an ordered list of pieces of data, called arguments, to a single piece of data, called the return value or result. When a function is invoked, it gains and keeps control of the machine until it has completed calculating the return value.
Two orthogonal classifications of functions exist. The first is normal versus macro. These differ in their behavior with respect to "stop" exceptions, which direct function termination and report return values. The other classification is named versus anonymous. Named functions are defined as those that are parts of procedures, where a procedure is a pair consisting of an identifying name and a function. Functions which are not named functions are called anonymous functions, also sometimes called "lambda expressions."
Associated with each function is a nonnegative integer value, the default number of arguments. This number is used when a function is in a command list, to assist in parsing its arguments.
Commands
A command is an object which performs some computation when it is invoked, possibly producing side effects, and generates a return value. A command may be a data constant, or a procedure with its arguments. A word constant command is represented by a word consisting of a quote (") followed by the representation of the data itself. If the word is numeric, the quote may be omitted. A list constant command is simply represented by the list representation. A procedure command is represented by a left paren, followed by the procedure's name, followed by its arguments in order, followed by a right paren. If, however, the function is being passed its default number of arguments, then both parens may be (and usually are) omitted.
The semantics of the invocation of a command are as follows: If the command is a constant, then its return value is the value of that constant. If the command is a procedure, then its arguments are evaluated by first invoking those commands. The return values thereof are then given to the procedure's function as its arguments, and control of the machine is given to the function. The return value of the command is the return value generated by the function after it halts. If the function does not generate a return value, then the command does not generate a return value.
Command lists
A command list, sometimes called an executable list, is a list containing an ordered series of commands. The following are examples of command lists:
8. ["hello]
(One command: a word constant.)
9. [print "hello]
(One command: a named function followed by one argument: a word constant.)
10. [print "hello [hello world]]
(Two commands: a named function with one argument, and a list constant. The named function, print, has a default number of arguments value of 1.)
11. [(print "hello [hello world])]
(One command: a named function with two arguments.)
12. [print sqrt 30]
(One command: a function with one argument: a function with a word constant as an argument.)
13. [print sqrt 30 make "a "b]
(Two commands, both functions. The first function has a default number of arguments of 1; the second has a default number of arguments of 2.)
14. []
(The empty command list: no commands.)
The semantics of the execution of a command list are as follows: all commands in the list are invoked in order. The return value of the command list is the return value of the first command that generates a return value. If no command in the list generates a return value, the command list generates no return value. If more than one command generates a return value, the semantics of the command list are to raise an "error" exception upon the generation of the second return value.
Lambda lists
A lambda list is a list describing an anonymous function. It contains a formal argument list and a command list. The formal argument list must be a list of words, which are interpreted as name identifiers. There are two classifications of lambda lists: normal lambda lists and macro lambda lists. A normal lambda list contains two elements: the first being the formal argument list, and the second being the command list. A macro lambda list contains at least one element: the first being the formal argument list, and the rest of the elements comprising the command list.
Here are examples of lambda lists:
15. [[x][output :x*:x]]
(Normal lambda list with one formal argument.)
16. [[x] :x*:x]
(Macro lambda list with one formal argument.)
17. [[]]
(Empty macro lambda list with no arguments.)
The semantics of the invocation of a lambda list are as follows: First, a new scope is created on top of the scope stack. Next, the formal argument names are bound in this new scope to the arguments passed into the function. Then, the command list is executed, and a return value is generated. Once the command list has completed execution, either by finishing the invocation of all its commands or by having an exception thrown out of it, the new scope is removed. Lambda lists are often invoked by the execution of the primitive APPLY, but may be invoked in other ways.
The means by which a return value is generated depends on the type of function-- i.e. the type of lambda list. If the lambda list is a macro lambda list, then the return value is the return value of the command list. If, however, the lambda list is a normal lambda list, then the return value is the value associated with any "stop" exception thrown out of the command list. If the command list does not throw a "stop" exception, or it throws a "stop" exception without an associated value, then no return value is generated. "Stop" exceptions are generally thrown by the invocation of the primitives STOP or OUTPUT.
Procedures
Two types of procedures exist: user-defined procedures and primitives. A primitive is a procedure that is implemented in Java and cannot be generated, modified or removed from within the Logo runtime environment (with certain exceptions). A user-defined procedure consists of an identifying word, a list of formal argument names, and a text string describing the procedure. This text string is parsed into a command list upon invocation of the procedure. User-defined procedures can be modified and manipulated from within the Logo runtime environment, through primitives such as DEFINE and TEXT, and the special forms TO and TOMACRO.
The semantics of invoking a user-defined procedure are the same as the semantics of invoking a lambda list. A scope is created, and the formal arguments are bound, the command list is executed, a return value is optionally generated, and the scope is destroyed. User-defined procedures may also be classified into normal and macro procedures, with semantic differences analogous to the corresponding lambda lists.
Exceptions
An exception is a pair consisting of an identifying word called the id, and an optional piece of data called the value. Two operations on exceptions are possible: throwing and catching.
Exception semantics are as follows: An exception is thrown by a command. The exception propogates up the evaluation tree until it is caught, or until the execution has reached the top level. When an exception is caught, it is prevented from propogating further, and its parts may optionally be processed.
There are three types of exceptions: error exceptions, stop exceptions, and user-defined exceptions. Error exceptions are usually thrown by commands when they encounter an unexpected condition such as a runtime type error. If they are not caught, they typically cause execution to terminate with an error message. Stop exceptions are thrown by the STOP and OUTPUT primitive. A stop exception is caught automatically once it attempts to propogate out of a normal (non-macro) function. Stop and error exceptions are usually not explicitly caught by a Logo program. The third type, user-defined exceptions, are thrown by the THROW primitive and are usually caught explicitly by the program using the TRY or CATCH primitives.
- topTop
|Parsing, operators and precedence |
This section of the manual not completed.
- topTop
|Key features |
This section of the manual not completed.
- topTop
|Runtime environment |
The Turtle Tracks environment is unique because it was designed from the ground up to run atop the Java runtime environment. Because of this, it supports some features and abilities that are uncommon among more traditional Logo implementations, and it also suffers a few drawbacks related to its dependence on Java. In addition, several key differences exist between Turtle Tracks and traditional Logo runtimes.
Threaded operation
All operations in Turtle Tracks are run in Java threads. In particular, when a direct command is entered from the console, a new thread named ".MAIN" is created for it, even if the command itself does not involve threading. This provides a high degree of flexibility and responsiveness in the user interface and allows instant and clean interruption of running command lists. However, because of this, some aspects of the operation of Turtle Tracks may be slightly dependent on the thread implemenetation of the Java runtime and/or the underlying operating system. Some runtimes may limit the number of threads that may be run simultaneously, and some runtimes may exhibit various levels of decreased interactivity while a Logo command is being run due to idiosyncracies in thread time sharing. A few Java runtimes may contain bugs that cause instability at high levels of thread activity. Consult the technical documentation for your Java VM for further details.
Runtime linking
Java programs are linked at runtime instead of at compile time like most language systems. This dynamic linking opens the door for powerful extension features, and Turtle Tracks takes advantage of this by providing a plug-in primitive group architecture. In addition to the standard set of primitives provided, external primitive sets can be loaded and linked in or unloaded at will using the LOADPRIMITIVES and UNLOADPRIMITIVES commands, providing a powerful opportunity for customization. An API, described in the Turtle Tracks Java Programmers Guide (not yet available), allows Java programmers to create custom primitive sets for use with Turtle Tracks, and even supports embedding the entire Turtle Tracks engine within an external Java program.
Dynamic memory allocation
Most traditional implementations of Logo preallocate a fixed number of "nodes" for use as list nodes. Turtle Tracks instead uses a dynamic memory allocation model based on Java's memory model and garbage collection system. Words and lists may be of any arbitrary length, and the number of available nodes is limited only by the system resources allocated to the Java VM. This was done to improve cross-platform capability on Java VMs that may provide different amounts of system resources to the running program, to improve flexibility in word lengths, and to provide maximum garbage collection performance by using the native garbage collection facilities of the Java VM. Because of this, the traditionial NODES primitive is meaningless and not implemented. Turtle Tracks does, however, provide a GC primitive which invokes the garbage collector of the host Java VM.
Lists and arrays combined
Turtle Tracks lists are actually implemented as arrays. Because array copies are native methods in Java, manipulating the beginning of a long array is usually as fast or nearly as fast as manipulating the beginning of a long list. Thus, to simplify the language implementation, lists are implemented as arrays, and arrays are not included as a separate data type. This also has several beneficial side effects, among them being that the ITEM primitive is of constant order when given a list as the parameter.
Note: this section of the manual not yet completed.
- topTop
Daniel Azuma (dazuma@)
Last updated 6 December 1997
Standard Commands
Data structures
• Constructors
• Selectors
• Queries
• String Manipulation
Unless otherwise indicated, all these primitives are in virtuoso.logo.lib.StandardPrimitives.
|Constructors |
Logo data structures are in the form of words and lists. These commands are some common ways of creating these data structures.
WORD expr1 expr2
(WORD expr1 ...)
WORD concatenates the given arguments, which should be words, into a single word and returns the result. If an argument is a list, WORD throws an error.
Example:
? PRINT WORD "abra "cadabra
abracadabra
LIST expr1 expr2
(LIST expr1 ...)
LIST creates a new list in which the given arguments are the members. The arguments can be either words or lists.
Example:
? PRINT LIST "abra "cadabra
abra cadabra
? PRINT (LIST "This "is [a list])
This is [ a list ]
SENTENCE expr1 expr2
SE expr1 expr2
(SENTENCE expr1 ...)
(SE expr1 ...)
SENTENCE creates a new list by concatenating the arguments. If an argument is a word, it becomes a member of the new list. If an argument is a list, its members become members of the new list.
Example:
? PRINT SENTENCE "abra "cadabra
abra cadabra
? PRINT (SENTENCE "This "is [a sentence])
This is a sentence
? PRINT (SENTENCE "This "is [[yet another] sentence])
This is [ yet another ] sentence
FPUT expr list
FPUT creates a new list in which the first argument is the first element, and the members of the second argument are the remaining elements. If the second argument is not a list, FPUT throws an error.
Example:
? PRINT FPUT "Logo [is a cool language]
Logo is a cool language
? PRINT FPUT [Logo] [is a [cool] language]
[ Logo ] is a [ cool ] language
LPUT expr list
LPUT creates a new list in which the first argument is the last element, and the members of the second argument are the remaining elements. If the second argument is not a list, LPUT throws an error.
Example:
? PRINT LPUT "Logo [Cool people program in]
Cool people program in Logo
? PRINT LPUT [Turtle Tracks] [Cool people program using]
Cool people program using [ Turtle Tracks ]
PARSE word
PARSE parses the given word as a list and returns the new list. If the given expression is not a word, or if it is badly formatted, PARSE throws an error.
Example:
? MAKE "x PARSE "|Hello world, [This is][a list]|
? SHOW :x
[ Hello world, [ This is ] [ a list ] ]
? PRINT LENGTH :x
4
|virtuoso.logo.lib.LibraryPrimitives |
QSORT list lambda
QSORT sorts the given list using the QuickSort algorithm, and using the second argument as a comparison function. The second argument should be a function which returns "TRUE if its first argument should be placed before its second argument, or "FALSE otherwise. The lambda may either be a lambda list or a procedure or primitive name. Typically, it should be one of the primitive names "BEFOREP or "LESSP. If the first argument to QSORT is not a list, or its second argument is not a lambda that takes two arguments, QSORT throws an error.
Example:
? SHOW QSORT [Turtle Tracks includes powerful list primitives] "BEFOREP
[ includes list powerful primitives Tracks Turtle ]
? SHOW QSORT [3 1 4 1 5 9] "LESSP
[ 1 1 3 4 5 9 ]
? SHOW QSORT [3 1 4 1 5 9] "GREATERP
[ 9 5 4 3 1 1 ]
? SHOW QSORT [1 2 4 8 16 32] "BEFOREP
[ 1 16 2 32 4 8 ]
|virtuoso.logo.lib.LibraryPrimitives |
GENSYM
GENSYM generates and returns a unique symbol of the form ".n" where n is a unique positive integer.
Example:
? PRINT GENSYM
.1
? PRINT GENSYM
.2
- topTop
|Selectors |
Logo provides a number of list manipulation commands, with which you can parse and extract parts of words and lists.
FIRST expr
FIRST returns the first element of the given argument, if it is a list, or the first character, if it is a word. If the list or word is empty, FIRST will throw an error.
Example:
? PRINT FIRST "turtle
t
? PRINT FIRST [[The first element] is a list]
The first element
LAST expr
LAST returns the last element of the given argument, if it is a list, or the first character, if it is a word. If the argument is empty, LAST will throw an error.
Example:
? PRINT LAST "turtle
e
? PRINT LAST [Logo is fun]
fun
BUTFIRST expr
BF expr
BUTFIRST returns the the given argument with FIRST removed. If the argument is empty, BUTFIRST will throw an error. BUTFIRST can be abbreviated BF.
Example:
? PRINT BUTFIRST "turtle
urtle
? PRINT BUTFIRST [[The first element] is a list]
is a list
BUTLAST expr
BL expr
BUTLAST returns the the given argument with LAST removed. If the argument is empty, BUTLAST will throw an error. BUTLAST can be abbreviated BL.
Example:
? PRINT BUTLAST "turtle
turtl
? PRINT BUTLAST [Logo is fun]
Logo is
ITEM num expr
ITEM returns the num'th element of the second argument. Num must be an integer. If the second argument is a list, ITEM returns the num'th element of the list. If the second argument is a word, ITEM returns the num'th character of the word. If num is not an integer, or if num is less than 1 or greater than the number of elements in the second argument, ITEM will throw an error.
Example:
? PRINT ITEM 3 "turtle
r
? PRINT ITEM 4 [Turtle Tracks has many advanced features]
many
|virtuoso.logo.lib.LibraryPrimitives |
PICK expr
PICK chooses and returns a random element of the given argument. If the argument is a list, PICK returns a randomly-chosen element of the list. If the argument is a word, PICK returns a randomly-chosen character of the word. If the argument is the empty list or the empty word, PICK will throw an error.
Example:
? PRINT PICK "turtle
u
? PRINT PICK "turtle
t
? PRINT PICK [Turtle Tracks has many advanced features]
advanced
- topTop
|Queries |
Using these commands, you can gather information about logo data structures.
LENGTH expr
LENGTH returns the length of the given argument. If the argument is a word, LENGTH returns the number of characters it contains. If the argument is a list, LENGTH returns the number of elements it contains.
Example:
? PRINT LENGTH "abracadabra
11
? PRINT LENGTH [[The first element] is a list]
4
EMPTYP expr
EMPTYP returns "TRUE if the argument is the empty word or the empty list, or "FALSE if it is not.
Example:
? PRINT EMPTYP "
TRUE
? PRINT EMPTYP []
TRUE
? PRINT EMPTYP (LIST ")
FALSE
WORD? expr
WORDP expr
WORD? returns "TRUE if the argument is a word, or "FALSE if it is a list.
Example:
? PRINT WORD? "abracadabra
TRUE
? PRINT WORD? [abracadabra]
FALSE
LIST? expr
LISTP expr
LIST? returns "TRUE if the argument is a list, or "FALSE if it is a word.
Example:
? PRINT LIST? [abracadabra]
TRUE
? PRINT LIST? "abracadabra
FALSE
NUMBER? expr
NUMBERP expr
NUMBER? returns "TRUE if the argument is a number, or "FALSE if it is a list or a non-numeric word.
Example:
? PRINT NUMBER? 3.5
TRUE
? PRINT NUMBER? "three
FALSE
? PRINT NUMBER? [3.5]
FALSE
MEMBER? expr list
MEMBERP expr list
MEMBER? returns "TRUE if the first argument is a member of the second argument, or "FALSE if it is not. If the second argument is not a list, MEMBER? will throw an error.
Example:
? PRINT MEMBER? "Logo [Anyone can program in Logo]
TRUE
? PRINT MEMBER? "Logo [Anyone can program in [Logo]]
FALSE
IGNORE expr
IGNORE takes one argument and does nothing with it. This can be useful if a primitive or procedure you must call returns some output that you don't need.
- topTop
|String Manipulation |
Using these commands, you can manipulate words as strings.
BEFORE? word1 word2
BEFOREP word1 word2
BEFORE? returns "TRUE if the first argument comes before the second in lexical order. Case is ignored, so "apple comes before "BANANA. If either argument is not a word, BEFORE? throws an error.
Example:
? PRINT BEFORE? "apple "BANANA
TRUE
? PRINT BEFORE? 3 10
FALSE
ASCII char
ASCII returns the ascii value of the given character as an integer. If the input is a list, or if it is a word whose length is not 1, ASCII will throw an error.
Example:
? PRINT ASCII "a
97
? PRINT ASCII "A
65
CHAR integer
CHAR returns a character whose ascii value is the given integer. If the input is not an integer, CHAR will throw an error.
Example:
? PRINT CHAR 113
q
UPPERCASE word
UPPERCASE returns the given argument with all letters converted to upper case. If the argument is not a word, UPPERCASE throws an error.
Example:
? PRINT UPPERCASE "Hello123
HELLO123
LOWERCASE word
LOWERCASE returns the given argument with all letters converted to lower case. If the argument is not a word, LOWERCASE throws an error.
Example:
? PRINT LOWERCASE "Hello123
hello123
Daniel Azuma (dazuma@)
Last updated 3 February 1999
Flow Control
• Executor Structures
• Mapping Structures
• Conditional Structures
• Loop Structures
• Threads
• Error Handling
• Jumps
Unless otherwise indicated, all these primitives are in virtuoso.logo.lib.StandardPrimitives.
|Executor Structures |
Executors take a list as an argument, interpret it as a command list or a lambda list, and execute it.
RUN cmdlist
RUN parses the given list as a sequence of Logo commands, and executes them. If the command list evaluates to a value, RUN returns that value, otherwise it returns nothing. If the argument is not a list, if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, RUN throws an error.
Example:
? RUN [PRINT 4+5]
9
? PRINT RUN [4+5]
9
RUNRESULT cmdlist
RUNRESULT parses the given list as a sequence of Logo commands, and executes them. If the command list returns a value, RUNRESULT returns a list with that value as the single element, otherwise it returns the empty list. If the argument is not a list, if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, RUNRESULT throws an error.
Example:
? SHOW RUNRESULT [4+5]
[ 9 ]
? SHOW RUNRESULT [PRINT 4+5]
9
[ ]
APPLY lambda argslist
APPLY parses the given list as a lambda list, and executes it, creating a local scope and binding the formal arguments with the values given in the argslist. It returns the result of the invocation, or nothing if the lambda returns nothing. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. The second argument should be a list, whose elements are treated as the arguments to the function invocation. If the second argument is not a list, or the number of elements in the list given does not match the number of formal arguments in the lambda, APPLY throws an error.
Example:
? MAKE "dist [ [x y] [OUTPUT SQRT :x*:x+:y*:y] ]
? PRINT APPLY :dist [3 4]
5
? MAKE "baddist [ [x y] [SQRT :x*:x+:y*:y] ]
? PRINT APPLY :baddist [3 4]
I don't know what to do with 5
... while executing APPLY
? MAKE "macrodist [ [x y] SQRT :x*:x+:y*:y ]
? PRINT APPLY :macrodist [3 4]
5
? MAKE "badmacrodist [ [x y] OUTPUT SQRT :x*:x+:y*:y ]
? PRINT APPLY :badmacrodist [3 4]
Can use STOP or OUTPUT only inside a procedure
APPLYRESULT lambda argslist
APPLYRESULT parses the first argument as a lambda list, and executes it, creating a local scope and binding the formal arguments with the values given in the argslist. It returns a list containing the result of the invocation as the single element, or the empty list if the lambda returns nothing. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. The second argument should be a list, whose elements are treated as the arguments to the function invocation. If the second argument is not a list, or the number of elements in the list given does not match the number of formal arguments in the lambda, APPLYRESULT throws an error.
Example:
? MAKE "dist [ [x y] [OUTPUT SQRT :x*:x+:y*:y] ]
? SHOW APPLYRESULT :dist [3 4]
[ 5 ]
? MAKE "dist2 [ [x y] [PRINT SQRT :x*:x+:y*:y] ]
? SHOW APPLYRESULT :dist2 [3 4]
5
[ ]
? SHOW APPLYRESULT "product [1 2 3 4 5]
[ 120 ]
INVOKE lambda arg
(INVOKE lambda arg1 arg2 ...)
INVOKE parses the given list as a lambda list, and executes it, creating a local scope and binding the formal arguments with the values given. It returns the result of the invocation, or nothing if the lambda returns nothing. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. If the number of arguments given does not match the number of formal arguments in the lambda, INVOKE throws an error.
Example:
? MAKE "dist [ [x y] [OUTPUT SQRT :x*:x+:y*:y] ]
? PRINT (INVOKE :dist 3 4)
5
? MAKE "baddist [ [x y] [SQRT :x*:x+:y*:y] ]
? PRINT INVOKE :baddist [3 4]
I don't know what to do with 5
... while executing INVOKE
? MAKE "macrodist [ [x y] SQRT :x*:x+:y*:y ]
? PRINT INVOKE :macrodist [3 4]
5
? MAKE "badmacrodist [ [x y] OUTPUT SQRT :x*:x+:y*:y ]
? PRINT INVOKE :badmacrodist [3 4]
Can use STOP or OUTPUT only inside a procedure
INVOKERESULT lambda arg
(INVOKERESULT lambda arg1 arg2 ...)
INVOKERESULT parses the first argument as a lambda list, and executes it, creating a local scope and binding the formal arguments with the values given. It returns a list containing the result of the invocation as the single element, or the empty list if the lambda returns nothing. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. If the number of arguments given does not match the number of formal arguments in the lambda, INVOKERESULT throws an error.
Example:
? MAKE "dist [ [x y] [OUTPUT SQRT :x*:x+:y*:y] ]
? SHOW (INVOKERESULT :dist 3 4)
[ 5 ]
? MAKE "dist2 [ [x y] [PRINT SQRT :x*:x+:y*:y] ]
? SHOW (INVOKERESULT :dist2 3 4)
5
[ ]
? SHOW (INVOKERESULT "product 1 2 3 4 5)
[ 120 ]
- topTop
|Mapping Structures |
|virtuoso.logo.lib.LibraryPrimitives |
MAP lambda argslist
(MAP lambda argslist1 argslist2 ...)
MAP parses the first argument as a lambda list, and executes it for each of the arguments given in the argument lists, creating a local scope and binding the formal arguments with the values given. It returns a list containing results of the invocation on each of the elements of the argument lists. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. If an invocation of the lambda does not return a value, that invocation is ignored during construction of the return list (i.e. the list returned from MAP is shorter.) If the number of argument lists given does not match the number of formal arguments in the lambda, the argument lists are not all of the same length, or the first argument is a procedure name that is not defined, MAP throws an error.
Example:
? SHOW MAP [[x] [OUTPUT 2*:x]] [3 -5 1]
[ 6 -10 2 ]
? SHOW (MAP [[x y] SQRT :x*:x+:y*:y] [3 5 1] [4 12 1])
[ 5 13 1.4142135623730951 ]
? SHOW MAP "uppercase [Logo is FUN]
[ LOGO IS FUN ]
? SHOW (MAP [[x] if number? :x [:x]] [43 six 3.4 [55] -4.5e2])
[ 43 3.4 -450 ]
|virtuoso.logo.lib.LibraryPrimitives |
FOREACH argslist lambda
(FOREACH argslist1 argslist2 ... lambda)
FOREACH parses the last argument as a lambda list, and executes it for each of the arguments given in the argument lists, creating a local scope and binding the formal arguments with the values given. It does not return anything. If the first argument is a normal lambda list, it executes it as a normal procedure-- that is, you must use the OUTPUT command to return a value, or the STOP command to exit in the middle without returning a value. If the first argument is a macro lambda list, it executes as a macro procedure-- that is, it evaluates directly, and if you call STOP or OUTPUT, it will exit the enclosing procedure. If the first argument is a word, it is interpreted as a procedure name, and that procedure is invoked. If the number of argument lists given does not match the number of formal arguments in the lambda, the argument lists are not all of the same length, the last argument is a procedure name that is not defined, or the function returns a value, FOREACH throws an error.
Example:
? FOREACH [3 -5 1] [[x] [PRINT 2*:x]]
6
-10
2
? FOREACH SHELL [ls] "print
animals.logo
logotelnet.logo
mandel.logo
threads.logo
torus.logo
Note: The above output was generated on a unix-based platform. The exact behavior of the SHELL primitive is undefined and platform-dependent.
- topTop
|Conditional Structures |
Conditionals conditionally execute a runnable list. Like RUN, conditionals typically return the value of the list expression that was executed, or no value if the expression doesn't evaluate to a value.
IF expr cmdlist
IF first evaluates the given expression. If it evaluates to "TRUE, the given list is then parsed as a sequence of Logo commands and executed, otherwise the given list is ignored. IF never returns a value, even if the command list is executed and evaluates to a value. If expr does not evaluate to "TRUE or "FALSE, a non-list is given as an input, or if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, IF throws an error.
Example:
? IF 1=1 [PRINT "Yes]
Yes
? IF 1=2 [PRINT "Whoops]
IFELSE expr cmdlist1 cmdlist2
(IF expr cmdlist1 cmdlist2)
IFELSE first evaluates the given expression. If it evaluates to "TRUE, list1 is then parsed as a sequence of Logo commands and executed, otherwise list2 is executed. If the executed list evaluates to a value, then IFELSE returns that value. If expr does not evaluate to "TRUE or "FALSE, a non-list is given as an input, or if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, IFELSE throws an error. Note that IF can also behave in the same way as IFELSE by enclosing it in parentheses.
Example:
? IFELSE 1=1 [PRINT "Yes] [PRINT "Whoops]
Yes
? IFELSE 1=2 [PRINT "Whoops] [PRINT "No]
No
? PRINT IFELSE 1=2 [1+1] [2+2]
4
TEST expr
TEST sets the current test value, which is used in subsequent IFTRUE and IFFALSE commands. If the given expression evaluates to "TRUE then the test value is set to true. If the given expression evaluates to "FALSE then the test value is set to false. If the given expression does not evaluate to "TRUE or "FALSE then TEST throws an error.
IFTRUE cmdlist
IFT cmdlist
If the current test value set by TEST is true, the given list is parsed as a sequence of Logo commands and executed, otherwise the given list is ignored. IFTRUE never returns a value, even if the command list is executed and evaluates to a value. If there is no current test value, a non-list is given as an input, or if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, IFTRUE throws an error.
Example:
? RUN [TEST 1+1=2 IFTRUE [PRINT "Yes]]
Yes
IFFALSE cmdlist
IFF cmdlist
If the current test value set by TEST is false, the given list is parsed as a sequence of Logo commands and executed, otherwise the given list is ignored. IFFALSE never returns a value, even if the command list is executed and evaluates to a value. If there is no current test value, a non-list is given as an input, or if the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, IFFALSE throws an error.
Example:
? RUN [TEST 1+1=3 IFFALSE [PRINT "No] IFTRUE [PRINT "Whoops]]
No
- topTop
|Loop Structures |
Loop primitives can execute a set of commands repeatedly.
REPEAT integer cmdlist
The given list is parsed as a sequence of Logo commands and executed the number of times specified by the given integer. REPEAT never returns a value, even if the command list evaluates to a value. If the first input is not a valid integer, a non-list is given as the second input, the list cannot be parsed as a valid sequence of Logo commands, or if an error occurs while running the list, REPEAT throws an error.
Example:
? REPEAT 3 [PRINT "Hello]
Hello
Hello
Hello
REPCOUNT
REPCOUNT evaluates to the current iteration number in the innermost repeat loop. If invoked while not inside a repeat loop, REPCOUNT returns -1.
Example:
? REPEAT 2 [REPEAT 3 [PRINT REPCOUNT]]
1
2
3
1
2
3
? MAKE "x 1 WHILE [:x ................
................
In order to avoid copyright disputes, this page is only a partial summary.
To fulfill the demand for quickly locating and searching documents.
It is intelligent file search solution for home and business.
Related download
Related searches
- potion of the turtle master minecraft
- potion of the turtle master ii
- minecraft turtle master
- tiny turtle school map
- best edm tracks 2020
- free music tracks instrumental
- gospel performance tracks download
- accounting software that tracks inventory
- piano hymnal accompaniment tracks free
- free instrumental tracks for singers
- best dance tracks 2020
- top dance tracks 2020