Skip to content

Blogs de Développeurs: Aggrégateur de Blogs d'Informatique sur .NET, Java, PHP, Ruby, Agile, Gestion de Projet

Forum Logiciel

Forum Logiciel : diffusion de connaissance et d’informations sur toutes les activités liées au développement d’applications informatiques en entreprise.

Taverne d'Arma - Programmation
Syndiquer le contenu
Mis à jour : il y a 6 heures 47 min

JS et Programmation Fonctionnelle - Part 1

mar, 09/13/2016 - 11:20

Je vais me lancer sur une série d'articles concernant la programmation fonctionnelle, appliquer au monde JS. L'objectif pour moi est de préparer, à terme, une présentation sur le sujet. Aujourd'hui, je vais donc commencer par les bases : c'est quoi au juste la programmation fonctionnelle.

Du rĂ´le de la fonction

Fonctionnelle comme fonction. Mais la fonction dont on parle ici correspond-elle au mots-clés 'function' de notre langage ? Presque, mais pas tout à fait. En fonctionnel, une fonction est un élément prévisible qui prend des paramètres entrants et qui renvoies une nouvelle valeur. Cela implique que :

  • Les paramètres entrants ne sont pas modifiĂ©s
  • Le retour de la fonction est un nouvel objet ou une nouvelle valeur
  • Tout appel avec des paramètres identiques renvoi le mĂŞme rĂ©sultat

Les avantages de ce type de fonction sont multiples :

  • Meilleure testabilitĂ© : elles ne dĂ©pendent pas d'un Ă©tat.
  • Meilleure reproductibilitĂ© : si l'on trouve un bug, il suffit de rappeler la fonction avec les mĂŞmes paramètres pour obtenir les mĂŞmes rĂ©sultats.
  • Meilleurs "scalabilitĂ©" : on ne mute pas les objets, il n'y aura donc pas de problème de concurrences sur des threads diffĂ©rents.
De l'immutabilité

Je viens de glisser le point dans le dernier avantage, mais l'un des grands principes de la programmation fonctionnelle est de tirer à maximum parti d'objet immutable : c'est-à-dire un objet qui ne peut pas être modifié. La conséquence, c'est qu'à chaque fois que l'on veut modifier un objet, nous allons créer une nouvelle instance complètement indépendant de l'objet.

Encore une fois les avantages sont multiples :

  • La scalabilitĂ©, comme abordĂ© plus haut.
  • La limitation des effets de bord : vu que l'on ne modifie pas un objet, l'on ne risque pas de modifier par inadvertance un objet qui aurait Ă©tĂ© transmis Ă  d'autres parties de l'application.

Bien entendu, la plupart des applications ne peuvent pas être 100% immutable : l'idée est d'isoler au maximum les endroits où un état est mémorisé et de ne faire ces mutations que de manières conscientes et complètement volontaire.

De la programmation déclarative

La programmation impérative met en avant le "comment" : ajoute 1 au compteur, passe à l'élément suivant, modifie tel caractère, ... L'objectif de la programmation déclarative est de s'attacher au "quoi". Pour s'approcher au maximum de ce style, la programmation fonctionnelle, mais en avant non pas les données, mais les traitements : le but est de décrire des chaînes de traitement qui vont s'appliquer aux données.

Prenons l'exemple très simple d'une somme. En impératif :

function sum(vals) {
  var total = 0;
  for(var i = 0; i < vals.length; i++) {
    total = total + vals[i];
  }
  return sum;
}

Et en fonctionnelle :

function sum(vals) {
  return vals.reduce(add);

  function add(e1, e2) {
    return e1 + e2;
  }
}

Le code est équivalent, mais dans le second cas, il décrit l'intention : réduire la liste en additionnant ses éléments.

Pour résumé

La programmation fonctionnelle a pour objectif :

  • d'amĂ©liorer la lisibilitĂ© du code (style impĂ©ratif).
  • de faire du code plus facile Ă  tester et Ă  debugger (pas d'effet de bord).
  • d'ĂŞtre plus rĂ©sistant aux concurrences.

Par contre, l'immutabilité est une contrainte qui demande une certaine discipline à l'usage.

Fonctionnelle versus POO

Souvent, ces deux paradigmes de programmations sont mis en oppositions. Faut-il faire de la POO, ou faut-il faire du fonctionnelle ? Aujourd'hui, je pense sincèrement qu'il faut faire les deux :

  • La POO permet de bien structurer son application et d'y faciliter la navigation
  • Le fonctionnelle permet de rendre son code plus lisible

Utiliser les deux, c'est avoir accès aux forces de chacun. Pourquoi se priver ?

Catégories: Blog Individuel

Productivité personelle - Mon organisation

sam, 09/03/2016 - 09:10

J’ai récemment effectué une présentation au boulot concernant la productivité personnelle. Le but était de parler des grands principes partagés par différentes méthodologies (Personal Kanban, GTD, ...). Je comptais partager les slides ici mais, en eux-même, ils n’ont guère d'intérêt. A la place je me suis dit que parler de ma propre organisation serait probablement plus intéressant.

Personal Kanban

Vous avez surement déjà aperçu ses tableaux de post-it a colonne multiple, contenant en général au minimum “Todo, En-Cours, Done”. Personal Kanban est une méthode qui se base dessus et dont les grands principes sont :

  • Toutes nos actions sont des tâches Ă  mettre dans ce tableau.
  • Une tâche va toujours de l’avant, elle ne doit pas reculer.
  • Les colonnes correspondent au “en-cours” sont limitĂ© au nombre de tâche qu’elles peuvent contenir. Quand l’on arrive au plafond, il faut s’arranger pour terminer des tâches.
  • On choisit la tâche que l’on effectue en fonction du contexte (temps dispo, niveau de concentration, lieu, …) et non pas seulement en fonction de la prioritĂ©.

Bref, on retrouve le principe de base des méthodes d’organisations, le recensement des tâches, et on y adjoint un mécanisme nous forçant à terminé les tâches commencés plutôt que d’en prendre une nouvelle.

Au quotidien j’utilise :

  • Des post-it papier, si possible, pour le boulot
  • Un outil informatique (Trello), pour le perso (histoire d’y avoir accès de partout)

Quel que soit l’outil, le point important est de créer une tâche “rapidement” avec un libellé, et potentiellement une “catégorie” (un projet par exemple).

C’est léger et souple d’utilisation, bref, c’est une méthode qui me correspond bien. J’ai tellement fait rentrer le mono-tasking dans mes habitudes qu’en général mon en-cours n’excède pas une tâche.

Pomodoro

En complément du Kanban, je pratique de temps à autres la méthode Pomodoro. C’est en quelque sort mon “mode de productivité” quand j’ai besoin d’être concentré, d’aller vite, et d’abattre beaucoup de travail. Cette méthode est à mon sens très efficace et présente quelques avantages :

  • On se rend compte du temps qui passe.
  • On se force Ă  des crĂ©neaux ininterrompu de concentration.
  • Mais en se prĂ©voyant les breaks nĂ©cessaire Ă  ne pas saturer.

Revers de la médaille : elle demande une discipline que j’ai du mal à appliquer en permanence. C’est pour cela que je la pratique “à la demande” uniquement.

Autres petites pratiques

En dehors de ces méthodologies, il y a aussi quelques principes que j’applique pour booster ma productivité :

  • Pas de notification visuel, ou très peu. Ma boĂ®te reçoit ses mails discrètement et je les consulte quand j’en ai envie, et non dès qu’ils arrivent. J’évite aussi de laisser ouvert les rĂ©seaux sociaux et autres petites pollutions de ce genre. Je prĂ©fère me rĂ©server des moments pour aller les consulter.
  • Je connais mes moments “productifs” : ces pĂ©riodes de la journĂ©es oĂą vous abattez deux fois plus de boulot qu’à tout autre moment. Personnellement c’est entre 7h et 11h que je suis le efficaces. Entre 11h et midi, c’est la catastrophe. Je regagne un peu de productivitĂ© en dĂ©but d’après midi et, fin d’après midi, je commence Ă  saturer et Ă  avoir du mal. Du coup je m’assure de faire les tâches difficile dans ces crĂ©neaux lĂ .
  • Je profite de mes temps de transport pour faire ma veille. Dès qu’un article intĂ©ressant arrivent dans mon flux RSS, je l’envoi sur pocket pour que ma liseuse le rĂ©cupère. Cela m’évite de lire Ă  un moment oĂą je pourrais faire quelque chose de plus profitable. Cerise sur gâteau, je sais aussi que je lit mieux sur ma liseuse que sur Ă©cran.
Catégories: Blog Individuel

Code fonctionnel en PHP

lun, 08/29/2016 - 12:38

Ah le php... Une technologie que je n'apprécie guère pour des tas de bonnes et mauvaises raisons. Mais il faut bien lui reconnaître une qualité : il est très facile de lui trouver un hébergement.

Mais là n'est pas le sujet du jour ! Un nouveau projet s'ouvre à moi et, bien qu'il soit en php, je n'ai pas envie de mettre de coté mon centre d'interêt du moment : la programmation fonctionnelle. Me voilà donc à chercher comment la mettre en oeuvre en php.

PHP et Closure.

La base de la programmation fonctionnelle, c'est de manipuler des fonctions. Et l'un des outils très utile autour des fonctions, ce sont les Closures : des fonctions qui "embarque" avec elle des variables en plus de leur paramètre entrant.

En php, la closure est un peu particulière car il faut expliciter les variables qui sont utilisable à l'intérieur de la fonction. Elle se déclare ainsi :

function ($param) use ($varEmbarque1, $varEmbarque2) {
    // Mon corps de méthode
    // $varEmbarque1 et $varEmbarque2 sont accessible
}

Un exemple d'utilisation ?

public function raise($event) {
    Arrays::each($this->listeners, function($fn) use($event) {
        call_user_func($fn, $event);
    });
}

Je reviendrai plutard sur le Arrays::each. Ce qui est important ici c'est que each appelle la méthode pour chaque élement du table. La valeur de l'élement est alors donné en paramètre. Ici ma fonction a besoin de deux élements pour fonctionner : une callback contenue dans le tableau, et un évènement à transmettre. L'un est passé en paramètre, l'autre est passé via la closure.

Et si comme moi vous n'aimez pas spécialement les fonctions anonymes (question de lisibilité), vous pouvez appliquer le pattern builder :

public function raise($event) {
    Arrays:each($this->listeners, $this->emit(event));
}

// (DomainEvent) -> (Fn) -> ()
private function emit($event) {
    return function($fn) use($event) {
        call_user_func($fn, $event);
    };
}
Manipulations de collections et plus si affinité.

map, filter, ... Ces petites fonctions de manipulations de collections sont le premier outil issue du fonctionnel que j'ai utilisé. Je les trouve tellement confortable que je n'ai pas envie de m'en passer.

Malheureusement les fonctions fournies par php sont limitées (map, filter et reduce uniquement). En fouillant un peu sur internet, je suis tombé sur underscore.php, une librairie très sympathique qui fournit le panel complet des fonctions de ce genre (all, any, find, ...).

Petit bonus, elle nous offre aussi des fonctions de manipulations de fonctions tels que compose, memoize, once et throttle qui peuvent s'avérer très pratique.

Et enfin, les monades

Dernier outils du fonctionnel : les monades. Je ne les utilise pas encore tout à fait naturellement mais je reconnaîs ce qu'elles peuvent apporter. Cette fois-ci j'ai envie de les utiliser davantage et pour cela, j'ai trouvé la librairie php-functional.

Les monades, ce sont des outils très utiles tels que Either qui présente deux "chemins" (réussite ou échec), avec deux types de retours différents, ou Maybe qui est une autre façon de gérer l'abscence de valeur.

Un exemple d'utilisation :

// (String, String) -> Either[FunctionalError, User]
protected function checkAuthentification($login, $password) {
    return $this->userRepository
        ->findByLogin($login)
        ->bind($this->checkPassword(Password::fromValue($password)));
}

$this->userRepository->findByLogin() est une fonction qui renvoi un Either. Bind permet d'appliquer à la valeur retourné une autre fonction qui renverra elle aussi un Either uniquement dans le cas Right (chemin de succès). La fonction donné à bind sera appellé avec la valeur en paramètre.

A l'intérieur de findByLogin, on va retrouvé deux retour possible :

\Monad\Either\Right::of($user);

ou

\Monad\Either\Left::of(new FunctionalError("Utilisateur inconnu"));

Dans un code classique, j'aurai utilisé un mécanisme d'exception qui aurait pas forcément été aussi lisible.

En sortie de checkAuthentification j'ai toujours une Either. L'appellant pourra donc faire quelque chose comme cela :

// (String, String) -> Either[FunctionalError, User]
public function exec($login, $password) {
    $user = $this->checkAuthentification($login, $password);
    $user->map($this->storeInSession())
         ->map($this->raiseUserConnected());
    return $user;
}

En cas de succès de l'authentification, j'effectue deux fonctions :

  • Stockage en session
  • Lever d'un Ă©vènement

Quand je veut extraire définitivement la valeur de la monade, je peut faire ceci :

$myEither->extract()

Je m'arrêterais ici dans l'explication sur les monades : ils faudraient un article entier (voir plus) pour vraiment démontrer leurs valeurs.

Des commentaires Ă©tranges ?

Vous avez pu apercevoir au-dessus de mes fonctions des commentaires ayant cette forme :

// (String, String) -> Either[FunctionalError, User]

Ces commentaires sont uniquement présent à des fins de documentations. C'est une manière de donner des indications sur les types utilisés sans passé par une phpDoc bien plus verbeuse : je trouve toujours les javadocs / phpdocs aussi useless...

Ces quelques indications me sont bien plus précieuses et sont suffisament légère pour que je garde la discipline de les rajouter à chaque fois.

Catégories: Blog Individuel

The Mostly Adequate Guide to FP

jeu, 08/04/2016 - 07:19

En continuant mes recherches a propos de programmation fonctionnelle en javascript, je suis tombé sur un ouvrage disponible gratuitement : The Mostly Adequate Guide to FP. Disponible en ebook ou pour une lecture «en ligne», ce livre d’environ 150 pages abordent les différents aspects de la programmation fonctionnelle de manière plutôt didactique.

Au sommaire : currying, composition, monades et applicative. A mon sens les explications sont un peu moins facile à appréhender que celle-présente dans «Functional Programming in Javascript» mais elles sont tout de même facile à suivre.

Mention spéciale pour le chapitre sur la composition que je trouve vraiment très complet. Ici l’auteur nous présente vraiment une autre manière de développez et d’agencer nos fonctions. Les exemples donnés sont vraiment très parlant et illustre l’intérêt de cette approche. Je pense notamment à des déclarations comme celle-ci qui sont un exemple de concision :

var loudLastUpper = compose(exclaim, toUpperCase, head, reverse);

loudLastUpper(['jumpkick', 'roundhouse', 'uppercut']);
//=> 'UPPERCUT!'

Après la lecture de ces deux ouvrages, me voilà complètement armée pour passer à la pratique ! Et pour m’échauffer, j’ai suivi les exercices de NodeSchool sur le sujet ( «functional javascript» ). Ces exercices n’explore pas la composition ni les monades, mais le reste y passe.

Au passage pour ceux qui ne connaisse pas (et c’étais mon cas il y a quelques jours), NodeSchool est un site vraiment sympa bourré de «tutoriel» sous la forme d’exercice+corrigé. Vraiment très sympa :)

Catégories: Blog Individuel

Partagez la connaissance

Partagez BlogsdeDeveloppeurs.com sur les réseaux sociaux