Show Lecture.ProgrammingParadigms as a slide show.
CS253 Programming Paradigms
Overview
Imperative programming
- 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 run the wires.
- Instead, the architect describes the goal, as opposed
to detailing how to obtain the goal.
- Mathematicians tend to think declaratively. x = y+2,
to a mathematician, doesn’t mean “fetch the value in y, add 2,
and put the result in x”. It means to define
the variable x as always being 2 larger than y.
- Examples:
- functional programming
- spreadsheets (e.g., Microsoft Excel)
- Makefile, really a mix:
- dependencies are declarative
- commands are imperative
Functional programming example
Here are parallel JavaScript implementations,
taken from Wikipedia:
Traditional imperative look:
const numList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
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, 9, 10]
.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.
C++ declarative programming
Here are two ways to add some numbers in C++:
vector<int> v = {11,22,33,44,55};
int sum = 0;
// imperative style
for (size_t i=0; i<v.size(); i++)
sum += v[i];
cout << sum;
165
vector<int> v = {11,22,33,44,55};
int sum = 0;
// declarative style
for (int n : v)
sum += n;
cout << sum;
165
It might even be the same instructions both times. I don’t care.
Certainly, there are still imperative aspects.
The point is that, in the second program, 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”.
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.