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

8 Control Structures


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

8.1 Control

Note: in the following descriptions, an instructionlist can be a list or a word. In the latter case, the word is parsed into list form before it is run. Thus, RUN READWORD or RUN READLIST will work. The former is slightly preferable because it allows for a continued line (with ~) that includes a comment (with ;) on the first line.

A tf input must be the word TRUE, the word FALSE, or a list. If it’s a list, then it must be a Logo expression, which will be evaluated to produce a value that must be TRUE or FALSE. The comparisons with TRUE and FALSE are always case-insensitive.

A runlist can consist of either a single expression (that produces a value) or zero or more instructions (that do something, rather than output a value), depending on the context:

PRINT IFELSE :X<0 ["NEGATIVE] ["POSITIVE]  ; one value in each case
REPEAT 4 [PRINT "A PRINT "B]  ; two instructions

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

run

RUN instructionlist

command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs.

See section readword , readlist .


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

runresult

RUNRESULT instructionlist

runs the instructions in the input; outputs an empty list if those instructions produce no output, or a list whose only member is the output from running the input instructionlist. Useful for inventing command-or-operation control structures:

local "result
make "result runresult [something]
if emptyp :result [stop]
output first :result

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

repeat

REPEAT num instructionlist

command. Runs the instructionlist repeatedly, num times.


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

forever

FOREVER instructionlist

command. Runs the "instructionlist" repeatedly, until something inside the instructionlist (such as STOP or THROW) makes it stop.

See section stop , See section throw .


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

repcount

REPCOUNT

outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs –1.

The abbreviation # can be used for REPCOUNT unless the REPEAT is inside the template input to a higher order procedure such as FOREACH, in which case # has a different meaning.


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

if

IF tf instructionlist
(IF tf instructionlist1 instructionlist2)

command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE.

For compatibility with earlier versions of Logo, if an IF instruction is not enclosed in parentheses, but the first thing on the instruction line after the second input expression is a literal list (i.e., a list in square brackets), the IF is treated as if it were IFELSE, but a warning message is given. If this aberrant IF appears in a procedure body, the warning is given only the first time the procedure is invoked in each Logo session.


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

ifelse

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.


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

test

TEST tf

command. Remembers its input, which must be TRUE or FALSE, for use by later IFTRUE or IFFALSE instructions. The effect of TEST is local to the procedure in which it is used; any corresponding IFTRUE or IFFALSE must be in the same procedure or a subprocedure.

See section iffalse .


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

iftrue

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.


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

iffalse

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.

See section test .


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

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.


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

output

OUTPUT value
OP value

command. Ends the running of the procedure in which it appears. That procedure outputs the value value to the context in which it was invoked. Don’t be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation.


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

catch

CATCH tag instructionlist

command or operation. Runs its second input. Outputs if that instructionlist outputs. If, while running the instructionlist, a THROW instruction is executed with a tag equal to the first input (case-insensitive comparison), then the running of the instructionlist is terminated immediately. In this case the CATCH outputs if a value input is given to THROW. The tag must be a word.

If the tag is the word ERROR, then any error condition that arises during the running of the instructionlist has the effect of THROW "ERROR instead of printing an error message and returning to toplevel. The CATCH does not output if an error is caught. Also, during the running of the instructionlist, the variable ERRACT is temporarily unbound. (If there is an error while ERRACT has a value, that value is taken as an instructionlist to be run after printing the error message. Typically the value of ERRACT, if any, is the list [PAUSE].)

See section error , erract , pause .


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

throw

THROW tag
(THROW tag value)

command. Must be used within the scope of a CATCH with an equal tag. Ends the running of the instructionlist of the CATCH. If THROW is used with only one input, the corresponding CATCH does not output a value. If THROW is used with two inputs, the second provides an output for the CATCH.

THROW "TOPLEVEL can be used to terminate all running procedures and interactive pauses, and return to the toplevel instruction prompt. Typing the system interrupt character (<alt-S> for wxWidgets; otherwise normally <control-C> for Unix, <control-Q> for DOS, or <command-period> for Mac) has the same effect.

THROW "ERROR can be used to generate an error condition. If the error is not caught, it prints a message (THROW "ERROR) with the usual indication of where the error (in this case the THROW) occurred. If a second input is used along with a tag of ERROR, that second input is used as the text of the error message instead of the standard message. Also, in this case, the location indicated for the error will be, not the location of the THROW, but the location where the procedure containing the THROW was invoked. This allows user-defined procedures to generate error messages as if they were primitives. Note: in this case the corresponding CATCH "ERROR, if any, does not output, since the second input to THROW is not considered a return value.

THROW "SYSTEM immediately leaves Logo, returning to the operating system, without printing the usual parting message and without deleting any editor temporary file written by EDIT.

See section edit .


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

error

ERROR

outputs a list describing the error just caught, if any. If there was not an error caught since the last use of ERROR, the empty list will be output. The error list contains four members: an integer code corresponding to the type of error, the text of the error message (as a single word including spaces), the name of the procedure in which the error occurred, and the instruction line on which the error occurred.


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

pause

PAUSE

command or operation. Enters an interactive pause. The user is prompted for instructions, as at toplevel, but with a prompt that includes the name of the procedure in which PAUSE was invoked. Local variables of that procedure are available during the pause. PAUSE outputs if the pause is ended by a CONTINUE with an input.

If the variable ERRACT exists, and an error condition occurs, the contents of that variable are run as an instructionlist. Typically ERRACT is given the value [PAUSE] so that an interactive pause will be entered in the event of an error. This allows the user to check values of local variables at the time of the error.

Typing the system quit character (<alt-S> for wxWidgets; otherwise normally <control-\> for Unix, <control-W> for DOS, or <command-comma> for Mac) will also enter a pause.

See section erract .


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

continue

CONTINUE value
CO value
(CONTINUE)
(CO)

command. Ends the current interactive pause, returning to the context of the PAUSE invocation that began it. If CONTINUE is given an input, that value is used as the output from the PAUSE. If not, the PAUSE does not output.

Exceptionally, the CONTINUE command can be used without its default input and without parentheses provided that nothing follows it on the instruction line.


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

wait

WAIT time

command. Delays further execution for time 60ths of a second. Also causes any buffered characters destined for the terminal to be printed immediately. WAIT 0 can be used to achieve this buffer flushing without actually waiting.


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

bye

BYE

command. Exits from Logo; returns to the operating system.


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

.maybeoutput

.MAYBEOUTPUT value				(special form)

works like OUTPUT except that the expression that provides the input value might not, in fact, output a value, in which case the effect is like STOP. This is intended for use in control structure definitions, for cases in which you don’t know whether or not some expression produces a value. Example:

to invoke :function [:inputs] 2
.maybeoutput apply :function :inputs
end

? (invoke "print "a "b "c)
a b c
? print (invoke "word "a "b "c)
abc

This is an alternative to RUNRESULT. It’s fast and easy to use, at the cost of being an exception to Logo’s evaluation rules. (Ordinarily, it should be an error if the expression that’s supposed to provide an input to something doesn’t have a value.)

See section output , stop , runresult .


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

goto

GOTO word

command. Looks for a TAG command with the same input in the same procedure, and continues running the procedure from the location of that TAG. It is meaningless to use GOTO outside of a procedure.


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

tag

TAG quoted.word

command. Does nothing. The input must be a literal word following a quotation mark ("), not the result of a computation. Tags are used by the GOTO command.


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

ignore

IGNORE value					(library procedure)

command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant.


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

` list						(library procedure)

outputs a list equal to its input but with certain substitutions. If a member of the input list is the word ‘,’ (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word ‘,@’ (comma atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the ‘,@’ and the instructionlist. Example:

show `[foo baz ,[bf [a b c]] garply ,@[bf [a b c]]]

will print

[foo baz [b c] garply b c]

A word starting with ‘,’ or ‘,@’ is treated as if the rest of the word were a one-word list, e.g., ‘,:foo’ is equivalent to ‘,[:Foo]’.

A word starting with ‘",’ (quote comma) or ‘:,’ (colon comma) becomes a word starting with ‘"’ or ‘:’ but with the result of running the substitution (or its first word, if the result is a list) replacing what comes after the comma.

Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found:

? show `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f]
[a ` [b , [1+2] , [foo 4 d] e] f]

?make "name1 "x
?make "name2 "y
? show `[a `[b ,:,:name1 ,",:name2 d] e]
[a ` [b , [:x] , ["y] d] e]

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

for

FOR forcontrol instructionlist			(library procedure)

command. The first input must be a list containing three or four members: (1) a word, which will be used as the name of a local variable; (2) a word or list that will be evaluated as by RUN to determine a number, the starting value of the variable; (3) a word or list that will be evaluated to determine a number, the limit value of the variable; (4) an optional word or list that will be evaluated to determine the step size. If the fourth member is missing, the step size will be 1 or –1 depending on whether the limit value is greater than or less than the starting value, respectively.

The second input is an instructionlist. The effect of FOR is to run that instructionlist repeatedly, assigning a new value to the control variable (the one named by the first member of the forcontrol list) each time. First the starting value is assigned to the control variable. Then the value is compared to the limit value. FOR is complete when the sign of (current - limit) is the same as the sign of the step size. (If no explicit step size is provided, the instructionlist is always run at least once. An explicit step size can lead to a zero-trip FOR, e.g., FOR [I 1 0 1] ...). Otherwise, the instructionlist is run, then the step is added to the current value of the control variable and FOR returns to the comparison step.

? for [i 2 7 1.5] [print :i]
2
3.5
5
6.5
?

See section run .


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

do.while

DO.WHILE instructionlist tfexpression		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated

@var{tfexpres-sion}
remains TRUE. Evaluates the first input first, so the instructionlist is always run at least once. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


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

while

WHILE tfexpression instructionlist		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated

@var{tfexpres-sion}
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.


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

do.until

DO.UNTIL instructionlist tfexpression		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated

@var{tfexpres-sion}
remains FALSE. Evaluates the first input first, so the instructionlist is always run at least once. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


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

until

UNTIL tfexpression instructionlist		(library procedure)

command. Repeatedly evaluates the instructionlist as long as the evaluated

@var{tfexpres-sion}
remains FALSE. Evaluates the first input first, so the instructionlist may never be run at all. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.


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

case

CASE value clauses					(library procedure)

command or operation. The second input is a list of lists (clauses); each clause is a list whose first element is either a list of values or the word ELSE and whose butfirst is a Logo expression or instruction. CASE examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. If the first input to CASE is a member of the first element of a clause, then the butfirst of that clause is evaluated and CASE outputs its value, if any. If neither of these conditions is met, then CASE goes on to the next clause. If no clause is satisfied, CASE does nothing. Example:

to vowelp :letter
output case :letter [ [[a e i o u] "true] [else "false] ]
end

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

cond

COND clauses						(library procedure)

command or operation. The input is a list of lists (clauses); each clause is a list whose first element is either an expression whose value is TRUE or FALSE, or the word ELSE, and whose butfirst is a Logo expression or instruction. COND examines the clauses in order. If a clause begins with the word ELSE (upper or lower case), then the butfirst of that clause is evaluated and CASE outputs its value, if any. Otherwise, the first element of the clause is evaluated; the resulting value must be TRUE or FALSE. If it’s TRUE, then the butfirst of that clause is evaluated and COND outputs its value, if any. If the value is FALSE, then COND goes on to the next clause. If no clause is satisfied, COND does nothing. Example:

to evens :numbers	; select even numbers from a list
op cond [ [[emptyp :numbers] []]
          [[evenp first :numbers]	; assuming EVENP is defined
           fput first :numbers evens butfirst :numbers]
          [else evens butfirst :numbers] ]
end

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

8.2 Template-based Iteration

The procedures in this section are iteration tools based on the idea of a template. This is a generalization of an instruction list or an expression list in which slots are provided for the tool to insert varying data. Four different forms of template can be used.

The most commonly used form for a template is ‘explicit-slot’ form, or ‘question mark’ form. Example:

? show map [? * ?] [2 3 4 5]
[4 9 16 25]
?

In this example, the MAP tool evaluated the template [? * ?] repeatedly, with each of the members of the data list [2 3 4 5] substituted in turn for the question marks. The same value was used for every question mark in a given evaluation. Some tools allow for more than one datum to be substituted in parallel; in these cases the slots are indicated by ?1 for the first datum, ?2 for the second, and so on:

? show (map [(word ?1 ?2 ?1)] [a b c] [d e f])
[ada beb cfc]
?

If the template wishes to compute the datum number, the form (? 1) is equivalent to ?1, so (? ?1) means the datum whose number is given in datum number 1. Some tools allow additional slot designations, as shown in the individual descriptions.

The second form of template is the ‘named-procedure’ form. If the template is a word rather than a list, it is taken as the name of a procedure. That procedure must accept a number of inputs equal to the number of parallel data slots provided by the tool; the procedure is applied to all of the available data in order. That is, if data ?1 through ?3 are available, the template "PROC is equivalent to [PROC ?1 ?2 ?3].

? show (map "word [a b c] [d e f])
[ad be cf]
?

to dotprod :a :b	; vector dot product
op apply "sum (map "product :a :b)
end

The third form of template is ‘named-slot’ or ‘lambda’ form. This form is indicated by a template list containing more than one member, whose first member is itself a list. The first member is taken as a list of names; local variables are created with those names and given the available data in order as their values. The number of names must equal the number of available data. This form is needed primarily when one iteration tool must be used within the template list of another, and the ? notation would be ambiguous in the inner template. Example:

to matmul :m1 :m2 [:tm2 transpose :m2]	; multiply two matrices
output map [[row] map [[col] dotprod :row :col] :tm2] :m1
end

The fourth form is ‘procedure text’ form, a variant of lambda form. In this form, the template list contains at least two members, all of which are lists. This is the form used by the DEFINE and TEXT primitives, and APPLY accepts it so that the text of a defined procedure can be used as a template.

Note: The fourth form of template is interpreted differently from the others, in that Logo considers it to be an independent defined procedure for the purposes of OUTPUT and STOP. For example, the following two instructions are identical:

? print apply [[x] :x+3] [5]
8
? print apply [[x] [output :x+3]] [5]
8

although the first instruction is in named-slot form and the second is in procedure-text form. The named-slot form can be understood as telling Logo to evaluate the expression :x+3 in place of the entire invocation of apply, with the variable x temporarily given the value 5. The procedure-text form can be understood as invoking the procedure

to foo :x
output :x+3
end

with input 5, but without actually giving the procedure a name. If the use of OUTPUT were interchanged in these two examples, we’d get errors:

? print apply [[x] output :x+3] [5]
Can only use output inside a procedure
? print apply [[x] [:x+3]] [5]
You don't say what to do with 8

The named-slot form can be used with STOP or OUTPUT inside a procedure, to stop the enclosing procedure.

The following iteration tools are extended versions of the ones in Appendix B of the book Computer Science Logo Style, Volume 3: Advanced Topics by Brian Harvey [MIT Press, 1987]. The extensions are primarily to allow for variable numbers of inputs.


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

apply

APPLY template inputlist

command or operation. Runs the template, filling its slots with the members of inputlist. The number of members in inputlist must be an acceptable number of slots for template. It is illegal to apply the primitive TO as a template, but anything else is okay. APPLY outputs what template outputs, if anything.

See section to .


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

invoke

INVOKE template input				(library procedure)
(INVOKE template input1 input2 ...)

command or operation. Exactly like APPLY except that the inputs are provided as separate expressions rather than in a list.


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

foreach

FOREACH data template				(library procedure)
(FOREACH data1 data2 ... template)

command. Evaluates the template list repeatedly, once for each member of the data list. If more than one data list are given, each of them must be the same length. (The data inputs can be words, in which case the template is evaluated once for each character.)

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


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

map

MAP template data				(library procedure)
(MAP template data1 data2 ...)

outputs a word or list, depending on the type of the data input, of the same length as that data input. (If more than one data input are given, the output is of the same type as data1.) Each member of the output is the result of evaluating the template list, filling the slots with the corresponding member(s) of the data input(s). (All data inputs must be the same length.) In the case of a word output, the results of the template evaluation must be words, and they are concatenated with WORD.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.

See section word .


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

map.se

MAP.SE template data				(library procedure)
(MAP.SE template data1 data2 ...)

outputs a list formed by evaluating the template list repeatedly and concatenating the results using SENTENCE. That is, the members of the output are the members of the results of the evaluations. The output list might, therefore, be of a different length from that of the data input(s). (If the result of an evaluation is the empty list, it contributes nothing to the final output.) The data inputs may be words or lists.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E]. If multiple parallel slots are used, then (?REST 1) goes with ?1, etc.

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.

See section sentence .


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

filter

FILTER tftemplate data				(library procedure)

outputs a word or list, depending on the type of the data input, containing a subset of the members (for a list) or characters (for a word) of the input. The template is evaluated once for each member or character of the data, and it must produce a TRUE or FALSE value. If the value is TRUE, then the corresponding input constituent is included in the output.

? print filter "vowelp "elephant 
eea 
?

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E].

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


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

find

FIND tftemplate data				(library procedure)

outputs the first constituent of the data input (the first member of a list, or the first character of a word) for which the value produced by evaluating the template with that consituent in its slot is TRUE. If there is no such constituent, the empty list is output.

In a template, the symbol ?REST represents the portion of the data input to the right of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then ?REST would be replaced by [C D E].

In a template, the symbol # represents the position in the data input of the member currently being used as the ? slot-filler. That is, if the data input is [A B C D E] and the template is being evaluated with ? replaced by B, then # would be replaced by 2.


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

reduce

REDUCE template data				(library procedure)

outputs the result of applying the template to accumulate the members of the data input. The template must be a two-slot function. Typically it is an associative function name like SUM. If the data input has only one constituent (member in a list or character in a word), the output is that consituent. Otherwise, the template is first applied with ?1 filled with the next-to-last consitient and ?2 with the last constituent. Then, if there are more constituents, the template is applied with ?1 filled with the next constituent to the left and ?2 with the result from the previous evaluation. This process continues until all constituents have been used. The data input may not be empty.

Note: If the template is, like SUM, the name of a procedure that is capable of accepting arbitrarily many inputs, it is more efficient to use APPLY instead of REDUCE. The latter is good for associative procedures that have been written to accept exactly two inputs:

to max :a :b
output ifelse :a > :b [:a] [:b]
end

print reduce "max [...]

Alternatively, REDUCE can be used to write MAX as a procedure that accepts any number of inputs, as SUM does:

to max [:inputs] 2
if emptyp :inputs ~
   [(throw "error [not enough inputs to max])]
output reduce [ifelse ?1 > ?2 [?1] [?2]] :inputs
end

See section sum , apply .


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

crossmap

CROSSMAP template listlist			(library procedure)
(CROSSMAP template data1 data2 ...)

outputs a list containing the results of template evaluations. Each data list contributes to a slot in the template; the number of slots is equal to the number of data list inputs. As a special case, if only one data list input is given, that list is taken as a list of data lists, and each of its members contributes values to a slot. CROSSMAP differs from MAP in that instead of taking members from the data inputs in parallel, it takes all possible combinations of members of data inputs, which need not be the same length.

? show (crossmap [word ?1 ?2] [a b c] [1 2 3 4])
[a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4]
?

For compatibility with the version in the first edition of CSLS (1), CROSSMAP templates may use the notation :1 instead of ?1 to indicate slots.

See section map .


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

cascade

CASCADE endtest template startvalue		(library procedure)
(CASCADE endtest tmp1 sv1 tmp2 sv2 ...)
(CASCADE endtest tmp1 sv1 tmp2 sv2 ... finaltemplate)

outputs the result of applying a template (or several templates, as explained below) repeatedly, with a given value filling the slot the first time, and the result of each application filling the slot for the following application.

In the simplest case, CASCADE has three inputs. The second input is a one-slot expression template. That template is evaluated some number of times (perhaps zero). On the first evaluation, the slot is filled with the third input; on subsequent evaluations, the slot is filled with the result of the previous evaluation. The number of evaluations is determined by the first input. This can be either a nonnegative integer, in which case the template is evaluated that many times, or a predicate expression template, in which case it is evaluated (with the same slot filler that will be used for the evaluation of the second input) repeatedly, and the CASCADE evaluation continues as long as the predicate value is FALSE. (In other words, the predicate template indicates the condition for stopping.)

If the template is evaluated zero times, the output from CASCADE is the third (startvalue) input. Otherwise, the output is the value produced by the last template evaluation.

CASCADE templates may include the symbol # to represent the number of times the template has been evaluated. This slot is filled with 1 for the first evaluation, 2 for the second, and so on.

? show cascade 5 [lput # ?] []
[1 2 3 4 5]
? show cascade [vowelp first ?] [bf ?] "spring
ing
? show cascade 5 [# * ?] 1
120
?

Several cascaded results can be computed in parallel by providing additional template-startvalue pairs as inputs to CASCADE. In this case, all templates (including the endtest template, if used) are multi-slot, with the number of slots equal to the number of pairs of inputs. In each round of evaluations, ?2, for example, represents the result of evaluating the second template in the previous round. If the total number of inputs (including the first endtest input) is odd, then the output from CASCADE is the final value of the first template. If the total number of inputs is even, then the last input is a template that is evaluated once, after the end test is satisfied, to determine the output from CASCADE.

to fibonacci :n
output (cascade :n [?1 + ?2] 1 [?1] 0)
end

to piglatin :word
output (cascade [vowelp first ?] ~
                [word bf ? first ?] ~
                :word ~
                [word ? "ay])
end

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

cascade.2

CASCADE.2 endtest temp1 startval1 temp2 startval2  (library procedure)

outputs the result of invoking CASCADE with the same inputs. The only difference is that the default number of inputs is five instead of three.


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

transfer

TRANSFER endtest template inbasket		(library procedure)

outputs the result of repeated evaluation of the template. The template is evaluated once for each member of the list inbasket. TRANSFER maintains an outbasket that is initially the empty list. After each evaluation of the template, the resulting value becomes the new outbasket.

In the template, the symbol ?IN represents the current member from the inbasket; the symbol ?OUT represents the entire current outbasket. Other slot symbols should not be used.

If the first (endtest) input is an empty list, evaluation continues until all inbasket members have been used. If not, the first input must be a predicate expression template, and evaluation continues until either that template’s value is TRUE or the inbasket is used up.


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

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