Yann Moisan

Scala, Web, Linux…

Functional Programming Principles in Scala

Le cours de programmation fonctionnelle en Scala sur coursera se termine. Il est assuré par Martin Odersky, qui n'est rien moins que l'inventeur du langage. Le cours, avec ces 50.000 inscrits, a rencontré un franc succès, révélateur de l'émulation autour de ce langage.

Il a duré 7 semaines, à raison de 5-7 heures par semaine. J'en suis très satisfait. Chaque semaine, il y a 2 grandes parties : un cours théorique en vidéo et des exercices portant, bien évidemment, sur le contenu du cours. Les vidéos sont en anglais mais relativement simples à comprendre et le discours est appuyé par des slides. De plus, le professeur est un excellent pédagogue. Les exercices, parfois ardus, permettent, au fur et à mesure, d'appréhender un mode de raisonnement fonctionnel. Et un astucieux système de notation en quasi temps réel permet d'avoir un feedback rapide sur son travail.

Une nouvelle thématique est abordée chaque semaine. Voici le programme semaine par semaine, avec quelques points qui ont retenu mon attention, en tant que développeur Java :

  • Semaine 1 : Fonctions et Evaluations

    Le mécanisme de substitution et le lambda-calcul.

    La possibilité de choisir entre call by value (évalue les arguments avant d'appeler la fonction) et call by name (évalue la fonction en premier, et ensuite les arguments si besoin). En Java, il n'y a que du call by value…

  • Semaine 2 : Les fonctions d'ordre supérieur (c.-à-d. une fonction qui prend en paramètre une fonction ou qui retourne une fonction)

    La récursivité, la recursivité terminale et l'astuce de l'accumulateur.

    La curryfication.

  • Semaine 3 : Données et abstraction

    L'associativité de l'opérateur est déterminée par le dernier caractère (: pour associativité à droite). En Java, seul l'opérateur = est associatif à droite.

    En Scala, tout est objet (pas de type primitif comme en Java). La hiérarchie des objets est : Any, AnyVal, AnyRef

  • Semaine 4 : Type et pattern matching

    Les fonctions sont des objets avec une méthode apply. À creuser eta expansion.

    Les deux formes de polymorphisme : subtype et generics - Les types paramétrés s'écrivent MaClasse[T] (au lieu de MaClasse<T> en Java).

    La notion de variance. Étant donné que A <: B, si C[A] <: C[B] C est covariant. Un objet immuable peut-être covariant. Pour rappel, en Java, Array est mutable et covariant, ce qui peut entrainer des erreurs à l'execution (ArrayStoreException). Une bonne pratique : Les fonctions doivent être contravariant dans leurs types d'argument et covariant dans leurs types de résultats (trait Function[-T, +U]{ def apply(x: T): U }).

    Le pattern matching

  • Semaine 5 : Les listes

    xs ++ ys (concaténation) est équivalent à : (xs foldRight ys)(_ :: _)

  • Semaine 6 : Les collections

    flatten est équivalent à foldRight (_++_)

    xs flatMap f est équivalent à (xs map f).flatten

    Un exemple pour calculer un produit scalaire en une seule ligne montre la richesse de l'API : for ((x,y)<-xs zip ys) yield x*y).sum

    les for-comprehension (un sucre syntaxique pour les méthodes map, flatMap, filter)

    for (x <- e1) yield e2 est équivalent à e1.map(x => e2)

    for (x <- e1 if f) yield e2 est équivalent à for (x <- e1.filter(x => f)) yield e2

    for (x <- e1; y <- e2) yield e3 est équivalent à e1.flatMap(x => for (y < - e2) yield e3)

    le trait Option.

    une instance de Map est une fonction partielle. Un article sur le sujet

    Le pattern Iterator est un concept imperatif.

  • Semaine 7 : L'evaluation lazy : les streams…

Avec ce cours, j'ai clairement progressé en Scala, et appris à raisonner de manière plus fonctionnel. Je recevrai même un certificat grâce à ma note de 80/80. Il reste cependant pleins de sujets à creuser. Voici d'ailleurs une liste glanée au fil de mes pérégrinations sur la toile, pour donner des idées à ceux qui voudraient aller plus loin :

  • SBT, l'outil de build utilisé par le cours, pour remplacer définitivement Maven ?
  • Akka, un framework d'Actor, pour faciliter l'écriture de code concurrent
  • Play, un framework web
  • un article de Jonas Boner sur le Cake pattern, pour implémenter l'injection de dépendances
  • Une video sur l'injection de dépendances avec une monade Reader
  • un article sur le trampoline, pour optimiser la récursion
  • les monades, pour comprendre ce qui ce cache derrière l'obscure formule : Monads are just monoids in the category of endofunctors.
  • scoobi, pour écrire des jobs MapReduce Hadoop en Scala
  • scalding, pour écrire des jobs MapReduce Hadoop en Scala
  • et continuer à pratiquer avec les 99 scala problèmes
  • et pour les parisiens, il y a le PSUG.