Greboca  

LinuxFr.org : les journaux  -  Les 7 étapes pour devenir un programmeur Go.

 -  Mars 2019 - 

Sommaire

Je vous propose ici une traduction sans prétention d'un article de Daisuke Maki publié sur www.opensource.com concernant les différentes étapes à traverser pour devenir un vrai programmeur en Go sur base de son expérience. Si vous maîtrisez l'anglais, la lecture de l'original sera sans doute plus agréable.

Que vous soyez nouveau à Go ou que vous soyez un utilisateur chevronné, vous reconnaîtrez peut-être ces étapes sur le chemin de l’illumination.

Un jour, au travail, nous discutions du langage de programmation Go. À un moment donné, j'ai commenté une diapositive d'un collègue (co-worker) en disant quelque chose du genre :

"Je pense que c'est similaire à la troisième étape des sept étapes pour devenir un programmeur Go."

Naturellement, mes collègues (co-workers) voulaient connaître le reste des étapes, alors je les ai brièvement décrites. Voici, développées avec plus de contexte, les sept étapes pour devenir un programmeur Go. Peut-être pourrez vous vous voir sur ce cheminement.

Étape 1 : Vous croyez que vous pouvez faire en sorte que Go se comporte comme un langage orienté objet

Après votre premier passage sur Un tour de Go, vous commencez à vous dire : « Maintenant, comment puis-je faire en sorte que ce langage se comporte davantage comme un langage orienté objet…  ? » Après tout, vous êtes habitué à ce genre de choses. Vous voulez faire du code robuste. Vous voulez du polymorphisme.

Vous vous dites : "Il doit y avoir un moyen !". Et vous trouvez l'incrustation des strutures (struct embedding). Cela vous permet de déléguer intelligemment les méthodes de l'objet inclus à l'objet incorporé sans avoir à dupliquer le code. Super !

Bien sûr, ce n'est pas vrai. L’incrustation vous permet seulement de déléguer des appels de méthode. Même s'il semble que vous effectuez une répartition de méthode polymorphe, cela n’est pas le cas. En effet, le récepteur de l'appel de méthode n'est pas l'objet enfermant : le récepteur est toujours l'objet incorporé auquel l'appel de méthode a été délégué.

Vous NE FAITES PAS de programmation orientée objet dans Go. Point final.

Etape 2 : Vous pensez que les goroutines vont résoudre tous vos problèmes

Vous avez été attiré à Go par la promesse qu'il vous permettra d'exécuter facilement du code concurrent, ce qu’il fait via les goroutines ! Tout ce que vous avez à faire est d’utiliser le mot-clé go, et vous pouvez exécuter à peu près n’importe quelle fonction ou appel de méthode simultanément. Il est donc naturel que vous souhaitiez maximiser l'efficacité de votre code en créant autant de code à exécuter en parallèle. Et parce que vous masquez ce fait en faisant vos appels de fonction pour créer automatiquement des goroutines, l'appelant n'a même pas besoin d'en être conscient.

Bon, ça pourrait rendre votre code un peu plus compliqué mais maintenant tout fonctionne en même temps !

Go vous permet de créer des millions de goroutines sans sacrifier beaucoup d’efficacité, mais vous ne devriez pas vraiment utiliser les goroutines juste parce que vous le pouvez. Un code simultané est plus difficile à maintenir et à déboguer que le code qui ne circule que dans un seul thread. Autrement dit, avez-vous sérieusement réfléchi à la question de savoir si vos objets partagés sont vraiment synchronisés correctement lorsqu’ils sont accessibles depuis plusieurs goroutines à la fois ? Êtes-vous sûr que l’ordre d’exécution est absolument correct ? Avez-vous vraiment vérifié si ces goroutines disparaissent vraiment quand on n’en a plus besoin ?

Les goroutines sont utilisées au mieux lorsqu’elles sont réellement nécessaires, et à moins que vos exigences ne vous obligent à tout faire en mémoire ou autre, vous ne devriez jamais abandonner l’utilisation des bons vieux modèles multi-processus.

Enfin, N'ESSAYEZ PAS de créer des goroutines dans le dos de vos utilisateurs, surtout si vous écrivez une bibliothèque. Les appels explicites à l'utilisation des appels de go donnent généralement à l'utilisateur plus de flexibilité et de puissance.

Les goroutines ne font pas plus que ce qu’elles font. Utilisez-les seulement lorsque cela a vraiment du sens.

Étape 3 : Vous pensez qu'au lieu d'une programmation orientée objet, les interfaces vont résoudre tous vos problèmes.

Après avoir perdu vos illusions de pouvoir faire en sorte que vos objets se comportent de manière polymorphe, vous réalisez soudain les capacités offertes par les interfaces. Les interfaces vous permettent de décrire les APIs ; il doit y avoir un moyen de les utiliser pour écrire du code plus robuste.

Donc maintenant, quand vous écrivez des bibliothèques, vous définissez des interfaces pour tout. Vous exportez seulement les interfaces et avez des structures privées pour que l’encapsulation soit parfaite. Cela devrait également vous donner plus de flexibilité lors de modifications de l'implémentation sous-jacente, car vous avez maintenant réussi à découpler l'API de son implémentation.

Les interfaces vous donnent beaucoup de puissance, mais ce n’est pas une solution toute faite. Cela ne fournit toujours pas de véritable polymorphisme au sens de la programmation orientée objet. Vous êtes également limité par le fait que les interfaces ne peuvent définir que l'API et que vous ne pouvez y associer aucune donnée.

De plus, bien qu’il y ait des cas légitimes où exporter uniquement des interfaces au lieu de structures en béton soit logique, cela ne devrait vraiment pas être votre mode de fonctionnement par défaut. Les interfaces sont meilleures lorsqu’elles sont petites (par opposition à la description d’une liste complète de méthodes définies pour un objet). De plus, si vous n’êtes pas prudent, vous devrez soit écrire beaucoup d’options pour remplir l’interface, soit écrire du code qui nécessite beaucoup de vérifications de type.

Pour tirer le meilleur parti des interfaces, vous ne devez les utiliser que lorsque vous voulez rendre certains types interchangeables.

Étape 4 : Vous croyez que les channels résoudront tous vos problèmes

Après avoir passé beaucoup de temps à réfléchir sur la façon de forcer Go à travailler de votre façon, vous êtes maintenant à la recherche de cette pièce manquante qui va tout faire fonctionner à votre façon. "Attendez, il y a encore des channels !"

Les channels gèrent correctement implicitement les accès simultanés. Vous pensez qu’il devrait être possible de contourner plusieurs des obstacles rencontrés jusqu’à présent en utilisant intelligemment les channels pour gérer la synchronisation, retourner les valeurs, et le contrôle de flux avec des instructions sélectionnées avec différents channels.

Encore une fois, les canaux sont extrêmement utiles, mais ils sont seulement aussi utiles que leur but initial, qui est de fournir une primitive pour passer des valeurs entre goroutines.

Je suis sûr que vous trouverez beaucoup d’idiomes Go utilisant des canaux : pour les timeouts, le blocage des Entrés/Sorties, les astuces de synchronisation, etc. Mais encore une fois, parce que les channels sont des constructions de concurrence (concurency constructs), en abuser conduira à un code plus compliqué, difficile à déboguer.

Étape 5 : Vous pensez maintenant que Go n'est pas aussi puissant que ce que les gens prétendent.

"Pourquoi ?! Pourquoi est-ce si douloureux d'écrire du code en Go ? Ça ne me permet pas d'écrire du code comme je l’ai toujours fait."

Vous êtes frustré. Pas de polymorphisme. La concomitance est difficile. Les chaînes ne résolvent pas vos problèmes. Vous ne comprenez même pas pourquoi Go existe. Vous avez l’impression d’avoir été dépouillé de tous les beaux outils et de toutes les belles constructions que d’autres langages vous offrent.

Vous croyez que des outils plus puissants pour exprimer des idées abstraites sont absolument nécessaires. Go ne suffit pas.

Go est résolument tourné vers l’avenir. Je viens d’une famille Perl, et pendant un moment je n’arrivais pas à croire à quel point le Go était limitatif. Donc oui, je comprends que vous soyez frustré.

Mais est-ce parce que le langage est vraiment contraignant, ou est-ce parce que vous essayez de le faire fonctionner comme vous le voulez, sans tenir compte de ce que les auteurs du langage avaient l’intention de faire ?

Étape 6 : Vous réalisez que les étapes 1 à 5 n'étaient que votre imagination.

À un moment donné, vous décidez à contrecœur d’écrire du code Go en fonction de la façon dont la plupart des bibliothèques standard sont écrites. Vous renoncez également d’essayer d’être intelligent, et vous commencez à écrire du code simple.

Alors, une voix intérieure déclare : Tu ne voulais pas accepter la voie du Go.

Tout commence à avoir un sens.

Sérieusement, l’apprentissage du Go nécessite un peu de désapprentissage. J’ai dû désapprendre un peu la programmation orientée objet, en plus d’accepter le fait que peu importe le nombre d’outils utiles que le langage peut vous donner, écrire du code concurrent est tout simplement trop difficile pour de simples mortels. J’ai aussi dû désapprendre à utiliser des exceptions.

Je n’ai pas vérifié avec les auteurs de Go, donc c’est juste mon opinion, mais je crois que l’objectif du langage est de rendre plus difficile pour les développeurs d’écrire du code complexe. Il vous donne assez de code pour écrire du code qui exécute des tâches complexes, mais en supprimant certains outils clés, le code que vous finissez par écrire est plus simple et plus difficile à gâcher.

Une fois que j’ai décidé d’accepter les fonctionnalités et les structures telles qu’elles sont, écrire du code Go est devenu beaucoup plus facile, et certainement beaucoup plus amusant.

Étape 7 : Vous êtes maintenant en paix

Vous avez accepté la voie du Go. Vous écrivez maintenant tout, y compris ce pour quoi vous auriez normalement utilisé Perl/Ruby/Python, dans Go. Vous réalisez que if err != nil ne vous dérange plus. Vous n’utilisez les goroutines et les canaux que lorsque cela est nécessaire.

Vous ne faites qu’un avec le Gopher (aucune idée comment traduire ce mot). Vous sentez son chi glorieux, et pleurez quand vous vous rendez compte de sa miséricorde pour vous permettre d’écrire du code dans un langage aussi majestueux.

Félicitations. Félicitations. Maintenant vous êtes un programmeur Go.


Même si cela peut sembler un peu ironique, ce sont des problèmes réels que j’ai ressentis ou vécus lorsque je m’habituais à Go. Peut-être que vous êtes d’accord, peut-être que non, mais l’étape 6 s’est vraiment déroulé comme ça pour moi. J’ai finalement renoncé à essayer de faire fonctionner Go comme je le voulais et j’ai décidé d’écrire ce que Go me disait de faire. Ça a l’air idiot, mais après ça, les choses ont vraiment commencé à avoir un sens.

Commentaires : voir le flux atom ouvrir dans le navigateur

par tisaac

LinuxFr.org : les journaux

LinuxFr.org : Journaux

Regata OS 24 “Arctic Fox” avec KDE Plasma 6 et d'autres améliorations

 -  27 mars - 

Regata OS 24 “Arctic Fox” avec KDE Plasma 6 et d'autres améliorationsLa version 24 de Regata OS, baptisée "Arctic Fox", est une distribution basée (...)


Redis Open Source bronsonisé

 -  22 mars - 

Bonjour Nal.Désolé pour ce titre un peu putaclick. Personne n'est décédé cette fois ci.Juste Redis qui change de licence, passant de BSD3 a une (...)


PullRequest d'une application en Rust

 -  16 mars - 

Sommaire Le commencement Description du pool de stockage de BackupPC Le format des fichiers compressés Le format des fichiers d'attributs Le (...)


Jouons un peu avec linuxfr et CSS3

 -  16 mars - 

De temps en temps, j'ai besoin de me détendre, et je joue un peu avec les tech du web, entre deux déploiements.J'aime bien HTML5 et CSS, (...)


Traduction : Payer ne permet pas d'échapper aux monopoles

 -  6 mars - 

Sommaire Contexte Traduction ContexteAyant récemment découvert dans la section liens de LinuxFr le plus récent blog de C. Doctorow, le caractère (...)