---
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)