catala/examples/tutoriel_fr/tutoriel_fr.catala_fr

407 lines
17 KiB
Plaintext
Raw Normal View History

@@Tutoriel d'utilisation du langage Catala@@
Bienvenue dans ce tutoriel, son objectif est de vous accompagner dans les
fonctionnalités du langage Catala et de vous apprendre à 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 appétences
en informatique devraient pouvoir s'en sortir.
@@Programmation littéraire@@+
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 faire un copier-coller du texte de la loi dans
un fichier de source Catala et le formatter afin que Catala puisse le comprendre.
Les fichiers de source 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".
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, cela apparaîtera comme un seul paragraphe dans la sortie.
Si vous voulez créer un nouveau paragraphe laisser une ligne vierge dans la source.
Catala vous permet de déclarer des entêtes de section ou de sous-section,
2020-12-24 18:09:40 +03:00
en les précédant et les suivant de deux arobases. Vous pouvez
diminuer l'importance du titre en augmentant le nombre de "+" après le titre de
l'entête.
2020-12-24 18:09:40 +03:00
L'unité de division fondamentale est l'article, encadré par un simple arobase.
Étudions un exemple ficitif qui définit un impôt sur le revenu.
@Article 1@
2020-12-22 12:20:06 +03:00
L'impôt sur le revenu d'un individu est calculé en tant qu'un pourcentage
fixe des revenus d'une personne pour une année.
/*
2020-12-24 18:09:40 +03:00
# Bienvenue dans le mode code de Catala.
# Ceci est un commentaire car la ligne débute par le caractère #.
2020-12-22 12:20:06 +03:00
# Nous allons bientôt apprendre ce que l'on doit écrire ici pour traduire
# le sens d'un article de loi en code Catala.
*/
2020-12-24 18:09:40 +03:00
Afin de faire cela, nous allons entremêler courts bouts de code et phrases
du texte législatif. Chaque bout de code devra être aussi court que possible
2020-12-22 12:20:06 +03:00
et aussi proche que possible de la phrase qui justifie le code. Ce style
s'appelle programmation littéraire, un paradigme de programmation inventé par le
célèbre informaticien Donald Knuth dans les années 70.
2020-12-22 13:41:29 +03:00
@@Définir un impôt sur le revenu fictif@@+
2020-12-24 18:09:40 +03:00
Le contenu de l'article 1 utilise beaucoup d'éléments du contexte implicite :
2020-12-22 13:41:29 +03:00
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.
2020-12-22 13:41:29 +03:00
Commençons notre section métadonnées en déclarant l'information sur le type
personne :
2020-12-22 13:41:29 +03:00
@@Début métadonnées@@
/*
2020-12-22 13:41:29 +03:00
déclaration structure Personne:
# Le nom de la structure "Personne", doit commencer
# par une lettre majuscule: c'est la convention CamlCase.
donnée revenu contenu argent
# A cette ligne, revenu est le nom du champ de la structure et
# "argent" est le type de de données de ce champ.
2020-12-24 18:09:40 +03:00
# On peut utiliser d'autres types comme : entier, décimal,
# argent, date, durée ou tout autre structure ou énumération
# que vous aurez déclaré
2020-12-22 13:41:29 +03:00
donnée nombre_enfants contenu entier
# "revenu" and "nombre_enfants" commençent par une lettre minuscule,
# ils adhèrent à la convention snake_case
*/
2020-12-22 13:41:29 +03:00
@@Fin métadonnées@@
2020-12-22 13:41:29 +03:00
Cette structure contient deux champs de 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.
2020-12-22 13:41:29 +03:00
Parfois, la loi donne une énumération de différentes situations. Ces énumérations
sont modélisés en Catala par le type énumération, comme suit :
@@Début métadonnées@@
/*
2020-12-24 18:09:40 +03:00
déclaration énumération CréditImpôt:
# Le nom "CréditImpôt" s'écrit aussi en CamlCase
-- AucunCréditImpôt
# Cette ligne indique que "CréditImpôt" peut être en situation
# "AucunCréditImpôt"
-- CréditImpôtEnfants contenu entier
# Cette ligne indique, de manière alternative, que "CréditImpôt" peut aussi
# être une situation "CréditImpôtEnfants". Cette situation porte un contenu
2020-12-22 13:41:29 +03:00
# de type entier qui correspond au nombre d'enfants concernés par le crédit
2020-12-24 18:09:40 +03:00
# d'impôt. Cela signifie que si vous êtes dans la situation
# "CréditImpôtEnfants", vous aurez aussi accès à ce nombre d'enfants.
*/
2020-12-22 13:41:29 +03:00
@@Fin métadonnées@@
2020-12-24 18:09:40 +03:00
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.
2020-12-22 13:41:29 +03:00
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 "champs d'application" en Catala.
2020-12-24 18:09:40 +03:00
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:
2020-12-22 13:41:29 +03:00
@@Début métadonnées@@
/*
2020-12-24 18:09:40 +03:00
déclaration champ d'application CalculImpôtRevenu:
2020-12-22 13:41:29 +03:00
# Les champs d'application utilisent le CamlCase
contexte personne contenu Personne
# Cette ligne déclare un élémént de contexte du champ d'application,
# cela ressemble à un paramètre de fonction en informatique. C'est la
# donnée sur laquelle le champ d'application va intervenir
contexte pourcentage_fixe contenu décimal
2020-12-24 18:09:40 +03:00
contexte impôt_revenu contenu argent
*/
2020-12-22 13:41:29 +03:00
@@Fin métadonnées@@
2020-12-22 13:41:29 +03:00
Nous avons maintenant tout ce dont nous avons besoin pour annoter le contenu
de l'article 1 qui a été copié ci-dessous.
@Article 1@
2020-12-22 15:44:40 +03:00
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.
/*
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
définition impôt_revenu égal à
personne.revenu *€ pourcentage_fixe
*/
2020-12-22 15:44:40 +03:00
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 fomules, vous avez accès à tous les opérateurs
arithmétiques habituels : addition "+", soustraction "-", multiplication "*"
2020-12-24 18:09:40 +03:00
et division (barre oblique).
2020-12-22 15:44:40 +03:00
Toutefois, dans le code Catala, vous pouvez voir que nous utilisons "*€"
2020-12-22 15:44:40 +03:00
pour multiplier les revenus d'une personne par le pourcentage fixe. Le
suffixe € inique que nous effectuons une multiplication sur une somme d'argent.
2020-12-22 15:44:40 +03:00
En effet, en Catala, vous devez rester conscient de la donnée manipulée :
est-ce de l'argent ? est-ce un entier ? Utiliser simple "+" ou "*" est ambigu
en termes d'arrondis car l'argent est habituellement arrondi au centime.
Ainsi, afin d'être clair, nous suffixons ces opérations avec quelque chose
qui indique le type de donnée manipulé. Les suffixes sont "€" pour de l'argent,
2020-12-22 15:44:40 +03:00
"." pour les décimales, arobase (comme dans les adresses mail) pour les dates et
le symbole chapeau pour les durées. Si vous oubliez le suffixe, le vérificateur
2020-12-24 18:09:40 +03:00
de types de Catala va afficher une message d'erreur afin de vous aider à le placer
2020-12-22 15:44:40 +03:00
comme il le faut.
Mais dans l'article 1, une question reste sans réponse: quelle est la valeur
de la pourcentage fixe? Souvent, des valeurs précises sont définis ailleurs
dans les sources législatives. Ici, supposons que nous avons:
@Article 2@
2020-12-22 15:44:40 +03:00
Le pourcentage fixe mentionné à l'article 1 est égal à 20%.
/*
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
définition pourcentage_fixe égal à 20%
2020-12-22 15:44:40 +03:00
# Ecrire 20% est juste une abbréviation pour 0.20
*/
2020-12-22 15:44:40 +03:00
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.
2020-12-22 15:44:40 +03:00
@@Définitions conditionnelles@@+
2020-12-22 15:44:40 +03:00
Jusqu'à là tout va bien mais maintenant le texte législatif présente quelques
difficultés. Supposons que le troisième article dispose :
2020-12-22 15:44:40 +03:00
@Article 3@ Si l'individu a à sa charge deux ou plus enfants alors
le pourcentage fixe mentionné à l'article 1 vaut 15 %.
/*
2020-12-22 15:44:40 +03:00
# Comment redéfinir pourcentage_fixe ?
*/
2020-12-22 15:44:40 +03:00
Cet article donne en réalité une autre définition pour le pourcentage fixe,
préalablement défini à l'article 2. Toutefois, si l'article 3 définit le pourcentage
de manière conditionnelle pour la personne ayant plus de deux enfants.
2020-12-24 18:09:40 +03:00
Catala permet de redéfinir précisément une variable sous une condition :
/*
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
2020-12-22 15:44:40 +03:00
définition pourcentage_fixe sous condition
personne.nombre_enfants >= 2
2020-12-24 18:09:40 +03:00
conséquence égal à 15%
2020-12-22 15:44:40 +03:00
# Ecrire 15% est juste une abbréviation pour 0.15
*/
2020-12-24 18:09:40 +03:00
Quand le programme Catala va s'exécuter, la juste définition sera choisie
dynamiquement en déterminant laquelle des condition est vraie dans le contexte.
Une source législative rédigée correctement doit toujours garantir qu'au maximum
une seule condition soit vraie à tout moment. Toutefois, si ce n'est pas le cas,
Catala vous permettra de définir un ordre des priorités sur les conditions,
qui doit être justifié par un raisonnement juridique.
2020-12-22 16:10:09 +03:00
@@Fonctions@@+
2020-12-22 16:10:09 +03:00
Catala vous permet de définir des fonctions partout dans vos données. Voici
à quoi cela ressemble dans la définition des métadonnées quand nous voulons
définir un calcul de l'impôt sur le revenu à deux tranches :
@@Début métadonnées@@
/*
2020-12-22 16:10:09 +03:00
déclaration structure DeuxTranches:
donnée seuil contenu argent
donnée taux1 contenu décimal
donnée taux2 contenu décimal
2020-12-24 18:09:40 +03:00
déclaration champ d'application CalculImpôtDeuxTranches :
2020-12-22 16:10:09 +03:00
contexte tranches contenu DeuxTranches
contexte formule_imposition contenu argent dépend de argent
*/
2020-12-22 16:10:09 +03:00
@@Fin métadonnées@@
2020-12-22 16:10:09 +03:00
Et dans le code :
2020-12-22 16:10:09 +03:00
@Article4@ Le montant d'impôt pour le calcul à deux tranches
est égal au montant d'impôt dans chaque tranche multiplié
par le taux de chaque branche.
/*
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtDeuxTranches :
2020-12-22 16:10:09 +03:00
définition formule_imposition de revenu égal à
si revenu <=€ tranches.seuil alors
revenu *€ tranches.taux1
2020-12-22 16:10:09 +03:00
sinon (
tranches.seuil *€ tranches.taux1 +€
(revenu -€ tranches.seuil) *€ tranches.taux2
)
*/
2020-12-22 16:27:49 +03:00
@@Inclusion de champ d'application@@+
2020-12-22 16:27:49 +03:00
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 de calcul de l'impôt.
@Article 5@ Pour les individus dont le revenu est supérieur à 100 000€,
2020-12-22 16:27:49 +03:00
l'impôt sur le revenu de l'article 1 est de 40% du revenu au-dessus de
100 000€. En dessous de 100 000€, l'impôt sur le revenu est de 20% du revenu.
/*
2020-12-24 18:09:40 +03:00
déclaration champ d'application NouveauCalculImpôtRevenu:
contexte deux_tranches champ d'application CalculImpôtDeuxTranches
2020-12-22 16:40:13 +03:00
# Cette ligne indique que nous ajoutons l'élément deux_tranches au contexte.
# Toutefois, les mots clé "champ d'application" indique que l'élément n'est
2020-12-24 18:09:40 +03:00
# pas une donnée mais plutôt un sous-champ d'application qui peut être
# utilisé pour calculer des choses.
2020-12-22 16:27:49 +03:00
contexte personne contenu Personne
2020-12-24 18:09:40 +03:00
contexte impôt_revenu contenu argent
2020-12-22 16:27:49 +03:00
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenu :
2020-12-22 16:27:49 +03:00
définition deux_tranches.tranches égal à DeuxTranches {
-- seuil: 100 000€
2020-12-22 16:27:49 +03:00
-- taux1: 20%
-- taux2: 40%
}
2020-12-24 18:09:40 +03:00
définition impôt_revenu égal à
deux_tranches.formule_imposition de personne.revenu
*/
@Article 6@
2020-12-24 18:09:40 +03:00
Les personnes ayant moins de 10 000€ de revenus sont exemptés de l'impôt
sur le revenu prévu à l'article 1.
/*
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenu:
définition impôt_revenu sous condition
personne.revenu <=€ 10 000€
conséquence égal à 0€
*/
2020-12-22 16:49:56 +03:00
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 auront vu quelque chose de curieux dans les
articles 5 et 6. Que se passe-t-il si le revenu d'une personne se situe entre
10 000€ et 100 000€ ?
2020-12-22 16:49:56 +03:00
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.
2020-12-22 17:48:28 +03:00
@@Tester les programmes Catala@@+
2020-12-22 17:48:28 +03:00
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 appelée "tests unitaires" dans la
2020-12-24 18:09:40 +03:00
communauté du génie logicielle. Les cas de test sont définis dans des
2020-12-22 17:48:28 +03:00
champ d'application :
2020-12-22 17:48:28 +03:00
@Tester NouveauCalculImpotRevenu@
/*
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test1:
2020-12-24 18:09:40 +03:00
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenu
2020-12-22 17:48:28 +03:00
champ d'application Test1:
définition
2020-12-24 18:09:40 +03:00
calcul_impôt.personne
2020-12-22 17:48:28 +03:00
# L'on définit le paramètre au sous-champ d'application
égal à
# Les quatre lignes ci-dessous définissent une structure entière
# en valorisant chacun des champs
Personne {
-- revenu: 230 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
2020-12-22 17:48:28 +03:00
# Ensuite, nous récupérons le montant d'impôt, calculé par
# sous-champ d'application et nous assertons qu'il vaut bien
# la valeur attendue :
# (230 000€ - 100 000€) * 40% + 100 000€ * 20% = 72 000€
2020-12-24 18:09:40 +03:00
assertion calcul_impôt.impôt_revenu = 72 000€
*/
2020-12-22 17:48:28 +03:00
Ce test devrait être bon. Maintenant étudions un test en échec :
/*
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test2:
2020-12-24 18:09:40 +03:00
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenu
2020-12-22 17:48:28 +03:00
champ d'application Test2:
2020-12-24 18:09:40 +03:00
définition calcul_impôt.personne égal à Personne {
-- revenu: 4 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
2020-12-24 18:09:40 +03:00
assertion calcul_impôt.impôt_revenu = 0€
*/
Ce cas de test devrait calculer un impôt sur le revenu de 0€,
2020-12-22 17:48:28 +03:00
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.
2020-12-22 17:48:28 +03:00
@@Définir des exceptions à des règles@@+
2020-12-22 17:48:28 +03:00
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.
2020-12-22 17:48:28 +03:00
@Régler correctement le calcul@
2020-12-22 17:48:28 +03:00
Cette priorité implicite doit être explicitement déclaré en Catala. Voici une
version correcte du champ d'application NouveauCalculImpotRevenu :
/*
2020-12-24 18:09:40 +03:00
déclaration champ d'application NouveauCalculImpôtRevenuCorrect:
contexte deux_tranches champ d'application CalculImpôtDeuxTranches
2020-12-22 17:48:28 +03:00
contexte personne contenu Personne
2020-12-24 18:09:40 +03:00
contexte impôt_revenu contenu argent
2020-12-22 17:48:28 +03:00
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenuCorrect :
2020-12-22 17:48:28 +03:00
définition deux_tranches.tranches égal à DeuxTranches {
-- seuil: 100 000€
2020-12-22 17:48:28 +03:00
-- taux1: 20%
-- taux2: 40%
}
2020-12-22 17:48:28 +03:00
# 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.
étiquette article_5
2020-12-24 18:09:40 +03:00
définition impôt_revenu égal à
deux_tranches.formule_imposition de personne.revenu
2020-12-22 17:48:28 +03:00
# Puis, vous pouvez déclarez l'exception par référence à l'étiquette
exception article_5
2020-12-24 18:09:40 +03:00
définition impôt_revenu sous condition
personne.revenu <=€ 10 000€
conséquence égal à 0€
*/
2020-12-22 17:48:28 +03:00
Le test devrait désormais fonctionner :
/*
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test3:
2020-12-24 18:09:40 +03:00
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
2020-12-22 17:48:28 +03:00
champ d'application Test3:
2020-12-24 18:09:40 +03:00
définition calcul_impôt.personne égal à Personne {
-- revenu: 4 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
2020-12-24 18:09:40 +03:00
assertion calcul_impôt.impôt_revenu = 0€
*/
@@Conclusion@@+
2020-12-22 17:48:28 +03:00
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.
2020-12-22 17:48:28 +03:00
Il n'y pas une seule bonne façon d'écrire des programmes Catala car le style de
programmation doit être adapté au texte de loi annoté. Cependant, Catala est un
2020-12-24 18:09:40 +03:00
langage basé sur la programmation fonctionnelle, donc suivre les
patrons de conception habituels de la programmation fonctionnelle
2020-12-22 17:48:28 +03:00
devrait aider à obtenir du code concis et lisible.