Introduction To Programming Concepts: Carlos Varela RPI Adapted With Permission From: Seif Haridi KTH Peter Van Roy UCL
Introduction To Programming Concepts: Carlos Varela RPI Adapted With Permission From: Seif Haridi KTH Peter Van Roy UCL
Concepts
Carlos Varela
RPI
Adapted with permission from:
Seif Haridi
KTH
Peter Van Roy
UCL
C. Varela; Adapted w. permission from S. Haridi and
Introduction
Variables
Variables are short-cuts for values, they cannot be assigned
more than once
declare
V = 9999*9999
{Browse V*V}
Functions
Compute the factorial function:
Start with the mathematical definition
declare
fun {Fact N}
if N==0 then 1 else N*{Fact N-1} end
end
n! 1 2 (n 1) n
0! 1
n! n (n 1)! if n 0
Composing functions
Combinations of r items taken from n.
The number of subsets of size r taken from a set of size n
n
n!
r r!( n r )!
declare
fun {Comb N R}
{Fact N} div ({Fact R}*{Fact N-R})
end
Comb
Fact
Fact
Fact
1
1
1
1
1
1
2
3
4
1
3
1
4
declare
H=1
T = [2 3 4 5]
{Browse H|T} % This will show [1 2 3 4 5]
Lists (2)
Taking lists apart (selecting components)
A cons has two components a head, and tail
declare L = [5 6 7 8]
|
L.1 gives 5
L.2 give [6 7 8]
6
|
|
7
8
nil
Pattern matching
Another way to take a list apart is by use of pattern
matching with a case instruction
case L of H|T then {Browse H} {Browse T} end
1
1
(0) 1
1
1
2
3
4
1
3
1
4
(0)
1
Shift right [0 1 3 3 1]
Shift left [1 3 3 1 0]
Pascal N-1
Pascal N-1
ShiftLeft
ShiftRight
AddList
10
11
12
13
Mathematical induction
Select one or more input to the function
Show the program is correct for the simple cases (base
case)
Show that if the program is correct for a given case, it is
then correct for the next case.
For integers base case is either 0 or 1, and for any integer n
the next case is n+1
For lists the base case is nil, or a list with one or few
elements, and for any list T the next case H|T
14
Correctness of factorial
fun {Fact N}
if N==0 then 1 else N*{Fact N-1} end
end
1 2 (n 1) n
Fact ( n 1)
15
Complexity
Pascal runs very slow,
try {Pascal 24}
{Pascal 20} calls: {Pascal 19} twice,
{Pascal 18} four times, {Pascal 17}
eight times, ..., {Pascal 1} 219 times
Execution time of a program up to a
constant factor is called programs
time complexity.
Time complexity of {Pascal N} is
proportional to 2N (exponential)
Programs with exponential time
complexity are impractical
declare
fun {Pascal N}
if N==1 then [1]
else
{AddList
{ShiftLeft {Pascal N-1}}
{ShiftRight {Pascal N-1}}}
end
end
16
Faster Pascal
fun {FastPascal N}
if N==1 then [1]
else
local L in
L={FastPascal N-1}
{AddList {ShiftLeft L} {ShiftRight L}}
end
end
end
17
Lazy evaluation
The functions written so far are evaluated eagerly (as soon
as they are called)
Another way is lazy evaluation where a computation is
done only when the results is needed
Calculates the infinite list:
0 | 1 | 2 | 3 | ...
declare
fun lazy {Ints N}
N|{Ints N+1}
end
18
19
declare
L = {PascalList [1]}
{Browse L}
{Browse L.1}
{Browse L.2.1}
L<Future>
[1]
[1 1]
20
Higher-order programming
Assume we want to write another Pascal function which
instead of adding numbers performs exclusive-or on them
It calculates for each number whether it is odd or even
(parity)
Either write a new function each time we need a new
operation, or write one generic function that takes an
operation (another function) as argument
The ability to pass functions as argument, or return a
function as result is called higher-order programming
Higher-order programming is an aid to build generic
abstractions
C. Varela; Adapted w. permission from S. Haridi and
21
Variations of Pascal
Compute the parity Pascal triangle
fun {Xor X Y} if X==Y then 0 else 1 end end
1
1
1
1
1
1
2
3
4
1
1
1
3
1
1
1
1
1
0
1
0
1
1
1
0
22
Higher-order programming
fun {GenericPascal Op N}
if N==1 then [1]
else L in L = {GenericPascal Op N-1}
{OpList Op {ShiftLeft L} {ShiftRight L}}
end
end
fun {OpList Op L1 L2}
case L1 of H1|T1 then
case L2 of H2|T2 then
{Op H1 H2}|{OpList Op T1 T2}
end
else nil end
end
23
Concurrency
thread
P in
P = {Pascal 21}
{Browse P}
end
{Browse 99*99}
24
Dataflow
25
Dataflow (II)
declare X
thread
{Delay 5000} X=99
end
{Browse Start} {Browse X*X}
declare X
thread
{Browse Start} {Browse X*X}
end
{Delay 5000} X=99
26
State
declare
C = {NewCell 0}
{Assign C {Access C}+1}
{Browse {Access C}}
27
Example
Add memory to Pascal to
remember how many times
it is called
The memory (state) is
global here
Memory that is local to a
function is called
encapsulated state
declare
C = {NewCell 0}
fun {FastPascal N}
{Assign C {Access C}+1}
{GenericPascal Add N}
end
28
Objects
Functions with internal
memory are called objects
The cell is invisible outside
of the definition
declare
fun {FastPascal N}
{Browse {Bump}}
{GenericPascal Add N}
end
declare
local C in
C = {NewCell 0}
fun {Bump}
{Assign C {Access C}+1}
{Access C}
end
end
29
Classes
A class is a factory of
objects where each object
has its own internal state
Let us create many
independent counter
objects with the same
behavior
fun {NewCounter}
local C Bump in
C = {NewCell 0}
fun {Bump}
{Assign C {Access C}+1}
{Access C}
end
Bump
end
end
30
Classes (2)
Here is a class with two
operations: Bump and
Read
fun {NewCounter}
local C Bump Read in
C = {NewCell 0}
fun {Bump}
{Assign C {Access C}+1}
{Access C}
end
fun {Read}
{Access C}
end
[Bump Read]
end
end
31
Object-oriented programming
In object-oriented programming the idea of objects and
classes is pushed farther
Classes keep the basic properties of:
State encapsulation
Object factories
32
Nondeterminism
What happens if a program has both concurrency and state
together?
This is very tricky
The same program can give different results from one
execution to the next
This variability is called nondeterminism
Internal nondeterminism is not a problem if it is not
observable from outside
33
Nondeterminism (2)
declare
C = {NewCell 0}
thread {Assign C 1} end
thread {Assign C 2} end
t0
C = {NewCell 0}
cell C contains 0
t1
{Assign C 1}
cell C contains 1
t2
{Assign C 2}
cell C contains 2 (final value)
time
34
Nondeterminism (3)
declare
C = {NewCell 0}
thread {Assign C 1} end
thread {Assign C 2} end
t0
C = {NewCell 0}
cell C contains 0
t1
{Assign C 2}
cell C contains 2
t2
{Assign C 1}
cell C contains 1 (final value)
time
35
Nondeterminism (4)
declare
C = {NewCell 0}
thread I in
I = {Access C}
{Assign C I+1}
end
thread J in
J = {Access C}
{Assign C J+1}
end
36
Nondeterminism (5)
Another possible final result is the cell
C containing the value 1
t0
declare
C = {NewCell 0}
thread I in
I = {Access C}
{Assign C I+1}
end
thread J in
J = {Access C}
{Assign C J+1}
end
C = {NewCell 0}
t1
I = {Access C}
t2
J = {Access C}
I equal 0
J equal 0
t3
{Assign C J+1}
t4
{Assign C I+1}
C contains 1
C contains 1
time
37
Lessons learned
38
Atomicity
How can we master the interleavings?
One idea is to reduce the number of interleavings by
programming with coarse-grained atomic operations
An operation is atomic if it is performed as a whole or
nothing
No intermediate (partial) results can be observed by any
other concurrent activity
In simple cases we can use a lock to ensure atomicity of a
sequence of operations
For this we need a new entity (a lock)
C. Varela; Adapted w. permission from S. Haridi and
39
Atomicity (2)
declare
L = {NewLock}
lock L then
sequence of ops 1
end
Thread 1
lock L then
sequence of ops 2
end
Thread 2
40
The program
declare
C = {NewCell 0}
L = {NewLock}
thread
lock L then I in
I = {Access C}
{Assign C I+1}
end
end
thread
lock L then J in
J = {Access C}
{Assign C J+1}
end
end
41
Memoizing FastPascal
declare
S = {NewStore}
{Put S 2 [1 1]}
{Browse {Get S 2}}
{Browse {Size S}}
42
Exercises
1.
2.
3.
4.
Define Add using the Zero and Succ functions representing numbers
in the lambda-calculus. Prove that it is correct using induction.
Write the memoizing Pascal function using the store abstraction
(available at http://www.info.ucl.ac.be/people/PVR/ds/booksuppl.oz)
Reason about the correctness of AddList and ShiftLeft using induction
VRH Exercise 1.6 (page 24)
c) Change GenericPascal so that it also receives a number to use as an identity
for the operation Op: {GenericPascal Op I N}. For example, you could
then use it as:
{GenericPascal Add 0 N}, or
{GenericPascal fun {$ X Y} X*Y end 1 N}
5.
43