builtins
builtins for pylogo Ian Bicking <ianb@colorstudy.com>
The builtins module is accessible via the pylogo module.
These implement the builtins, as much as possible using the standard library of UCBLogo as a model. See also the UCBLogo Manual.
Organization of this module follows the organization of the UCB manual.
All missing functions are noted in comments and marked with '@@'
Attributes
Functions
f word(*args) ...
WORD word1 word2 (WORD word1 word2 word3 ...)
outputs a word formed by concatenating its inputs.
f logo_list(*args) ...
LIST thing1 thing2 (LIST thing1 thing2 thing3 ...)
outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array).
f logo_soft_repr(arg) ...
Like logoRepr, only we're already in a quoted context, so we don't have to quote strings.
f sentence(*args) ...
SENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...)
outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists.
f fput(thing, l) ...
FPUT thing list
outputs a list equal to its second input with one extra member, the first input, at the beginning.
f lput(thing, l) ...
LPUT thing list
outputs a list equal to its second input with one extra member, the first input, at the end.
f combine(thing1, thing2) ...
COMBINE thing1 thing2
if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2.
f reverse(l) ...
REVERSE list
outputs a list whose members are the members of the input list, in reverse order.
f gensym() ...
GENSYM
outputs a unique word each time it's invoked. The words are of the form G1, G2, etc.
f first(thing) ...
FIRST thing
if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array).
f firsts(things) ...
FIRSTS list
outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as:
to firsts :list output map "first :list end
but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH:
to transpose :matrix if emptyp first :matrix [op []] op fput firsts :matrix transpose bfs :matrix end
f last(thing) ...
LAST wordorlist
if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list.
f butfirst(thing) ...
BUTFIRST wordorlist BF wordorlist
if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input.
f butfirsts(things) ...
BUTFIRSTS list BFS list
outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as:
to butfirsts :list output map "butfirst :list end
but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH.
f butlast(thing) ...
BUTLAST wordorlist BL wordorlist
if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input.
f item(index, thing) ...
ITEM index thing
if the thing is a word, outputs the index``th character of the word. If the ``thing is a list, outputs the index``th member of the list. If the ``thing is an array, outputs the index``th member of the array. ``Index starts at 1 for words and lists; the starting index of an array is specified when the array is created.
f remove(thing, l) ...
REMOVE thing list
outputs a copy of list with every member equal to thing removed.
f remdup(l) ...
REMDUP list
outputs a copy of list with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output.
f setitem(index, thing, value) ...
SETITEM index array value
command. Replaces the index``th member of ``array with the new value. Ensures that the resulting array is not circular, i.e., value may not be a list or array that contains array.
f dotsetfirst(lst, value) ...
.SETFIRST list value
command. Changes the first member of list to be value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; and unexpected changes to other data structures that share storage with the list being modified.
f dotsetbf(lst, value) ...
.SETBF list value
command. Changes the butfirst of list to be value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified. list.
f emptyp(thing) ...
EMPTYP thing EMPTY? thing
outputs TRUE if the input is the empty word or the empty list, FALSE otherwise.
f equalp(thing1, thing2) ...
EQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2
outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.)
f beforep(word1, word2) ...
BEFOREP word1 word2 BEFORE? word1 word2
outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1.
f doteq(thing1, thing2) ...
.EQ thing1 thing2
outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value.
f memberp(thing1, l) ...
MEMBERP thing1 thing2 MEMBER? thing1 thing2
if thing2 is a list or an array, outputs TRUE if thing1 is EQUALP to a member of thing2, FALSE otherwise. If thing2 is a word, outputs TRUE if thing1 is a one-character word EQUALP to a character of thing2, FALSE otherwise.
f substringp(thing1, thing2) ...
SUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2
if thing1 or thing2 is a list or an array, outputs FALSE. If thing2 is a word, outputs TRUE if thing1 is EQUALP to a substring of thing2, FALSE otherwise.
f numberp(thing) ...
NUMBERP thing NUMBER? thing
outputs TRUE if the input is a number, FALSE otherwise.
f count(thing) ...
COUNT thing
outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.)
f ascii(char) ...
ASCII char
outputs the integer (between 0 and 255) that represents the input character in the ASCII code.
f char(int) ...
CHAR int
outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255.
f member(thing1, thing2) ...
MEMBER thing1 thing2
if thing2 is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of thing2 from the first instance of thing1 to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of thing2. It is an error for thing2 to be an array.
f lowercase(word) ...
LOWERCASE word
outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter.
f uppercase(word) ...
UPPERCASE word
outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter.
f pr(*args) ...
PRINT thing thing2 thing3 ... PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...)
command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays.
f logo_type(*args) ...
TYPE thing thing2 thing3 ... (TYPE thing1 thing2 ...)
command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces.
f show(*args) ...
SHOW thing thing2 thing3 ... (SHOW thing1 thing2 ...)
command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets.
f readlist() ...
READLIST RL
reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character.
f readrawline() ...
READRAWLINE
reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters.
f difference(num1, num2) ...
DIFFERENCE num1 num2 num1 - num2
outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.)
f minus(num) ...
MINUS num - num
outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms:
MINUS 3 + 4 ; means -(3+4) - 3 + 4 ; means (-3)+4
f product(*args) ...
PRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2
outputs the product of its inputs.
f quotient(num1, num2) ...
QUOTIENT num1 num2 (QUOTIENT num) num1 / num2
outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input.
f remainder(num1, num2) ...
REMAINDER num1 num2
outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num1.
f modulo(num1, num2) ...
MODULO num1 num2
outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num2.
f logo_int(num) ...
INT num
outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input.
f power(num1, num2) ...
POWER num1 num2
outputs num1 to the num2 power. If num1 is negative, then num2 must be an integer.
f arctan(num, second=None) ...
ARCTAN num (ARCTAN x y)
outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or -90 depending on the sign of y, if x is zero.
f radarctan(num, second=None) ...
RADARCTAN num (RADARCTAN x y)
outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or -pi/2 depending on the sign of y, if x is zero.
The expression 2*(RADARCTAN 0 1) can be used to get the value of pi.
f iseq(from_num, to_num) ...
ISEQ from to
outputs a list of the integers from FROM to TO, inclusive:
? show iseq 3 7 [3 4 5 6 7] ? show iseq 7 3 [7 6 5 4 3]
f rseq(from_num, to_num, length) ...
RSEQ from to count
outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive:
? show rseq 3 5 9 [3 3.25 3.5 3.75 4 4.25 4.5 4.75 5] ? show rseq 3 5 5 [3 3.5 4 4.5 5]
f lessp(num1, num2) ...
LESSP num1 num2 LESS? num1 num2 num1 < num2
outputs TRUE if its first input is strictly less than its second.
f greaterp(num1, num2) ...
GREATERP num1 num2 GREATER? num1 num2 num1 > num2
outputs TRUE if its first input is strictly greater than its second.
f logo_random(num) ...
RANDOM num
outputs a random nonnegative integer less than its input, which must be an integer.
f rerandom(seed=None) ...
RERANDOM (RERANDOM seed)
command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers.
f bitand(*args) ...
BITAND num1 num2 (BITAND num1 num2 num3 ...)
outputs the bitwise AND of its inputs, which must be integers.
f bitor(*args) ...
BITOR num1 num2 (BITOR num1 num2 num3 ...)
outputs the bitwise OR of its inputs, which must be integers.
f bitxor(*args) ...
BITXOR num1 num2 (BITXOR num1 num2 num3 ...)
outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers.
f ashift(num1, num2) ...
ASHIFT num1 num2
outputs num1 arithmetic-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers.
f lshift(num1, num2) ...
LSHIFT num1 num2
outputs num1 logical-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers.
f logo_and(interp, *vals) ...
AND tf1 tf2 (AND tf1 tf2 tf3 ...)
outputs TRUE if all inputs are TRUE, otherwise FALSE. An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example:
MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5]
to avoid the division by zero if the first part is false.
f logo_or(interp, *vals) ...
OR tf1 tf2 (OR tf1 tf2 tf3 ...)
outputs TRUE if any input is TRUE, otherwise FALSE. An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example:
IF OR :X=0 [some.long.computation] [...]
to avoid the long computation if the first condition is met.
f logo_not(interp, val) ...
NOT tf
outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value.
f logo_define(interp, procname, text) ...
DEFINE procname text
command. Defines a procedure with name procname and text text. If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.)
f text(interp, procname) ...
TEXT procname
outputs the text of the procedure named procname in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces.
f thing(interp, v) ...
THING varname :quoted.varname
outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination so that :FOO means THING "FOO.
f procedurep(interp, name) ...
PROCEDUREP name PROCEDURE? name
outputs TRUE if the input is the name of a procedure.
f primitivep(interp, name) ...
PRIMITIVEP name PRIMITIVE? name
outputs TRUE if the input is the name of a primitive procedure (one built into Logo).
f definedp(interp, name) ...
DEFINEDP name DEFINED? name
outputs TRUE if the input is the name of a user-defined procedure.
f namep(interp, name) ...
NAMEP name NAME? name
outputs TRUE if the input is the name of a variable.
f procedures(interp) ...
PROCEDURES
outputs a list of the names of all unburied user-defined procedures in the workspace.
f names(interp) ...
NAMES
outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace.
f erase(interp, l) ...
ERASE contentslist ER contentslist
command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE.
f erall(interp) ...
ERALL
command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS.
f erps(interp) ...
ERPS
command. Erases all unburied procedures from the workspace. Abbreviates ERASE PROCEDURES.
f erns(interp) ...
ERNS
command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES.
f logo_help(interp, name) ...
HELP name
command. Prints information from the reference manual about the primitive procedure named by the input.
f logo_run(interp, l) ...
RUN instructionlist
command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs.
f repeat(interp, n, block) ...
REPEAT num instructionlist
command. Runs the instructionlist repeatedly, num times.
f repcount(interp) ...
REPCOUNT
outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs -1.
f iftrue(interp, lst) ...
IFTRUE instructionlist IFT instructionlist
command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure.
f iffalse(interp, lst) ...
IFFALSE instructionlist IFF instructionlist
command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure.
f logo_if(interp, expr, block, elseBlock=None) ...
IF tf instructionlist (IF tf instructionlist1 instructionlist2)
command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE.
f logo_ifelse(interp, expr, trueBlock, falseBlock) ...
IFELSE tf instructionlist1 instructionlist2
command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value.
f stop() ...
STOP
command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value.
f output(value) ...
OUTPUT value OP value RETURN value
command. Ends the running of the procedure in which it appears. That procedure outputs the value value to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation.
f ignore(value) ...
IGNORE value
command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant.
f backtick(interp, lst) ...
BACKTICK list
outputs a list equal to its input but with certain substitutions. If a member of the input list is the word , (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word @ (atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the @ and the instructionlist. Example:
show `[foo baz ,[bf [a b c]] garply @[bf [a b c]]]
will print:
[foo baz [b c] garply b c]
f logoWhile(interp, test, block) ...
WHILE tfexpression instructionlist
command. Repeatedly evaluates the instructionlist as long as the evaluated tfexpression remains TRUE. Evaluates the first input first, so the instructionlist may never be run at all. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.
Classes
See the source for more information.