🫕 Newsletter #2
Où on parle de la queen of dev Barbara Liskov, de comment évaluer son propre niveau en dev et de nos actus🧋
News News News
Campagne Ulule : on a dépassé les 50 % ✊
TLDR : des micro-bootcamps solidaires sur un week-end pour progresser en algo, en system design et en craft
👉 https://fr.ulule.com/micro-bootcamps
Il reste 13 jours, on a dépassé les 50 %, on ne lâche pas la patate 🥔
On donne et on fait tourner l’info autour de nous !
(et pourquoi on a soudain un ton de prof de gym, c’est une vraie bonne question.)
Tu te demandes si nos futurs micro-bootcamps sont pour toi ? Écris-nous à contact@electronictales.io, on fera un diagnostic flash personnalisé ensemble (sans appel ni visio gênante, c’est promis).
Modern World
Auto-évaluer son niveau
Un des points douloureux, quand on débute dans le dev (et même ensuite), est de réussir à évaluer son propre niveau de compétences.
L’association Code Collectif a traduit en français une matrice d’auto-évaluation des compétences en programmation, qui permet de mieux se situer, à l’image des niveaux de langues (A1, B1, etc.).
C’est super utile et c’est ici.
Ancient World
Le “Elle” de SOLID 🥁
Une chronique par Officier Azarov
L’autre jour, il y a trois ou quatre ans, j’étais tranquille chez ma psy, à parler du capitalisme et de ma mère, comme tout le monde. Ce qu’il s’est passé ensuite, je ne saurais pas dire. Peut-être qu’il se faisait tard et qu’elle commençait à être grognon de faim. Peut-être qu’elle s’était rappelé qu’elle devait changer les piles du détecteur de fumée du cabinet après mon départ. Toujours est-il que, soudain, elle m’a demandé de décrire les émotions que je ressentais.
Je ne sais pas si ça n’arrive qu’à moi, ce problème, mais il y a toujours un moment où les psys veulent que je décrive mes émotions. S’ensuit un Question pour un champion bizarre où je tente, pêle-mêle, “anxiété”, “culpabilité” ou encore “angoisse”, mais à chaque fois on me répond que ce n’est pas une émotion. Comme si on était tou·te·s censé·e·s connaître la liste par coeur – un truc que les psys voient probablement en premier semestre de L1, soit dit en passant. Sauf que je ne suis pas allée en L1 de psycho, moi, bon sang.
Dans ce moments-là, tandis que je sèche honteusement, tout au fond de moi, un être odieux et malfaisant – probablement un·e dev à qui son manager demande de pousser en prod un vendredi soir – a envie de hurler “mais est-ce que je vous demande de m’énumérer les principes SOLID, moi ?”.
En vrai, je ne les connais même pas, ces principes. C’est bon, personne ne les connaît. Tout le monde google en douce sur son téléphone quand un·e collègue un peu plus surexcité·e que les autres décide que c’est le moment d’en parler, là maintenant tout de suite, en plein pendant le déjeuner. C’est pour quoi, déjà, le S ? Et le I ? Est-ce que c’est pour “injection” ? “Inversion” ? “Indépendence” ? “(Salade) Iceberg” ?
Derrière cette abréviation aussi engageante qu’un pain de mie oublié dans le toaster la veille d’un départ en vacances, il y a pourtant un principe qui vaut le détour d’un point de vue historique et militant : le principe de Liskov – aka le “L” de SOLID.
🦫🦫 Avant de voir ensemble le principe en lui-même, moment Père (Mère ? Parent ?) Castor 🦫🦫
Once upon a time
Dans la famille “incroyable mais vrai, il n’y pas qu’Ada Lovelace et Margaret Hamilton dans l’histoire de la programmation”, je demande Barbara Liskov, donc. Car oui, le seul nom propre, dans l’acronyme SOLID, est bien celui d’une femme.
Comme elle le raconte dans cette interview, Liskov doit participer à une conf en 1987. À ce moment là, elle se dit que ce serait une bonne occasion de se mettre à jour sur ce qu’il se fait de beau dans le monde de la programmation orientée objet, qui parlait beaucoup de classes et de types à l’époque. Elle compulse des articles scientifiques. Et là, attention moment Queen of Dev absolu :
Okay Barbara, mic drop 🎤🕶️
(Petite blague en option – peu importe si on ne sait pas trop ce qu’est une stack et une queue, la formulation reste savoureuse à souhait : )
Huhuhu.
Je ne sais pas vous, mais moi, à ce stade, je remplis déjà les papiers pour lui demander de m’adopter.
Donc voilà, on est dans les années 80, Barbara Liskov participe à une conf en présentant un principe qu’elle arrive à dégager “de façon informelle”, nomme ça “Behavioral subtyping” et retourne travailler sur CLU, un langage de programmation sur lequel elle bosse pour le MIT (en toute simplicité).
Ce n’est que dans les années 90 qu’elle reçoit, un jour, un e-mail de quelqu’un lui demandant de confirmer s’iel avait bien compris le “principe de substitution de Liskov”. Et là, elle découvre qu’il y a tout un tas de gens, sur Internet, qui débattent de ce qu’est le principe de Liskov.
Pour la petite histoire, Barbara Liskov a fait des études de mathématiques. Au début des années 1960, elle a postulé à Berkeley et Princeton pour continuer en master, mais Princeton n’acceptait pas les femmes dans sa filière mathématiques à l’époque. Dommage pour eux : elle a été une des premières femmes au monde à obtenir un doctorat en informatique, a eu le prix Turing et enseigne au MIT depuis presque 50 ans.
A quand une série Apple TV uchronique qui imaginerait un monde où Barbara aurait eu pour nom de famille Piskov, Miskov ou Viskov ? 🍿
Mais c’est quoi, ce principe ?!
Allez, voyons ensemble ce qu’est ce fameux principe de Liskov !
Bon, déjà, ce principe s’applique à la programmation orientée objet (= POO).
Petit recap de l’héritage en POO
Peu importent les subtilités. En gros, ce qu’il faut savoir, c’est qu’en POO, on a des classes (dites aussi “types”), et qu’à partir de ces classes on peut créer des sous-classes (dites aussi “sous-types”). Comme dans la vraie vie mais en plus flippant, les classes enfants héritent des propriétés de leur parent.
Imaginons qu’on veuille coder un simulateur de colocation inter-espèces (oui déso, on va utiliser la métaphore vue et revue des animaux – mais, hey, n’est-ce pas plus tech et woke avec ce superbe design ?).
Disons que, dans notre coloc, on veut qu’il y ait des chiens, des canards et des lions (parce que pourquoi pas). On pourrait créer une classe pour représenter chaque type d’animal et définir pour chacun que celui-ci a un nom, respire, mange, boit, dort, etc. Puis écrire le code correspondant.
Par exemple, pour Lion :
mâcher() {
print(“Je mâche.”)
}
Et pour Canard :
mâcher() {
print(“Je mâche.”)
}
Et là bim, on se rend compte qu’ils font TOUS ça, les petits mignons. Ni une ni deux, notre Surmoi crie, fulmine et pleure : on a du code dupliqué dans tous les sens, le principe Don’t Repeat Yourself n’est pas respecté.
Pour éviter ça, on sort notre plus beau monocle de dev orienté objet et on crée une classe Animal qui va centraliser les éléments communs à toutes nos petites bêtes :
La classe Animal est la classe parent. Les classes Chien, Lion et Canard sont les classes enfants. Tous les enfants héritent des propriétés d’Animal, à savoir avoir un nom et mâcher()
(et c’est déjà beaucoup).
Avec la création de cette classe parent, on a réglé le problème du code qui se répète.
Mais ce n’est pas tout !
La beauté de la programmation objet, c’est qu’on peut aussi utiliser cette classe parent pour écrire un code générique, c’est-à-dire un code qui marchera aussi bien pour la classe Chien que Lion ou Canard. Et même pour des classes qui n’existent pas encore, du moment qu’elles sont dérivées d’Animal – par exemple, Chat ou Eléphant.
Moins de mots, plus de dodo code (oui oui, c’est du pseudo code – les jedis du Java, rangez vos sabres laser, merci) :
Voilà. Basta. Finito. Ce code va nous permettre de gérer tous les cas où on a besoin de mâcher()
.
“Mais où sont les lions, où sont les canards, où sont les chiens ?”, me direz-vous.
L’injection de dépendances
Entre en scène encore un autre truc génial, qui s’appelle l’injection de dépendances 💉
No worries, on n’a pas besoin de savoir en détails ce que c’est ici. Imaginons juste que, dans un programme fait en POO, on va avoir des classes qui se baladent (et qui sont, chacune, un petit fichier) et un fichier principal, qui va dire ce que fait le programme. Ce fichier principal a une sorte de conseiller de l’ombre, qui orchestre tous ces éléments : le manager de dépendances.
Ainsi, lorsque, par exemple, nous cliquerons sur le canard sur notre interface graphique, le manager va recevoir l’info de remplacer l’instance d’Animal pour une instance de Canard. En code, c’est comme si le manager faisait ça :
Et sur notre application, voilà quel sera le résultat :
Maintenant, imaginons qu’on invite des bactéries à venir vivre avec nous. On veut qu’elles soient des habitantes à part entière de la coloc, donc on crée une classe Bacteria dérivée d’Animal (à ce stade, je prie définitivement pour qu’aucun·e biologiste qualifié·e ne tombe sur cet article).
Bacteria va hériter de mâcher(), comme les autres.
Allez super, on a bien avancé, on peut fermer l’ordi et aller boire un moji…
WAIT A MINUTE ! MAIS ÇA NE MÂCHE PAS, UNE BACTÉRIE !!
Sans le savoir, nous venons d’enfreindre le principe de Liskov :
Si S (ici, Bacteria) est une sous-classe de T (ici, Animal), alors les objets de type T (Animal) peuvent être remplacés par des objets de type S (Bacteria) sans altérer la cohérence du programme.
Eeeeeh oui. On se retrouve dans une situation fascinante : par erreur, on a créé un écart entre l’ordinateur et nous, les êtres humains qui avons conçu le programme.
Pour l’ordinateur, tout va bien : la syntaxe est ok, le code tourne, tout s’affiche.
Mais pour nous, ça chauffe. Sur le plan sémantique, ça ne va plus. Notre programme a un comportement inattendu.
Ce que demande le principe de Liskov, c’est que les méthodes héritées (comme mâcher()
) soient utilisables par toutes les sous-classes, avec des résultats conformes aux attentes du·de la programmeur·se.
Or là, on a fait hériter Bacteria de la méthode mâcher()
telle quelle, sans l’adapter au cas précis de notre petite bactérie (pourquoi est-ce que je mets “petite” devant “bactérie”, allez savoir).
Et, du coup, notre code générique n’est plus si générique que ça.
Pas de drame, que des solutions
On l’ a dit : dans cette situation, l’ordi est content, mais l’être humain voit l’incohérence sémantique. C’est donc au·à la programmeur·euse d’aller rétablir l’harmonie de l’Univers, et ce en redéfinissant la méthode mâcher()
pour Bacteria :
class Bacteria extends Animal {
mâcher() {
print(“Je ne mâche pas, je dégrade des macromolécules.”)
}
}
Maintenant, notre programme respecte à nouveau le principe de Liskov : toutes les sous-classes d’Animal, y compris Bacteria, peuvent utiliser mâcher()
sans créer d’incohérence sémantique.
Pour le mot de la fin, je ne résiste pas à l’envie de citer une dernière fois la professeure Liskov :
Passionnant !