DSL en Swift : comment créer votre propre langage de programmation en une soirée

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : quand l'universalité est l'ennemi

\n\n

Imaginez que vous écrivez du code pour la configuration réseau, l'analyse de logs ou la description de règles métier. À chaque fois, des constructions identiques, des tonnes de parenthèses, des opérateurs conditionnels imbriqués et une lecture pénible du code des autres. Cela vous dit quelque chose ?

\n\n

Dans ces situations, les langages dédiés (DSL) viennent à la rescousse. Ce n'est ni de la magie ni une réinvention de la roue – c'est une façon de rendre le code si lisible qu'il se documente lui-même. Dans cet article, nous allons voir comment créer votre propre DSL en Swift – puissant, élégant et sans nécessiter de compilateur.

\n\n

Le DSL en Swift n'est pas seulement une tendance du développement iOS. C'est un outil utilisé dans SwiftUI, Combine et même dans les bibliothèques backend. Vous apprendrez à concevoir des langages qui résolvent des problèmes spécifiques : de l'analyse de données à la description d'UI. C'est parti !

\n\n

Qu'est-ce qu'un DSL et pourquoi un développeur en a-t-il besoin ?

\n\n

Domain-Specific Language est un langage conçu pour un domaine restreint. Contrairement à un langage général (comme Swift ou Python), le DSL parle le langage de votre domaine métier. Par exemple, au lieu de :

\n\n
let config = NetworkConfig()\nconfig.host = "api.example.com"\nconfig.port = 443\nconfig.timeout = 30
\n\n

Vous écrivez :

\n\n
let config = networkConfig {\n    host("api.example.com")\n    port(443)\n    timeout(30)\n}
\n\n

La deuxième version se lit comme une instruction en langage humain. C'est l'objectif du DSL – réduire la charge cognitive et rendre le code auto-documenté.

\n\n

En Swift, pour créer un DSL, on utilise le plus souvent :

\n
    \n
  • Result Builders – une fonctionnalité de Swift 5.4+ permettant de construire des structures imbriquées avec une syntaxe déclarative.
  • \n
  • Les chaînes fonctionnelles – le pattern builder classique.
  • \n
  • Les opérateurs – la surcharge d'opérateurs pour créer des interfaces fluides.
  • \n
\n\n

Mais allons droit au but. Nous allons créer un DSL pour analyser des fichiers CSV – une tâche qui tourmente chaque développeur au moins une fois dans sa vie.

\n\n

Exemple 1 : Un DSL simple pour la configuration réseau

\n\n

Commençons par un exemple basique qui montre le mécanisme. Supposons que nous devions décrire des requêtes HTTP. Au lieu d'une multitude de paramètres – un DSL concis.

\n\n
// Définition de la structure de requête\nstruct HTTPRequest {\n    var method: String = "GET"\n    var path: String = "/"\n    var headers: [String: String] = [:]\n    var body: Data? = nil\n}\n\n// Création du DSL via Result Builder\n@resultBuilder\nstruct RequestBuilder {\n    static func buildBlock(_ components: HTTPRequestModifier...) -> HTTPRequest {\n        var request = HTTPRequest()\n        for mod in components {\n            mod.apply(&request)\n        }\n        return request\n    }\n}\n\n// Modificateurs de requête\nprotocol HTTPRequestModifier {\n    func apply(_ request: inout HTTPRequest)\n}\n\nstruct MethodModifier: HTTPRequestModifier {\n    let method: String\n    func apply(_ request: inout HTTPRequest) {\n        request.method = method\n    }\n}\n\nstruct PathModifier: HTTPRequestModifier {\n    let path: String\n    func apply(_ request: inout HTTPRequest) {\n        request.path = path\n    }\n}\n\n// Fonctions auxiliaires\nfunc method(_ m: String) -> HTTPRequestModifier { MethodModifier(method: m) }\nfunc path(_ p: String) -> HTTPRequestModifier { PathModifier(path: p) }\n\n// Utilisation\n@RequestBuilder\nfunc buildGetRequest() -> HTTPRequest {\n    method("GET")\n    path("/users")\n}\n\nlet request = buildGetRequest()\nprint(request.method, request.path) // GET /users
\n\n

Ce code est la base de tout DSL en Swift. @resultBuilder rassemble toutes les expressions à l'intérieur du bloc et les transforme en une structure unique. Important : chaque élément est un modificateur qui change l'état.

\n\n

Maintenant, complexifions la tâche : ajoutons l'imbrication et les conditions.

Blogs

Book Recommendations