Chapitre 24
24 - Tendances
> Les tendances actuelles et futures de l'écosystème Go : 2024-2026 et au-delà.
Cours 24 : Tendances de l'écosystème Go
300+ lignes d'analyse des tendances 2024-2026.
1. Go 1.23+ : Range over Func et Iterators
Introduction
Go 1.22 a introduit le range over int, et Go 1.23 a généralisé le range pour fonctionner avec des fonctions itératrices. C'est le changement le plus significatif depuis les generics (Go 1.18).
Syntaxe de base
// Go 1.22 : range over int
for i := range 5 {
fmt.Println(i) // 0, 1, 2, 3, 4
}
// Go 1.23 : range over func (iterators)
for v := range myIterator {
fmt.Println(v)
}
Le package iter
import "iter"
// Un iterateur est une fonction avec cette signature :
// func(yield func(T) bool) bool
// Seq[T] = func(yield func(T) bool) bool
// Seq2[T, U] = func(yield func(T, U) bool) bool
Exemple : Iterateur personnalisé
// Iterateur sur une arborescence
func Walk(root *Node) iter.Seq[*Node] {
return func(yield func(*Node) bool) {
var walk func(*Node) bool
walk = func(n *Node) bool {
if n == nil {
return true
}
if !yield(n) {
return false
}
if !walk(n.Left) {
return false
}
return walk(n.Right)
}
walk(root)
}
}
// Usage
for node := range Walk(root) {
fmt.Println(node.Value)
}
Exemple : Pagination
func Paginate[T any](items []T, pageSize int) iter.Seq2[int, []T] {
return func(yield func(int, []T) bool) {
for i := 0; i < len(items); i += pageSize {
end := i + pageSize
if end > len(items) {
end = len(items)
}
if !yield(i/pageSize, items[i:end]) {
return
}
}
}
}
// Usage
for page, items := range Paginate(allItems, 20) {
fmt.Printf("Page %d: %v\n", page, items)
}
Standard library avec iterators
// maps.All, maps.Keys, maps.Values
for k, v := range maps.All(myMap) {
fmt.Println(k, v)
}
// slices.All, slices.Values, slices.Backward
for i, v := range slices.All(mySlice) {
fmt.Println(i, v)
}
for v := range slices.Backward(mySlice) {
// Itération inverse
}
Impact
- + Performances : les itérateurs sont paresseux (lazy), pas d'allocation intermédiaire
- + Expressivité : code plus déclaratif
- + Compatibilité : toutes les bibliothèques peuvent exposer des iterators
- - Complexité : la signature
func(yield func(T) bool) boolest intimidante
Limitations
- Pas de
breakoucontinuepersonnalisés dans l'iterateur (le yield retourne false pour break) - Pas de try-catch dans l'iterateur
- Les iterators ne sont pas des types de première classe (pas de stockage dans une variable)
2. WebAssembly (WASM)
État actuel
Go compile en WASM depuis Go 1.11 (2018). Aujourd'hui, le support est mature, avec des améliorations significatives :
| Version | Amélioration |
|---|---|
| Go 1.11 | Support WASM initial (js/wasm) |
| Go 1.19 | WebAssembly System Interface (WASI) preview 1 |
| Go 1.21 | Améliorations WASI |
| Go 1.23 | WASI preview 2 support, meilleure performance |
Exemple : Application WASM
package main
import (
"syscall/js"
)
func main() {
c := make(chan struct{}, 0)
js.Global().Set("compute", js.FuncOf(compute))
<-c
}
func compute(this js.Value, args []js.Value) interface{} {
input := args[0].String()
result := process(input)
return js.ValueOf(result)
}
Build WASM
# Pour navigateur (js/wasm)
GOOS=js GOARCH=wasm go build -o main.wasm main.go
# Pour edge runtime (WASI)
GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
Cas d'usage
- Edge Computing : Cloudflare Workers, Fastly Compute, Fermyon Spin
- Plugin Systems : exécution de code utilisateur dans un sandbox
- Frontend : avec Vue.js/React via des frameworks comme Vugu
- Serverless : fonctions serverless en Go compilées en WASM
- IoT : exécution de code Go sur des devices contraints
Frameworks WASM pour Go
| Framework | Description |
|---|---|
| Vugu | Composants web en Go (similaire à Vue.js) |
| Gio | UI multiplateforme (mobile, desktop, web) |
| TinyGo | Compilateur pour petits devices (WASM friendly) |
| Wazero | Runtime WASM zero-dependency en Go |
Limitations actuelles
- Taille du binaire (~10MB pour une app simple)
- Pas de goroutines en WASI (GOOS=wasip1)
- Pas d'accès complet au système (système de fichiers, réseau)
- Performance inférieure au natif
3. AI/ML avec Go
Positionnement de Go dans l'écosystème AI
Go n'est pas un langage de training ML (Python domine), mais il excelle dans l'infrastructure autour du ML :
Python (Training) -------> ONNX/TensorRT -------> Go (Serving)
│ │
│ Data pipelines │ API
│ Feature stores │ Scaling
│ ETL │ Monitoring
▼ ▼
[Python tools] [Go services]
Bibliothèques ML en Go
// goml : bibliothèque ML en Go pur
import "github.com/cdipaolo/goml"
// Gorgonia : réseau de neurones (comme PyTorch)
import "gorgonia.org/gorgonia"
import "gorgonia.org/tensor"
// OpenCV : vision par ordinateur
import "gocv.io/x/gocv"
// ONNX Runtime : inférence ONNX
import "github.com/yalue/onnxruntime_go"
Exemple : Inférence ONNX en Go
package main
import (
"github.com/yalue/onnxruntime_go"
)
func main() {
// Charger un modèle ONNX exporté depuis Python
rt, _ := onnxruntime_go.NewRuntime()
defer rt.Close()
inputTensor, _ := onnxruntime_go.NewTensor(...)
outputTensor, _ := onnxruntime_go.NewEmptyTensor(...)
session, _ := onnxruntime_go.NewSession("model.onnx", input, output)
defer session.Destroy()
session.Run()
result := outputTensor.GetData()
}
Go dans les data pipelines
// Pipeline feature engineering avec Go
type FeaturePipeline struct {
transformers []Transformer
}
type Transformer interface {
Transform(ctx context.Context, data []Record) ([]Feature, error)
}
// Ce pattern est très utilisé dans des outils comme
// Feast (feature store) écrit en Go
Tendances AI/Go 2025-2026
-
Model serving : Go est le langage dominant pour servir des modèles ML en production
- TensorFlow Serving (C++, bindings Go)
- TorchServe (Java, mais alternative Go : Cortex)
- Custom inference servers en Go
-
Vector databases : Go utilisé dans Milvus, Weaviate, Qdrant
-
RAG (Retrieval-Augmented Generation) : Go pour les pipelines de retrieval
- Embeddings, vector search, reranking
-
Feature stores : Feast (Go), Tecton
-
Data engineering : Go pour les pipelines ETL haute performance
Limitations
- Pas de GPU computing natif (CUDA via CGO)
- Écosystème ML moins riche que Python
- Pas de Jupyter Notebook-like pour l'exploration
- Communauté ML plus petite
4. Go Generics Adoption
État des lieux (2026)
Les generics (Go 1.18, 2022) sont maintenant largement adoptés :
- 2022 : adoption prudente, bugs, limitations
- 2023 : adoption croissante dans les bibliothèques
- 2024 : maturité, la plupart des nouvelles bibliothèques utilisent les generics
- 2025-2026 : standard de facto
Patterns de generics adoptés
// 1. Conteneurs typés (Stack, Queue, Cache)
type Stack[T any] struct { ... }
// 2. Higher-order functions (Map, Filter, Reduce)
func Map[T, U any](s []T, f func(T) U) []U { ... }
// 3. Repository pattern
type Repository[T, ID comparable] interface {
Get(ctx context.Context, id ID) (*T, error)
Create(ctx context.Context, entity *T) error
Update(ctx context.Context, entity *T) error
Delete(ctx context.Context, id ID) error
}
// 4. Type-safe builders
type Option[T any] func(*T)
// 5. Sum types (discriminated unions) avec generics
type Result[T any] struct {
Value T
Err error
}
Impact sur la stdlib
// Avant (interfaces + assertions)
sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
// Après (si stdlib évolue - proposition)
slices.SortFunc(s, func(a, b T) int { return cmp.Compare(a, b) })
Limitations persistantes
- Méthodes génériques : toujours pas possible (seuls les types peuvent avoir des params)
- Performance : monomorphisation augmente la taille du binaire
- Complexité : les signatures avec des contraintes complexes sont dures à lire
- Interopérabilité : une
Stack[int]et uneStack[string]sont des types différents
Prédictions
- Constraint inference améliorée
- Méthodes génériques (Go 2.0?)
- Meilleure intégration avec les interfaces
- Adoption massive dans les ORM (gorm v3+)
5. Framework Evolution
Le retour du stdlib
Tendance forte : les frameworks "batteries-included" (Gin, Echo, Fiber) perdent du terrain face au stdlib enrichi.
Avant (2015-2020) :
// Nécessité d'un framework pour le routage
r := gin.Default()
r.GET("/api/users", handler)
Après (2024+) :
// Go 1.22+ : routage avancé dans le stdlib
mux.HandleFunc("GET /api/users/{id}", handler)
id := r.PathValue("id")
Évolution des frameworks
| Framework | Tendance | Raison |
|---|---|---|
| chi | Stable | Routage simple, middleware |
| Gin | Stable | Performance, grande communauté |
| Fiber | Stable | Express-like, performance |
| Echo | Stable | Middleware, documentation |
| gorilla/mux | Archive | Abandonné, plus maintenu |
| stdlib | Croissance | Go 1.22+ routage amélioré |
Nouveaux venus
// Huma : API REST avec OpenAPI généré
import "github.com/danielgtaylor/huma/v2"
type GreetingInput struct {
Name string `path:"name"`
}
type GreetingOutput struct {
Message string `json:"message"`
}
huma.Get(api, "/greeting/{name}", func(ctx context.Context, input *GreetingInput) (*GreetingOutput, error) {
return &GreetingOutput{Message: fmt.Sprintf("Hello, %s!", input.Name)}, nil
})
Connect (gRPC + HTTP)
// Connect : Unifie gRPC et HTTP
import "connectrpc.com/connect"
greetClient := greetv1connect.NewGreetServiceClient(httpClient, baseURL)
greetResponse, err := greetClient.Greet(ctx, connect.NewRequest(&greetv1.GreetRequest{
Name: "Jane",
}))
Tendances frameworks
- API-first avec génération automatique de clients (Connect, Huma)
- OpenAPI intégrée : spécification générée depuis le code
- Déclin des mega-frameworks : préférence pour des bibliothèques composables
- Type-safe routing : paramètres de route typés
6. Go in Embedded
TinyGo : le compilateur pour l'embarqué
// Clignotement de LED avec TinyGo
package main
import (
"machine"
"time"
)
func main() {
led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
for {
led.High()
time.Sleep(time.Millisecond * 500)
led.Low()
time.Sleep(time.Millisecond * 500)
}
}
Compilation :
tinygo build -target=arduino-nano33 -o firmware.hex main.go
Plateformes supportées
| Plateforme | Microcontrôleur | RAM |
|---|---|---|
| Arduino | ATmega328P | 2KB |
| ESP32 | Xtensa LX6 | 520KB |
| Raspberry Pi Pico | RP2040 | 264KB |
| STM32 | ARM Cortex-M | 20KB-2MB |
| nRF52 | ARM Cortex-M4 | 64KB-256KB |
Cas d'usage concrets
- IoT Sensors : collecte de données environnementales
- Edge Computing : processing local avant envoi cloud
- Drone controllers : vol stationnaire et navigation
- Smart home : domotique avec MQTT
- Robotics : contrôle de moteurs
Limitations
- Go standard nécessite un OS (pas de bare metal)
- TinyGo supporte un sous-ensemble du langage (pas de reflect, unsafe limité)
- Pas de goroutines sur les très petits devices
- Taille de binaire plus grande que C
7. Go 2.0 : Spéculations
Timeline probable
2024-2025 : Go 1.23, 1.24 (features incrémentales)
2025-2026 : Go 1.25, 1.26 (préparation Go 2.0)
2026-2027 : Go 2.0 annoncé (ou renommé)
2027-2028 : Go 2.0 released
Features potentielles
-
Generics improvements :
- Méthodes génériques
- Covariance/contravariance
- Better type inference
-
Error handling :
try/handleproposé (mais controversé)?operator pour propager les erreurs- Meilleure ergonomie
-
Pattern matching :
- Match expressions
- Destructuring
- Type patterns enrichis
-
Immutabilité :
constpour les variables- Immutable structs
- Valeurs défensives
-
Modules v2 :
- Meilleure résolution des dépendances
- Registry privé
- Build reproducibility améliorée
Défis
- Backward compatibility : la promesse Go 1.x
- Complexity budget : ne pas devenir Java
- Tooling : tout l'écosystème à mettre à jour
La philosophie Go 2.0
D'après les talks de Russ Cox (GopherCon 2023, 2024) :
"Go 2.0 n'est pas une réécriture, c'est une évolution. Nous voulons préserver ce qui rend Go génial : la simplicité, la productivité, et la performance."
Principes :
- Go 1.x continue d'être supporté
- Migration automatique (go fix)
- Pas de breaking changes sans nécessité absolue
- Chaque feature doit simplifier plus qu'elle ne complexifie
Ce qui ne changera PAS
- Goroutines et channels (modèle CSP)
- Interfaces structurelles (duck typing)
- Compilation rapide
- Binaire statique unique
- Garbage collector concurrent
gofmtstandardisation- Pas de classes/héritage
Résumé des tendances
| Tendance | Impact | Quand | Recommandation |
|---|---|---|---|
| Iterators | ★★★★★ | 2024-2025 | Adopter immédiatement |
| Generics | ★★★★ | 2023-2026 | Adopter pour les conteneurs |
| WASM | ★★★ | 2023-2027 | Surveiller, adopter pour edge |
| AI/ML serving | ★★★★ | 2024-2026 | Adopter pour l'infra ML |
| Stdlib renaissance | ★★★★ | 2023-2025 | Réduire les dépendances |
| Embedded (TinyGo) | ★★★ | 2024-2028 | Surveiller, cas spécifique |
| Go 2.0 | ★★ | 2026-2028 | Pas de décision urgente |
Conseils pour rester à jour
- Suivre le Go Blog : chaque release a un article détaillé
- GopherCon talks : YouTube, slides
- Go Release Notes : lisez chaque release notes
- Contributeur à un projet Go : meilleur moyen de suivre
- GoTip : newsletter, issues GitHub
Les 5 choses à retenir
- Les iterators changent la donne : adoptez-les dans vos APIs
- Le stdlib est suffisant : avant d'ajouter une dépendance, vérifiez si le stdlib ne fait pas le job
- Go + Cloud = dominant : serveurs, microservices, edge
- Go + AI = infrastructure : model serving, data pipelines
- Go évolue, mais ne change pas : la philosophie reste la même