123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993 |
- PSL Manual 7 February 1983 Flow Of Control
- section 9.0 page 9.1
- CHAPTER 9
CHAPTER 9
CHAPTER 9
- FLOW OF CONTROL
FLOW OF CONTROL
FLOW OF CONTROL
- 9.1. Introduction . . . . . . . . . . . . . . . 9.1
- 9.2. Conditionals . . . . . . . . . . . . . . . 9.1
- 9.2.1. Conds and Ifs. . . . . . . . . . . . . 9.1
- 9.2.2. The Case Statement . . . . . . . . . . . 9.3
- 9.3. Sequencing Evaluation . . . . . . . . . . . . 9.4
- 9.4. Iteration . . . . . . . . . . . . . . . . 9.7
- 9.4.1. For . . . . . . . . . . . . . . . . 9.8
- 9.4.2. Mapping Functions . . . . . . . . . . . 9.13
- 9.4.3. Do . . . . . . . . . . . . . . . . 9.16
- 9.5. Non-Local Exits . . . . . . . . . . . . . . 9.18
- 9.1. Introduction
9.1. Introduction
9.1. Introduction
- Most of the constructs presented in this Chapter have a special syntax in
- RLISP. This syntax is presented along with the definitions of the
- underlying functions. Many of the examples are presented using this
- special RLISP syntax as well as LISP.
- 9.2. Conditionals
9.2. Conditionals
9.2. Conditionals
- 9.2.1. Conds and Ifs
9.2.1. Conds and Ifs
9.2.1. Conds and Ifs
- Cond
Cond _ ____ ____ ___ ____ ________ _____
(Cond [U:form-list]): any open-compiled, fexpr
- Cond If
Cond If
The LISP function Cond corresponds to the If statement of most
- If
If
programming languages. In RLISP this is simply the familiar If
- Then Else
Then Else
... Then ... Else construct. For example:
- _________ ______
IF predicate THEN action1
- ______
ELSE action2
- _________ ______
==> (COND (predicate action1)
- ______
(T action2))
- ______ _________
Action1 is evaluated if the predicate has a non-NIL evaluation;
- Else
______ Else
otherwise, action2 is evaluated. Dangling Elses are resolved in
- Then
Then
the ALGOL manner by pairing them with the nearest preceding Then.
- For example:
Flow Of Control 7 February 1983 PSL Manual
- page 9.2 section 9.2
- IF F(X) THEN
- IF G(Y) THEN PRINT(X)
- ELSE PRINT(Y);
- is equivalent to
- IF F(X) THEN
- << IF G(Y) THEN PRINT(X)
- ELSE PRINT(Y) >>;
- Note that if F(X) is NIL, nothing is printed.
- Taken simply as a function, without RLISP syntax, the arguments
- Cond
Cond
to Cond have the form:
- _________ ______ ______
(COND (predicate action action ...)
- _________ ______ ______
(predicate action action ...)
- ...
- _________ ______ ______
(predicate action action ...) )
- The predicates are evaluated in the order of their appearance
- until a non-NIL value is encountered. The corresponding actions
- are evaluated and the value of the last becomes the value of the
- Cond Else
Cond Else
Cond. The dangling Else example above is:
- (COND ((F X) (COND ((G X) (PRINT X))
- ( T (PRINT Y)) ) ))
- Go Return
Go Return
The actions may also contain the special functions Go, Return,
- Exit Next
Exit Next
Exit, and Next, subject to the constraints on placement of these
- Cond
Cond
functions given in Section 9.3. In these cases, Cond does not
- have a defined value, but rather an effect. If no predicate is
- Cond
Cond
non-NIL, the value of Cond is NIL.
- The following MACROs are defined in the USEFUL module for convenience,
- and are mostly used from LISP syntax:
- If
If _ ____ __ ____ _ ____ ___ _____
(If E:form S0:form [S:form]): any macro
- If Cond
If Cond
If is a macro to simplify the writing of a common form of Cond in
- which there are only two clauses and the antecedent of the second
- is T. It cannot be used in RLISP syntax.
- (IF E S0 S1...Sn)
- __ _
The then-clause S0 is evaluated if and only if the test E is
- _
non-NIL, otherwise the else-clauses Si are evaluated, and the
- last returned. There may be no else-clauses.
- Related macros for common COND forms are WHEN and UNLESS.
PSL Manual 7 February 1983 Flow Of Control
- section 9.2 page 9.3
- When
When _ ____ _ ____ ___ _____
(When E:form [S:form]): any macro
- (WHEN E S1 S2 ... Sn)
- evaluates the Si and returns the value of Sn if and only if the
- When
_ When
test E is non-NIL. Otherwise When returns NIL.
- Unless
Unless _ ____ _ ____ ___ _____
(Unless E:form [U:form]): any macro
- (UNLESS E S1 S2 ... Sn)
- _
Evaluates the Si if and only if the test E is NIL. It is
- equivalent to
- (WHEN (NOT E) S1 S2 ... Sn)
- And Or
And Or
While And and Or are primarily of interest as Boolean connectives, they
- are often used in LISP as conditionals. For example,
- (AND (FOO) (BAR) (BAZ))
- has the same result as
- (COND ((FOO) (COND ((BAR) (BAZ)))))
- See Section 4.2.3.
- 9.2.2. The Case Statement
9.2.2. The Case Statement
9.2.2. The Case Statement
- PSL provides a numeric case statement, that is compiled quite
- efficiently; some effort is made to examine special cases (compact vs. non
- compact sets of cases, short vs. long sets of cases, etc.). It has mostly
- been used in SYSLISP mode, but can also be used from LISP mode provided
- that case-tags are numeric. There is also an FEXPR, CASE, for the
- interpreter.
- The RLISP syntax is:
- Case-Statement ::= CASE expr OF case-list END
- Case-list ::= Case-expr [; Case-list ]
- Case-expr ::= Tag-expr : expr
- tag-expr ::= DEFAULT | OTHERWISE |
- tag | tag, tag ... tag |
- tag TO tag
- Tag ::= Integer | Wconst-Integer
Flow Of Control 7 February 1983 PSL Manual
- page 9.4 section 9.2
- For example:
- CASE i OF
- 1: Print("First");
- 2,3: Print("Second");
- 4 to 10: Print("Third");
- Default: Print("Fourth");
- END
- The RLISP syntax parses into the following LISP form:
- Case
Case _ ____ _ ____ ____ ___ ____ ________ _____
(Case I:form [U:case-list]): any open-compiled, fexpr
- _ _______
I is meant to evaluate to an integer, and is used as a selector
- _
amongst the various Us. Each case-list has the form (case-expr
- form) where case-expr has the form:
- NIL -> default case
- (I1 I2 ... In) -> where each Ik is an integer or
- (RANGE low high)
- The above example becomes:
- (CASE i ((1) (Print "First"))
- ((2 3) (Print "Second"))
- (((Range 4 10)) (Print "Third"))
- ( NIL (Print "Fourth")))
- [??? Perhaps we should move SELECTQ (and define a SELECT) from the
[??? Perhaps we should move SELECTQ (and define a SELECT) from the
[??? Perhaps we should move SELECTQ (and define a SELECT) from the
- COMMON module to the basic system ???]
COMMON module to the basic system ???]
COMMON module to the basic system ???]
- .
- 9.3. Sequencing Evaluation
9.3. Sequencing Evaluation
9.3. Sequencing Evaluation
- These functions provide for explicit control sequencing, and the
- definition of blocks altering the scope of local variables.
- ProgN
ProgN _ ____ ___ ____ ________ _____
(ProgN [U:form]): any open-compiled, fexpr
- _
U is a set of expressions which are executed sequentially. The
- value returned is the value of the last expression.
PSL Manual 7 February 1983 Flow Of Control
- section 9.3 page 9.5
- Prog2
Prog2 _ ____ _ ____ ___ ____ ________ ____
(Prog2 A:form B:form): any open-compiled, expr
- _
Returns the value of B (the second argument).
- [??? Redefine prog2 to take N arguments, return second. ???]
[??? Redefine prog2 to take N arguments, return second. ???]
[??? Redefine prog2 to take N arguments, return second. ???]
- Prog1
Prog1 _ ____ ___ _____
(Prog1 [U:form]): any macro
- Prog1
Prog1
Prog1 is a function defined in the USEFUL package; to use it,
- Prog1
Prog1
type (LOAD USEFUL). Prog1 evaluates its arguments in order, like
- ProgN
ProgN
ProgN, but returns the value of the first.
- Prog
Prog ____ __ ____ _______ __ ____ ___ ____ ________ _____
(Prog VARS:id-list [PROGRAM:{id,form}]): any open-compiled, fexpr
- Prog
____ ____ __ Prog
VARS is a list of ids which are considered FLUID if the Prog is
- interpreted and LOCAL if compiled (see the "Variables and
- Prog
Prog
Bindings" Section, 10.2). The Prog's variables are allocated
- Prog
Prog
space if the Prog form is applied, and are deallocated if the
- Prog Prog
Prog Prog
Prog is exited. Prog variables are initialized to NIL. The
- _______
PROGRAM is a set of expressions to be evaluated in order of their
- Prog
Prog __________
appearance in the Prog function. identifiers appearing in the
- _______
top level of the PROGRAM are labels which can be referred to by
- Go Prog
Go Prog
Go. The value returned by the Prog function is determined by a
- Return Prog
Return Prog
Return function or NIL if the Prog "falls through".
- There are restrictions as to where a number of control functions, such as
- Go Return
Go Return
Go and Return, may be placed. This is so that they may have only locally
- determinable effects. Unlike most LISPs, which make this restriction only
- in compiled code, PSL enforces this restriction uniformly in both compiled
- and interpreted code. Not only does this help keep the semantics of
- compiled and interpreted code the same, but we believe it leads to more
- readable programs. For cases in which a non-local exit is truly required,
- Catch Throw
Catch Throw
there are the functions Catch and Throw, described in Section 9.5.
- Go Return Exit Next
Go Return Exit Next
The functions so restricted are Go, Return, Exit, and Next. They must be
- placed at top-level within the surrounding control structure to which they
- Prog Return
Prog Return
refer (e.g. the Prog which Return causes to be terminated), or nested
- within only selected functions. The functions in which they may be nested
- (to arbitrary depth) are:
- ProgN
ProgN
- ProgN (compound statement)
- Cond
Cond
- actions of Conds (if then else)
- Case
Case
- actions in Cases
- Go
Go _____ __ ____ ________ ____ ________ _____
(Go LABEL:id): None Returned open-compiled, fexpr
- Go Prog
Go Prog
Go alters the normal flow of control within a Prog function. The
- Prog
Prog
next statement of a Prog function to be evaluated is immediately
- Go
_____ Go
preceded by LABEL. A Go may appear only in the following
- situations:
Flow Of Control 7 February 1983 PSL Manual
- page 9.6 section 9.3
- Prog
Prog _____
a. At the top level of a Prog referring to a LABEL that also
- Prog
Prog
appears at the top level of the same Prog.
- Cond
Cond
b. As the action of a Cond item
- Prog
Prog
i. appearing on the top level of a Prog.
- Cond
Cond
ii. which appears as the action of a Cond item to any
- level.
- ProgN
ProgN
c. As the last statement of a ProgN
- Prog
Prog
i. which appears at the top level of a Prog or in a
- ProgN Cond
ProgN Cond
ProgN appearing in the action of a Cond to any level
- subject to the restrictions of b.i, or b.ii.
- ProgN Cond ProgN
ProgN Cond ProgN
ii. within a ProgN or as the action of a Cond in a ProgN
- to any level subject to the restrictions of b.i,
- b.ii, and c.i.
- Prog
_____ Prog
If LABEL does not appear at the top level of the Prog in which
- Go
Go
the Go appears, an error occurs:
- ***** LABEL is not a label within the current scope
- Go
Go
If the Go has been placed in a position not defined by rules a-c,
- another error is detected:
- ***** Illegal use of GO To LABEL
- Return
Return _ ____ ____ ________ ____ ________ ____
(Return U:form): None Returned open-compiled, expr
- Prog Return Prog
Prog Return Prog
Within a Prog, Return terminates the evaluation of a Prog and
- Prog
_ Prog
returns U as the value of the Prog. The restrictions on the
- Return Go
Return Go
placement of Return are exactly those of Go. Improper placement
- Return
Return
of Return results in the error:
- ***** Illegal use of RETURN
- 9.4. Iteration
9.4. Iteration
9.4. Iteration
- While
While _ ____ _ ____ ___ _____
(While E:form [S:form]): NIL macro
- This is the most commonly used construct for indefinite iteration
- _ _
in LISP. E is evaluated; if non-NIL, the S's are evaluated from
- _
left to right and then the process is repeated. If E evaluates
- While Exit
While Exit
to NIL the While returns NIL. Exit may be used to terminate the
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.7
- While Next
While Next
While from within the body and to return a value. Next may be
- used to terminate the current iteration. In RLISP syntax this is
- While Do
While Do
While ... Do ... . Note that in RLISP syntax there may be only a
- Do ProgN
Do ProgN
single expression after the Do; however, it may be a ProgN
- delimited by <<...>>. That is,
- (While E S1 S2)
- should be written in RLISP as
- While E do <<S1; S2>>;
- Repeat
Repeat _ ____ _ ____ ___ _____
(Repeat E:form [S:form]): NIL macro
- _ _
The S's are evaluated left to right, and then E is evaluated.
- Repeat
_ Repeat
This is repeated until the value of E is NIL, if Repeat returns
- Next Exit
Next Exit _
NIL. Next and Exit may be used in the S's branch to the next
- Repeat
Repeat
iteration of a Repeat or to terminate one and possibly return a
- Go Return
Go Return _
value. Go, and Return may appear in the S's. The RLISP syntax
- Repeat Repeat Until While
Repeat Repeat Until While
for Repeat is Repeat Until. Like While, RLISP syntax only allows
- _
a single S, so
- (REPEAT E S1 S2)
- should be written in RLISP as
- REPEAT << S1; S2 >> UNTIL E;
- [??? maybe do REPEAT S1 ... Sn E ???]
[??? maybe do REPEAT S1 ... Sn E ???]
[??? maybe do REPEAT S1 ... Sn E ???]
- Next
Next ____ ________ ____ ________ __________ _____
(Next ): None Returned open-compiled, restricted, macro
- This terminates the current iteration of the most closely
- While Repeat
While Repeat
surrounding While or Repeat, and causes the next to commence.
- See the note in Section 9.3 about the lexical restrictions on
- GO
GO
placement of this construct, which is essentially a GO to a
- special label placed at the front of a loop construct.
- Exit
Exit _ ____ ____ ________ ____ ________ __________ _____
(Exit [U:form]): None Returned open-compiled,restricted, macro
- _
The U's are evaluated left to right, the most closely surrounding
- While Repeat
While Repeat _
While or Repeat is terminated, and the value of the last U is
- returned. With no arguments, NIL is returned. See the note in
- Section 9.3 about the lexical restrictions on placement of this
- Return
Return
construct, which is essentially a Return.
- While Repeat Prog Next Exit
While Repeat Prog Next Exit
While and Repeat each macro expand into a Prog; Next and Exit are macro
- Go Return Prog
Go Return Prog
expanded into a Go and a Return respectively to this Prog. Thus using a
- Next Exit Prog While Repeat
Next Exit Prog While Repeat
Next or an Exit within a Prog within a While or Repeat will result only in
Flow Of Control 7 February 1983 PSL Manual
- page 9.8 section 9.4
- Prog
Prog
an exit of the internal Prog. In RLISP be careful to use
- WHILE E DO << S1;...;EXIT(1);...;Sn>>
- not
- WHILE E DO BEGIN S1;...;EXIT(1);...;Sn;END;
- 9.4.1. For
9.4.1. For
9.4.1. For
- For
For
A simple For construct is available in the basic PSL system and RLISP; an
- extended form can obtained by loading USEFUL. It is planned to make the
- extended form the version available in the basic system, combining all the
- FOR ForEach For
FOR ForEach For
features of FOR and ForEach. The basic PSL For provides only the (FROM ..)
- ForEach
ForEach
iterator, and (DO ...) action clause, and uses the ForEach construct for
- some of the (IN ...) and (ON ...) iterators. Most PSL syntax users should
- For
For
use the full For construct.
- For
For _ ____ ___ _____
(For [S:form]): any macro
- For
For
The arguments to For are clauses; each clause is itself a list of
- a keyword and one or more arguments. The clauses may introduce
- local variables, specify return values and when the iteration
- should cease, have side-effects, and so on. Before going
- further, it is probably best to give some examples.
- (FOR (FROM I 1 10 2) (DO (PRINT I)))
- Prints the numbers 1 3 5 7 9
- (FOR (IN U '(A B C)) (DO (PRINT U)))
- Prints the letters A B C
- (FOR (ON U '(A B C)) (DO (PRINT U)))
- Prints the lists (A B C) (B C) and (C)
- Finally, the function
- (DE ZIP (X Y)
- (FOR (IN U X) (IN V Y)
- (COLLECT (LIST U V))))
- produces a list of 2 element lists, each consisting of the the
- corresponding elements of the three lists X, Y and Z. For
- example,
- (ZIP '(1 2 3 4) '(A B C) )
- produces
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.9
- ((1 a)(2 b)(3 c))
- The iteration terminates as soon as one of the (IN ..) clauses is
- exhausted.
- Note that the (IN ... ), (ON ...) and (FROM ...) clauses
- introduce local variables U, V or I, that are referred to in the
- action clause.
- All the possible clauses are described below. The first few
- introduce iteration variables. Most of these also give some
- means of indicating when iteration should cease. For example, if
- In
____ In
a list being mapped over by an In clause is exhausted, iteration
- For
For
must cease. If several such clauses are given in For expression,
- iteration ceases when one of the clauses indicates it should,
- whether or not the other clauses indicate that it should cease.
- (IN V1 V2)
- ____
assigns the variable V1 successive elements of the list
- V2.
- This may take an additional, optional argument: a
- function to be applied to the extracted element or
- sublist before it is assigned to the variable. The
- following returns the sum of the lengths of all the
- elements of L.
- [??? Rather a kludge -- not sure why this is here.
[??? Rather a kludge -- not sure why this is here.
[??? Rather a kludge -- not sure why this is here.
- Perhaps it should come out again. ???]
Perhaps it should come out again. ???]
Perhaps it should come out again. ???]
- (DE LENGTHS (L)
- (FOR (IN N L LENGTH)
- (COLLECT (LIST N N)))
- is the same as
- (DE LENGTHS (L)
- (FOR (IN N L)
- (COLLECT
- (LIST (LENGTH N) (LENGTH N))))
- )
- but only calls LENGTH once. Using the (WITH ..) form to
- introduce a local LN may be clearer.
- For example,
- (SUMLENGTHS
- '((1 2 3 4 5)(a b c)(x y)))
- is
- ((5 5) (3 3) (2 2))
Flow Of Control 7 February 1983 PSL Manual
- page 9.10 section 9.4
- (ON V1 V2)
- Cdr
Cdr ____
assigns the variable V1 successive Cdrs of the list V2.
- (FROM VAR INIT FINAL STEP)
- is a numeric iteration clause. The variable is first
- assigned INIT, and then incremented by step until it is
- larger than FINAL. INIT, FINAL, and STEP are optional.
- INIT and STEP both default to 1, and if FINAL is
- omitted the iteration continues until stopped by some
- other means. To specify a STEP with INIT or FINAL
- omitted, or a FINAL with INIT omitted, place NIL (the
- constant -- it cannot be an expression) in the
- appropriate slot to be omitted. FINAL and STEP are
- only evaluated once.
- (FOR VAR INIT NEXT)
- assigns the variable INIT first, and subsequently the
- value of the expression NEXT. INIT and NEXT may be
- omitted. Note that this is identical to the behavior
- Do
Do
of iterators in a Do.
- (WITH V1 V2 ... Vn)
- introduces N locals, initialized to NIL. In addition,
- each Vi may also be of the form (VAR INIT), in which
- case it is initialized to INIT.
- (DO S1 S2 ... Sn)
- causes the Si's to be evaluated at each iteration.
- There are two clauses which allow arbitrary code to be executed
- before the first iteration, and after the last.
- (INITIALLY S1 S2 ... Sn)
- causes the Si's to be evaluated in the new environment
- (i.e. with the iteration variables bound to their
- initial values) before the first iteration.
- (FINALLY S1 S2 ... Sn)
- causes the Si's to be evaluated just before the
- function returns.
- The next few clauses build up return types. Except for the
- RETURNS/RETURNING clause, they may each take an additional
- argument which specifies that instead of returning the
- appropriate value, it is accumulated in the specified variable.
- For example, an unzipper might be defined as
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.11
- (DE UNZIP (L)
- (FOR (IN U L) (WITH X Y)
- (COLLECT (FIRST U) X)
- (COLLECT (SECOND U) Y)
- (RETURNS (LIST X Y))))
- Zip
Zip ____
This is essentially the opposite of Zip. Given a list of 2
- ____ ____ ____
element lists, it unzips them into 2 lists, and returns a list of
- ____
those 2 lists. For example, (unzip '((1 a)(2 b)(3 c))) returns
- is ((1 2 3)(a b c)).
- (RETURNS EXP)
- For
For
causes the given expression to be the value of the For.
- Returning is synonymous with returns. It may be given
- additional arguments, in which case they are evaluated
- in order and the value of the last is returned
- ProgN
ProgN
(implicit ProgN).
- (COLLECT EXP)
- causes the successive values of the expression to be
- Append
____ Append
collected into a list. Each value is Appended to the
- ____
end of the list.
- (UNION EXP)
- ____
is similar, but only adds an element to the list if it
- is not equal to anything already there.
- (CONC EXP)
- NConc
NConc
causes the successive values to be NConc'd together.
- (JOIN EXP)
- causes them to be appended.
- (COUNT EXP)
- returns the number of times EXP was non-NIL.
- (SUM EXP), (PRODUCT EXP), (MAXIMIZE EXP), and (MINIMIZE EXP)
- do the obvious. Synonyms are summing, maximizing, and
- minimizing.
- (ALWAYS EXP)
- returns T if EXP is non-NIL on each iteration. If EXP
- is ever NIL, the loop terminates immediately, no
- epilogue code, such as that introduced by finally is
- run, and NIL is returned.
- (NEVER EXP)
- is equivalent to (ALWAYS (NOT EXP)).
- (WHILE EXP) and (UNTIL EXP)
- Explicit tests for the end of the loop may be given
Flow Of Control 7 February 1983 PSL Manual
- page 9.12 section 9.4
- using (WHILE EXP). The loop terminates if EXP becomes
- NIL at the beginning of an iteration. (UNTIL EXP) is
- While Until
While Until
equivalent to (WHILE (NOT EXP)). Both While and Until
- may be given additional arguments; (WHILE E1 E2 ... En)
- is equivalent to (WHILE (AND E1 E2 ... En)) and
- (UNTIL E1 E2 ... En) is equivalent to
- (UNTIL (OR E1 E2 ... En)).
- (WHEN EXP)
- causes a jump to the next iteration if EXP is NIL.
- (UNLESS EXP)
- is equivalent to (WHEN (NOT EXP)).
- For
For
For is a general iteration construct similar in many ways to the LISP
- Loop
Loop
Machine and MACLISP Loop construct, and the earlier Interlisp CLISP
- For
For
iteration construct. For, however, is considerably simpler, far more
- For
For
"lispy", and somewhat less powerful. For only works in LISP syntax.
- All variable binding/updating still precedes any tests or other code.
- When Unless
When Unless
Also note that all When or Unless clauses apply to all action clauses, not
- For
For
just subsequent ones. This fixed order of evaluation makes For less
- Loop
Loop
powerful than Loop, but also keeps it considerably simpler. The basic
- order of evaluation is
- a. bind variables to initial values (computed in the outer
- environment)
- Initially
Initially
b. execute prologue (i.e. Initially clauses)
- c. while none of the termination conditions are satisfied:
- When Unless
When Unless
i. check conditionalization clauses (When and Unless), and
- start next iteration if all are not satisfied.
- ii. perform body, collecting into variables as necessary
- iii. next iteration
- d. (after a termination condition is satisfied) execute the
- Finally
Finally
epilogue (i.e. Finally clauses)
- For
For
For does all variable binding/updating in parallel. There is a similar
- For*
For*
macro, For*, which does it sequentially.
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.13
- For!*
For!* _ ____ ___ _____
(For!* [S:form]): any macro
- 9.4.2. Mapping Functions
9.4.2. Mapping Functions
9.4.2. Mapping Functions
- )
- The mapping functions long familiar to LISP programmers are present in
- For
For
PSL. However, we believe that the For construct described above or the
- ForEach
ForEach
simpler ForEach described below is generally more useful, since it obviates
- the usual necessity of constructing a lambda expression, and is often more
- transparent. Mapping functions with more than two arguments are not
- ____
currently supported. Note however that several lists may be iterated along
- For
For
with For, and with considerably more generality. For example:
- (Prog (I)
- (Setq I 0)
- (Return
- (Mapcar L
- (Function (Lambda (X)
- (Progn
- (Setq I (Plus I 1))
- (Cons I X)))))))
- may be expressed more transparently as
- (For (IN X L) (FROM I 1) (COLLECT (CONS I X)))
- Note that there is currently no RLISP syntax for this, but we are
- contemplating something like:
- FOR X IN L AS I FROM 1 COLLECT I . X;
- For
For
To augment the simpler For loop present in basic PSL and support the
- For Each
For Each
RLISP For Each construct, the following list iterator has been provided:
- ForEach
ForEach _ ___ ___ _____
(ForEach U:any): any macro
- _____
_____
_____
macro
macro
This macro is essentially equivalent to the the map functions as
- follows:
- Possible forms are:
- Setting X to successive elements (CARs) of U:
- (FOREACH X IN U DO (FOO X)) --> (MAPC U 'FOO)
- (FOREACH X IN U COLLECT (FOO X))--> (MAPCAR U 'FOO)
- (FOREACH X IN U CONC (FOO X)) --> (MAPCAN U 'FOO)
- (FOREACH X IN U JOIN (FOO X)) --> (MAPCAN U 'FOO)
- Setting X to successive CDRs of U:
- (FOREACH X ON U DO (FOO X)) --> (MAP U 'FOO)
Flow Of Control 7 February 1983 PSL Manual
- page 9.14 section 9.4
- (FOREACH X ON U COLLECT (FOO X))--> (MAPLIST U 'FOO)
- (FOREACH X ON U CONC (FOO X)) --> (MAPCON U 'FOO)
- (FOREACH X ON U JOIN (FOO X)) --> (MAPCON U 'FOO)
- The RLISP syntax is quite simple:
- FOR EACH x IN y DO z;
- FOR EACH x ON y COLLECT z;
- etc.
- Note that FOR EACH may be written as FOREACH
- Map
Map _ ____ __ ________ ___ ____
(Map X:list FN:function): NIL expr
- Cdr
__ Cdr _
Applies FN to successive Cdr segments of X. NIL is returned.
- This is equivalent to:
- (FOREACH u ON x DO (FN u))
- MapC
MapC _ ____ __ ________ ___ ____
(MapC X:list FN:function): NIL expr
- Car
__ Car ____ _
FN is applied to successive Car segments of list X. NIL is
- returned. This is equivalent to:
- (FOREACH u IN x DO (FN u))
- MapCan
MapCan _ ____ __ ________ ____ ____
(MapCan X:list FN:function): list expr
- Car
____ __ Car _
A concatenated list of FN applied to successive Car elements of X
- is returned. This is equivalent to:
- (FOREACH u IN x CONC (FN u))
- MapCar
MapCar _ ____ __ ________ ____ ____
(MapCar X:list FN:function): list expr
- ____ __
Returned is a constructed list, the elements of which are FN
- Car
Car ____ _
applied to each Car of list X. This is equivalent to:
- (FOREACH u IN x COLLECT (FN u))
- MapCon
MapCon _ ____ __ ________ ____ ____
(MapCon X:list FN:function): list expr
- Cdr
____ __ Cdr
Returned is a concatenated list of FN applied to successive Cdr
- _
segments of X. This is equivalent to:
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.15
- (FOREACH u ON x CONC (FN u))
- MapList
MapList _ ____ __ ________ ____ ____
(MapList X:list FN:function): list expr
- ____ __
Returns a constructed list, the elements of which are FN applied
- Cdr
Cdr _
to successive Cdr segments of X. This is equivalent to:
- (FOREACH u ON x COLLECT (FN u))
- 9.4.3. Do
9.4.3. Do
9.4.3. Do
- Do Let
Do Let
The MACLISP style Do and Let are now partially implemented in the USEFUL
- module.
- Do
Do _ ____ _ ____ _ ____ ___ _____
(Do A:list B:list [S:form]): any macro
- Do
Do
The Do macro is a general iteration construct similar to that of
- LISPM and friends. However, it does differ in some details; in
- Do
Do
particular it is not compatible with the "old style Do" of
- MACLISP, nor does it support the "no end test means once only"
- Do
Do
convention. Do has the form
- (DO (I1 I2 ... In)
- (TEST R1 R2 ... Rk)
- S1
- S2
- ...
- Sm)
- in which there may be zero or more I's, R's, and S's. In general
- the I's have the form
- (var init step)
- Do
Do
On entry to the Do form, all the inits are evaluated, then the
- variables are bound to their respective inits. The test is
- evaluated, and if non-NIL the form evaluates the R's and returns
- the value of the last one. If none are supplied it returns NIL.
- If the test evaluates to NIL the S's are evaluated, the variables
- are assigned the values of their respective steps in parallel,
- and the test evaluated again. This iteration continues until
- test evaluates to a non-NIL value. Note that the inits are
- evaluated in the surrounding environment, while the steps are
- Do
Do
evaluated in the new environment. The body of the Do (the S's)
- Prog Go
Prog Go
is a Prog, and may contain labels and Go's, though use of this is
- Return
Return
discouraged. It may be changed at a later date. Return used
- Do
Do
within a Do returns immediately without evaluating the test or
- exit forms (R's).
Flow Of Control 7 February 1983 PSL Manual
- page 9.16 section 9.4
- There are alternative forms for the I's: If the step is omitted,
- the variable's value is left unchanged. If both the init and
- __
step are omitted or if the I is an id, it is initialized to NIL
- and left unchanged. This is particularly useful for introducing
- SetQ
SetQ
dummy variables which are SetQ'd inside the body.
- Do!*
Do!* _ ____ _ ____ _ ____ ___ _____
(Do!* A:list B:list [C:form]): any macro
- Do!* Do
Do!* Do
Do!* is like Do, except the variable bindings and updatings are
- done sequentially instead of in parallel.
- Do-Loop
Do-Loop _ ____ _ ____ _ ____ _ ____ ___ _____
(Do-Loop A:list B:list C:list [S:form]): any macro
- Do-Loop Do
Do-Loop Do
Do-Loop is like Do, except that it takes an additional argument,
- a prologue. The general form is
- (DO-LOOP (I1 I2 ... In)
- (P1 P2 ... Pj)
- (TEST R1 R2 ... Rk)
- S1
- S2
- ...
- Sm)
- Do
Do
This is executed just like the corresponding Do, except that
- after the bindings are established and initial values assigned,
- but before the test is first executed the P's are evaluated, in
- order. Note that the P's are all evaluated exactly once
- (assuming that none of the P's err out, or otherwise throw to a
- surrounding context).
- Do-Loop!*
Do-Loop!* _ ____ _ ____ _ ____ _ ____ ___ _____
(Do-Loop!* A:list B:list C:list [S:form_]): any macro
- Do-Loop!*
Do-Loop!*
Do-Loop!* does the variable bindings and undates sequentially
- instead of in parallel.
- Let
Let _ ____ _ ____ ___ _____
(Let A:list [B:form]): any macro
- Let
Let
Let is a macro giving a more perspicuous form for writing lambda
- expressions. The basic form is
- (LET ((V1 I1) (V2 I2) ...(Vn In)) S1 S2 ... Sn)
- The I's are evaluated (in an unspecified order), and then the V's
- are bound to these values, the S's evaluated, and the value of
- the last is returned. Note that the I's are evaluated in the
- outer environment before the V's are bound.
PSL Manual 7 February 1983 Flow Of Control
- section 9.4 page 9.17
- __
Note: the id LET conflicts with a similar construct in RLISP and
- REDUCE
- Let!*
Let!* _ ____ _ ____ ___ _____
(Let!* A:list [B:form]): any macro
- Let!* Let
Let!* Let
Let!* is just like Let except that it makes the assignments
- sequentially. That is, the first binding is made before the
- value for the second one is computed.
- 9.5. Non-Local Exits
9.5. Non-Local Exits
9.5. Non-Local Exits
- One occasionally wishes to discontinue a computation in which the lexical
- Return
Return
restrictions on placement of Return are too restrictive. The non-local
- Catch Throw
Catch Throw
exit constructs Catch and Throw exist for these cases. They should not,
- however, be used indiscriminately. The lexical restrictions on their more
- local counterparts ensure that the flow of control can be ascertained by
- Catch Throw
Catch Throw
looking at a single piece of code. With Catch and Throw, control may be
- passed to and from totally unrelated pieces of code. Under some
- conditions, these functions are invaluable. Under others, they can wreak
- havoc.
- Catch
Catch ___ __ ____ ____ ___ ____ ________ _____
(Catch TAG:id [FORM:form]): any Open-Compiled, fexpr
- Catch Eval
Catch ___ Eval ____
Catch evaluates the TAG and then calls Eval on the FORMs in a
- Throw
Throw ___ ___
protected environment. If during this evaluation (Throw TAG VAL)
- Catch Throw
Catch ___ Throw
occurs, Catch immediately returns VAL. If no Throw occurs, the
- ____
value of the last FORM is returned. Note that in general only
- Throw Throw Eq
Throw ___ Throw ___ Eq
Throws with the same TAG are caught. Throws whose TAG is not Eq
- Catch Catch
Catch Catch ___
to that of Catch are passed on out to surrounding Catches. A TAG
- Catch
Catch
of NIL, however, is special. (Catch NIL @var[form)] catches any
- Throw
Throw
Throw.
- __________ ______
THROWSIGNAL!* [Initially: NIL] global
- __________ ______
THROWTAG!* [Initially: NIL] global
- The FLUID variables THROWSIGNAL!* and THROWTAG!* may be
- Catch
Catch
interrogated to find out if the most recently evaluated Catch was
- Throw Throw
Throw Throw
Thrown to, and what tag was passed to the Throw. THROWSIGNAL!*
- Set Catch
Set Catch
is Set to NIL upon normal exit from a Catch, and to T upon normal
- Throw Set
Throw Set
exit from Throw. THROWTAG!* is Set to the first argument passed
- Throw Throw Eval
Throw Throw Eval ____
to the Throw. (Mark a place to Throw to, Eval FORM.)
Flow Of Control 7 February 1983 PSL Manual
- page 9.18 section 9.5
- Throw
Throw ___ __ ___ ___ ____ ________ ____
(Throw TAG:id VAL:any): None Returned expr
- Catch Eq
Catch Eq
This passes control to the closest surrounding Catch with an Eq
- Catch
___ Catch
or null TAG. If there is no such surrounding Catch it is an
- _____
_____
_____
Throw
__ ___ _______ __ ___ Throw
error in the context of the Throw. That is, control is not
- Throw Error
Throw Error
Thrown to the top level before the call on Error. (Non-local
- Goto
Goto
Goto.)
- Some examples:
- In LISP syntax, with
- (DE DOIT (x)
- (COND ((EQN x 1) 100)
- (T (THROW 'FOO 200))))
- (CATCH 'FOO (DOIT 1) (PRINT "NOPE") 0)
- will continue and execute the PRINT statement
- and return 0
- while
- (CATCH 'FOO (DOIT 2) (PRINT "NOPE") 0)
- will of course THROW, returning 200 and not executing
- the last forms.
- A common problem people encounter is how to pass arguments and/or
- CATCH
CATCH
computed functions or tags into CATCH for protected evaluation. The
- following examples should illustrate. Note that TAG is quoted, since it is
- evaluated before use in CATCH and THROW.
- In LISP syntax:
- (DE PASS-ARGS(X1 X2)
- (CATCH 'FOO (FEE (PLUS2 X1 X2) (DIFFERENCE X1 X2))))
- This is simple, because CATCH compiles open. No FLUID declarations or
- Apply
Apply
LIST building is needed, as in previous versions of PSL. An explicit Apply
- must be used for a function argument; usually, the APPLY will compile open,
- with no overhead:
- In LISP syntax:
- (DE PASS-FN(X1 FN)
- (CATCH 'FOO (APPLY FN (LIST X1))))
- Catch Throw
Catch Throw
The following MACROs are provided to aid in the use of Catch and Throw
- with a NIL tag, by examining the THROWSIGNAL!* and THROWTAG!*:
PSL Manual 7 February 1983 Flow Of Control
- section 9.5 page 9.19
- Catch!-All
Catch!-All __ ________ ____ ____ ___ _____
(Catch!-All FN:function [FORM:form]): any macro
- Catch
Catch
This issues a (Catch NIL ...); if a Throw was actually done, the
- __
function FN is applied to the two arguments THROWTAG!* and the
- throw Throw
throw Throw
value returned by the throw. Thus FN is applied only if a Throw
- was executed.
- Unwind!-All
Unwind!-All __ ________ ____ ____ ___ _____
(Unwind!-All FN:function [FORM:form]): any macro
- Catch
Catch __
This issues a (Catch NIL ...). The function FN is always called,
- and applied to the two arguments THROWTAG!* and the value
- throw Throw
throw Throw __
returned by the throw. If no Throw was done then FN is called on
- NIL and the value returned.
- Unwind!-Protect
Unwind!-Protect _ ____ _ ____ ___ _____
(Unwind!-Protect F:form [C:form]): any macro
- _
The idea is to execute the "protected" form, F, and then run some
- _
"clean-up" forms C even if a Throw (or Error) occurred during the
- Catch
_ Catch
evaluation of F. This issues a (Catch NIL ...), the cleanup forms
- are then run, and finally either the value is returned if no
- Throw occurred, or the Throw is "re-thrown" to the same tag.
- A common example is to ensure a file be closed after processing,
- even if an error or throw occurred:
- (SETQ chan (OPEN file ....))
- (UNWIND-PROTECT (process-file)
- (CLOSE chan))
- Note: Certain special tags are used in the PSL system, and should not be
- interfered with casually:
- Error ErrorSet
Error ErrorSet
!$ERROR!$ Used by Error and ErrorSet which are implemented in terms of
- Catch Throw
Catch Throw
Catch and Throw, see Chapter 14).
- !$UNWIND!-PROTECT!$
- A special TAG placed to ensure that ALL throws pause at the
- UNWIND-PROTECT "mark".
- PROG GO RETURN
PROG GO RETURN
!$PROG!$ Used to communicate between interpreted PROGs, GOs and RETURNs.
|