- La commande
go fix entièrement réécrite est introduite dans Go 1.26 et permet d’améliorer automatiquement le code afin d’exploiter les fonctionnalités les plus récentes du langage et des bibliothèques
- L’outil détecte des motifs de code via des dizaines d’analyseurs (analyzers) et applique divers modernizers comme
minmax, rangeint et stringscut pour transformer du code répétitif ou obsolète en formes plus modernes
- Pour prendre en charge la nouvelle fonctionnalité
new(expr), un analyseur newexpr a été ajouté afin de simplifier automatiquement des fonctions utilitaires comme newInt
go fix produit un effet de synergie lorsqu’il est exécuté plusieurs fois : différents analyseurs peuvent proposer des améliorations successives, avec fusion automatique en cas de conflit et suppression des imports inutiles
- L’équipe Go prévoit à l’avenir d’étendre l’outil via un paradigme d’analyse « libre-service » (Self-service), afin de permettre aux développeurs de définir et diffuser des modernizers pour leurs propres API
Aperçu de la commande go fix
- Dans Go 1.26,
go fix a été entièrement réimplémenté pour fournir une conversion automatique des bases de code vers un style Go moderne
- La commande
go fix ./... modifie tous les packages sous le répertoire courant
- L’option
-diff permet de prévisualiser les changements
- La liste des analyseurs enregistrés peut être consultée avec
go tool fix help, avec diverses règles de transformation comme any, forvar, mapsloop, minmax, etc.
- Pour exécuter un seul analyseur, utilisez un drapeau comme
-any ; pour l’exclure, indiquez -any=false
- En tenant compte des différences de code selon la plateforme, il peut être exécuté plusieurs fois pour différentes combinaisons
GOOS, GOARCH
Modernizers — outils de modernisation du code
- Depuis Go 1.18, l’introduction des génériques a fortement accru les possibilités de simplification du code
- Exemples : collecte des clés d’une map avec
maps.Keys, séparation de chaînes avec strings.Cut
- Pour corriger le fait que les outils de génération de code basés sur les LLM conservent souvent des motifs obsolètes, l’article souligne la nécessité de mettre à jour le code open source avec les idiomes Go les plus récents
- Les modernizers inclus dans
go fix et gopls améliorent la lisibilité du code et son intérêt pédagogique
- Exemples de modernizers :
- minmax : remplace une instruction
if par les fonctions min/max
- rangeint : convertit une boucle
for à 3 clauses en range-over-int
- stringscut : simplifie du code basé sur
strings.Index en utilisant strings.Cut
La fonctionnalité new(expr) de Go 1.26
- La fonction
new est étendue pour accepter un argument de valeur, permettant une initialisation sous la forme new("go1.26")
- L’analyseur
newexpr repère des fonctions utilitaires comme newInt, les simplifie en return new(x), puis remplace les appels par new(expr)
- Cette transformation n’est appliquée que si la version minimale de Go est satisfaite (par exemple avec la directive
go 1.26)
- Elle peut être appliquée à toute la base de code via la commande
$ go fix -newexpr ./...
- Après usage, les fonctions utilitaires devenues inutiles peuvent être identifiées avec l’outil
deadcode
Synergie et gestion des conflits
- Une modification peut créer un effet de synergie en ouvrant la voie à d’autres corrections
- Exemple : après application de
minmax, des transformations supplémentaires peuvent être proposées
- Une optimisation en chaîne peut aller de
stringsbuilder vers fmt.Fprintf
go fix utilise un algorithme de fusion à 3 voies pour fusionner automatiquement les conflits de modification
- En cas de conflit syntaxique, la modification concernée est ignorée et un avertissement est affiché
- Les conflits sémantiques (par ex. suppression de variable, import non utilisé) nécessitent un ajustement manuel
- Les imports inutiles sont supprimés automatiquement
Intégration avec le framework d’analyse Go
go vet et go fix sont intégrés pour partager un framework d’analyse commun
vet se concentre sur la détection d’erreurs, fix sur les corrections automatiques sûres
- Les analyseurs peuvent être exécutés dans divers drivers comme
unitchecker, multichecker, gopls, staticcheck et Tricorder
- Le système de facts permet de partager des informations entre packages
- Exemple : déduire que
log.Printf est un wrapper de fmt.Printf
gopls fournit des diagnostics en temps réel et des propositions de correction automatique
Améliorations de l’infrastructure d’analyse
- L’extension du package inspector améliore l’efficacité de parcours de l’AST, avec un type
Cursor permettant une navigation haut/bas/gauche/droite
- L’indexation des appels de fonction via typeindex peut accélérer l’analyse jusqu’à 1000 fois
- Autres améliorations :
- fourniture du graphe de dépendances de la bibliothèque standard
- prise en charge de requêtes de version Go par fichier
- enrichissement des primitives de refactoring pour des modifications sûres du code, comme la mise en commentaire
- Certains modernizers sont exclus en raison de changements de comportement subtils (cas
append([]string{}, slice...) → slices.Clone(slice))
- Sont également prévus : un moteur de pattern matching, un harnais de test automatisé et une bibliothèque d’opérateurs de correction précis
Paradigme Self-service
- À partir de Go 1.26, l’introduction d’un modèle d’analyse en libre-service est annoncée
- Les développeurs pourront définir et distribuer des modernizers pour leurs propres API
- Ils pourront être exécutés au niveau du projet sans procédure d’approbation centralisée
- En première étape, une fonctionnalité d’inliner piloté par annotations est incluse en aperçu
- Feuille de route :
- exécution d’analyseurs personnalisés via chargement dynamique (dans
go fix ou gopls)
- généralisation des vérifications basées sur le flux de contrôle, par exemple vérifier des invariants comme « open puis close » ou « lock puis unlock »
- L’objectif est d’améliorer l’efficacité de maintenance et de favoriser l’adoption rapide des fonctionnalités Go les plus récentes
1 commentaires
Commentaires sur Hacker News
Fin 2024, quand les assistants de code LLM se sont rapidement généralisés, il était frappant de voir que ces outils tendaient à reproduire tels quels les styles de code Go existants présents dans leurs données d’entraînement
Même en leur demandant d’utiliser la syntaxe la plus récente, ils l’ignoraient, voire niaient parfois qu’elle existait
Pour que les futurs modèles reflètent les idiomes de Go 1.25 les plus récents, il faudra que l’ensemble du code open source soit mis à jour dans ce style
magic_quotes)Mais avec les LLM, une fois que de mauvaises données sont intégrées, il est presque impossible de les corriger
Il est difficile de retracer sur quelle base le modèle a tiré sa conclusion, et il ne reste qu’à espérer que ce soit corrigé dans la génération suivante
Il a l’air simple et passe les revues, mais en réalité il lui manque la gestion des erreurs et les cas limites
Si on le redonne au LLM après revue, il produit un code qui semble corrigé, mais qui introduit en fait des data races ou des deadlocks
C’est un problème qui se répète avec presque tous les modèles
Go compile grâce à sa bonne rétrocompatibilité, mais le style de code devient très différent
En Python, les changements d’API provoquent de vraies ruptures de compatibilité
Malgré cela, Go reste un excellent langage pour la génération de code grâce à sa stabilité et à sa bibliothèque standard
Comme l’avait averti Rob Pike, cette technologie est une pollution de l’écosystème logiciel
Beaucoup de gens veulent ce slop de la “commodité”, mais c’est précisément là le fond du problème
Un outil capable de convertir automatiquement du code source vers le style le plus récent est vraiment formidable
OpenRewrite pour Java est l’exemple le plus connu, mais on pense difficilement à des équivalents dans d’autres langages
Quand cette capacité est intégrée au langage comme en Go, cela fait énormément progresser sa maturité
Les nouveaux langages s’inspireront probablement de cette approche intégrée de Go
Les IDE JetBrains peuvent refactorer des millions de lignes d’un coup ou convertir automatiquement vers une nouvelle syntaxe
Il existe aussi des fonctions comme ConvertToPrimaryConstructor
Et Structural Search and Replace travaille au niveau de la syntaxe du langage, pas seulement du texte
Les analyseurs Roslyn de .NET proposent eux aussi des suggestions de correction dans l’IDE
Lien vers le tutoriel
Grâce à lui, le code est devenu bien plus propre
Il remplace
concatetmapparconcatMap, ou simplifie des expressionsifinutilesLes serveurs LSP sont limités, et ne prennent même pas en charge des refactorings de base comme la suppression d’arguments
Je me demande si une combinaison de jscodeshift et Claude pourrait faire l’affaire
Grâce à ce type d’outil de correction automatique (
go fix), Go est vraiment un langage remarquableJe me réjouis aussi de voir la nouvelle fonctionnalité rangeint être intégrée automatiquement via
go fixBravo à l’équipe Go
Même la vitesse de compilation est incroyablement rapide
foravec des regex, mais cet outil le fait maintenant de façon bien plus éléganteCe n’est pas mentionné dans l’article, mais ma fonctionnalité préférée est la directive
//go:fix inlineElle permet d’inliner une fonction d’une seule ligne directement dans l’appelant
Cela permet aux auteurs de bibliothèques de migrer automatiquement et en douceur les anciennes fonctions vers les nouvelles
Même si la version semver change, une mise à niveau automatique reste possible avec
go fixDans un récent podcast avec Wes McKinney,
il disait que Go est idéal pour les agents de code grâce à son cycle compilation-exécution rapide, son système de types fort et sa stabilité en multithreading
Cela m’a redonné envie de m’intéresser à Go
L’outillage et les conventions bien établies de Go sont une grande aide pour le développement piloté par agents
On peut lancer immédiatement l’environnement de dev avec
go run main.go, tout en gérant plusieurs worktrees, une configuration centrale et même une base de données migréehousecat-inc/cheetah partage ce type d’outil
J’envisage d’ajouter
go fixà cette boucle rapide qui inclut déjàgo generate,go build,go testetgo vetEn apprenant Python, j’ai trouvé qu’il y avait bien trop de façons différentes de faire la même chose, sans vraie cohérence
J’en suis presque venu à regretter C, où il n’y a qu’une seule façon de faire
Je me demande si Go est arrivé à ce stade
Je voudrais savoir si c’est un langage où l’on peut suivre les bonnes pratiques sans l’aide d’un LLM
Il est frappant de voir les efforts faits pour éviter la complexité et préserver la simplicité
Je le recommande à ceux qui sont fatigués de la confusion de Python
Le concept d’analyseur en self-service est vraiment intéressant
J’ai l’impression qu’il sera largement adopté par les grandes bibliothèques ou les équipes infrastructure
Avec un tel outil, on se demande si même des langages sans rétrocompatibilité ne pourraient pas devenir viables
Dans l’écosystème TypeScript, biome joue ce rôle
Par exemple, il recommande
for...ofà la place deforEach, et utilisé avec ultracite, le workflow devient bien plus fluideJ’ai indiqué dans le fichier
agents.mdqu’il faut exécuter biome fix après les modifications, ce qui permet de maintenir automatiquement la qualité du codeC’est une expérience bien plus légère et efficace qu’avec eslint