`02-main-programming-paradigms/pthread.c`
]
???
- Another imperative paradigm is the concurrent one.
- With this paradigm the programmer uses various features provided by the language to describe parallel and interleaving operations.
- Here we have an example with a C library named the POSIX threads.
- The important part is within the for loop where we create a certain number of threads.
- These threads are parallel execution flows and each will execute the function named thread function.
---
# **Imperative Concurrent** Programming Paradigm
Execution example with 4 threads and 2 parallel processing units (cores):
- Many imperative languages provide ways to exploit concurrency:
- Shared-memory threads/processes in C/C++, Java, Python, etc.
- Message passing (for example MPI) in C/C++/FORTRAN
- Semi-automatic loop paralelization with libraries such as OpenMP
- GPU programming with CUDA
- ...
- Use cases: HPC, distributed computing, graphic processing, etc.
???
- Here is an execution example of 4 threads on a CPU with 2 cores.
- Core 1 starts with thread 1, that gets kicked off the CPU by thread2 after some time, comes back later, and so on.
- Something similar happens on core 2 with thread 3 and thread 4.
- A concurrent programming language describes in particular how the execution flows can communicate, can they share data structures, and if yes what is the consistency of that sharing.
- There are many methods for concurrent programming in imperative languages.
- They include shared memory threads and processes, message passing and automatic parallelization libraries, GPU programming languages, and so on.
- Important use cases for concurrent programming are of course high performance and distributed computing, graphic processing, etc.
---
# **Declarative** Programming Paradigm
.center[The programmer describes the **meaning/result of computations**]
```html
Hello, world!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
sed leo sit amet urna accumsan aliquam. Fusce et aliquet nibh.
```
See the result [here](src/listing7.html). These slides are also created with a
combination of 2 declarative languages: HTML and Markdown -- try typing ctrl+U
:)
???
- Now let's switch to declarative paradigms.
- Contrary to imperative programming where the programmer describes a sequence of instructions, in other words the way to obtain a certain result, with declarative programming the programmer describes how the result should look like.
- A good example of a pure declarative language is HTML.
- Here I am constructing a web page, declaring elements such as headings and paragraphs with tags.
- We can see the result page here.
- Fun fact: these slides are also realised with declarative languages.
- Load them in your browser and type control plus u to see the sources.
---
# **Declarative** Programming Paradigm
- High level of abstraction
- Code can easily become convoluted
- Languages: HTML, SQL, XML, CSS, Latex (non-Turing complete)
- Usage: document rendering, structured data storage and manipulation
???
- Declarative programming is at a much higher level of abstraction compared to imperative programming that is closer to the machine model
- One can describe complex programs with few lines of code and the low level implementation details are abstracted
- A downside is that the code can easily become convoluted and hard to understand in large programs
- Some examples of pure declarative languages include: HTML, SQL, XML, CSS, Latex.
- Note that these are not Turing complete.
- Pure declarative programming is useful for document rendering, structured data storage and manipulation
---
# **Declarative Functional** Programming Paradigm
- Calling and composing functions to describes the program
Example in Haskell:
```haskell
add_10 x = x + 10
twice f = f . f
main = do
print $ twice (add_10) 7
```
.codelink[`02-main-programming-paradigms/functional.hs`
]
???
- A very important declarative subparadigm is functional programming.
- With this paradigm, the programmer calls and composes functions to describe the program.
- Here is an example in Haskell.
- We define a function add_10 that takes one parameter and adds ten to it.
- We also define another function that takes a function as parameter and applies it twice.
- The last line will print 27 as it first adds 10 to 7 and passes the result as parameter to a second invocation of add 10.
---
# **Declarative Functional** Programming Paradigm
```ml
(* Example in OCaml *)
let width, height = 800, 600
let pi = 4. *. atan 1.;;
let endpoint x y angle length =
x +. length *. cos angle,
y +. length *. sin angle;;
let drawLine x y angle length width =
let x_end, y_end = endpoint x y angle length in
set_line_width (truncate width);
moveto (truncate x) (truncate y);
lineto (truncate x_end) (truncate y_end);;
let rec drawRec x y angle length width =
if length > 0. then
let endx, endy = endpoint x y angle length in
drawLine x y angle length width;
drawRec endx endy (angle +. pi *. 0.133) (length -. 4.) (width *. 0.75);
drawRec endx endy (angle +. pi *. -0.166) (length -. 4.) (width *. 0.75);;
moveto 400 200;;
drawRec 400. 200. (pi *. 0.5) 50.0 4.;;
```
.codelink[`02-main-programming-paradigms/functional.ml`
]
.small[Source: https://github.com/DaQuirm/ocaml-fractals]
???
- Here is another nice example written in objective caml.
- It uses recursion to create a potentially never ending pattern, a fractal.
- Here is how it looks like.
- We compile and run like that.
- It turns out that we need very few lines of code to describe this with a functional language.
---
# **Declarative Functional** Programming Paradigm
- First-class/higher-order functions
- Loops implemented with **recursion**
- **Pure functions have no side-effects**
- Languages: Haskell, Scala, F#, etc.
???
- With functional programming we have first-class/higher-order functions can be bound to identifier and passed as parameters or returned.
- Loops are implemented with recursion, which is well suited for some optimisations, as well as operations such as tree traversal problems, used for example when parsing.
- Pure functions have no side-effects on global state.
- It is easier to understand and reason about what they do, it is also easier to proof, test and debug, because having less state means less chances for mistakes.
- Some example of functional languages are Haskell, Scala, F#, etc.
---
# **Declarative Concurrent** Programming Paradigm
```erlang
% Example in Erlang using the actor model
server() ->
receive
{From, {convert, TempC}} -> From ! {converted, 32 + TempC *9/5},
server();
{stop} -> io:format("Stopping~n");
Other -> io:format("Unknown: ~p~n", [Other]),
server()
end.
client(ClientID, ServerPID) ->
TempC = rand:uniform(40),
ServerPID ! {self(), {convert, TempC}},
receive
{converted, TempF} -> io:fwrite("~p: ~p deg. C is ~p deg. F~n.",
[ClientID, TempC, TempF]),
timer:sleep(100),
client(ServerPID);
{stop} -> io:format("Stopping~n");
Other -> io:format("Unknown: ~p~n", [Other])
end.
start() ->
Pid1 = spawn(temperature, server, []),
spawn(temperature, client, [0, Pid1]),
spawn(temperature, client, [1, Pid1]),
```
.codelink[`02-main-programming-paradigms/declarative-concurrent.erl`
]
???
- Some declarative languages also provide ways to describe concurrent operations.
- Here is an example in Erlang, using what is called the actor model.
- We declare two concurrent execution flows, a server offering to convert temperature values between Celsius and Fahrenheit degrees, and a client sending conversion requests.
---
# **Declarative Concurrent** Programming Paradigm
- Less need for synchronisation
- Use cases: distributed applications, web services, etc.
???
- We can easily spawn multiple clients and obtain something like that.
- One of the advantages of this model is a reduction in synchronisation operations, for example there is no lock.
- Declarative concurrent languages are useful when designing distributed applications, web services, and so on.
---
# There are Many Other Programming Paradigms
- **Logic**, **Dataflow**, **Metaprogramming/Reflexive**, Constraint,
Aspect-oriented, Quantum, etc.
https://en.wikipedia.org/wiki/Template:Programming_paradigms
???
- There are many other programming paradigms, some of them listed here.
- Don't hesitate to check out the Wikipedia page that contains a lot more information.
---
# Multi-Paradigm Languages
- Haskell: purely functional and does not allow OO style
- OCaml: mainly functional, allows OO and imperative constructs
- C, C++: imperative but allow some functional idioms:
```c
int fact(int x) {
if(x == 0) return 1;
return x * fact(x-1);
}
```
- So many languages are **multi-paradigm**
???
- A Language X is said to support paradigm Y if the language offers to possibility to program in the style defined by the paradigm
- For example Haskell is purely functional and does not allow OO style
- OCaml is mainly functional but allow OO and imperative constructs
- C, C++ and many others are imperative but allow some functional idioms.
- For example this is a recursive factorial implementation using C.
---
# It all Boils down to Machine Code
???
- A last thing to remember is that independently of the programming language used to build a program, the only language that the CPU understands is machine code, which is a binary representation of assembly.
- So in the end all programming language compile or translate to machine code.
---
# Summary
???
- Here is a summary of the main paradigms we have seen.
- We have the two principal categories, declarative on the left and imperative on the right.
- On the declarative side, a major subparadigm is functional programming, defined by several features including first class and higher order functions.
- Regarding imperative paradigms, we have procedural or structured programming enabled by control flow structures such as loops and functions or procedures.
- Adding to this the notion of object we get the object-oriented paradigm.
- And adding the notion of concurrent execution flows we get the imperative concurrent paradigm.
---
# Course Overview
???
- Now let's see how the different parts of COMP26020 map to these paradigms.
- We will start with imperative procedural programming in C
- After that, we will study compilation, the process of transforming language source code (for example C code) into the machine code that is eventually executed on the CPU.
- Then we will cover object-oriented programming, looking at the C++ language.
- Next we will see functional programming, with Haskell.
- And finally, we will see concurrent programming with a language named solidity.
---
# Feedback Form
.center[https://bit.ly/3lJIvWq]
???
- And that's it, feel free to leave some feedback if you have any
- In the next video, we will start to learn about C.