Apprendre la programmation en autodidacte
  1. La voie de l'autodidacte (1/2)
  2. La voie de l'autodidacte (2/2)

La voie de l'autodidacte (1/2)

(Nhat Minh Lê (rz0) @ 2010-08-27 00:08:36)

Tak tak voilà, la première partie d’un long article sur l’apprentissage autodidacte de la programmation… Hey, mais c’est pas un vrai article, ça ! Et bah non. :-° Dans ce numéro spécial, alp et blue (qui a depuis changé de pseudo pour un nom de brioche) répondent à mes questions sur leur parcours. Et vous avez également droit à mes commentaires sur ma propre expérience, incrustés de part et d’autre, parce que j’aime bien raconter ma vie.

(P.S. On attendait la réponse de dangerous, mais comme il semble ne pas porter beaucoup d’intérêt au sujet, on va faire sans. :])

Introduction

Pour répondre à la demande populaire, je me dois de vous présenter, cher lecteurs, les protagonistes du jour :

bluestorm

L’autre auteur du blog, celui qui fait généralement dire « oulala, ya des trucs compliqués sur ton blog » et m’oblige à répondre « nanan, c’est pas moi, c’est pas parce que j’ai les cheveux longs que… ». Aime bien la théorie qui théorise bien, quand c’est tout formel, tout beau, et tout et tout. Un autodidacte avec quelques années dans le bidou.

alp

Un sale hérétique qui fait du C++ et nous vient de developpez.com, même s’il le cache bien, maintenant (juste developpez.com, pas le C++, ça il en est fier…). S’intéresse à divers trucs… trop divers, même, et a choisi de faire des maths dans la vie, au lieu de devenir riche et puissant avec l’informatique, mwahahaha, ahem. Un autre autodidacte de longue date.

rz0

Moi. Hum, j’ai la flemme et je vais dormir, là. Mais je vous suggère de lire cet article Wikipédia sur les cochons d'Inde, qui aura occupé ma soirée, à la place. (Comprendra qui pourra. :-°)

Motivation

(1.1)

rz0

Quel facteur vous a-t-il fait découvrir la programmation ? À combien de temps cela remonte-t-il ?

alp

Mon père avait quelques petites notions de programmation (basic, tout ça) et on s’était intéressés ensemble à Game Maker, un logiciel pour faire des jeux avec une partie scripting invoquée lorsque des évènements se produisent. Je crois que c’est la première fois que j’ai « programmé », avec l’aide de mon père ; je devais avoir 11 ans.

bluestorm

J’ai découvert la programmation il y a 7 ans.

Au milieu de mon année de seconde, un ami m’a montré un jeu qu’il avait sur sa calculatrice. Je ne me souviens plus du jeu, mais je me souviens que j’ai découvert qu’il était stocké dans un fichier de code source (c’était du TI-Basic). Je ne comprenais rien au langage, mais j’ai repéré les chaînes de caractères affichées pendant le jeu, et je les ai modifiées pour afficher des messages plus amusants.

Après une observation plus attentive du code source, j’ai pu essayer d’écrire mon propre jeu; je ne me souviens plus de ce que j’ai fait en premier, mais j’ai écrit ensuite un Puissance 4 à deux joueurs. Pour remplir les bords de l’écran, je lui faisais afficher aléatoirement à certains tours des smileys. Les amis qui l’ont essayé étaient persuadés qu’il analysait les parties pour mettre un smiley souriant au joueur gagnant, et un smiley triste au perdant.

Je n’ai pas continué longtemps la programmation sur calculatrice (pour commencer, je n’avais pas moi-même une calculatrice programmable). Mon professeur de mathématiques, que j’appréciais énormément, était responsable d’un « club Algo » au lycée. Un ami y participait, et je me suis décidé à y aller un soir pour voir à quoi ça ressemblait : il y avait quelques personnes qui suivaient des cours en ligne pour apprendre à programmer, et d’autres plus avancés qui faisaient de l’algorithmique. Il fallait choisir un langage à apprendre, et cet ami faisait du C ; mais je suis tombé, par hasard, sur un étudiant de classe préparatoire qui m’a expliqué d’un ton mystérieux que « si tu aimes les maths, il faut faire du Caml ». J’ai été tenté, et ça m’est resté.

rz0

Pour ma part, j’ai d’abord essayé tout seul, puis ça n’a pas pris, et, quelques temps après, j’ai rencontré quelqu’un qui m’a dit qu’il « écrivait des logiciels » ; je lui ai demandé de m’apprendre, et c’est ainsi que tout a commencé, il y a maintenant bientôt dix ans…

(1.2)

rz0

Comme beaucoup de gens, pendant quelques années, j’ai eu des ambitions très peu modestes : jeux, systèmes d’exploitation, etc. Au final, ça m’a fait voir du pays. :)

Était-ce pareil pour vous ? Quelle était votre motivation originelle ? Était-elle réaliste ? Combien de temps vous y êtes-vous tenus ? En rétrospective, vous ont-elles aidé à avancer ?

alp

De ce côté là, j’ai toujours été assez réaliste. J’ai peut-être au tout début eu des ambitions bien grosses par rapport à mes connaissances et à mon expérience, le seul example me venant à l’esprit étant, en bon marseillais que je suis, l’écriture d’un jeu de pétanque 2D avec deux autres personnes alors que je débutais en C++. On avait commencé, mais c’est vite tombé à l’eau par manque de motivation et disponibilité. Donc c’était très peu réaliste (pour moi), ça n’a pas duré plus de deux mois et donc ça n’a pas eu tellement d’impact si ce n’est que tous les projets que j’ai fait après cela ont plus ou moins tous été relativement cohérents vis à vis de mes connaissances et de mon expérience.

bluestorm

Je ne me suis jamais lancé dans des projets énormes. La méthode des membres du Club Algo était de donner de petits problèmes à chercher, de plus en plus difficiles, et on apprenait en trouvant tout seul la réponse, en demandant des indications, puis en étudiant les solutions données. Très vite, j’ai trouvé des cours plus avancés (je me suis concentré sur le Caml, plutôt que de faire de l’algorithmique), et j’ai dû choisir mes sujets moi-même, mais j’ai conservé cette méthode.

J’ai toujours été plus motivé par la façon de programmer que le résultat final. J’ai trouvé un cours de Caml assez complet (le DA-OCAML) que j’ai essayé de lire en entier, en faisant des efforts pour utiliser chaque fonctionnalité du langage. Ça m’a pris du temps (sans doute environ un an), mais j’ai beaucoup appris, et surtout un peu de tout : beaucoup de programmation fonctionnelle, un peu d’impératif, mais aussi un peu de graphique, de parsing, de bas niveau, de l’objet, du système, du réseau… Ça donne un point de vue d’ensemble.

Après-coup, je me rends compte que certains des exercices, si j’avais eu envie d’aller jusque au bout, d’écrire un système équivalent à ce qui existait, auraient été (beaucoup) trop gros pour moi. Je pense en particulier à une petite bibliothèque GUI (avec les primitives pixels par pixels de Caml, que du bonheur…), un forum Web (quand j’ai appris le PHP l’été suivant), et un serveur Web en Caml. Mais je n’avais pas d’ambition : après avoir obtenu quelque chose de simple mais qui marche, je suis passé à autre chose.

(1.3)

rz0

Quel est votre « but » aujourd’hui ? Avez-vous trouvé des domaines qui vous intéressent plus particulièrement ? Et si oui, les avez-vous rapidement trouvés ?

Pensez-vous que ce soit un facteur déterminant pour garder la motivation tout au long de son apprentissage ?

alp

Étant donné que je m’oriente vers les mathématiques académiquement, je suis naturellement attiré par tout ce qui s’en rapproche dans la programmation. Cela peut être du très abstrait comme la théorie des catégories mais aussi du très concret comme des algorithmes géometriques. Mais sinon, du point de vue du développement pur, je suis assez investi dans 2 domaines : le bon vieux C++ que j’ai commencé à apprendre il y a maintenant 6 ans, à quelques semaines près, ainsi que la programmation fonctionnelle avec les langages Haskell et Objective Caml. Le C++, je suis tombé dessus assez « rapidement ». J’avais fait mumuse avec un peu de Visual Basic et de C pur avant ça, et je me suis lancé dans le C++. Depuis, j’ai essayé bien d’autres langages mais aucun ne m’a sérieusement plu, à part justement les deux langages fonctionnels mentionnés ci-dessus, Haskell et Objective Caml. J’ai probablement commencé l’apprentissage d’OCaml il y a bientôt 2 ans, et plutôt 1 an pour Haskell — mais j’avais déjà tout le bagage d’OCaml avec moi ce qui a grandement facilité l’apprentissage. Donc pour le monde de la programmation fonctionnelle, il m’a fallu un bon moment avant de tomber dedans, et encore un moment avant de l’apprécier tout particulièrrement. En dehors de cela, de façon plus détachée des langages, je m’intéresse à des choses diverses et variées qui n’ont pas forcément traits aux mathématiques, comme les questions de design logiciel, tout ce qui tourne autour de la création de langages de programmation, le multithreading et la programmation parallèle, entre autres.

Je pense que tout autodidacte doit passer par une phase où il va un peu toucher à tout, afin de voir ce qui lui plaît. Mais effectivement après un certain moment (ça se compte en années, et pas seulement une ou deux…), avoir quelques domaines précis où l’on se spécialise en quelque sorte, est bénéfique car à mon sens cela permet d’approfondir (ce que l’on n’a pas trop tendance à faire dans la phase précédente) et d’acquérir une certaine expertise dans ce(s) domaine(s) et donc logiquement de pouvoir entreprendre la réalisation de projets sérieux dans ce domaine, ou carrément aller contribuer aux gros projets opensource liés au(x) domaine(s) en question. Et, c’est bien connu, lorsque l’on est autodidacte la motivation est généralement assez liée à la réalisation de projets !

bluestorm

J’ai envie de pouvoir implémenter ce qui me fait envie, d’une façon qui me plaît. De ce que j’ai fait au départ, j’ai gardé mon intérêt pour Caml, et plus généralement pour les langages de programmation. Je m’intéresse surtout à la sémantique (systèmes de type, formalisation des langages), à la compilation. Il y a d’autres sujets qui m’intéressent, comme la syntaxe (qu’est-ce qu’une bonne syntaxe ?), les outils autours des langages, les méthodes de programmation, etc.

Mais j’ai une préférence pour ce qui est formalisable, car la formalisation permet de faire des choix pour des raisons profondes. Quand un domaine repose uniquement sur des facteurs informels (par exemple : quel style d’indentation adopter ?), il y a souvent plusieurs possibilités mais pas de « bonne » réponse.

J’ai mis longtemps à vraiment me rendre compte de cette préférence. J’ai même fait de la programmation Web pendant plusieurs années. Je pense qu’au long de l’apprentissage, la curiosité des choses nouvelles est plus importante qu’une fixation sur un ou plusieurs sujets, tant qu’on ne se lasse pas.

rz0

En ce qui me concerne, on peut difficilement ignorer le fait que je suis particulièrement investi dans les langages, leur traitement, interprétation, compilation, etc. Ça, et le système, dans une moindre mesure. Rétrospectivement, cela a probablement été un facteur déterminant dans mon apprentissage, même si je ne l’ai pas compris tout de suite. Cela m’a permis d’arrêter les expérimentations foireuses à droite et à gauche pour me concentrer sur une direction, et lentement progresser sur cette voie.

Apprentissage

(2.1)

rz0

Pour moi, l’apprentissage en autodidacte s’est traduit par trois phases :

  1. l’isolation (apprentissage dans mon coin, peur de la confrontation ; ~2 ans, dans mon cas) ;
  2. l’arrogance (trop de confiance en mes compétences et mes connaissances nouvelles ; ~2-3 ans, dans mon cas) ;
  3. la prise de conscience, lente et progressive (en cours :-°).

Vous y identifiez-vous ? Avez-vous un autre modèle à proposer ?

Idéalement, je pense que la phase arrogante pourrait être évitée, mais c’est un peu un effet de bord de la volonté et de l’ambition qui sont des sources de motivation majeures pour l’autodidacte. En ce sens, c’est un sacrifice raisonnable. Êtes-vous d’accord avec cet argument ?

alp

Je m’identifie totalement avec cette description. Et c’est marrant, quand on est à la phase 2 on pense tout savoir parce qu’on commence à avoir des connaissances respectables, et on cherche quelque part un peu à s’affirmer, et l’on voit pleins de jeunes autodidactes passer par cette phase, par exemple dans la communauté #sdz, qu’il s’agisse de simples « trolls » ou de discussions assez vives, ce qui ne fait que me rappeler que je suis passé par là.

Et oui, je me dis que quelque part la plupart des autodidactes « doivent » passer par là, car finalement on tire quelques leçons de cette phase — ce qui permet de passer à la phase 3 — et que c’est un sacrifice tout à fait raisonnable.

bluestorm

Je ne me reconnais pas vraiment dans les idées d’isolation ou d’arrogance (mais peut-être que d’autre m’y reconnaissent… j’espère que non). Je pense qu’il y a plutôt une série de cycles courts : au début, on a du mal avec quelque chose, on apprend progressivement comment le faire, puis il y a un déclic où on comprend bien et on veut l’expliquer aux autres, et on finit par se lasser de répéter la même chose, et passer à un autre sujet où on est à nouveau débutant.

(2.2)

rz0

Cela m’a pris un bon nombre d’années (je dirais bien six ou sept ans au moins) avant de produire du code utilisable « dans la vie ». Pour moi, il y a donc une phase improductive nécessaire, durant laquelle on apprend sans se soucier du résultat, juste pour apprendre, avant la phase productive, où, par définition, on tente de produire quelque chose (et l’on doit y sacrifier une partie du temps que l’on aurait pu passer à apprendre).

Le même constat vous a-t-il frappé ? Y a-t-il eu des rechutes dans l’improductivité ? Si oui, comment vous en êtes-vous sorti ?

alp

J’ai été frappé par le même constat. D’une part, au début de mon apprentissage du C++. Le code que j’écrivais n’était tout simplement pas assez robuste/efficace/etc. et je passais effectivement un temps monstrueux à en apprendre et en découvrir tous les jours dans mon exemplaire de « Le Langage C++ » de Bjarne Stroustrup, ainsi que d’autres bouquins, achetés par la suite. Ensuite, je commençais à bien connaître la programmation orientée objet et le C++ lui-même, mais pas énormément non plus ; j’étais tout juste familier avec les templates notamment (comparé à ce que je sais aujourd’hui, et ce qui se fait dans Boost par exemple). Et là, j’ai eu une rechute quand je me suis sérieusement mis à la métaprogrammation. J’ai passé à nouveau beaucoup de temps à apprendre et expérimenter, avant d’ensuite être capable d’écrire du code utilisable (et utilisé) «_dans la vie_». Il s’est ensuite à nouveau passé la même chose lorsque je me suis plongé dans le monde de la programmation fonctionnelle, d’abord en Objective Caml, puis en Haskell. Cela fait d’ailleurs pas si longtemps que j’écris du Haskell d’une qualité « acceptable » et je suis loin d’être au bout du tunnel pour cela… Quoiqu’il en soit, à chaque fois, c’est la motivation, la persévérance, le refus de ne pas comprendre qui m’a permis de m’en sortir et de surmonter les difficultés, bien que desfois on en ait un peu marre d’en ramer sur la compréhension d’une notion ou autre (« fuck that monoid in category of endofunctors shit » — à propos des monades).

bluestorm

Ce n’est pas l’état improductif qui est anormal ; c’est l’inverse ! Pendant l’apprentissage, tout est excitant, on essaie de nouvelles techniques et on apprend de nouvelles choses. Quand on essaie de produire quelque chose de définitif, il faut se mettre à se soucier de tous les détails pénibles (documentation utilisateur, distribution…). C’est encore pire quand on a des utilisateurs ! Se forcer à finir un produit, c’est accepter de passer du temps sur des choses sans intérêt, pour en conterpartie être utile à quelqu’un d’autre que soi-même.

Pour moi, l’important c’est de ne jamais se mentir. Si on a envie de recoder un programme déjà existant d’une façon novatrice, avec un design intéressant et tout, c’est qu’on est en phase d’apprentissage et qu’on code pour soi. Je n’aime pas qu’on prétende coder pour les autres alors qu’en réalité on s’amuse pour soi-même, sans se soucier des besoins réels des utilisateurs.

Formation

(3.1)

rz0

Comment positionneriez-vous votre formation autodidacte par rapport à la formation académique que vous avez reçue après coup ?

alp

Étant donné que je n’ai eu qu’un seul cours d’informatique pendant un semestre, dans toute ma vie, ce que je peux le plus assimiler à une formation académique ce sont les bouquins de référence utilisés par les professeurs dans le monde entier, que j’ai acheté pour me former moi-même sur ces sujets. Et pour moi ils constituent une base, solide, parfois un peu théorique, influence que je trouve complémentaire à celle de la formation autodidacte, qui consiste souvent à tâtonner, pratiquer, etc.

bluestorm

J’ai eu des cours plus ou moins théoriques qui concernaient des domaines de l’informatique, mais jamais de cours de programmation. Dans tous les cours où il y a de l’informatique, on suppose que les gens savent déjà programmer et se débrouillent par eux-mêmes pour pratiquer. Pour moi c’est donc deux choses complémentaires : la pratique est une expérience personnelle, et les cours peuvent apporter un aspect théorique qu’on n’aurait pas forcément la motivation de creuser tout seul.

rz0

Mon avis sur cette question est quelque peu partagé. D’un côté, il est clair que ma formation à l’Ensimag m’a apporté un point de vue plus généraliste et a aidé à consolider mes bases théoriques. En cela, les deux sont complémentaires. D’un autre, techniquement parlant, pour moi, il n’y a aucune comparaison possible : le cursus en école d’ingénieur (mais je crois que c’est partout pareil) ne peut rivaliser avec des années à se démêler par soi-même avec les ressources du bord ; ça donne des automatismes et ça forge le caractère. Pour reprendre le modèle ci-dessus, l’école, c’est la phase d’apprentissage, la phase improductive, dans tout son éclat ; ce n’est pas bien ou mauvais en soi, mais il faut en être conscient.

(3.2)

rz0

Avec le recul, je peux dire que j’ai appris un peu n’importe comment, chaotiquement, en lisant et en pratiquant ce que j’avais sous la main, et récursivement, en m’intéressant aux topics sous-jacents que je ne maitrisais pas. Mais je pense que c’est une bonne technique, si l’on a la motivation (et le temps) nécessaire, comme c’est le cas quand on est au collège ou au lycée. C’est une sorte de filtrage naturel : on va de soi-même vers les sujets qui paraissent intéressants. On commence avec un petit nombre de choses inconnues et à sa portée, et le processus est d’abord lent et très aléatoire, dans son contenu, mais il se dessine peu à peu des préférences, et à mesure que le contenu potentiellement accessible explose, on met instinctivement des priorités, et ainsi se forment les goûts et les vocations.

Quelle méthode avez-vous adoptée ? Était-ce conscient (wow, j’admire le méthodique) ? La conseilleriez-vous maintenant à des novices ?

alp

Moi aussi j’ai beaucoup appris de cette façon, même si avec le temps j’arrive un peu mieux à structurer mon apprentissage. Généralement, je me renseigne un minimum sur le sujet de mon apprentissage et me procure un cours ou livre de référence sur le sujet. Je peux faire ainsi car j’ai une assez bonne idée aujourd’hui des différents domaines de la programmation, en particulier de ceux qui m’intéressent. Mais ce n’était pas le cas il y a quelques temps… Toutefois c’est une bonne stratégie sur les novices, clairement, à mon avis.

bluestorm

Bien sûr, il n’y a pas de méthode miracle, pour pouvoir affiner ses goûts il faut machouiller un peu tout ce qui nous tombe sous la main. Après-coup, il y a quand même des choses qu’on se dit qu’on aurait pu faire selon un cheminement moins tortueux, par exemple en lisant directement un ouvrage de référence au lieu de s’éparpiller sur des dizaines de textes introductifs.

Ça s’apprend, et aujourd’hui j’ai une approche plus directe : trouver un bon document de référence sur le sujet, commencer par le survoler puis lire les parties qui m’intéressent. Mais pour certains sujets qui demandent plus d’efforts, on est parfois forcé de revenir au stade du machouillage pour que ce soit comestible.