`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.
- In Semester one we will start with imperative procedural programming in C
- And then you will cover object-oriented programming with C++
- Next you will see functional programming, with Haskell.
- After that, in Semester two, you will firs study compilation, the process of
transforming the textual sources of programs written in various languages
into the machine code that is eventually executed on the CPU.
- And finally, you 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.