SlideShare a Scribd company logo
Procedural Programming
It's Back? It Never Went Away
@KevlinHenney
Brycgstow
Bricstow
Bristow
Bristol
procedure
procedural
procedural?
Procedural Programming: It’s Back? It Never Went Away
µονόλιθος
Procedural Programming: It’s Back? It Never Went Away
This is the Unix philosophy:
Write programs that do one
thing and do it well.Write
programs to work together.
Doug McIlroy
µservices
In McIlroy's summary, the hard
part is his second sentence:
Write programs to work
together.
John D Cook
Procedural Programming: It’s Back? It Never Went Away
In the long run every
program becomes rococo
— then rubble.
Alan Perlis
1960s
1960s
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
I began to use the term “software
engineering” to distinguish it from
hardware and other kinds of engineering;
yet, treat each type of engineering as part of
the overall systems engineering process.
Margaret Hamilton
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Define a subset of the system which is
small enough to bring to an operational
state [...] then build on that subsystem.
E E David
This strategy requires that the system
be designed in modules which can be
realized, tested, and modified
independently, apart from conventions
for intermodule communication.
E E David
The design process
is an iterative one.
Andy Kinslow
There are two classes of system designers.
The first, if given five problems will solve
them one at a time.
Andy Kinslow
The second will come back and announce
that these aren’t the real problems, and
will eventually propose a solution to the
single problem which underlies the
original five.
Andy Kinslow
This is the ‘system type’ who is great
during the initial stages of a design project.
However, you had better get rid of him
after the first six months if you want to get
a working system.
Andy Kinslow
A software system can best be
designed if the testing is interlaced
with the designing instead of
being used after the design.
Alan Perlis
proc is leap year = (int year) bool:
skip;
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
proc is leap year = (int year) bool:
false;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
void: (assert (not is leap year (1967))))
);
mode proposition = struct (string name, proc void test);
proc is leap year = (int year) bool:
false;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
void: (assert (not is leap year (1967))))
);
test (leap year spec)
mode proposition = struct (string name, proc void test);
proc test = ([] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
test of spec [entry];
print (new line)
od;
proc is leap year = (int year) bool:
year mod 4 = 0;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
void: (assert (not is leap year (1967)))),
("Years divisible by 4 but not by 100 are leap years",
void: (assert (is leap year (1968))))
);
test (leap year spec)
proc is leap year = (int year) bool:
year mod 4 = 0 and year mod 100 /= 0;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
void: (assert (not is leap year (1967)))),
("Years divisible by 4 but not by 100 are leap years",
void: (assert (is leap year (1968)))),
("Years divisible by 100 but not by 400 are not leap years",
void: (assert (not is leap year (1900))))
);
test (leap year spec)
proc is leap year = (int year) bool:
year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
void: (assert (not is leap year (1967)))),
("Years divisible by 4 but not by 100 are leap years",
void: (assert (is leap year (1968)))),
("Years divisible by 100 but not by 400 are not leap years",
void: (assert (not is leap year (1900)))),
("Years divisible by 400 are leap years",
void: (assert (is leap year (2000))))
);
test (leap year spec)
Procedural Programming: It’s Back? It Never Went Away
proc is leap year = (int year) bool:
year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0;
[] proposition leap year spec =
(
("Years not divisible by 4 are not leap years",
with (2018, 2001, 1967, 1), expect (false)),
("Years divisible by 4 but not by 100 are leap years",
with (2016, 1984, 1968, 4), expect (true)),
("Years divisible by 100 but not by 400 are not leap years",
with (2100, 1900, 100), expect (false)),
("Years divisible by 400 are leap years",
with (2000, 1600, 400), expect (true))
);
test (is leap year, leap year spec)
mode expect = bool;
mode with = flex [1:0] int;
mode proposition = struct (string name, with inputs, expect result);
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print (if report = "" then (new line) else (new line, report, new line) fi)
od;
proc test = (proc (int) bool function, [] proposition spec) void:
for entry from lwb spec to upb spec
do
print (name of spec [entry]);
string report := "", separator := " failed for ";
[] int inputs = inputs of spec [entry];
for value from lwb inputs to upb inputs
do
if
bool expected = result of spec [entry];
function (inputs [value]) /= expected
then
report +:= separator + whole(inputs[value], 0);
separator := " "
fi
od;
print ((report = "" | (new line) | (new line, report, new line)))
od;
We instituted a rigorous regression
test for all of the features of AWK.
Any of the three of us who put in a
new feature into the language [...],
first had to write a test for the new
feature.
Alfred Aho
http://www.computerworld.com.au/article/216844/a-z_programming_languages_awk/
There is no such question as testing things after the
fact with simulation models, but that in effect the
testing and the replacement of simulations with
modules that are deeper and more detailed goes on
with the simulation model controlling, as it were,
the place and order in which these things are done.
Alan Perlis
As design work progresses this
simulation will gradually evolve
into the real system.
The simulation is the design.
Tad B Pinkerton
Procedural Programming: It’s Back? It Never Went Away
goto
Procedural Programming: It’s Back? It Never Went Away
/ WordFriday
snowclone, noun
▪ clichéd wording used as a template, typically
originating in a single quote
▪ e.g., "X considered harmful", "These aren't
the Xs you're looking for", "X is the new Y",
"It's X, but not as we know it", "No X left
behind", "It's Xs all the way down", "All your
X are belong to us"
Procedural Programming: It’s Back? It Never Went Away
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
RETURN
20 ISLEAP = .TRUE.
END
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
RETURN
20 ISLEAP = .TRUE.
RETURN
END
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
GOTO 30
20 ISLEAP = .TRUE.
30 RETURN
END
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
GOTO 30
20 ISLEAP = .TRUE.
GOTO 30
30 RETURN
END
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
GOTO 30
20 ISLEAP = .TRUE.
GOTO 30
30 CONTINUE
RETURN
END
FUNCTION ISLEAP(Year)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) THEN
ISLEAP = .TRUE.
ELSE IF (MOD(YEAR, 100) .EQ. 0) THEN
ISLEAP = .FALSE.
ELSE IF (MOD(YEAR, 4) .EQ. 0) THEN
ISLEAP = .TRUE.
ELSE
ISLEAP = .FALSE.
END IF
END
FUNCTION ISLEAP(Year)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) THEN
ISLEAP = .TRUE.
ELSE IF (MOD(YEAR, 100) .EQ. 0) THEN
ISLEAP = .FALSE.
ELSE IF (MOD(YEAR, 4) .EQ. 0) THEN
ISLEAP = .TRUE.
ELSE
ISLEAP = .FALSE.
END IF
END
A goto completely
invalidates the high-level
structure of the code.
Taligent's Guide to Designing Programs
FUNCTION ISLEAP(YEAR)
LOGICAL ISLEAP
INTEGER YEAR
IF (MOD(YEAR, 400) .EQ. 0) GOTO 20
IF (MOD(YEAR, 100) .EQ. 0) GOTO 10
IF (MOD(YEAR, 4) .EQ. 0) GOTO 20
10 ISLEAP = .FALSE.
RETURN
20 ISLEAP = .TRUE.
END
send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}
send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}
I feel a combination of
pride and revulsion at
this discovery.
Tom Duff
send(to, from, count)
register short *to, *from;
register count;
{
register n=(count+7)/8;
switch(count%8){
case 0: do{ *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
}while(--n>0);
}
}
Many people have said that the worst
feature of C is that switches don't break
automatically before each case label.
This code forms some sort of argument
in that debate, but I'm not sure whether
it's for or against.
Tom Duff
break
Plankalkül
Bram Bruines
continue
break
return
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
One of the most powerful
mechanisms for program
structuring [...] is the block
and procedure concept.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
sequence
selection
iteration
Main Program and Subroutine
The goal is to decompose a program into
smaller pieces to help achieve modifiability.
A program is decomposed hierarchically.
Len Bass, Paul Clements & Rick Kazman
Software Architecture in Practice
afferent branch transform branch efferent branch
main
subroutine subroutine
subroutine
subroutine
subroutine
subroutine
subroutine
subroutine
There is typically a single thread of control
and each component in the hierarchy gets
this control (optionally along with some
data) from its parent and passes it along
to its children.
Len Bass, Paul Clements & Rick Kazman
Software Architecture in Practice
afferent branch transform branch efferent branch
main
subroutine subroutine
subroutine
subroutine
subroutine
subroutine
subroutine
subroutine
afferent branch transform branch efferent branch
main
procedure procedure
procedure
procedure
procedure
procedure
procedure
procedure
afferent branch transform branch efferent branch
main
function function
function
function
function
function
function
function
main
function function
function
function
function
function
function
function
You cannot teach beginners
top-down programming,
because they don't know
which end is up.
C A R Hoare
Everything should be built
top-down, except the first
time.
Alan Perlis
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Hamlet: To be, or not to be,
that is the question.
Ophelia: 'Tis in my memory
locked, and you yourself
shall keep the key of it.
Hamlet: Yea, from the table
of my memory I'll wipe
away all trivial fond records.
Procedural Programming: It’s Back? It Never Went Away
One of the most powerful
mechanisms for program
structuring [...] is the block
and procedure concept.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
begin
ref(Book) array books(1:capacity);
integer count;
procedure Push(top); ...
procedure Pop; ...
boolean procedure IsEmpty; ...
boolean procedure IsFull; ...
integer procedure Depth; ...
ref(Book) procedure Top; ...
count := 0
end;
A procedure which is capable of
giving rise to block instances which
survive its call will be known as a
class; and the instances will be
known as objects of that class.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
class Stack(capacity);
integer capacity;
begin
ref(Book) array books(1:capacity);
integer count;
procedure Push(top); ...
procedure Pop; ...
boolean procedure IsEmpty; ...
boolean procedure IsFull; ...
integer procedure Depth; ...
ref(Book) procedure Top; ...
count := 0
end;
const newStack = () => {
const items = []
return {
depth: () => items.length,
top: () => items[0],
pop: () => { items.shift() },
push: newTop => { items.unshift(newTop) },
}
}
const newStack = () => {
const items = []
return {
depth: () => items.length,
top: () => items[items.length - 1],
pop: () => { items.pop() },
push: newTop => { items.push(newTop) },
}
}
Concatenation is an operation
defined between two classes A
and B, or a class A and a block C,
and results in the formation of a
new class or block.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
Concatenation consists in a
merging of the attributes of both
components, and the composition
of their actions.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
const stackable = base => {
const items = []
return Object.assign(base, {
depth: () => items.length,
top: () => items[items.length - 1],
pop: () => { items.pop() },
push: newTop => { items.push(newTop) },
})
}
const newStack = () => stackable({})
const clearable = base => {
return Object.assign(base, {
clear: () => {
while (base.depth())
base.pop()
},
})
}
const newStack =
() => clearable(stackable({}))
const newStack =
() => compose(clearable, stackable)({})
const compose = (...funcs) =>
arg => funcs.reduceRight(
(composed, func) => func(composed), arg)
Concept Hierarchies
The construction principle involved is best
called abstraction; we concentrate on features
common to many phenomena, and we abstract
away features too far removed from the
conceptual level at which we are working.
Ole-Johan Dahl and C A R Hoare
"Hierarchical Program Structures"
A type hierarchy is composed of subtypes and
supertypes. The intuitive idea of a subtype is
one whose objects provide all the behavior of
objects of another type (the supertype) plus
something extra.
Barbara Liskov
"Data Abstraction and Hierarchy"
What is wanted here is something like the
following substitution property: If for each
object o1 of type S there is an object o2 of type
T such that for all programs P defined in terms
of T, the behavior of P is unchanged when o1 is
substituted for o2, then S is a subtype of T.
Barbara Liskov
"Data Abstraction and Hierarchy"
const nonDuplicateTop = base => {
const push = base.push
return Object.assign(base, {
push: newTop => {
if (base.top() !== newTop)
push(newTop)
},
})
}
tests = {
...
'A non-empty stack becomes deeper by retaining a pushed item as its top':
() => {
const stack = newStack()
stack.push('ACCU')
stack.push('2018')
stack.push('2018')
assert(stack.depth() === 3)
assert(stack.top() === '2018')
},
...
}
const newStack =
() => compose(clearable, stackable)({})
tests = {
...
'A non-empty stack becomes deeper by retaining a pushed item as its top':
() => {
const stack = newStack()
stack.push('ACCU')
stack.push('2018')
stack.push('2018')
assert(stack.depth() === 3)
assert(stack.top() === '2018')
},
...
}
const newStack =
() => compose(nonDuplicateTop, clearable, stackable)({})
tests = {
...
'A non-empty stack becomes deeper by retaining a pushed item as its top':
() => {
const stack = newStack()
stack.push('ACCU')
stack.push('2018')
stack.push('2018')
assert(stack.depth() === 3)
assert(stack.top() === '2018')
},
...
}
What is wanted here is something like the
following substitution property: If for each
object o1 of type S there is an object o2 of type
T such that for all programs P defined in terms
of T, the behavior of P is unchanged when o1 is
substituted for o2, then S is a subtype of T.
Barbara Liskov
"Data Abstraction and Hierarchy"
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
The Synchronisation Quadrant
Procedural Comfort Zone
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Procedural Discomfort Zone
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Procedural Comfort Zone
Threads and locks —
they’re kind of a dead
end, right?
BretVictor
"The future of programming"
So, I think if [...] we’re still using
threads and locks, we should
just, like, pack up and go home,
’cause we’ve clearly failed as an
engineering field.
BretVictor
"The future of programming"
Procedural Comfort Zone
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
single-threaded activity
no shared mutable state
coordination
Procedural Programming: It’s Back? It Never Went Away
N
bounded
buffered
asynchronous
N =
unbounded
buffered
asynchronous
∞
N = 1
bounded
buffered
asynchronous
futurepromise
N = 0
bounded
unbuffered
synchronous
Procedural Programming: It’s Back? It Never Went Away
Toutes choses sont dites
déjà; mais comme
personne n'écoute, il faut
toujours recommencer.
André Gide
Everything has been said
before; but since nobody
listens, we must always
start again.
André Gide

More Related Content

What's hot (20)

PDF
Haskell for data science
John Cant
 
PDF
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
PDF
Humble introduction to category theory in haskell
Jongsoo Lee
 
PDF
Real World Haskell: Lecture 5
Bryan O'Sullivan
 
PDF
Futures e abstração - QCon São Paulo 2015
Leonardo Borges
 
PDF
Lezione03
robynho86
 
PDF
Functional Algebra: Monoids Applied
Susan Potter
 
PPT
Java Generics for Dummies
knutmork
 
PDF
Java Class Design
Ganesh Samarthyam
 
PDF
Fp in scala part 2
Hang Zhao
 
PPTX
Scala Back to Basics: Type Classes
Tomer Gabel
 
PDF
Comparing JVM languages
Jose Manuel Ortega Candel
 
PDF
Declarative Thinking, Declarative Practice
Kevlin Henney
 
PDF
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Philip Schwarz
 
PDF
Monad Transformers - Part 1
Philip Schwarz
 
PDF
Real World Haskell: Lecture 6
Bryan O'Sullivan
 
PPTX
Introduction to Monads in Scala (1)
stasimus
 
PDF
Real World Haskell: Lecture 2
Bryan O'Sullivan
 
PDF
C# quick ref (bruce 2016)
Bruce Hantover
 
PPSX
Tuga IT 2017 - What's new in C# 7
Paulo Morgado
 
Haskell for data science
John Cant
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes
 
Humble introduction to category theory in haskell
Jongsoo Lee
 
Real World Haskell: Lecture 5
Bryan O'Sullivan
 
Futures e abstração - QCon São Paulo 2015
Leonardo Borges
 
Lezione03
robynho86
 
Functional Algebra: Monoids Applied
Susan Potter
 
Java Generics for Dummies
knutmork
 
Java Class Design
Ganesh Samarthyam
 
Fp in scala part 2
Hang Zhao
 
Scala Back to Basics: Type Classes
Tomer Gabel
 
Comparing JVM languages
Jose Manuel Ortega Candel
 
Declarative Thinking, Declarative Practice
Kevlin Henney
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Philip Schwarz
 
Monad Transformers - Part 1
Philip Schwarz
 
Real World Haskell: Lecture 6
Bryan O'Sullivan
 
Introduction to Monads in Scala (1)
stasimus
 
Real World Haskell: Lecture 2
Bryan O'Sullivan
 
C# quick ref (bruce 2016)
Bruce Hantover
 
Tuga IT 2017 - What's new in C# 7
Paulo Morgado
 

Similar to Procedural Programming: It’s Back? It Never Went Away (20)

PDF
White Box Testing (Introduction to)
Henry Muccini
 
DOCX
CSC8503 Principles of Programming Languages Semester 1, 2015.docx
faithxdunce63732
 
PDF
python lab programs.pdf
CBJWorld
 
DOCX
Lisp and prolog in artificial intelligence
ArtiSolanki5
 
PDF
programacion funcional.pdf
FranciscoJavierAcost31
 
PPT
Python Control structures
Siddique Ibrahim
 
PDF
COneShotPart2 (1).pdf...............................
komitag811
 
PDF
The Ring programming language version 1.5.4 book - Part 34 of 185
Mahmoud Samir Fayed
 
PDF
Chapter 5 exercises Balagurusamy Programming ANSI in c
BUBT
 
PDF
Matlab_basic2013_1.pdf
abdul basit
 
PPTX
NUMERICAL METHODS WITH MATLAB PROGRAMMING
DHARANI A
 
PDF
BASICS OF COMPUTER PROGRAMMING-TAKE HOME ASSIGNMENT 2018
musadoto
 
PPTX
Chapter 3 - Programming in Matlab. aaaapptx
danartalabani
 
PDF
The Ring programming language version 1.5.3 book - Part 34 of 184
Mahmoud Samir Fayed
 
PPTX
Csci101 lect02 selection_andlooping
Elsayed Hemayed
 
PDF
The Ring programming language version 1.7 book - Part 38 of 196
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.10 book - Part 44 of 212
Mahmoud Samir Fayed
 
PDF
C and Data structure lab manual ECE (2).pdf
janakim15
 
PDF
Let us c(by yashwant kanetkar) chapter 2 solution
rohit kumar
 
PDF
C- Programming Assignment practice set 2 solutions
Animesh Chaturvedi
 
White Box Testing (Introduction to)
Henry Muccini
 
CSC8503 Principles of Programming Languages Semester 1, 2015.docx
faithxdunce63732
 
python lab programs.pdf
CBJWorld
 
Lisp and prolog in artificial intelligence
ArtiSolanki5
 
programacion funcional.pdf
FranciscoJavierAcost31
 
Python Control structures
Siddique Ibrahim
 
COneShotPart2 (1).pdf...............................
komitag811
 
The Ring programming language version 1.5.4 book - Part 34 of 185
Mahmoud Samir Fayed
 
Chapter 5 exercises Balagurusamy Programming ANSI in c
BUBT
 
Matlab_basic2013_1.pdf
abdul basit
 
NUMERICAL METHODS WITH MATLAB PROGRAMMING
DHARANI A
 
BASICS OF COMPUTER PROGRAMMING-TAKE HOME ASSIGNMENT 2018
musadoto
 
Chapter 3 - Programming in Matlab. aaaapptx
danartalabani
 
The Ring programming language version 1.5.3 book - Part 34 of 184
Mahmoud Samir Fayed
 
Csci101 lect02 selection_andlooping
Elsayed Hemayed
 
The Ring programming language version 1.7 book - Part 38 of 196
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 44 of 212
Mahmoud Samir Fayed
 
C and Data structure lab manual ECE (2).pdf
janakim15
 
Let us c(by yashwant kanetkar) chapter 2 solution
rohit kumar
 
C- Programming Assignment practice set 2 solutions
Animesh Chaturvedi
 
Ad

More from Kevlin Henney (20)

PDF
Program with GUTs
Kevlin Henney
 
PDF
The Case for Technical Excellence
Kevlin Henney
 
PDF
Empirical Development
Kevlin Henney
 
PDF
Solid Deconstruction
Kevlin Henney
 
PDF
Get Kata
Kevlin Henney
 
PDF
Structure and Interpretation of Test Cases
Kevlin Henney
 
PDF
Agility ≠ Speed
Kevlin Henney
 
PDF
Old Is the New New
Kevlin Henney
 
PDF
Turning Development Outside-In
Kevlin Henney
 
PDF
Giving Code a Good Name
Kevlin Henney
 
PDF
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
PDF
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
PDF
Code as Risk
Kevlin Henney
 
PDF
Software Is Details
Kevlin Henney
 
PDF
Game of Sprints
Kevlin Henney
 
PDF
Good Code
Kevlin Henney
 
PDF
The Error of Our Ways
Kevlin Henney
 
PDF
Seven Ineffective Coding Habits of Many Programmers
Kevlin Henney
 
PDF
SOLID Deconstruction
Kevlin Henney
 
PDF
Object? You Keep Using that Word
Kevlin Henney
 
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Kevlin Henney
 
Solid Deconstruction
Kevlin Henney
 
Get Kata
Kevlin Henney
 
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Kevlin Henney
 
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
Code as Risk
Kevlin Henney
 
Software Is Details
Kevlin Henney
 
Game of Sprints
Kevlin Henney
 
Good Code
Kevlin Henney
 
The Error of Our Ways
Kevlin Henney
 
Seven Ineffective Coding Habits of Many Programmers
Kevlin Henney
 
SOLID Deconstruction
Kevlin Henney
 
Object? You Keep Using that Word
Kevlin Henney
 
Ad

Recently uploaded (20)

PDF
Code and No-Code Journeys: The Maintenance Shortcut
Applitools
 
PPTX
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
PDF
Salesforce Experience Cloud Consultant.pdf
VALiNTRY360
 
PPT
24-BuildingGUIs Complete Materials in Java.ppt
javidmiakhil63
 
PPTX
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
PPTX
API DOCUMENTATION | API INTEGRATION PLATFORM
philipnathen82
 
PPTX
From spreadsheets and delays to real-time control
SatishKumar2651
 
PDF
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
PPTX
Transforming Insights: How Generative AI is Revolutionizing Data Analytics
LetsAI Solutions
 
PPTX
Library_Management_System_PPT111111.pptx
nmtnissancrm
 
PDF
NSF Converter Simplified: From Complexity to Clarity
Johnsena Crook
 
PDF
Latest Capcut Pro 5.9.0 Crack Version For PC {Fully 2025
utfefguu
 
PDF
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
PPTX
UI5con_2025_Accessibility_Ever_Evolving_
gerganakremenska1
 
PPTX
Lec 2 Compiler, Interpreter, linker, loader.pptx
javidmiakhil63
 
PDF
How Attendance Management Software is Revolutionizing Education.pdf
Pikmykid
 
PPTX
How Can Reporting Tools Improve Marketing Performance.pptx
Varsha Nayak
 
PPTX
Odoo Migration Services by CandidRoot Solutions
CandidRoot Solutions Private Limited
 
PDF
Everything you need to know about pricing & licensing Microsoft 365 Copilot f...
Q-Advise
 
PDF
Understanding the EU Cyber Resilience Act
ICS
 
Code and No-Code Journeys: The Maintenance Shortcut
Applitools
 
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
Salesforce Experience Cloud Consultant.pdf
VALiNTRY360
 
24-BuildingGUIs Complete Materials in Java.ppt
javidmiakhil63
 
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
API DOCUMENTATION | API INTEGRATION PLATFORM
philipnathen82
 
From spreadsheets and delays to real-time control
SatishKumar2651
 
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
Transforming Insights: How Generative AI is Revolutionizing Data Analytics
LetsAI Solutions
 
Library_Management_System_PPT111111.pptx
nmtnissancrm
 
NSF Converter Simplified: From Complexity to Clarity
Johnsena Crook
 
Latest Capcut Pro 5.9.0 Crack Version For PC {Fully 2025
utfefguu
 
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
UI5con_2025_Accessibility_Ever_Evolving_
gerganakremenska1
 
Lec 2 Compiler, Interpreter, linker, loader.pptx
javidmiakhil63
 
How Attendance Management Software is Revolutionizing Education.pdf
Pikmykid
 
How Can Reporting Tools Improve Marketing Performance.pptx
Varsha Nayak
 
Odoo Migration Services by CandidRoot Solutions
CandidRoot Solutions Private Limited
 
Everything you need to know about pricing & licensing Microsoft 365 Copilot f...
Q-Advise
 
Understanding the EU Cyber Resilience Act
ICS
 

Procedural Programming: It’s Back? It Never Went Away

  • 1. Procedural Programming It's Back? It Never Went Away @KevlinHenney
  • 12. This is the Unix philosophy: Write programs that do one thing and do it well.Write programs to work together. Doug McIlroy
  • 14. In McIlroy's summary, the hard part is his second sentence: Write programs to work together. John D Cook
  • 16. In the long run every program becomes rococo — then rubble. Alan Perlis
  • 17. 1960s
  • 18. 1960s
  • 24. I began to use the term “software engineering” to distinguish it from hardware and other kinds of engineering; yet, treat each type of engineering as part of the overall systems engineering process. Margaret Hamilton
  • 27. Define a subset of the system which is small enough to bring to an operational state [...] then build on that subsystem. E E David
  • 28. This strategy requires that the system be designed in modules which can be realized, tested, and modified independently, apart from conventions for intermodule communication. E E David
  • 29. The design process is an iterative one. Andy Kinslow
  • 30. There are two classes of system designers. The first, if given five problems will solve them one at a time. Andy Kinslow
  • 31. The second will come back and announce that these aren’t the real problems, and will eventually propose a solution to the single problem which underlies the original five. Andy Kinslow
  • 32. This is the ‘system type’ who is great during the initial stages of a design project. However, you had better get rid of him after the first six months if you want to get a working system. Andy Kinslow
  • 33. A software system can best be designed if the testing is interlaced with the designing instead of being used after the design. Alan Perlis
  • 34. proc is leap year = (int year) bool: skip;
  • 37. proc is leap year = (int year) bool: false; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))) );
  • 38. mode proposition = struct (string name, proc void test);
  • 39. proc is leap year = (int year) bool: false; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))) ); test (leap year spec)
  • 40. mode proposition = struct (string name, proc void test); proc test = ([] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); test of spec [entry]; print (new line) od;
  • 41. proc is leap year = (int year) bool: year mod 4 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))) ); test (leap year spec)
  • 42. proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))), ("Years divisible by 100 but not by 400 are not leap years", void: (assert (not is leap year (1900)))) ); test (leap year spec)
  • 43. proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", void: (assert (not is leap year (1967)))), ("Years divisible by 4 but not by 100 are leap years", void: (assert (is leap year (1968)))), ("Years divisible by 100 but not by 400 are not leap years", void: (assert (not is leap year (1900)))), ("Years divisible by 400 are leap years", void: (assert (is leap year (2000)))) ); test (leap year spec)
  • 45. proc is leap year = (int year) bool: year mod 4 = 0 and year mod 100 /= 0 or year mod 400 = 0; [] proposition leap year spec = ( ("Years not divisible by 4 are not leap years", with (2018, 2001, 1967, 1), expect (false)), ("Years divisible by 4 but not by 100 are leap years", with (2016, 1984, 1968, 4), expect (true)), ("Years divisible by 100 but not by 400 are not leap years", with (2100, 1900, 100), expect (false)), ("Years divisible by 400 are leap years", with (2000, 1600, 400), expect (true)) ); test (is leap year, leap year spec)
  • 46. mode expect = bool; mode with = flex [1:0] int; mode proposition = struct (string name, with inputs, expect result);
  • 47. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 48. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 49. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 50. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 51. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 52. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 53. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print (if report = "" then (new line) else (new line, report, new line) fi) od;
  • 54. proc test = (proc (int) bool function, [] proposition spec) void: for entry from lwb spec to upb spec do print (name of spec [entry]); string report := "", separator := " failed for "; [] int inputs = inputs of spec [entry]; for value from lwb inputs to upb inputs do if bool expected = result of spec [entry]; function (inputs [value]) /= expected then report +:= separator + whole(inputs[value], 0); separator := " " fi od; print ((report = "" | (new line) | (new line, report, new line))) od;
  • 55. We instituted a rigorous regression test for all of the features of AWK. Any of the three of us who put in a new feature into the language [...], first had to write a test for the new feature. Alfred Aho http://www.computerworld.com.au/article/216844/a-z_programming_languages_awk/
  • 56. There is no such question as testing things after the fact with simulation models, but that in effect the testing and the replacement of simulations with modules that are deeper and more detailed goes on with the simulation model controlling, as it were, the place and order in which these things are done. Alan Perlis
  • 57. As design work progresses this simulation will gradually evolve into the real system. The simulation is the design. Tad B Pinkerton
  • 59. goto
  • 62. snowclone, noun ▪ clichéd wording used as a template, typically originating in a single quote ▪ e.g., "X considered harmful", "These aren't the Xs you're looking for", "X is the new Y", "It's X, but not as we know it", "No X left behind", "It's Xs all the way down", "All your X are belong to us"
  • 64. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. RETURN 20 ISLEAP = .TRUE. END
  • 65. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. RETURN 20 ISLEAP = .TRUE. RETURN END
  • 66. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. GOTO 30 20 ISLEAP = .TRUE. 30 RETURN END
  • 67. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. GOTO 30 20 ISLEAP = .TRUE. GOTO 30 30 RETURN END
  • 68. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. GOTO 30 20 ISLEAP = .TRUE. GOTO 30 30 CONTINUE RETURN END
  • 69. FUNCTION ISLEAP(Year) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) THEN ISLEAP = .TRUE. ELSE IF (MOD(YEAR, 100) .EQ. 0) THEN ISLEAP = .FALSE. ELSE IF (MOD(YEAR, 4) .EQ. 0) THEN ISLEAP = .TRUE. ELSE ISLEAP = .FALSE. END IF END
  • 70. FUNCTION ISLEAP(Year) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) THEN ISLEAP = .TRUE. ELSE IF (MOD(YEAR, 100) .EQ. 0) THEN ISLEAP = .FALSE. ELSE IF (MOD(YEAR, 4) .EQ. 0) THEN ISLEAP = .TRUE. ELSE ISLEAP = .FALSE. END IF END
  • 71. A goto completely invalidates the high-level structure of the code. Taligent's Guide to Designing Programs
  • 72. FUNCTION ISLEAP(YEAR) LOGICAL ISLEAP INTEGER YEAR IF (MOD(YEAR, 400) .EQ. 0) GOTO 20 IF (MOD(YEAR, 100) .EQ. 0) GOTO 10 IF (MOD(YEAR, 4) .EQ. 0) GOTO 20 10 ISLEAP = .FALSE. RETURN 20 ISLEAP = .TRUE. END
  • 73. send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } }
  • 74. send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } I feel a combination of pride and revulsion at this discovery. Tom Duff
  • 75. send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } Many people have said that the worst feature of C is that switches don't break automatically before each case label. This code forms some sort of argument in that debate, but I'm not sure whether it's for or against. Tom Duff
  • 76. break
  • 92. One of the most powerful mechanisms for program structuring [...] is the block and procedure concept. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 94. Main Program and Subroutine The goal is to decompose a program into smaller pieces to help achieve modifiability. A program is decomposed hierarchically. Len Bass, Paul Clements & Rick Kazman Software Architecture in Practice
  • 95. afferent branch transform branch efferent branch main subroutine subroutine subroutine subroutine subroutine subroutine subroutine subroutine
  • 96. There is typically a single thread of control and each component in the hierarchy gets this control (optionally along with some data) from its parent and passes it along to its children. Len Bass, Paul Clements & Rick Kazman Software Architecture in Practice
  • 97. afferent branch transform branch efferent branch main subroutine subroutine subroutine subroutine subroutine subroutine subroutine subroutine
  • 98. afferent branch transform branch efferent branch main procedure procedure procedure procedure procedure procedure procedure procedure
  • 99. afferent branch transform branch efferent branch main function function function function function function function function
  • 101. You cannot teach beginners top-down programming, because they don't know which end is up. C A R Hoare
  • 102. Everything should be built top-down, except the first time. Alan Perlis
  • 112. Hamlet: To be, or not to be, that is the question.
  • 113. Ophelia: 'Tis in my memory locked, and you yourself shall keep the key of it.
  • 114. Hamlet: Yea, from the table of my memory I'll wipe away all trivial fond records.
  • 116. One of the most powerful mechanisms for program structuring [...] is the block and procedure concept. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 117. begin ref(Book) array books(1:capacity); integer count; procedure Push(top); ... procedure Pop; ... boolean procedure IsEmpty; ... boolean procedure IsFull; ... integer procedure Depth; ... ref(Book) procedure Top; ... count := 0 end;
  • 118. A procedure which is capable of giving rise to block instances which survive its call will be known as a class; and the instances will be known as objects of that class. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 119. class Stack(capacity); integer capacity; begin ref(Book) array books(1:capacity); integer count; procedure Push(top); ... procedure Pop; ... boolean procedure IsEmpty; ... boolean procedure IsFull; ... integer procedure Depth; ... ref(Book) procedure Top; ... count := 0 end;
  • 120. const newStack = () => { const items = [] return { depth: () => items.length, top: () => items[0], pop: () => { items.shift() }, push: newTop => { items.unshift(newTop) }, } }
  • 121. const newStack = () => { const items = [] return { depth: () => items.length, top: () => items[items.length - 1], pop: () => { items.pop() }, push: newTop => { items.push(newTop) }, } }
  • 122. Concatenation is an operation defined between two classes A and B, or a class A and a block C, and results in the formation of a new class or block. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 123. Concatenation consists in a merging of the attributes of both components, and the composition of their actions. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 124. const stackable = base => { const items = [] return Object.assign(base, { depth: () => items.length, top: () => items[items.length - 1], pop: () => { items.pop() }, push: newTop => { items.push(newTop) }, }) }
  • 125. const newStack = () => stackable({})
  • 126. const clearable = base => { return Object.assign(base, { clear: () => { while (base.depth()) base.pop() }, }) }
  • 127. const newStack = () => clearable(stackable({}))
  • 128. const newStack = () => compose(clearable, stackable)({}) const compose = (...funcs) => arg => funcs.reduceRight( (composed, func) => func(composed), arg)
  • 129. Concept Hierarchies The construction principle involved is best called abstraction; we concentrate on features common to many phenomena, and we abstract away features too far removed from the conceptual level at which we are working. Ole-Johan Dahl and C A R Hoare "Hierarchical Program Structures"
  • 130. A type hierarchy is composed of subtypes and supertypes. The intuitive idea of a subtype is one whose objects provide all the behavior of objects of another type (the supertype) plus something extra. Barbara Liskov "Data Abstraction and Hierarchy"
  • 131. What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. Barbara Liskov "Data Abstraction and Hierarchy"
  • 132. const nonDuplicateTop = base => { const push = base.push return Object.assign(base, { push: newTop => { if (base.top() !== newTop) push(newTop) }, }) }
  • 133. tests = { ... 'A non-empty stack becomes deeper by retaining a pushed item as its top': () => { const stack = newStack() stack.push('ACCU') stack.push('2018') stack.push('2018') assert(stack.depth() === 3) assert(stack.top() === '2018') }, ... }
  • 134. const newStack = () => compose(clearable, stackable)({}) tests = { ... 'A non-empty stack becomes deeper by retaining a pushed item as its top': () => { const stack = newStack() stack.push('ACCU') stack.push('2018') stack.push('2018') assert(stack.depth() === 3) assert(stack.top() === '2018') }, ... }
  • 135. const newStack = () => compose(nonDuplicateTop, clearable, stackable)({}) tests = { ... 'A non-empty stack becomes deeper by retaining a pushed item as its top': () => { const stack = newStack() stack.push('ACCU') stack.push('2018') stack.push('2018') assert(stack.depth() === 3) assert(stack.top() === '2018') }, ... }
  • 136. What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. Barbara Liskov "Data Abstraction and Hierarchy"
  • 141. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 142. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation The Synchronisation Quadrant
  • 143. Procedural Comfort Zone Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 144. Procedural Discomfort Zone Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation Procedural Comfort Zone
  • 145. Threads and locks — they’re kind of a dead end, right? BretVictor "The future of programming"
  • 146. So, I think if [...] we’re still using threads and locks, we should just, like, pack up and go home, ’cause we’ve clearly failed as an engineering field. BretVictor "The future of programming"
  • 147. Procedural Comfort Zone Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 150. single-threaded activity no shared mutable state coordination
  • 157. Toutes choses sont dites déjà; mais comme personne n'écoute, il faut toujours recommencer. André Gide
  • 158. Everything has been said before; but since nobody listens, we must always start again. André Gide