Ce document a été produit à partir d’un ensemble de fichiers sources écrits dans le langage de programmation Catala, mêlant le texte législatif et le code informatique qui le traduit. Pour plus d’informations sur la méthodologie et sur la façon de lire le code, veuillez consulter le site https://catala-lang.org.
Fichiers sources tissés dans ce document:
Bienvenue dans ce tutoriel, son objectif est de vous accompagner dans les fonctionnalités du langage Catala et de vous apprendre d’annoter des textes législatifs avec ce langage. Ce document s’adresse principalement à des développeurs ou des personnes ayant déjà programmé, même si des juristes avec des compétences en informatique devraient pouvoir s’en sortir.
Pour commencer à écrire un programme Catala, vous devez partir du texte d’une source législative qui va justifier le code que vous écrirez. Concrètement, cela signifie de faire un copier-coller du texte de la loi dans un fichier source Catala, et de le formater afin que Catala puisse le comprendre. Les fichiers sources Catala ont l’extension « .catala_en » en version anglaise. Si vous écriviez un programme Catala pour une loi française, vous devrez utiliser l’extension « .catala_fr »; pour une loi polonaise, « catala_pl », etc.
Vous pouvez écrire n’importe quel texte simple en Catala, cela sera affiché sans modification dans une sortie PDF ou HTML. Vous pouvez découper votre texte en de courtes lignes de moins de 80 caractères, donnant un style « terminal », et cela apparaîtra comme un seul paragraphe en sortie. Si vous voulez créer un nouveau paragraphe, laisser une ligne vierge dans le fichier source. Dans un programme Catala, la syntaxe du texte, autre que du code, reprend un sous-ensemble du langage Markdown qui supporte des titres et des blocs de code Catala.
Catala vous permet de déclarer des en-têtes de section ou de sous-section, comme c’est le cas ici, avec le symbole «#». Vous pouvez diminuer l’importance du titre en augmentant le nombre de «#» après le titre de l’en-tête. Généralement, la syntaxe de la programmation littéraire de Catala suit la syntaxe de Markdown (bien qu’il n’ait pas toutes ses fonctionnalités).
Dans le reste de ce tutoriel, nous allons étudier un exemple fictif qui définit un impôt sur le revenu. Cet impôt sur le revenu est définit à travers différents articles de loi, chacun d’eux étant introduit par un en-tête. Le premier commence ici :
L’impôt sur le revenu d’un individu est calculé en tant qu’un pourcentage fixe sur les revenus d’une personne pour une année.
Afin de traduire cette définition fictive de l’impôt sur le revenu en un programme Catala, nous allons entremêler des bouts de code entre les phrases du texte législatif. Chaque bout de code devra être aussi court que possible et aussi proche que possible de la phrase qui justifie le code. Ce style s’appelle la programmation littéraire, un paradigme de programmation inventé par le célèbre informaticien Donald Knuth dans les années 70.
Le contenu de l’article 1 utilise beaucoup d’éléments contextuels implicites : il existe une personne avec un revenu et en même temps un impôt sur le revenu, qu’une personne doit acquitter chaque année. Même si ce contexte implicite n’est pas inscrit en tant que tel dans la loi, nous devons l’expliciter pour le traduire en code. Concrètement, nous avons besoin d’une section « métadonnées » qui définit la forme et les types de données contenues dans la loi.
Commençons notre section métadonnée en déclarant l’information sur le type « personne », c’est à dire le contribuable qui sera le sujet du calcul de l’impôt. Cette personne a un revenu et un nombre d’enfants, qui sont des pièces d’information qui seront nécessaires pour les objectifs fiscaux :
Cette structure contient deux champs de données, « revenu » et « nombre_enfants ». Les structures sont utiles pour regrouper des données qui vont ensemble. Typiquement, vous aurez une structure pour une entité concrète sur laquelle s’applique la loi (comme une personne). C’est à vous de décider comment regrouper les données, mais vous devrez viser à optimiser la lisibilité du code.
Parfois, la loi donne une énumération de différentes situations. Ces énumérations sont modélisées en Catala par le type énumération, comme suit :
En informatique, une telle énumération est appelée « type somme » ou simplement énumération. La combinaison de structures et d’énumération permet au programmeur Catala de déclarer toutes les formes possibles de données, car cette combinaison est équivalente à la puissante notion de « types de données algébriques ».
Nous avons défini et typé les données que le programme va manipuler. Maintenant, nous devons définir un contexte logique dans lequel ces données vont évoluer. On effectue cela par la notion de « champ d’application » en Catala. Les champs d’application sont proches des fonctions en termes de programmation traditionnelle. Les champs d’application doivent avoir été déclarés préalablement dans les métadonnées, de la manière suivante:
Le champ d’application est l’unité d’abstraction de base dans des programmes Catala, et la déclaration du champ d’application est semblable à une signature de fonction : elle contient une liste de tous les paramètres ainsi que leurs types. Mais dans Catala, les variables d’un champ d’application représentent trois choses: paramètres d’entrées, paramètres locaux et paramètres de résultats. La différence entre les trois catégories peuvent être spécifiées par les différents attributs d’entrée/résultat qui précèdent les noms de variables. « entrée » signifie que la variable doit être définie seulement quand le champ d’application « CalculImpôtRevenu » est appelé. « interne » signifie que la variable ne peut pas être vue en dehors du champ d’application : elle n’est ni une entrée, ni un résultat du champ d’application. « résultat » signifie qu’un appel au champ d’application peut récupérer la valeur calculée de la variable. Notez qu’une variable peut aussi être simultanément une entrée et un résultat du champ d’application, dans ce cas elle devrait être annotée avec “entrée résultat”.
Nous avons maintenant tout ce dont nous avons besoin pour annoter le contenu de l’article 1 qui a été copié ci-dessous.
L’impôt sur le revenu pour une personne est défini comme un pourcentage fixe des revenus de la personne pour une année.
Dans le code, nous définissons à l’intérieur de notre champ d’application le montant d’impôt sur le revenu selon la formule décrit dans l’article. Quand nous définissons des formules, vous avez accès à tous les opérateurs arithmétiques habituels : addition “+”, soustraction “-”, multiplication “*” et division (barre oblique).
Toutefois, dans le code Catala, ces opérateurs peuvent avoir un sens légèrement différent suivant les unités concernées. En effet, l’argent par exemple est arrondi au centime. Le compilateur Catala sélectionne automatiquement l’opération appropriée: ici, de l’argent est multiplié par un pourcentage (soit un nombre décimal), ce qui est une opération connue dont le résultat est une quantité d’argent, arrondie au centime. D’autres opérations sont rejetées, comme la multiplication de deux quantités d’argent entre elles, ou l’addition de deux dates.
Revenons à l’article 1, dont une question reste sans réponse: quelle est la valeur du pourcentage fixe ? Souvent, des valeurs précises sont définies ailleurs dans les sources législatives. Ici, supposons que nous avons:
Le pourcentage fixe mentionné à l’article 1 est égal à 20%.
Vous pouvez voir ici que Catala permet des définitions réparties dans toute l’annotation du texte législatif, afin que chaque définition soit le plus proche possible de sa localisation dans le texte.
Jusqu’à là tout va bien mais maintenant le texte législatif présente quelques difficultés. Supposons que le troisième article s’écrit :
Si l’individu a à sa charge deux ou plus enfants, alors le pourcentage fixe mentionné à l’article 1 vaut 15 %.
Cet article donne en réalité une autre définition pour le pourcentage fixe, préalablement défini à l’article 2. De plus, l’article 3 définit le pourcentage de manière conditionnelle pour la personne ayant plus de deux enfants. Catala permet de redéfinir précisément une variable sous une condition :
Même si les définitions conditionelles sont un outil puissant et expressif, une document juridique correctement rédigé doit toujours garantir qu’une seule condition au maximum soit vraie à tout moment. De cette façon, quand le programme Catala va s’exécuter, la juste définition sera choisie dynamiquement en déterminant quelle condition est vraie, selon le contexte.
Ici, nous pouvons détecter un conflit sur
pourcentage_fixe
entre la définition générale et celle
ci-dessus avec plus de ceux enfants. Catala donnera une erreur à
l’exécution si nous essayons d’utiliser ces définitions de
pourcentage_fixe
avec plus de deux enfants ; les deux
définitions contradictoires sont valables en même temps.
Dans des situations comme celle-ci, Catala vous permettra de définir un ordre des priorité sur les conditions, qui devra être justifié par un raisonnement juridique. Mais nous verrons comment faire cela plus tard.
Jusqu’à présent, vous avez appris comment déclarer un champ d’application avec quelques variables, et donner des définitions à ces variables dispersées à travers le texte de la loi, à des endroits pertinents. Mais il y a un modèle très fréquent dans des textes législatifs : qu’en est-il des conditions ? Une condition est une valeur qui peut être soit vraie ou fausse, comme un booléen en programmation. Cependant, la loi suppose implicitement qu’une condition est fausse, sauf indication contraire. Ce modèle est si commun en droit que Catala lui donne une syntaxe spéciale. Plus précisément, il nomme la définition de conditions des « règles », ce qui coïncide avec le sens habituel que les gens lui donneraient.
Voici un exemple de condition qui pourrait survenir dans la loi:
Les enfants éligiblent à l’application de l’article 3.
Lors de l’interaction avec d’autres éléments du code, les valeurs des conditions se comportent comme des valeurs booléennes.
Catala vous permet de définir des fonctions partout dans vos données. En effet, Catala est un langage de programmation fonctionnel et encourage, en utilisant des fonctions, à décrire les relations entre les données. Voici à quoi cela ressemble, dans la définition des métadonnées, lorsque nous voulons définir un calcul de l’impôt sur le revenu à deux tranches :
Et dans le code :
Le montant de l’impôt pour le calcul à deux tranches est égal au montant de l’impôt de chaque tranche, multiplié par le taux de chaque tranche.
Maintenant que nous avons défini notre champ d’application utilitaire pour calculer un impôt à deux tranches, nous voulons l’utiliser dans notre champ d’application principal du calcul de l’impôt. Comme mentionné précédement, le champ d’application de Catala peut être aussi pensé comme de grandes fonctions. Et ces grandes fonctions peuvent s’appeler entre elles, c’est ce que nous allons voir dans l’article ci-dessous.
Pour les individus dont le revenu est supérieur à 100 000€, l’impôt sur le revenu de l’article 1 est de 40% du revenu au-delà de 100 000€. En dessous de 100 000€, l’impôt sur le revenu est de 20% du revenu.
Maintenant que vous avez réussi de définir le calcul d’impôt sur le revenu, le législateur vient inévitablement pérturber nos belles et irréprochables formules pour rajouter un cas particulier ! L’article ci-dessous est un modèle très fréquent dans les lois, et allez voir comment Catala le gère.
Les personnes ayant moins de 10 000€ de revenus sont exemptés de l’impôt sur le revenu prévu à l’article 1.
Et voilà ! Nous avons défini un calcul d’impôt à deux tranches en annotant tout simplement un texte législatif par des bouts de code Catala. Cependant, les lecteurs attentifs ont vu quelque chose de curieux dans les articles 5 et 6. Que se passe-t-il si le revenu d’une personne est inférieur à 10 000€ ? Tout de suite, les deux définitions de l’article 5 et 6 pour l’impôt sur le revenu s’appliquent, et ils sont en conflit.
La loi ne le précise pas; nos articles sont clairement mal rédigés. Mais Catala vous aide à trouver ce genre d’erreur par de simples tests ou même la vérification formelle. Commençons par les tests.
Tester les programmes Catala peut se faire directement en Catala. En effet, écrire des cas de tests pour chaque champ d’application Catala que vous définissez est une bonne pratique, qui est appelée « tests unitaires » dans la communauté du génie logicielle. Les cas de test sont définis dans des champs d’application :
Ce test devrait être bon. Maintenant étudions un test en échec :
Ce cas de test devrait calculer un impôt sur le revenu de 0€, en raison de l’article 6. Mais au lieu de cela, l’exécution produira une erreur car il y a un conflit entre les règles.
En effet, la définition d’un impôt sur le revenu à l’article 6 entre en conflit avec la définition de l’article 5. Mais en réalité, l’article 6 est une simple exception à l’article 5. Dans la loi, il est implicite que si l’article 6 est applicable, alors son application est prioritaire sur l’article 5.
Cette priorité implicite doit être explicitement déclarée en Catala. Voici une version correcte du champ d’application NouveauCalculImpotRevenu :
Pour définir une exception à une règle, vous devez d’abord étiquetter la règle à laquelle vous voulez attacher l’exception. Vous pouvez mettre n’importe quel identifiant en « snake_case » pour l’étiquette :
Et le test devrait désormais fonctionner :
Notez que le système d’étiquettes vous permet de définir des modèles d’exception plus compliqués. Parfois, vous voulez déclarer une exception à un groupe de définitions par morceau. Pour cela, utilisez simplement la même étiquette à tout un morceau de définitions.
Comme nous l’avons vu… Deux exceptions s’appliquant pour une même règle, au même moment, sont en conflits et déclenchent une erreur. Cela arrive, cependant, que ces exceptions produisent le même résultat à la fin : par convenance, Catala tolère ce cas et retourne le résultat commun, aussi longtemps qu’il y a une stricte égalité syntaxique.
Des personnes avec 7 enfants ou plus sont exonérées de l’impôt sur le revenu mentionné à l’article 1.
Le même problème devrait être déclenché ci-dessus, pour des familles avec un revenu en dessous de 10 000€ et avec 7 enfants ou plus. Mais Catala peut détecter qu’il n’y aura pas de problèmes puisque le résultat est une éxonération dans les 2 cas.
Dans certains cas, il est utile d’appliquer le calcul d’un champ d’application seulement sous des circonstances spécifiques. Par exemple, certaines allocations sociales peuvent avoir différents modes de calcul, qui dépendent de la situation des allocataires. Dans ce cas définir chacun de ces modes de calcul, comme un sous-champ d’application, est ennuyeux pour deux raisons : premièrement, certaines valeurs en entrée peuvent ne pas être pertinantes dans des cas où un allocataire n’est pas concerné, et le langage continuera d’éxiger à ce que vous ne laissez rien d’indéfini ; deuxièmement, un calcul inutile aura lieu.
Pour ces cas, il est possible d’appeler un champ d’application directement, en spécifiant en même temps toutes ses variables d’entrées, et de récupérer ses variables de résultat de la même manière qu’avec des sous-champs d’application.
Ici le syntaxe « NouveauCalculImpôtRevenuCorrect avec » déclenche un appel au champ d’application, qui valorise sa variable d’entrée « personne ». Ensuite, la syntaxe du point « . » est utilisée pour récupérer le résultat « impôt_revenu » du champ d’application.
Avec ses variables « entrée », « interne » et « résultat », les champs d’application de Catala sont proches des fonctions avec des paramètres, des variables locales et des variables retournant un résultat. Cependant, la loi peut parfois être contradictoire aux bonnes pratiques de programmation, et ainsi définir des dispositions qui cassent la barrière d’abstraction normalement associée à une fonction.
Ceci peut être le cas quand un corps extérieur du texte législatif « réutilise » un concept légal, mais en y ajoutant un changement. Considérez l’exemple fictif suivant (mais pas tout à fait pathologique d’un point de vue informatique).
Le système de justice inflige des amendes aux individus quand ils commettent une infraction. Les amendes sont déterminées en fonction du montant des impôts payés par le particulier. Plus l’individu paie d’impôts, plus l’amende est élevée. Toutefois la détermination du montant de l’impôt à payer par un particulier, dans ce contexte, comprend des frais d’imposition fixes de 500€ pour les particuliers gagnant moins de 10 000€.
Lorsqu’une quantité est mentionnée dans la loi, elle ne correspond pas toujours exactement à une variable unique de Catala. Plus précisément, il arrive souvent que la loi définisse une quantité unique avec plusieurs étapes de calcul, chacune s’appuyant sur la précédente. Voici un exemple d’une telle configuration et la manière de la traiter grâce à une fonction dédiée de Catala.
Sous le capot, les différents états d’une variable de Catala sont mis en œuvre par des variables distinctes, à l’intérieur des représentations intermédiaires-inférieures du langage.
Fiscalement parlant, la valeur du bâtiment exploité à des fins caritatives peut être déduite du patrimoine d’une personne, qui est alors plafonné à 2 500 000€.
Jusqu’à présent, ce tutoriel vous a présenté la structure de base des programmes Catala avec le champ d’application, les définitions et les exceptions. Mais pour être en mesure de gérer la plupart des lois, Catala vient en soutien avec les types de données habituels sur lesquels les calculs legislatifs opèrent.
Le booléen est le type de donnée le plus élémentaire dans Catala : sa valeur peut être soit à « vrai », soit à « faux ». La condition est un simple booléen avec une valeur par défaut à « faux ». Rendez-vous à la section qui concerne les conditions, décrite plus haut.
Les entiers dans Catala sont en précision infinie : ils se comportent comme des vrais entiers en mathématique, et non comme des entiers d’ordinateur qui sont limités par une valeur maximale, en raison de leur stockage sur 32 ou 64 bits. Les entiers peuvent être négatifs.
Les décimales dans Catala sont aussi en précision infinie, qui se comportent comme de vrais nombres rationnels en mathématique, et non comme des nombres à virgule flottante dans un ordinateur qui effectuent des calculs approxmatifs. Les opérateurs sont suffixés avec « , ».
En Catala, l’argent est simplement représenté par un nombre entier de centimes. Il n’est pas possible en Catala d’avoir une quantité d’argent plus précise qu’un centime. Cependant, vous pouvez multiplier une quantité d’argent avec une décimale, et le résultat est arrondi au centime le plus proche.
Ce comportement vous permet de repérer l’endroit où vous avez besoin de précision dans vos calculs et de sélectionner les décimales en guise de précision, au lieu de vous fier sur des chiffres monétaires, où la précision est de l’ordre du centime d’euro. Deux sommes d’argent peuvent être divisées, produisant une décimale.
Catala prend en charge les dates du calendrier grégorien, ainsi que les calculs de durée en termes de jours, de mois et d’années. La soustraction entre une date et une durée est mesurée en jours, et l’addition entre une date et une durée donne une nouvelle date. Les durées sont mesurées en jours, en mois ou en années et ne peuvent pas être mélangées, car les mois et les années n’ont pas toujours le même nombre de jours. Cette non-mixité n’est pas prise en compte par le système de typage de Catala, mais des erreurs seront générées à l’exécution. Les dates sont spécifiées selon la norme ISO 8601 afin d’éviter toute confusion entre les notations américaines et européennes. Les opérateurs de date sont préfixés par « @ », tandis que les opérateurs de durée sont préfixés par « ^ ».
Souvent, les programmes Catala ont besoin de parler de collection de données parce que la loi parle du nombre d’enfants, du maximum d’une liste, etc. Catala propose un support de première classe pour les listes. Vous pouvez créer une liste, filtrer ses éléments, mais aussi agréger son contenu pour calculer toutes sortes de valeurs.
Ce tutoriel présente les concepts de base et la syntaxe des fonctionnalités du langage Catala. C’est à vous de les utiliser pour annoter du texte législatif avec leur traduction algorithmique.
Il n’y a pas une seule bonne façon d’écrire des programmes Catala, car le style de programmation doit être adapté au texte de loi qui sera annoté. Cependant, le coeur de Catala est un langage de programmation fonctionnelle. Par conséquent, suivre les modèles de conception habituels de la programmation fonctionnelle devrait aider à obtenir du code concis et lisible.
Les définitions de premier niveau permettent de définir des valeurs ou des fonctions directement dans le programme, sans les placer dans un champ d’application. Cela est utile pour les constantes ou les fonctions d’aide, comme le montrent les exemples ci-dessous.
Les définitions de premier niveau sont disponibles, en les appelant par leur nom, dans tout le programme ; elles peuvent dépendre les unes des autres (tant qu’il n’y a pas de cycles), mais elles ne sont pas autorisées à être dépendantes des évaluations faites dans des champs d’application.
Le montant à inclure dans le revenu brut est l’excédent de la juste valeur marchande du bien sur le montant payé.