Date post: | 04-Jan-2016 |
Category: |
Documents |
Upload: | priscilla-hamilton |
View: | 217 times |
Download: | 4 times |
1
Lecture 2: Basic Control and Procedures
Per Brand
2
Basic Control Structures
• Sequence of statements:
S1 S2• The thread executes statements in a sequential order.
However a thread, contrary to conventional languages, may suspend in some statement, so above a thread has to complete execution of S1, before starting S2.
• Empty statement:
skip
3
If Statement
• Oz provides a simple form of conditional statement having the following form:
if B then S1 else S2 end
– B should be a Boolean value.
• Semantics
– If B is bound to true S1 is executed
– if B is bound to false S2 is executed
– if B is bound to an non-Boolean value, an exception is raised
– otherwise if B is unbound the thread suspends until one of the cases above applies
4
Comparison Procedures
• Oz provides a number of built-in tertiary procedures These include == that we have seen earlier as well as \=, =<, <, >=, and >.
• Used as Boolean functions in an infix notation.
• In this example Z is bound to the maximum of X and Y, i.e. to Y:
declare X Y ZX = 5 Y = 10 if X >= Y then Z = X else Z = Y end
5
Abbreviations
• A statement using the keyword elseif:
if B1 then S1 elseif B2 then S2 else S3 end
• is shorthand for nested if-statements:
if B1 then S1
else if B2 then S2 else S3 end
end
• An if-statement missing the else part:
if B1 then S1 end
• is equivalent to:
• if B1 then S1 else skip end
6
Procedure Abstractions
• A procedure in Oz is a first class value:
– can be defined.
declare
proc {P X1 … Xn} S end
– can be applied
{P Y1 … Yn}
– passed around as argument to another procedure, e.g..
{Q P 1}
– and, stored in an arbitrary data-structure, e.g. record.
X=rec(P)
7
Procedure Definition & Application
• By example
declare Max X Y Z proc {Max X Y Z} if X >= Y then
Z = X else Z = Y end end X = 5 Y = 10 {Max X Y Z}
{Show Z} %% shows 10
8
Procedures cont’d
• Procedures don’t return anything directly
• Return achieved by using single-assignment variables as parameters
– e.g. {Max In1 In2 Return}
• More general as procedures can ‘return’ multiple valuesdeclare Two F S proc {Two In First Second} First=In.1
Second= In.2 end {Two f(a b) F S} % F is bound to a, S to b
9
Procedures cont’d
• Observe convention
– put the output parameter(s) at the end
• Very often there is one and exactly one return value
– Oz supports functional declaration as syntactic sugar
– Recommendation: use it for pure functions
fun {Max X Y} proc{Max X Y Aux} if X >= Y then X if X >= Y then Aux=X else Y else Aux=Y end end end end
10
Functions
fun{Max X Y} if X >= Y then
X else
Y endend
proc{Max X Y Aux} if X >= Y then
Aux=X else
Aux=Y endend
Max
X>=Y
X Y
Control ends in expression and not statement
11
More syntactic sugar
fun{Max X Y} if X >= Y then X
else Y endend
declare A
A={Max 1 3}
{Show A} %% shows 3
%% or
{Show {Max 1 3 $}} %% shows 3
%% or
{Show {Max 1 3}} %% shows 3
12
Procedures are first class
• Procedures and everything else in Oz are first class• declare Max Rec
Rec= rec(1 2) Max= proc {$ X Y Z} if X >= Y then
Z = X else Z = Y end end
• Max is bound to the procedure
• Rec is bound to the record
13
1st class
• Procedures and everything else in Oz are first class• declare Max
Max= proc {$ X Y Z} if X >= Y then
Z = X else Z = Y end end
• Max is bound to the procedure
• The procedure is in the store just like other data structures
• What can you do with Max??
– Usual stuff
– Apply it
– But more !!!
14
Equality
• Equality and equality test - token or pointer equality– records, numbers etc. have structural equality
• declare fun {Max X Y} if X >= Y then Z else Y end end fun {Max2 X Y} if X >= Y then Z else Y end end fun {Min X Y} if X >= Y then Y else Z end end Alias=Max {Show Max==Min} %% shows false {Show Max==Max2} %% shows false {Show Max==Alias} %% shows true
15
Example: procedures as parameters
declare A B proc {Twice Inc In Out}local Aux in {Inc In Aux} {Inc Aux Out} end end proc {Inc1 In Out}Out= In+1 end proc {Inc2 In Out}Out= s(In)
end
{Twice Inc1 1 A}{Twice Inc2 s(0) B}{Show A#B} %% shows 3#s(s(s(0)))
16
Example: procedures in data structure
declare fun{Max A B}
…
end fun {Min A B}
…
end MyMathModule=math(max:Max min:Min)
declare Max Min {MyMathModule.max 1 3 Max} {MyMathModule.min 1 3 Min} {Show Max#Min} %% 3#1
17
Example: procedures returning procedures
declare P1 P2 fun {GenInc2 Inc}
fun{$ A}
{Inc {Inc A}}
end
end P1={GenInc2 fun{$ A} A+1 end} {Show {P1 5}} %%% Shows 7
P2={GenInc2 fun{$ A} s(s(A)) end} {Show {P2 (s(0)}} %%% Shows s(s(s(0)))
18
Lexical Scoping
• In the statement S some variable occurrences are syntactically bound while others are free.
• A variable occurrence X in S is bound:
– If X is in the scope of the procedure formal-parameter X.
– Or is in the scope of a variable introduction statement, or other variable-binding construct, that introduces X.
– Otherwise, the identifier occurrence is free.
• Each free variable occurrence in an program is eventually bound by the closest textually surrounding identifier-binding construct.
• Lexical (static) scoping: when free variables in procedure, function, or a class are bound at their definition position by the nearest enclosing definition
• Dynamic scoping otherwise, at the context of call, or location of a call
19
Semantics: proc {P X1 … Xn} S end
The variable P should be already introduced.
Executing the above statement will create a procedure (closure): an abstraction: (X1 … Xn).S.
P is bound to the closure.
A closure contains
code
references to those entities referenced by the free variables in the procedure.
20
Closures
(X1 … Xn).S.
Assume Y1 … Yn occures free in S.
Y1
:
Yn
Environment
Y1
:
Yn
Code
for S
21
Example: procedures returning procedures revisited
declare proc{GenMax Less Aux1}
Aux1=proc{$ A B Aux2}
if {Less A B} then Aux2=B %% in closure
else Aux2=A end
end
end
P={GenMax fun{$ A B} A<B end}
Q={GenMax fun{$ A B} … end}
Closure of Aux1 contains the procedure Less
22
Example: closure containing data
declare Mod proc{MyMath Out}
local Pi A C in
Pi=3.14159
Out=math(area:A circ:C)
A=fun{$ Rad} Pi*Rad*Rad
B=fun{$ Rad} 2.0*Pi*Rad end
end
{MyMath Mod}
{Show {Mod.area 3.0}#{Mod.circ 3.0}}
23
Closures
• Closures contain code + arbitrary entites
• Most common
– other procedures
– stateful entities (dealt with in a later lecture)
24
Anonymous Procedures and Variable Initialization
• Why is a variable bound to a procedure in a way that is different from the variable being bound to record:
• X = Value?
• What you see is just a syntactic variant of the equivalent form:
P = proc {$ X1 … Xn} S end
• The R.H.S. defines an anonymous procedural value.
(X1 … Xn).S
25
variable-initialization equality
• Variables could be introduced and initialized simultaneously by:
X = OzValue or Record = OzValue
• between local and in, in a statement of the form: local ... in ... end.
local Max = proc {$ X Y Z} if X >= Y then Z = X else Z = Y end end X = 5 Y = 10 Zin {Max X Y Z} {Show Z}end
26
Variable-initialization equality
• Only the variables occurring on the L.H.S. of the equality are the ones being introduced
• local Y = 1in local M = f(M Y) [X1 Y] = L L = [1 2] in
{Show M} %% shows f(f(…) 2) endend
• The outer variable Y is invisible in the innermost: local ... end statement.
27
Variable-initialization equality
• local Y in Y = 1 local M X1 Y L in M = f(M Y) L = [Z Y] L = [1 2] {Show M} endend
• local Y = 1in local M = f(M Y) [Z Y] = L L = [1 2] in {Show M} endend
28
The exclamation mark ‘!’
• Used to suppress variable introduction.
• An exclamation mark ‘!’ is only meaningful in the L.H.S. of an initializing equality and in pattern matching constructs.
local Y = 1in local M = f(M Y) [X1 !Y] = L L = [1 2] in {Show M} endend
• local Y in Y = 1 local M X1 L in M = f(M Y) L = [X1 Y] L = [1 2] {Show M} endend
29
Variable declaration abbreviation
local X in S end often abbreviated
X in S
proc{MyMath Out}
Pi A C in
Pi=3.14159
Out=math(area:A circ:C)
A=fun{$ Rad} Pi*Rad*Rad
B=fun{$ Rad} 2.0*Pi*Rad
%% implicit end here
end
30
Pattern Matching
• Case Statement
• case E of Pattern1 then S1 [] Pattern2 then S2 [] ... else S end
• All variables introduced in Patterni are implicitly declared, and have a scope stretching over the corresponding Si.
31
Pattern Matching Semantics
• E is evaluated to V.
• Executing the case statement will sequentially match V against the patterns Pattern1, Pattern2, ...,Patternn in this order.
• Matching V against Patterni is done in left-to-right depth-first manner.
• If V matches Patterni without binding any variable occuring in V, the corresponding Si statement is executed.
• If V matches Patterni but binds some variables occuring in V, the thread suspends
• If the matching of V and Patterni fails, V is tried against the next pattern Patterni+1, otherwise the else statement S is executed.
• The else part may be omitted, in which case an exception is raised if all matches fail.
• Suppressing the introduction of a new local variable by using !. For example, in the following example:
– case f(X1 X2) of f(!Y Z) then ... else ... end
32
Case for pattern matching
• proc {Insert Key Value TreeIn ?TreeOut} case TreeIn of nil then TreeOut = tree(Key Value nil nil) [] tree(K1 V1 T1 T2) then if Key == K1 then TreeOut = tree(Key Value T1 T2) elseif Key < K1 then T in
TreeOut = tree(K1 V1 T T2) {Insert Key Value T1 T}
else T in TreeOut = tree(K1 V1 T1 T) {Insert Key Value T2 T}
end endend
33
Nesting
• Intermediate variables are introduced
• local T0 T1 T2 T3 in {Insert a 3 nil T0} {Insert b 15 T0 T1} {Insert c 10 T1 T2} {Insert d 7 T2 T3} end
• Oz provides syntactic support for nesting one procedure calls inside another
– local Y in {P ... Y ...} {Q Y ... }end
• could be written as:
– {Q {P ... $ ...} ... }
• using ‘$’ as a nesting marker.
34
Functional Nesting
• A procedure {P X … R} is a function; its result is the argument R.
• {P X …} is a function call that can be inserted in any expression instead of the result argument. {Q {P X … } … } is equivalent to: local R in {P X ... R} {Q R ... }endOur example, a more concise form using functional nesting is:
• {Insert d 7 {Insert c 10 {Insert b 15 {Insert a 3 nil}}}}}
35
Nested Application
• Nested application inside a record or a tuple:Zs = X|{SMerge Xr Ys $}
• The nested application goes after the record construction statement.local Zr in Zs = X|Zr {SMerge Xr Ys Zr}end
36
Example - merging two sorted lists
proc {SMerge Xs Ys Zs} case Xs#Ys of nil#Ys then Zs=Ys [] Xs#nil then Zs=Xs [] (X|Xr) # (Y|Yr) then if X=<Y then Zs = X|{SMerge Xr Ys $} else Zr in Zs = Y|{SMerge Xs Yr $} end end end
37
Procedures as Values
• The procedure BinaryTree checks a structure to verify whether it is a binary tree or not, and accordingly returns true or false in its result argument B. % What is a binary tree?local proc {And B1 B2 ?B} if B1 then B = B2 else B = false end endin proc {BinaryTree T ?B} case T of nil then B = true [] tree(K V T1 T2) then {And {BinaryTree T1} {BinaryTree T2} B} else B = false end endend
38
Problem and Fix
The call {And {BinaryTree T1}{BinaryTree T2} B}
is certainly doing unnecessary work.
According to our nesting rules, it evaluates its
2nd argument even if the first is false.
39
Problem & Fix
• The call {And {BinaryTree T1}{BinaryTree T2} B} may be doing unnecessary work.
– According to our nesting rules, it evaluates its 2nd argument even if the first is false.
• Define new procedure AndThen:
– It takes as its first two arguments two procedures, and calls the second procedure only if the first returns false.
– The procedure is another example of a higher-order procedure:
– fun{AndThen A B} if A then B else falseend
40
Control Abstractions
• Higher-order procedures are used in Oz to define various control abstractions. In modules Control and List as well as many others, you will find many control abstractions.
• Syntactic support for iterators
• for <iterators> do <S> end
• where iterators are
– X in L %% iterates over the list L
– X in I..J %% iterates over the integers I to J, inclusive
– X in I..J; K %% iterates over the integers I to J, inclusive with increments of K
41
More higher order procedures
proc {ForAll Xs P} case Xs of nil then skip [] X|Xr then {P X} {ForAll Xr P} endend
{ForAll [1 2 3] Show}
%%%% or use the below
for X in [1 2 3] do Show end
42
Example - iteration
local proc {HelpPlus C To Step P} if C=<To then {P C} {HelpPlus C+Step To Step P} end end proc {HelpMinus C To Step P} if C>=To then {P C} {HelpMinus C+Step To Step P} end endin proc {For From To Step P} if Step>0 then {HelpPlus From To Step P} else {HelpMinus From To Step P} end endend {For 3 7 2 proc{$ X} {Show X} end}%% orfor X in 3..7;2 do {Show X} end