Il existe un seuil dans l'évolution d'un architecte de systèmes — un moment précis où l'on réalise que la vraie puissance n'est pas d'écrire un meilleur langage, mais d'écrire un système capable d'en écrire d'autres. Ce seuil, je l'ai franchi en construisant le moteur de génération de CAKE. Ce jour-là, ma conception du logiciel a changé de manière irréversible.
Les langages classiques sont des réponses figées à des questions connues. On les conçoit en anticipant les besoins, en définissant une syntaxe, en stabilisant une sémantique. C'est du travail d'orfèvre — minutieux, raisonné, définitif. Mais que se passe-t-il quand les questions ne sont pas encore formulées ? Quand le domaine évolue plus vite que le langage qui le sert ? Quand chaque équipe, chaque contexte, chaque projet mérite ses propres constructs ?
La réponse de CAKE n'est pas de concevoir un langage plus grand. C'est de concevoir un générateur de langages — un système qui observe un domaine et produit le langage qui lui correspond.
Les macros, les plugins, les bibliothèques — ce sont des formes d'extension superficielle. Elles ajoutent des mots à un vocabulaire existant, mais elles ne changent pas la grammaire. Le langage sous-jacent reste le même, avec ses contraintes, ses idiomes, ses limitations inhérentes.
La génération dynamique de langages va plus loin. Elle permet de définir non seulement de nouvelles instructions, mais de nouvelles règles d'interprétation. De nouveaux modèles d'exécution. De nouvelles sémantiques. C'est la différence entre ajouter un mot à une langue et inventer une nouvelle façon de construire des phrases.
Dans CAKE, cette capacité est ancrée dans le cœur du système via le moteur C% et la couche CXML. Ces deux composants ne sont pas des langages finis — ce sont des infrastructures de langage. Des fondations sur lesquelles de nouveaux dialectes peuvent être construits, validés et connectés à des runtimes spécialisés sans toucher au pipeline central.
Un moteur générateur n'est pas magique. Il est le produit d'une discipline architecturale rigoureuse — la capacité à décomposer un langage en ses constituants fondamentaux et à rendre chacun de ces constituants programmable.
Ce processus peut sembler complexe décrit ainsi. En pratique, pour un développeur CAKE, il ressemble à ceci :
Quatre lignes de déclaration. Un langage spécialisé entier, connecté à son runtime, validé par son schéma, intégré dans l'infrastructure CAKE. C'est ce que j'entends par réduction de la complexité accidentelle — le développeur exprime l'intention, le système fait le travail de tuyauterie.
La conséquence la plus profonde de la génération dynamique de langages, c'est qu'elle transforme la nature même du développement. Dans un système ordinaire, un développeur adapte son code au langage disponible. Dans un système comme CAKE, le développeur peut adapter le langage au problème. Ce renversement est fondamental.
Cela signifie que la complexité du code diminue — non pas parce qu'on a simplifié le problème, mais parce qu'on a élevé le niveau d'abstraction jusqu'à ce que le code et le domaine parlent le même langage. Un DSL pour la gestion audio ressemble à de l'audio. Un DSL pour l'orchestration de pipelines ressemble à de la logique d'orchestration. Le fossé entre intention et implémentation se réduit.
Le signe d'un bon DSL, c'est quand un expert du domaine — quelqu'un qui ne sait pas programmer — peut lire le code et comprendre ce qu'il fait. Ce n'est pas de la simplification. C'est de la précision à un niveau d'abstraction plus élevé. — Sébastien Roy, CEO Unibool Inc.
Quand j'ai présenté CAKE pour la première fois, les développeurs voyaient un framework. Un système d'orchestration, peut-être. Certains voyaient un méta-langage. Mais très peu voyaient immédiatement ce que je voyais : une fonderie de langages.
CAKE n'est pas conçu pour être le langage ultime — celui qui répondrait à tous les besoins. Cette ambition est stérile. CAKE est conçu pour être le système à partir duquel des langages ciblés, évolutifs, gouvernés peuvent être produits rapidement, déployés avec confiance, et retirés proprement quand leur utilité est épuisée.
C'est une vision différente de celle des grandes plateformes monolithiques. Moins spectaculaire en apparence. Infiniment plus puissante en pratique — parce qu'elle reconnaît une vérité simple : aucun langage unique ne peut être optimal pour tous les contextes. La bonne réponse n'est pas un meilleur langage universel. C'est la capacité à produire le bon langage au bon moment.
Un système extensible ne se contente pas d'accueillir des langages existants. Au sommet de sa maturité, il devient capable d'en produire de nouveaux — adaptés, ciblés, gouvernés. Ce n'est plus de l'outillage. C'est de la méta-ingénierie.
Générer dynamiquement un langage, c'est refuser la fatalité des abstractions figées. C'est affirmer que le code peut toujours être plus proche de l'intention — si l'on accepte de travailler sur les outils autant que sur les solutions.