Show Lecture.ProgrammingParadigms as a slide show.
CS253 Programming Paradigms
Overview
Imperative programming
- Languages have an Imperative mood, used for giving commands.
- Statements that cause an immediate action.
- Like a commander in military combat,
or a foreman at a construction site.
- No reasoning need be given. Just do this!
- In programming languages, we usually call things
like if and while statements, not commands,
but that’s just nomenclature.
- Examples: C++, Java, Bash, Perl, Python, Javascript.
Declarative programming
- Not commands as much as description. Not a sergeant, a general.
- More like an architect designing a building.
- The architect doesn’t tell the electrician where to run the wires.
- The architect describes the goal,
not how to obtain the goal.
- Mathematicians think declaratively. x = y+2, to them, doesn’t
mean “fetch y, add 2, store in x”. It means
to define x as always being 2 larger than y.
- Examples:
- spreadsheets (e.g., Microsoft Excel)
- a regular expression/filename pattern
(the pattern, not the pattern-matching code)
- functional programming
- Makefile, a mix:
dependencies are declarative, commands are imperative
Functional programming example
Parallel JavaScript implementations, taken from
Wikipedia:
// Imperative style
const numList = [1, 2, 3, 4, 5, 6, 7, 8];
let result = 0;
for (let i = 0; i < numList.length; i++) {
if (numList[i] % 2 === 0) {
result += numList[i] * 10;
}
}
// Functional style
const result = [1, 2, 3, 4, 5, 6, 7, 8]
.filter(n => n % 2 === 0)
.map(a => a * 10)
.reduce((a, b) => a + b);
Sure, down at the machine instruction level, it’s all imperative.
However, the programmer doesn’t have to think that way.
You don’t have to think about the mechanics of looping.
Instead you think about transforming the data.
C++ declarative programming
array a{18,19,20,21,22,23,24,25,26,27,28};
int sum = 0;
// imperative loop:
for (size_t i=0; i<a.size(); i++)
sum += a[i];
cout << sum;
253
array a{18,19,20,21,22,23,24,25,26,27,28};
int sum = 0;
// declarative loop:
for (int n : a)
sum += n;
cout << sum;
253
- It might even be the same instructions both times—it doesn’t matter.
- Certainly, there are still imperative aspects.
- In the latter, I don’t have to think about the
mechanics of “start at element 0, increment by 1 until I get to the last
element of the array”. I just think “do this for each element”.
- Hey, a std::array! It has methods like a vector,
but a fixed size—no dynamic memory overhead.
Event-driven programming
- In event-driven programming, your code is not in charge.
Often, you don’t write main().
- Instead, your code spends most of the time waiting to be invoked.
- Examples:
- web browser:
your code gets called on a key press, mouse click, or window motion.
- clock program:
your code gets called each second to update the clock.
- interrupt service routine:
your code gets called to deal with the interrupt.
- Linux signals:
signal handler function gets called to deal with the signal.
Clock example
An imperative clock program might work like this pseudocode:
int main() {
while (true) {
sleepms(1000);
display_time();
}
}
Or, it might be event-driven, where the event is a clock triggering:
int main() {
schedule_periodic_callback(1000, &display_time);
do_nothing_but_service_interrupts();
}
The event-driven code could be easily modified to handle other
event-driven tasks: keyboard input, mouse clicks, etc.