Functional Programming in Scala sur Coursera

Un an ! J’ai attendu un an pour produire ce post suite au cours « functional programming in Scala » ! Je n’avais pas le temps, pas l’humeur, je changeais de boulot, etc. En fait, je suis peut-être simplement un pro de la procrastination. Enfin voilà!

Ce cours proposé par le créateur de Scala n’avait pas pour but de nous initier au langage, mais de nous faire découvrir la programmation fonctionnelle en nous appuyant sur celui-ci. C’est donc plus particulièrement une facette précise du langage que nous avons découvert, et non le langage dans sa totalité.

Le cours

Le format est plutôt bien choisi, avec des « petits tronçons » de 10 à 15 minutes. Parfois les sujets plus volumineux s’enchainent sur 2 tronçons avec juste un entr’acte entre les deux. Deux mentions spéciales :

  • Aux quizz qui émaillent ces séquences. Ils ne sont pas toujours évidents !
  • A la chevelure de Martin Odersky qui apparait régulièrement en superposition des vidéo !

Certains cours sont présents mais font en fait partie du cursus d’Odersky à l’EPFL. On les reconnait à leur niveau mathématique franchement plus élevé !

Ce n’est pas un cours sur Scala ! Il s’agit d’un cours de programmation fonctionnelle en Scala. Ainsi il y a tout un pan (au moins) du langage qui n’est pas évoqué. De même, le cours n’est pas directement transposable à un autre langage fonctionnel.

Les exos

C’est un peu la partie dure de ce cours. Ils sont de complexité croissante et arrivé vers la 3ème semaine deviennent de vrai casse-tête. Ils sont aussi très consommateurs de temps. Pas question de les laisser pour le dernier moment ! Si les premiers exercices m’ont pris largement moins de temps qu’indiqué, les derniers ont nettement dépassé le temps normalement requis en ce qui me concerne.

Les exercices sont aussi extrêmement cadrés. La plupart du temps, le squelette des méthode est fourni, on s’attend donc à ce que nous écrivions la solution imaginée par l’auteur du cours. C’est probablement bien, mais assez frustrant.

Une dernière chose : les exercices sont très bien instrumentés : il y a une commande SBT qui permet de soumettre l’exercice en ligne, le résultat est noté et argumenté en retours. On peut aussi pratiquement recommencer « ad noseum ». Seul le meilleurs résultat est conservé !

Scala : ce que j’ai aimé

Multi-paradigmes

Même si l’on n’en parle peu durant ce cours, Scala est en fait un langage « multi paradigmes ». En fonction de la sensibilité du développeur, il y a plusieurs voies pour résoudre un problème, en favorisant un paradigme plutôt qu’un autre, en les mixant…

Bien entendu, ceci en fait un langage difficile d’abord. En fait, il me rapelle C++ ! Si pour beaucoup cette comparaison frise l’insulte, ce n’est pas mon cas…

Le support de l’immutabilité

Le nom même du langage vient de « scalable ». Dans les architectures modernes en général et pour Odersky en particulier, être scalable, c’est offrir peu de prise à la concurrence et permettre de clusteriser les traitements. Pour Scala, l’un des secrets consiste à travailler avec des objets immutables. En choisissant d’en faire des val ou des var, on contrôle parfaitement ce que l’on souhaite faire.

Dommage quand même que l’on ait pas de mécanisme pour effectuer cette déclaration au niveau de la classe elle-même, pour interdire son utilisation mutable ! OK, OK, vous allez me dire qu’il me suffit de déclarer tous les champs de ma class « val »…

La surcharge d’opérateurs

Voici une fonctionnalité qui doit hérisser le poil de bien des Javanais ! Je n’ai rien contre la surcharge d’opérateur lorsque sa sémantique est bien inscrite dans celle qui est implicitement attendue par l’utilisateur. C’est d’ailleurs un des pièges en C++ !

Des objets à la place de singletons

Je ne suis pas fan des Singletons, mais le suis encore moins des bricolages à base de méthodes statiques. Donc si l’on veut une instance unique de quelque chose, il suffit de le déclarer en « Object » plutôt qu’en « Class ». Voilà !

D’ailleurs, il n’y a tout simplement plus de membre statique en Scala : bon débarras !

Les Traits

Les interfaces Java me posent un problème depuis le début. Je ne fais que peu de différence entre une interface et un pattern « template method » : refactorer une interface pour en faire un Template Method est pour moi une évolution naturelle. Oui mais voilà en Java, il faut passer d’une interface à une classe abstraite pour faire cela, et ce sont deux choses radicalement différentes ! Il faut repenser le design, ce qui est même souvent impossible « grâce » à l’héritage unique de Java !

Vous allez me dire que que maintenant c’est possible en Java 8 grâce aux « défaut methods ». C’est vrai, même si conceptuellement ce n’est pas ce que j’essaie d’exprimer avec le template method, je peux m’en servir pour cela (en sacrifiant le « final » que j’aurais souhaité utiliser).

Avec les Traits, on peut pratiquement utiliser toutes les fonctionnalités disponibles sur une superclasse ! De notables différence existent cependant (par exemple les traits n’héritent pas d’Object que j’éxecre de toute façon). Et le mécanisme sous-jacent appelé « linéarisation » est très différent.

On peut désormais penser son design de manière très différente : les classes deviennent des « mix in » de fragments de comportements. Et l’importance de l’arbre d’héritage à la papa est grandement diminué.

Des types spéciaux bien utiles…

En lieu et place d’Object, Scala nous propose différents types de base et différents « bottom types ».

image

Any, AnyVal et AnyRef sont les types parents du système de type Java. AnyRef est en fait un déguisement de Object, car il faut quand même tourner sur la JVM…

Plus intéressant : NULL est une vrai classe (à instance unique) et sous-classe tous les descendants de AnyRef. Nothing fait la même chose pour tous les descendants de Any. Il faut un peu apprendre à se servir de tout cela, ce n’est pas évident.

Les case classes

Elles offrent des facilités d’écriture et d’utilisation bien sympathiques, surtout dans le cas de value classes immutables. Par exemple, les paramètres du constructeur sont disponibles en tant qu’attributs “val” sans qu’il n’y ait rien à faire…

for expressions

Pas très facile à appréhender, le for (…) yield {…}, qui est en fait une combinaison de map, flatmap et filter.

Scala : ce que j’aime moins

Le « mode compression »

Je déteste la plupart des raccourcis syntaxiques qui permettent d’économiser un caractère par ci, un caractère par là… Comme par exemple se passer de parenthèses dans certains cas, ou de l’appel de méthode avec la notation à point.

Comme me le faisais remarquer si justement un de mes collègues, la motivation premières de la plupart de ces sucres syntaxiques est de permettre de transformer Scala en syntaxe type DSL ! C’est à mon avis un mauvais calcul, où l’apparente élégance d’écriture se traduit par plus de difficulté pour appréhender la sémantique. Il y a des fois où le côté rustique…

On ne saurait bien entendu passer sous silence le désormais célèbre « _ » ! Là encore, ces apparente économies rappellent les aspects les moins glorieux du Perl !

Bref, Martin aurait mieux fait de se casser une jambe le jour où il a pondu ces trucs là !

La programmation fonctionnelle, ce n’est pas très objet

Je me faisais un plaisir de masquer les listes, d’encapsuler les algorithmes. Avec la programmation fonctionnelle, j’ai l’impression de les exhiber à nouveau. Sans compter bien entendu que cette chère programmation fonctionnelle est le domaine des matheux …ce que je ne suis pas !

Bref, il me faudra pas mal réflechir pour voir si on peut concilier l’élégance de l’objet avec l’efficacité du fonctionnel. Odersky prétend que c’est ce que fait Scala, mais je n’en ai pas d’exemples frappants pour l’instant.

Un syntaxe dense, même sans le mode compression !

Le code Scala, c’est sans aucun doute élégant et efficace. Mais la lecture en demande pas mal de concentration et d’effort. Là encore, je retrouve un aspect un peu C++.

A côté, la syntaxe plus « paysanne » de Java permet plus facilement de débrancher le cerveau (sauf si vous commencez à utiliser les trucs de Java 8…).

La surcharge d’opérateurs

Oui, je sais, je l’avais mis dans les points positifs ! C’est parce qu’hélas Scala ne s’arrête pas à vous permettre de redéfinir les opérateurs prévus dans le langage. Il permet de définir les vôtres (encore cette satané velléité de faire de Scala une machine à DSL). Du coup cela permet de délirer tranquillement à définir des opérateurs en ASCII art sur 4 ou 5 caractères. Et c’est bien parti !!

Next step…

Le cours n’est pas une ballade de santé. C’était une opportunité pour aborder Scala, mais rétrospectivement, ce n’était pas la plus simple ! Commencer par du « better Java » aurait été plus raisonnable à mon âge…

Il y a beaucoup de choses intelligentes que j’aime bien dans Scala. Entre autre son aspect assumé « ulti-paradigmes », qui en fait aussi un langage difficile ! Ce dernier point signifie qu’il faut beaucoup le pratiquer, ce que je ne fais pas. Je me pose donc pas mal de questions sur le fait de persister…

D’autres langages alternatifs sur la JVM proposent des améliorations allant dans le sens de Scala tout en restant centré sur la facilité de lecture. Je pense spécialement à Ceylon. Bien sûr ils n’ont pas non plus le potentiel de Scala. Ils n’ont pas non plus la « traction » de Scala qui est réelle aujourd’hui et qu’on ne saurait ignorer.

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s