- Un article où l’auteur explique les limites et les problèmes du langage Go, ressentis après plusieurs années d’utilisation avant de passer à Java
- Il avance l’idée que le caractère simple et ennuyeux (« boring ») de Go peut être non pas un avantage, mais un inconvénient
- Philosophie de Go : l’équipe de conception de Go chez Google a mis l’accent sur la simplicité et les restrictions, mais cela entraîne des tâches répétitives que l’utilisateur doit résoudre lui-même
1. Le fait que Go soit « pas amusant » peut être un défaut
- Argument de Russ Cox :
- Go insiste sur le fait qu’être « boring » est une qualité
- Il n’existe qu’une seule boucle,
for, et des fonctions comme filter, map ou reduce ne sont pas fournies nativement
- L’absence de nombreuses fonctionnalités avancées présentes dans la plupart des autres langages est considérée comme une composante de cette simplicité
- Avis d’un utilisateur Reddit :
- La frontière entre « ennuyeux » et « puissant » est floue
- Il soutient qu’il est probable que les fonctionnalités de base manquantes dans Go soient ajoutées au langage un jour
- Dépendance à des packages tiers :
- Le package
samber/lo, souvent utilisé pour combler ces manques :
- inclut des fonctions essentielles comme filter, map et search
- compte 18.1k étoiles sur GitHub et est utilisé dans plus de 12.6k projets
- Certaines fonctions ont été ajoutées via le package
slices, mais l’ensemble reste encore insuffisant sur le plan fonctionnel
- Frustrations de l’auteur :
- obligation d’écrire des boucles répétitives
- difficulté à traiter de façon concise des opérations comme filter et map
- possibilité d’extraire cela dans des méthodes receiver séparées, mais au détriment de la propreté du code
- La simplicité de Go est souvent un avantage, mais l’absence de fonctions de confort élémentaires peut devenir un défaut en réduisant la productivité et la lisibilité du code
2. Cela nuit aux principes du Clean Code
- Problème de gestion des erreurs :
- La plupart des fonctions incluent
error dans leurs valeurs de retour :
- il faut répéter sans cesse le motif
if err != nil
- en voulant nettoyer le code, on se retrouve au contraire à le complexifier
- Même dans un projet simple, du code de handler HTTP dépasse facilement 20 lignes
- alors que l’objectif initial était de rester autour de 4 lignes
- Frustration telle que l’auteur envisage
panic() avec un middleware de récupération
- Recommandation de noms courts :
- Go recommande des noms courts pour les variables, méthodes et fonctions :
- des noms comme
c ou a ne disent pas clairement ce qu’ils signifient
- par exemple,
c désigne-t-il Command, Controller, Argument ou Amendment ?
- des noms plus longs seraient plus explicites, mais la philosophie de Go préfère les noms courts
- Cela provoque des débats sans fin dans les revues de code d’équipe, y compris sur les noms de méthodes de test
- La philosophie de Go met en avant un code concis et simple, mais peut en pratique aboutir à une complexité et une inefficacité contraires aux principes du clean code
3. Une philosophie de langage volontairement minimal et une culture du DIY
- Fonctionnalités de base insuffisantes :
- Il est facile d’implémenter un handler HTTP simple, mais dès qu’il faut des middlewares de base (par ex. backoff exponentiel, configuration cross-site, etc.), il faut chercher plusieurs packages
- Il est alors difficile d’être sûr que ces packages (1) sont maintenus, (2) fonctionnent comme attendu
- Augmentation du travail répétitif :
- La philosophie de conception de Go, qui cherche à préserver la simplicité, finit paradoxalement par demander aux développeurs de « réinventer la roue »
- Exemple : devoir implémenter soi-même même une simple fonction de filter
- Écosystème de packages encore immature :
- De nombreux projets GitHub sont abandonnés ou n’ont publié que peu de versions
- Le fait que le langage soit relativement jeune rend la comparaison avec .NET/Java potentiellement injuste, mais dans la réalité, la stabilité et la maturité des packages Go restent insuffisantes
- Limites des ORM :
- Le principal package ORM de Go, Gorm, est en retrait fonctionnellement par rapport à Hibernate ou Entity Framework
- Il présente des comportements étranges et une documentation insuffisante
- Réaction de la communauté Go : « Pas besoin d’ORM en Go, Do It Yourself! »
- La simplicité de Go peut être un avantage selon le projet et l’équipe, mais le manque de fonctionnalités fournies en standard peut avoir un effet négatif sur la productivité et l’expérience de développement
4. Il n’existe pas une seule façon de faire en Go
- Malentendu sur la cohérence et l’uniformité :
- Table tests :
- utilisation de suites de test comme
stretchr/testify (employé dans 557k projets)
- écriture de subtests personnalisés à l’intérieur des table tests
- Cela crée un décalage entre la philosophie Go d’une « manière unifiée » et la réalité
- Source de conflits dans les équipes :
- Les discussions sur les styles de test et les façons d’implémenter augmentent au contraire entre équipes
- La philosophie de Go et même son équipe de conception manquent elles-mêmes de cohérence :
- exemple : incohérences sur le nommage des méthodes getter
- Refus de fonctionnalités et dépendance aux packages :
- L’équipe Go refuse d’ajouter des assertions, et est critiquée pour une attitude qui rejette la faute sur l’insuffisance des programmeurs
- Résultat : il faut encore installer un autre package (
go get) pour utiliser la fonctionnalité voulue
- Go vise la simplicité et l’uniformité, mais en pratique plusieurs styles d’implémentation coexistent, et les ambiguïtés de la philosophie de conception aggravent le problème
5. Déboguer en Go n’est pas amusant
- Impossible d’évaluer des expressions pendant le débogage :
- On ne peut pas évaluer une expression ni vérifier la représentation textuelle personnalisée d’un objet pendant une session de débogage
- Il est donc difficile de comprendre clairement l’état d’un objet à l’exécution
- Stack traces et logs peu intuitifs :
- Lorsqu’un gros ensemble de tests échoue (par ex. des milliers de tests exécutés en CI), les stack traces et logs fournis sont confus
- Cela rend le débogage plus difficile et réduit la productivité
- Une expérience de débogage de style C :
- La chaîne d’outils de débogage de Go fonctionne sur une base proche de C :
- elle offre une expérience de débogage primitive, similaire à celle du C
- elle n’est pas pensée pour être conviviale pour les développeurs
- Comparaison avec Rust :
- Rust corrige certaines limites de Go :
- il fournit des informations d’erreur claires et utiles
- ses messages d’erreur incluent des suggestions de correction précises
- L’expérience de débogage en Go repose sur une philosophie de conception axée sur la fourniture de binaires optimisés, mais cela se fait au détriment de l’expérience développeur. Dans des environnements où l’efficacité du débogage compte, envisager un langage alternatif peut être pertinent
Résumé : adéquation et limites de Go
- Avantages des outils intégrés de Go :
- fournit une chaîne d’outils de base pour la gestion des packages, les tests et la supervision des performances
- utilisable sans configuration supplémentaire, ce qui simplifie la mise en place de l’environnement de développement initial
- Limites :
- « Code ennuyeux » et travail répétitif :
- la toolchain de Go est fonctionnelle, mais force à écrire du code répétitif (plumbing code)
- exemple : une syntaxe monotone et des fonctionnalités limitées rendent le travail moins stimulant
import cycle not allowed :
- les dépendances circulaires ne sont pas autorisées dans les tests
- dans un travail orienté Domain-Driven Design (DDD), cette contrainte structurelle augmente la complexité
- Dépendance à l’embarquement de
struct :
- la mécanique d’embarquement de
struct, étrange et limitée, rend son utilisation pénible
- Domaines d’utilisation adaptés :
- adapté au développement d’infrastructure :
- des outils système comme Docker, Drone et Hugo sont écrits en Go
- utile pour développer des serveurs légers et des applications CLI
- Domaines d’utilisation inadaptés :
- développement d’applications d’entreprise complexes (par ex. des systèmes ERP) :
- en raison de sa philosophie de langage limitée et de ses outils, la gestion d’une logique métier à grande échelle y est inefficace
- Go offre une excellente efficacité pour certains usages, notamment liés à l’infrastructure, mais n’est pas un outil adapté aux applications de domaine métier complexes. Même si un CTO est biaisé en faveur de la stack technique de Google, le choix technologique doit rester prudent
5 commentaires
Si seulement Rust avait eu
?, ce serait déjà bien mieux qu’aujourd’hui…En utilisant Go, je me suis rendu compte à quel point je faisais jusque-là de la gestion d’erreurs implicite.
Bien sûr, traiter la gestion des erreurs en un seul point peut sembler plus propre sur le plan structurel, mais j’ai l’impression que le fait de montrer explicitement qu’une opération peut produire une réponse d’erreur pousse à écrire du code de manière plus sûre.
if err != nil {}est honnêtement un peu pénible. Je suis aussi d’accord avec les défauts qui ont été soulignés. Malgré tout, si on comprend clairement ce que ce langage cherche à accomplir et qu’on réfléchit à la manière d’exploiter davantage ses points forts, je pense qu’on peut en faire un meilleur usage malgré ces critiques. C’est un peu comme le C, mais avec un GC, la prise en charge des génériques, même limitée, et en plus la compilation croisée ! Vu comme ça, ce n’est pas aussi un langage plutôt généreux ?Quand je suis passé de Java à Go, j’ai eu l’impression au début de retrouver des sensations similaires.
Maintenant, j’apprécie Go au point de me dire que le temps que j’ai passé sur Java a presque été du gâchis. Dire qu’il ne convient pas aux applications métier complexes me donne surtout l’impression que l’on n’a pas suffisamment réfléchi à la manière de simplifier ces applications.
Avis Hacker News
Des problèmes surviennent quand des développeurs Java imposent un style Java à Go
Beaucoup de développeurs essaient d’abstraire trop tôt
La bibliothèque standard de Go est vaste, mais pas au point de tout couvrir
Il existe des défis plus importants que le choix du langage de programmation
Il est difficile de comprendre pourquoi certains aiment Go
Il est frustrant que l’équipe principale de Go revienne sur de mauvaises décisions
Go a des problèmes comparables à ceux d’UNIX