---
# System prepended metadata

title: PFON & MOB1
tags: [' mob1', ' PFON', ' S5', cours, ' Ing1', ' pfon', ' MOB1', ' notions', ' revisions']

---

---
tags: cours, pfon, PFON, MOB1, mob1, Ing1, S5, notions, revisions
author: Robin 'Pachichi' Boucher
---
# PFON & MOB1
## PFON
### Notions

**Paradigme** :
* Affecte la manière de penser
* Affecte l'expressivité
* Manière de s'exprimer

Une fonction est dite à **effet de bord** si elle modifie un état en dehors de son environnement local. Typiquement, les fonctions qui:  
* Modifient une variable locale statique
* Modifient une variable globale (*non locale*)
* Modifient une variable passée en argument par référence
* Appellent des fonctions à *effet de bord*

Langage fonctionnel **pur** :
* Calcul de la valeur de sortie (*retour*) en fonction des valeurs d'entrée (*arguments*)
* Que des constantes
* Pas d'effet de bord
* Pour une entrée, toujours la même sortie

Types d'expressions:
* Expressions **littérales** : s'évaluent à elles-mêmes
* Epressions **combinées** : application de procédures (*opérateurs, fonctions*) à des arguments (*expressions*)
* Expressions **abstraites** : nommage et assignation d'expressions

Abstraction **syntaxique** $\rightarrow$ déclarations $\rightarrow$ Haskell  
Abstraction **fonctionnelle** $\rightarrow$ expressions $\rightarrow$ Lisp

**Variadicité** (fonctions à nb d'args variables) en Lisp (*utilisation de &*). Exemple :
```lisp
(defun mklist (head &rest tail)
(cons head tail))
;; (mklist 'a 'b 'c)

(defun msg (str &optional (prefix "error: ") postfix)
(concatenate 'string prefix str postfix))
;; (msg "hello" nil "!")
```

Typage **dynamique** :
* **Valeurs** sont typées
* Vérification de type à l'**éxecution**
* $\rightarrow$ Lisp

Typage **statique** :
* **Variables** sont typées
* Vérification de type à la **compilation**
* $\rightarrow$ Haskell

Typage **faible**: Autorise l'affectation de variable avec des valeurs ne correspondant pas à son type déclaré $\rightarrow$ erreur de type difficilement détectable

Typage **fort**: Interdit l'affectation de variable avec des valeurs ne correspondant pas à son type déclaré $\rightarrow$ erreur de type facilement détectable

Typage **implicite**: Pas obligé lors de la déclaration d'une variable de donner son type

Typage **explicite**: Obligé lors de la déclaration d'une variable de donner son type

**Polymorphisme** : définition unique $\forall$ type
```haskell
length :: [a] -> Int
-- qqsoit le type de [a], la définition de la fonction reste la même
```

**Surcharge** ou *overloading*: différentes définitions selon le type

**Modèle de substitution**: Remplacement des paramètres formels par les arguments correspondants
```lisp
(defun exemple (a) (+ a a))
;; (exemple 2)
;; -> (+ 2 2)
```

Evaluation **stricte**
* Arguments (expressions) évalués d'abord
* Modèle de substitution
* Lisp :  
```lisp
(defun sq (x) (* x x))
(defun ssq (x y) (+ (sq x) (sq y)))
(defun f (a)
(ssq (+ a 1) (* a 2)))

;; (f 5)
;; (ssq (+ a 1) (* a 2))
;; (ssq (+ 5 1) (* 5 2))
;; (ssq 6 (* 5 2))
;; (ssq 6 10)
;; (+ (sq x) (sq y))
;; (+ (sq 6) (sq 10))
;; (+ (* x x) (sq 10))
;; (+ (* 6 6) (sq 10))
;; (+ 36 (sq 10))
;; (+ 36 (* x x))
;; (+ 36 (* 10 10))
;; (+ 36 100)
;; 136
```

**Lazy** évaluation
* Expressions évaluées seulement quand le besoin s'en fait sentir
* Modèle de substitution
* Seulement dans un langage fonctionnel pur
* Haskell :
```haskell
sq :: Float -> Float
sq x = x * x
ssq :: Float -> Float -> Float
ssq x y = sq x + sq y
f :: Float -> Float
f a = ssq (a + 1) (a * 2)

{-
f 5
ssq (a + 1) (a * 2)
ssq (5 + 1) (5 * 2)
sq x + sq y
sq (5 + 1) + sq (5 * 2)
(x * x) + (y * y)
(5 + 1) * (5 + 1) + (5 * 2) * (5 * 2)
6 * (5 + 1) + (5 * 2) * (5 * 2)
6 * 6 + (5 * 2) * (5 * 2)
36 + (5 * 2) * (5 * 2)
36 + 10 * (5 * 2)
36 + 10 * 10
36 + 100
136

-}
```

**Ordre applicatif/normal** : sémantique des langages  
**Strict** : se dit surtout d’une procédure / fonction  
**Paresseux** : se dit surtout d’un évaluateur  
Dans un langage d’*ordre applicatif*, toutes les procédures sont
strictes.  
Dans un langage d’*ordre normal*, toutes les procédures non
primitives sont non strictes (puisque l’évaluateur est paresseux), et les procédures primitives peuvent être strictes, ou pas.

Contextes/environnements locaux **implicites**:
* Args des fonctions ($\alpha$-conversion, imbrication)

Contextes/environnements locaux **explicites**:
* Données locales (évite la redondance d'éval)
* Fonctions locales (évite pollution des espaces de noms)

Variable **liée**: définie dans le contexte local (définition locale)  
Variable **libre**: non définie localement

**Scoping**: capture d'une variable libre  
1. Scoping **lexical**:
   * recherche dans l'environnement de *définition*
   * retour de fcts créées à la demande en toute sécurité
```lisp
(let ((x 10))
    (defun foo () x))
(let ((x 20))
    (foo)) ;; => 10
```
1. Scoping **dynamique**:
   * recherche dans l'environnement d'*appel*
   * retour fonctionnel limité aux fcts constantes
```lisp
(defparameter x 10)
(defun foo () x)
(let ((x 20))
    (foo)) ;; => 20
```

**Fermetures lexicales**: Combinaison entre une fonction et son environnement de définition (valeurs des variables libres au moment de la définition):
* Opérations génériques par fcts anonymes
```lisp
(defun list+ (lst n)
    (mapcar (lambda (x) (+ x n))
            lst))
```
```haskell
(+++) :: [Int] -> Int -> [Int]
(+++) lst n = map (\x -> x + n) lst
```
* Création dynamique de fcts à état local
```lisp
(defun make-adder (n)
    (lambda (x) (+ x n)))
```
```haskell
makeAdder :: Int -> Int -> Int
makeAdder n = \x -> x + n
```
* Encapsulation (portée restreinte)
* Etat local modifiable (**Lisp**)
```lisp
(let ((cnt 0))
    (defun newtag () (incf cnt))
    (defun resettag () (setq cnt 0)))
```

**Curryfication** : passage d'une fct $n$-aire à une fct unaire  
**Décurryfication**: inverse de *curryfication*

> [color=green] Note: Fonctions Haskell sont unaires. $\rightarrow$ curryfication


---
### A retenir des annales

**Fonction ordre supérieur**:
* Une ou $n$ fcts en entrée
* Renvoie une fct (via création de fct anonyme)

Dans un langage fonctionnel pur:
* Que des constantes
* Pas d'effet de bord
* Pour une entrée, toujours la même sortie

Typage statique $\rightarrow$ type des variables connues à la compilation

**Offside rule** : N comme syntaxe (comme en python)  
En Haskell, il existe un séparateur implicite qui remplace l'offside rule lors du parsing $\rightarrow$ `;`

En Lisp, les valeurs booléennes sont représentées par: *nil* ou la liste vide (**false**) et tout sauf *nil* (**true**)

Valeur de l'expression suivante en Haskell:
```haskell
[ x == 3 | x <- [2, 3, 4]]
-- which gives [False, True, False]
```

**Tree-accumulation**: Evaluation récursive de gauche à droite de toutes les sous-expressions d'une expression fonctionnelle

**Opérateur spécial** en Lisp: Fonction n'obéissant pas aux règles de l'évaluation stricte

Que signifie l'expression "*Lisp-2*" ? $\rightarrow$ Qu'il existe des espaces de noms distincts pour les variables et les fonctions

**mapping**: application d'une fonction à tous les éléments d'une liste

Fonction `complement` de Lisp: Prend une fct booléene et renvoie une fct produisant le résultat inverse

## MOB1
**Familles de langages**: Bottom-up & Top-down

Programmation impérative/procédurale: **bottom-up**

**UML**: **U**nified **M**odelling **L**anguage

++2 limitations en impératif/procédurale:++
* **Convergence d'état**: Pouvoir regrouper plusieurs choses différentes ds un même type et l'utiliser comme ça
* **Divergence de comportement**: Appliquer le même traitement à plusieurs types
=> **POO** (Programmation Orienté Objet)