« Dis-moi ce que t’aimes bien à propos de Go »
Il y a quelques semaines, on m’a demandé ce que j’aimais bien à propos de Go. C’était pendant un entretien d’embauche et j’ai réalisé sur le moment que je n’avais jamais vraiment songé aux raisons, et cela même si j’utilise Go pour presque tous mes projets depuis un bon bout de temps.
Donc j’y ai réfléchi, et voilà que je l’écris à présent. Je partage mon expérience à partir de deux perspectives :
- le côté développeur : sur le langage Go en lui-même, le tooling et l’écosystème qui va autour, et
- le côté "Ops" : sur le déploiement et la gestion des programmes écrits en Go (peut-être l’aspect qui m’importe le plus).
La perspective Ops
Performance
Pour mes usages et le genre de service que j’écris, Go offre des performances plus que décentes qui me permettent de faire tourner mes programmes sur des petites instances peu coûteuses et des environments serverless contraints (comme AWS Lambda ou Scaleway Serverless Jobs). Pour le serverless, les performances sont importantes car la tarification se fait en fonction du temps d’exécution.
Go n’est peut-être pas aussi performant que Rust ou C++, mais venant d’une expérience Python, Go me semble juste stratosphérique.
Cross-compilation facile
La facilité de déploiement sur une flotte hétérogène présentant plusieurs architectures est importante. J’écris des services qui vont tourner sur le Cloud (en serverless ou en IaaS), sur des serveurs physiques, sur mon laptop ou même sur mon Raspberry Pi 4. Avec l’avènement des serveurs Arm64 (peut-être RISC-V 64 dans le futur ?), j’ai besoin de cross-compiler, que ce soit sur ma machine ou dans ma CI, et ce sans tumutle.
Binaires statiques et conteneurisation
Comme évoqué, certains de mes projets tournent sur des environments hétérogènes. C’est donc tout naturellement que je privilégie les conteneurs pour déployer mes services. Conteneuriser des services en Go est plutôt simple, et comme le code en Go se compile rapidement, les images multi-stages se construisent rapidement également. Avoir des binaires statiques permet de choisir des images de base très légères, comme Alpine Linux, sans se soucier des dépendances à la libc, etc. Mes images sont ainsi légères, faisant quelques dizaines de mégaoctets.
Temps de démarrage
Quand je travaille avec des orchestrateurs comme Kubernetes ou AWS ECS, j’ai besoin de conteneurs qui démarrent vite. Ainsi, roller une nouvelle version du service prend moins de temps, tout comme le scaling out (démarrer plus de conteneurs). Pour les service serverless fonctionnant avec des conteneurs, un temps de démarrage moindre signifie aussi un temps d’exécution réduit, et donc moins de frais.
La perspective développeur
Équilibre bas-niveau / haut-niveau
Avant d’apprendre Go, j’ai fait beaucoup de Python (que j’utilise encore), qui est considéré comme un langage de haut niveau. En comparaison, Go est plutôt bas niveau, mais certainement pas aussi bas niveau qu’un C.
J’aime assez cet équilibre que Go a. Pas trop bas niveau pour ne pas se perdre dans des détails qui n’ont pas d’importance dans ce que je fais ; mais pas non plus trop haut niveau, me laissant ainsi utiliser des primitives telles que les instructions atomiques, ou me laisser contrôler la disposition d’un struct
.
Système de types
Celui-là est très subjectif. J’aime bien les types statiques, je fais souvent des erreurs idiotes évidentes qui sont facilement repérables à la phase de compilation. Go pousse aussi le typage structurel, ce qui m’est plus intuitif à l’usage que le nominal.
Programmation concurrente ergonomique
Cela ne signifie en rien que Go rend la programmation concurrente facile, car la programmation concurrente n’est jamais facile en premier lieu. Mais Go la rend au moins plus agréable, notamment grâce aux goroutines (évitant ainsi le problème des « fonctions colorées » avec l'async
) et les channels (parfois seulement).
Tooling standardisé
Comme pas mal d’autres langages de sa génération, Go vient avec son outil standard pour gérer les packages, lancer les tests, compiler les programmes, formater le code et même microbenchmarquer le code. C’est confortable.
Pas de code pompeux difficile à lire
Go propose essentiellement que des constructions simples. Cela décourage le code golfing et je pense que c’est une bonne chose.
Évidemment Go n’est pas parfait et j’aurais bien des choses à redire à son égard. Par ailleurs, je suis bien conscient que Go n’a pas l’exclusivité sur tous les points que je mentionne. Mais ce billet répond à la question qui m’avait été posé initialement : ce que j’appréciais à propos de Go
J’aimerais terminer sur une observation : je juge assez peu Go-le-langage en tant que tel pour parler beaucoup plus des implications opérationnelles d’un programme écrit en Go. J’aime aussi Go-le-langage, bien-sûr, mais au point où j’en suis aujourd’hui, je remarque que l’expérience Ops demeure l’aspect déterminant dans mon choix de techno, peut-être plus que l’expérience de développement et les qualités intrinsèques du langage.
Crédits
Image du billet : logo officiel de Go, utilisée selon les Brand and Trademark Usage Guidelines.