T13 · Extensibilité et invention des langages  ·  Chapitre 2 / 11

Concevoir un langage extensible

Trois couches, une seule discipline

La première erreur quand on parle de concevoir un langage, c'est de commencer par la syntaxe. Je comprends pourquoi — la syntaxe est ce que les développeurs voient, ce qu'ils écrivent, ce qui leur donne l'impression immédiate de tenir quelque chose de concret. Mais concevoir un langage en partant de la syntaxe, c'est construire une maison en commençant par les rideaux. La syntaxe est la surface. Ce qui compte, c'est ce qu'elle recouvre.

Quand j'ai commencé à concevoir C% et CXML, j'ai passé les premières semaines à ne pas écrire une seule ligne de grammaire. J'ai cartographié les opérations sémantiques que le système devait pouvoir exprimer. J'ai modélisé le runtime — comment les instructions devaient circuler, être interprétées, transformées en actions concrètes. Ce n'est qu'après avoir stabilisé ces deux couches que la syntaxe a émergé naturellement — comme la forme extérieure d'une architecture intérieure déjà cohérente.

Un langage bien conçu est le résultat d'une pensée en trois couches. Manquer l'une d'entre elles, ou les confondre, produit un langage qui ne vieillit pas bien.


Les trois couches fondamentales

Chaque langage — qu'il soit général ou spécialisé, interprété ou compilé, déclaratif ou impératif — repose sur trois strates distinctes. Ces strates ne sont pas indépendantes, mais elles ont chacune leur propre logique d'évolution. Un langage extensible est un langage dont chaque strate peut évoluer sans forcer les deux autres à rompre.

Couche 01
Syntaxe
Ce que l'on écrit
L'interface humaine du langage. Les mots-clés, les opérateurs, la structure des expressions. Elle doit être lisible, cohérente, mémorisable — mais elle n'est que la forme d'une substance plus profonde.
CAKE → CXML balises · C% mots-clés · CakeLang tokens
Couche 02
Sémantique
Ce que cela signifie
Le contrat de sens derrière chaque construction syntaxique. C'est ici que réside la vraie puissance d'un langage extensible : une sémantique ouverte permet d'introduire de nouvelles instructions sans redéfinir le cœur du langage.
CAKE → 214 opcodes · sémantique déclarative · contrats CXML
Couche 03
Runtime
Ce qui exécute réellement
Le moteur qui traduit les intentions sémantiques en actions concrètes. Dans un langage extensible, le runtime peut charger de nouveaux modules, intégrer de nouveaux moteurs, interpréter de nouvelles instructions — sans être réécrit.
CAKE → pipeline 7 étapes · 13 Controllers · runtimes déclarables

La sémantique est surlignée ici délibérément — c'est la couche la plus souvent négligée dans les projets de DSL. On investit dans une belle syntaxe, on câble un runtime fonctionnel, et on laisse la sémantique émerger de façon ad hoc. Le résultat est un langage dont le comportement est difficile à prédire, dont les cas limites ne sont pas documentés, et dont l'extension future devient un exercice d'archéologie de code.


La sémantique ouverte — le secret de la longévité

Un langage à syntaxe fixe mais sémantique ouverte peut évoluer pendant des décennies sans rupture. C'est le secret de la longévité de Lisp — sa syntaxe est minimaliste au point d'en être presque absente, mais sa sémantique est extensible à l'infini via les macros. C'est aussi le principe que j'ai appliqué dans C% : la syntaxe de base est petite et stable, mais le registre sémantique peut accueillir de nouveaux opcodes sans perturber les instructions existantes.

Cette distinction a des conséquences pratiques immédiates. Quand CAKE a intégré le support de l'AudioKit, je n'ai pas modifié la grammaire de C%. J'ai étendu le registre sémantique avec de nouveaux opcodes audio — et la syntaxe existante les a naturellement accueillis, parce qu'elle avait été conçue pour rester agnostique au contenu sémantique.

Un langage dont la sémantique est fermée est un langage qui a déjà choisi ses limites. Il peut être parfait pour ce qu'il fait aujourd'hui — et parfaitement inadapté à ce qu'on lui demandera demain. Concevoir une sémantique ouverte, c'est refuser de décider aujourd'hui des questions que le système posera dans dix ans. — Sébastien Roy, CEO Unibool Inc.

Le spectre de l'extensibilité — où se situe CAKE

Tous les langages ne sont pas extensibles au même degré. Il existe un spectre — depuis les langages totalement fermés, dont la spécification est fixée une fois pour toutes, jusqu'aux langages homoïconiques comme Lisp où le programme peut modifier sa propre grammaire à l'exécution. CAKE se positionne délibérément entre ces extrêmes — extensible dans sa sémantique et son runtime, stable dans sa syntaxe fondamentale.

Spectre d'extensibilité — positionnement comparatif
Langages fixes
syntaxe · sémantique · runtime figés
C classique, COBOL — stabilité maximale, évolution impossible sans rupture majeure.
Extensibles par bibliothèques
sémantique partielle
Java, Python — nouvelle fonctionnalité via packages, mais la sémantique du noyau reste fermée.
CAKE / C%
sémantique + runtime ouverts
Syntaxe stable, registre sémantique extensible, runtime déclarable. Évolution sans rupture, gouvernance maintenue.
Homoïconiques
tout ouvert
Lisp, Racket — puissance maximale, complexité de gouvernance maximale. Le programme peut se réécrire lui-même.

Ce positionnement n'est pas un compromis par défaut — c'est une décision architecturale consciente. La syntaxe de C% est stable parce que la stabilité syntaxique réduit le coût cognitif pour les développeurs qui l'utilisent. La sémantique est ouverte parce que les domaines évoluent et que le langage doit pouvoir suivre. Le runtime est déclarable parce que les besoins d'exécution varient selon les contextes et ne peuvent pas être anticipés à la conception.


Les langages comme modules — l'architecture CAKE

Dans une architecture modulaire, les langages ne sont plus des monolithes. Ils deviennent des composants — chacun avec son interface déclarée, son cycle de vie géré, sa capacité à être remplacé sans faire tomber le reste du système. CAKE pousse cette idée jusqu'à sa conclusion logique : le système lui-même est un orchestrateur de langages, pas un langage unique qui prétend tout faire.

Cela signifie que C% peut introduire de nouvelles syntaxes spécialisées sans toucher à son noyau. Que CXML peut évoluer dans ses capacités de représentation sans invalider les documents existants. Que les DSL de domaine peuvent naître, mûrir et être retirés proprement — parce que le système a été conçu dès le départ pour accueillir cette fluidité.

L'extensibilité n'est pas une fonctionnalité qu'on ajoute après. C'est une posture architecturale qu'on adopte avant d'écrire la première ligne. Et cette posture commence par comprendre que syntax, sémantique et runtime sont trois conversations différentes — qui méritent chacune d'être menée avec la rigueur qu'elle exige.


Principe clé — Chapitre 2

Un langage extensible n'est pas un langage avec plus de fonctionnalités. C'est un langage dont les trois couches fondamentales — syntaxe, sémantique, runtime — ont été conçues pour évoluer indépendamment, sans que l'évolution de l'une ne force la rupture des deux autres.

La syntaxe attire. La sémantique engage. Le runtime tient la promesse.

← Chapitre précédent C01 · Introduction à l'extensibilité
T13C02 · 37%
Chapitre suivant → C03 · Les DSL spécialisés
Auteur  ·  Sébastien Roy  ·  CEO, Unibool Inc.  ·  Canada  ·  Édition 2026