cours/Remplissage du plan de L3.md
Oscar Plaisant 342e212d7c update
2024-04-02 02:31:02 +02:00

37 KiB
Raw Blame History

up:: plan du mémoire de L3 #informatique #fac

Introduction

!mémoire de L3#^abstract

Définition et concepts importants

qu'est-ce qu'un paradigme

Un paradigme de programmation est une façon d'approcher la programmation et de formuler les problèmes et leurs formalisation dans un langage de programmation [@ParadigmeProgrammation2023]. En particulier, un paradigme fournit et détermine comment un développeur doit voir un programme. La notion de paradigme est notamment à dissocier de celles de méthode ou bien de design patterns, qui décrivent comment traîter des problèmes spécifiques et reconnus, et comment aboutir à une solution conceptuelle [@ParadigmeProgrammation2023]. Un paradigme est un concept plus "haut niveau", c'est-à-dire plus abstrait : chaque paradigme supporte un ensemble particulier de concepts (cohérents entre eux), qui peuvent être hérités d'une théorie mathématique, de principes fondamentaux, ou bien d'une vision sur ce que doit être la programmation 1.

[!cite]- Programming Paradigms for Dummies: What Every Programmer Should Know - Page 10 Each paradigm supports a set of concepts that makes it the best for a certain kind of problem. For example, object-oriented programming is best for problems with a large number of related data abstractions organized in a hierarchy. Logic programming is best for transforming or navigating complex symbolic structures according to logical rules. Discrete synchronous programming is best for reactive problems, i.e., problems that consist of reactions to sequences of external events.

[!note] Notes Les concepts supportés par les différents paradigmes les rendent adaptés pour la résolution de différents problèmes. ^4LQTA3Q8aP4L4LCJZg5383243p2

Un paradigme de programmation est souvent principalement décrit par les concepts qu'il implémente ou non [@royProgrammingParadigmsDummies, p.10]. C'est notamment cette approche qu'emploie la taxonomie des paradigmes de programmation (référence à une annexe) [@TaxonomiePrincipauxParadigmes].

Cependant, J.Huges, dans son article "Why Functional Programming Matters" [@hughesWhyFunctionalProgramming1989, p.1], fustige le fait que certains paradigmes (notamment la programmation fonctionnelle ref et la programmation structurée ref) sont trop souvent définis en termes des fonctionnalités qu'il n'implémentent pas, ou des contraintes qu'il posent 2. Cela est problématique car l'absence d'une fonctionnalité ne peut pas expliquer pourquoi un paradigme serait plus intéressant dans certains cas 3. L'auteur insiste donc sur le fait que les paradigmes devraient être définis en fonction des avantages structurels qu'il apportent pour résolution de certains types de problèmes.

C'est pour cette raison que, dans notre définition des différents paradigmes, nous chercherons à expliquer à la fois les principes fondamentaux de chaque paradigme, mais également à montrer brièvement pourquoi ceux-ci sont intéressants, c'est-à-dire répondre à la question "en quoi ce paradigme apporte-t-il quelque chose". Cela constituera une première partie de réponse à notre problématique.

Définitions

état

L'état est la capacité, pour un programme, à retenir de l'information. "State is the ability to remember information, or more precisely, to store a sequence of values in time." (L'état est la capacité à retenir de l'information, ou, plus précisément, à stocker une séquence de valeurs dans le temps) [@royProgrammingParadigmsDummies, p.14].

Il est important de noter que la présence de variables n'implique pas toujours la présence d'état. En effet, une fonction peut avoir un paramètre sans avoir nécessairement d'état. Les variables des fonctions, si elles constituent une référence à une valeur, n'impliquent pas la présence d'état.

Note: la logique combinatoire fournit la preuve qu'il est possible d'établir un système de calcul sans aucune variable ni référence, ce qui rend l'absence d'état évidente [@LogiqueCombinatoire2023].

Fonction et procédure

Les termes "fonction" et "procédure" sont, selon les contextes et les auteurs, utilisés pour désigner différentes choses.

[!cite]+ Function (computer programming) - Page In computer programming, a function, subprogram, procedure, method, routine or subroutine is a callable unit[1] that has a well-defined behavior and can be invoked by other software units to exhibit that behavior. ^GNQR9GC2aRIAPAJ6Eg5383243

Par exemple, le livre "Structure and interpretation of computer programs" [@abelsonStructureInterpretationComputer1996] fournit la distinction suivante : les fonctions sont l'aspect mathématique du concept et sont définies en déclarant "ce qu'elle est" , en donnant des propiétés de cette fonction (une définition déclarative, voir Remplissage du plan de L3#programmation déclarative). Les procédures sont l'aspect programmatique du concept, et sont définies en déclarant "comment elle doit faire", en décrivant comment elle doit s'exécuter 4.

Cependant, certains auteurs utilisent le terme procedure même pour parler du concept théorique et mathématique (qui se rapproche du lambda-calcul) 5.

Nous utiliserons donc principalement le terme fonction, avec les définitions suivantes :

[!definition] fonction Une fonction est l'encapsulation d'un ensemble d'instructions. Une fonction peut posséder des paramètres qui peuvent influencer son exécution. Ces paramètres sont des valeurs ou des références qui sont données ("passées en argument") lors de l'appel de cette fonction. Une fonction peut retourner une valeur. Une fonction peut être appelée plusieurs fois et à plusieurs endroits, ce qui la rend réutilisable dans plusieurs contextes.

[!definition] fonction pure Une fonction pure est une fonction déterministe, c'est-à-dire que les mêmes arguments donnent toujours la même valeur de retour. Une fonction pure est une fonction sans effet de bord, c'est-à-dire qu'elle ne modifie pas l'état du système (en dehors de son champ local propre, dont la durée de vie est limitée).

Fermeture

Une fermeture (de l'anglais closure) est une fonction à laquelle on attache l'environnement local de l'endroit où elle à été définie 6 7. Cela permet à cette fonction d'accéder aux valeurs et aux références de cet environnement local, même si elle est appelée depuis un autre contexte (dans un autre champ local) 7. Du point de vue du développeur, cela signifie que l'exécution d'une fermeture soit le même que si les instructions étaient exécutées "à l'endroit" (dans le contexte où) la fermeture à été créée 8.

Un avantage considérable des fermetures est qu'elles permettent d'accéder aux valeurs et références d'un environnement local qui n'existe plus (car il à été libéré de la pile d'exécution) 9.

les principaux paradigmes

taxonomie des paradigmes de programmation

programmation impérative

La programmation impérative est un paradigme de programmation dans lequel le contrôle de flot d'exécution est explicite. Cela signifique que le programme spécifie pas à pas la marche à suivre pour obtenir le bon résultat. En programmation impérative, chaque étape modifie l'état global du système 10.

programmation déclarative

La programmation déclarative est un paradigme de programmation dans lequel la définition des programme se fait en déclarant la forme du résultat plutôt que la manière l'obtenir (comme on le fait en Remplissage du plan de L3#programmation impérative) Le développeur ne s'occupe donc pas de l'exécution, mais plutôt de comment spécifier le résultat. Le contrôle du flot d'exécution est implicite. En cela, la programmation déclarative s'oppose à la programmation impérative 11.

programmation fonctionnelle

La programmation fonctionnelle est un paradigme de programmation dans lequel les programmes sont exprimés comme des arbres d'expressions.

Le contrôle du flot d'exécution est donc fait en combinant des fonctions 12: la fonction principale prends en argument l'entrée du problème, puis elle est définit a partir d'autres fonctions, qui sont elles-même définies à partir de fonctions, et ce jusqu'à ce que les fonctions à la base de la définition (les feuilles de l'arbre d'expressions) soient des primitives du langages, ou bien des constantes 13. Cela distingue la programmation fonctionnelle d'autres paradigmes, notamment en programmation impérative, où l'état est beaucoup plus utilisé, notamment pour le contrôle du flot d'exécution.

Ces propriétés rapprochent beaucoup la programmation fonctionnelle des mathématiques 13.

[!cite]+ What Is Functional Programming? - Page Functional programming is about writing pure functions, about removing hidden inputs and outputs as far as we can, so that as much of our code as possible just describes a relationship between inputs and outputs. ^IU2KWY7La8P4TX53Jg5383243

Les fonction d'ordre supérieur sont centrales en programmation fonctionnelle. Les fonctions d'ordre supérieur sont des fonctions qui prennent en argument, ou renvoient d'autres fonctions. Ces fonctions d'ordre supérieur (aussi appelées "fonctionnelles") permettent donc de modifier ou combiner entre elles d'autres fonctions 14.

Pour que les fonctions d'ordre supérieur existent, il est nécessaire que les fonctions soient des citoyens de première classe, c'est-à-dire des entités traitées comme des valeurs du langage. Il est également nécessaire que le langage implémente les Remplissage du plan de L3#Fermeture, le cas échéant il serait impossible d'implémenter certaines fonctions d'ordre supérieur. La programmation fonctionnelle privée des fermetures (et donc des fonction d'ordre supérieur) s'appelle la programmation fonctionnelle de premier ordre (ref à la taxonomie en annexe)

Programmation fonctionnelle pure

La programmation fonctionnelle pure (parfois appelée simplement programmation fonctionnelle) est un paradigme dans lequel toutes les fonctions sont pures, c'est-à-dire qu'il n'existe pas d'état 15.

programmation structurée

La programmation structurée peut être définie, du point du vue théorique, comme un paradigme dans lequel le contrôle du flot se fait en utilisant des instructions de contrôle du flot d'exécution particulières (des structures de sélection et d'itération), et qui sont sous la forme de blocks 16. Les structures de sélection sont des structures particulières qui permettent de choisir quel groupe d'instruction sera exécuté en fonction de l'état du programme 17. Les structures d'itération sont des instructions qui exécutent répétitivement un block jusqu'à ce que le programme atteigne un certain état, ou bien que certaines opérations aient été appliquées sur chaque élément d'une collection 18.

Il est important de voir que le but de la programmation structurée est de produire des programmes plus clairs et de meilleure qualité, de par la modularité induite par la structuration du programme 19.

Une autre définition de la programmation structurée est une façon de concevoir les programmes

"In the first phase, that of top-down design, or stepwise refinement, the problem is decomposed into a very small number of simpler subproblems." [@floydParadigmsProgramming1979a, p.1]

"The second phase of the structured programming paradigm entails working upward from the concrete objects and functions of the underlying machine to the more abstract objects and functions used throughout the modules produced by the top-down design. [...] This approach is reffered to as the method of levels of abstraction, or of information hiding." [@floydParadigmsProgramming1979a, pp. 1-2]

"The absence of gotos and so on, has very little to do with this [the advantages strutcured programming, especially modularity]. It helps with 'programming in the small', whereas modular design helps with 'programming in the large'. Thus one can enjoy the benefits of structured programming in FORTRAN or assembly language, even if it is a little more work." [@hughesWhyFunctionalProgramming1989, p.2]

les langages multi-paradigmes

Il existe beaucoup de langages qui implémentent plusieurs paradigmes de programmation [@ComparisonMultiparadigmProgramming2024]. Ces langages sotn appelés langages multi-paradigmes.

Par exemple, le langage prolog implémente à la fois la programmation logique et la programmation impérative 20. Un autre exemple peut être trouvé lorsque l'on ajoute une librairie de résolution de contraintes à un langage de programmation. Le paradigme de programmation par contraintes est alors ajouté au langage hôte, qui peut, par exemple, être un langage orienté objet 21.

Nous verrons l'avantage des langages de programmation multi-paradigmes dans la section Remplissage du plan de L3#diversité des approches

Définition de la puissance d'expression

La puissance d'expression (ou expressivité) d'un langage est la quantité et la diversité d'idées qu'il peut représenter ou communiquer 2223.

On distingue deux sens du terme. D'un côté, l'expressivité théorique, qui se concentre sur la possibilité théorique d'exprimer une idée dans un langage, indépendamment de la difficulté pour exprimer cette idée. De l'autre côté, l'expressivité pratique, qui se concentre sur la concision et la facilité d'expression de ces idées 24.

Expressivité au sens formel

La puissance d'expression au sens formel (ou expressivité formelle) est mesurée en regardant l'ensemble des idées qu'un langage peut exprimer. Ce concept d'expressivité formelle est surtout utile en mathématiques ou en informatique théorique (notamment dans la théorie des langages formels) 25

Pour un langage de programmation, il est presque indispensable d'être aussi expressif qu'une machine de Turing (Turing-complets) (ou un autre modèle de calcul équivalent), car cela est la condition nécessaire et suffisante pour qu'il puisse exprimer les problèmes calculables (par définition).

Il existe tout de même des langages qui n'ont pas la même expressivité formelle. On peut notamment citer les langages de description de données, dont le but est de représenter des données organisées (par exemple, les langages XML, JSON, YAML...), ou bien les langages de description d'ontologies, qui servent à représenter de façon informatique certains types d'ontologie. Notamment, OWL2 EL et OWL2 RL sont deux langages de description d'ontologies qui n'ont pas la même expressivité formelle : OWL2 EL n'implémente pas certains concepts qui peuvent pourtant être exprimés dans OWL2 RL 26.

Cependant, ces langages ne sont généralement pas qualifiés de "langages de programmation", puisqu'ils sont incapables d'exprimer un programme (c'est-à-dire des instructions exécutables), mais expriment seulement des données.

Il existe également des langages de programmation qui ne sont pas turing-complets (par exemple, le langage G-code, dans certaines implémentations 27), mais ces langages ne sont pas utilisés pour résoudre des problèmes de programmation : ils sont utilisés à des fins théoriques, ou pour des applications particulières (par exemple, le langage G-code est utilisé pour commander des machines à commande numérique 28).

Au sens commun

!expressivité pratique#^definition

compromis expressivité vs analysabilité

Plus un langage est expressif, plus il est complexe de l'analyser mathématiquement. Plus un langage est puissant expressivement au sens formel, plus il devient difficile (et impossible) de démontrer certains théorèmes sur ce formalisme 29. Cela est vrai également pour l'expressivité au sens commun : "le fait d'éviter certaines techniques peut permettre de rendre plus aisée la démonstration de théorèmes sur la correction d'un programme -- ou simplement la compréhension de son fonctionnement -- sans limiter la généralité du langage de programmation." [@ParadigmeProgrammation2023]. On peut voir ce compromis dans le cadre

C'est pourquoi certaines fonctionnalités, certains paradigmes, devraient être utilisés uniquement si cela est nécessaire 30.

Exemple de compromis : automates et grammaires

  • les automates à pile sont moins expressifs que les machines de Turing
    • les automates à pile reconnaissent exactement les grammaires non-contextuelles
    • les machines de Turing reconnaissent les langages récursivement énumérables
  • les automates à pile ont un formalisme plus pratique (certains théorèmes sont plus définis)
    • le problème qui demande si un mot est reconnu par un automate à pile est décidable
    • le problème qui demande si un mot est reconnu par une machine de Turing est indécidable

Les automates à pile et les machines de Turing forment un exemple de compromis entre analysabilité et expressivité formelle. Les automates à pile reconnaissent les langages non contextuels 31. Les machines de Turing reconnaissent les langages contextuels 32. Or, les langages non contextuels sont strictement inclus dans les langages récursivement énumérables 33 . On peut donc conclure que les machines de Turing ont un pouvoir d'expression formel supérieur à celui des automates à pile.

Cependant, si on pose le problème de l'appartenance d'un mot à un langage donné. Ce problème est décidable pour tous les langages non contextuels 34. Pourtant, ce problème est indécidable pour les machines de Turing 35.

On voit donc que les machines de Turing sont un formalisme plus expressif (certains concepts exprimés par des machines de Turing ne sont pas exprimables par des automates à pile) mais moins analysable (certains problèmes sont décidables sur les automates à pile, mais pas sur les machines de Turing).

Paradigmes dans l'apprentissages

avantages de la diversité

  • pour apprendre, il est mieux d'apprendre plusieurs langages
    • car il en existe plusieurs
    • car le fait de connaître différentes approches de la programmation permet de mieux résoudre de nouveaux problèmes
      • on pourra choisir le paradigme adapté à notre problème (voir section résolution de problèmes)
      • on construit des modèles mentaux pour les problèmes

[!cite]+ Form and Content in Computer Science (1970 ACM turing lecture) - Page 9

  • To help people learn is to help them build, in their heads, various kinds of computational models.
  • This can best be done by a teacher who has, in his head, a reasonable model of what is in the pupil's head.
  • For the same reason the student, when debugging his own models and procedures, should have a model of what he is doing, and must know good debugging techniques, such as how to formulate simple but critical test cases.
  • It will help the student to know something about computational models and programming. The idea of debugging itself, for example, is a very powerful concept - in contrast to the helplessness promoted by our cultural heritage about gifts, talents, and aptitudes. The latter encourages "I'm not good at this" instead of "How can I make myself better at it?" ^CCMAKXHCaH39XI9D9g5383243p9

[!cite]+ 10 Things Software Developers Should Learn about Learning - Page 81 One key difference between beginners and experts is that experts have seen it all before. Research into chess experts has shown that their primary advantage is their ability to remember and recognize the state of the board.

[!note] Notes L'avantage des experts est d'avoir en mémoire beaucoup de cas, quand les débutants doivent réfléchir pour chaque nouveau cas. ^7WYHBT9DaSQN4T6Z8g5383243p4

[!cite]+ 10 Things Software Developers Should Learn about Learning - Page 81 Experts build up a mental library of patterns ^K2JKSWGEaSQN4T6Z8g5383243p4

[!cite]+ 10 Things Software Developers Should Learn about Learning - Page 81 seeing a variety of programming paradigms will help further. ^2PSW4XYMaSQN4T6Z8g5383243p4

problèmes de la diversité

[!cite]+ 10 Things Software Developers Should Learn about Learning - Page 84 Knowing multiple languages can be beneficial once they have been mastered, but sometimes transferring knowledge from one programming language to another can lead to faulty knowledge

[!note] Notes le transfert de connaissances d'un langage à un autre peut être avantageux, mais peut aussi créer de la connaissance fausse (si le transfert n'est pas pertinent à ce moment). ^588UCYYDaSQN4T6Z8g5383243p7

Paradigmes pour la résolution de problèmes

diversité des approches

La diversité est utile, de nouveaux paradigmes apportent de nouvelles façons de voir. Langages multi-paradigmes

[!cite] Programming Paradigms for Dummies: What Every Programmer Should Know - Page 10 A language should ideally support many concepts in a well-factored way, so that the programmer can choose the right concepts whenever they are needed without being encumbered by the others.

[!note] Notes Les langages devraient tous être multiparadigmes, pour pouvoir choisir les bons concepts en fonction du problème. ^4YR7745QaP4L4LCJZg5383243p2

créer un paradigme pour chaque type de problème

avantages des langages multi-paradigme

Les paradigmes comme outil pour la pensée

Connaître un système de calcul ne permet pas d'immédiatement tout connaître sur son champ d'expressivité Notamment :

  • connaître un système de calcul ne permet pas (toujours) de connaître l'ensemble des problèmes décidables de ce système

De la même manière, connaître un langage de programmation ne permet pas de savoir immédiatement résoudre tous les problèmes que l'on peut rencontrer. Par exemple, la syntaxe des langages similaires à LISP est très simple et peut être apprise en quelques heures pour certains dialectes. Cependant, connaître la syntaxe complête et le fonctionnement de LISP ne permettra pas de résoudre tout problème : il est également nécessaire d'être capable de "faire le lien" entre un problème et un langage. C'est ce lien que les paradigmes de programmation permettent de faire, soit en donnant explicitement une méthode pour le faire (comme la paradigme programmation structurée), soit en définissant comment le programmeur doit voir les programmes, soit en implémentant certaines fonctionnalités utiles pour gérer certains problèmes.

!!!! contre la distinction entre les paradigmes !!!!

note: cette section pourrait être en ouverture

La dinstinction entre les différents paradigmes n'est pas toujours claire : beaucoup de langages sont Remplissage du plan de L3#les langages multi-paradigmes, et certains paradigmes peuvent être utilisés dans presque tous les langages (par exemple, la programmation structurée ref)

Certains auteurs considèrent que les paradigmes ne sont pas fondamentalement différents (voir : Remplissage du plan de L3#Au sens formel), mais plutôt que les paradigmes sont des courants de pensée, des traditions dans la programmation, rattachées à des communautés 36.

Greg Michaelson critique la distinction des paradigmes, en expliquant que, lorsqu'on les analyse profondément, les paradigmes sont en fait proche entre-eux 37.


  1. "A programming paradigm is an approach to programming a computer based on a mathematical theory or a coherent set of principles." [@royProgrammingParadigmsDummies] ↩︎

  2. "It says a lot about what functional programming is not [...] but not much about what it is." [@hughesWhyFunctionalProgramming1989, p.1] ↩︎

  3. "It is a logical impossibility to make a language more powerful by ommitting features, no matter how bad they may be" [@hughesWhyFunctionalProgramming1989, p.1] ↩︎

  4. "The contrast between function and procedure is a reflection of the general distinction between describing properties of things and describing how to do things, or, as it is sometimes referred to, the distinction between declarative knowledge and imperative knowledge. In mathematics we are usually concerned with declarative (what is) descriptions, whereas in computer science we are usually concerned with imperative (how to) descriptions." [@abelsonStructureInterpretationComputer1996, p.28] ↩︎

  5. par exemple, Fellesein dans cette expression : "(let x be v in e) is expressible as (apply (procedure x e) v)" [@felleisenExpressivePowerProgramming1990, p.135] ↩︎

  6. "From an implementation viewpoint, a closure combines a procedure with its external references (the references it uses at its definition)." [@royProgrammingParadigmsDummies, p.24] ↩︎

  7. "Dans un langage de programmation, une fermeture ou clôture (en anglais : closure) est une fonction accompagnée de son environnement lexical. L'environnement lexical d'une fonction est l'ensemble des variables non locales qu'elle a capturées, soit par valeur (c'est-à-dire par copie des valeurs des variables), soit par référence (c'est-à-dire par copie des adresses mémoires des variables)[1]. Une fermeture est donc créée, entre autres, lorsqu'une fonction est définie dans le corps d'une autre fonction et utilise des paramètres ou des variables locales de cette dernière." [@FermetureInformatique2024] ↩︎

  8. From the programmers viewpoint, a closure is a “packet of work”: a program can transform any instructions into a closure at one point in the program, pass it to another point, and decide to execute it at that point. The result of its execution is the same as if the instructions were executed at the point the closure was created. [@royProgrammingParadigmsDummies, p.24] ↩︎

  9. "Une fermeture peut être passée en argument d'une fonction dans l'environnement où elle a été créée (passée vers le bas) ou renvoyée comme valeur de retour (passée vers le haut). Dans ce cas, le problème posé alors par la fermeture est qu'elle fait référence à des données qui auraient typiquement été allouées sur la pile d'exécution et libérées à la sortie de l'environnement. Hors optimisations par le compilateur, le problème est généralement résolu par une allocation sur le tas de l'environnement." [@FermetureInformatique2024] ↩︎

  10. "Control flow in imperative programming is explicit: commands show how the computation takes place, step by step. Each step affects the global state of the computation." [@toalProgrammingParadigms] ↩︎

  11. "Control flow in declarative programming is implicit: the programmer states only what the result should look like, not how to obtain it." [@toalProgrammingParadigms] ↩︎

  12. "In functional programming, control flow is expressed by combining function calls, rather than by assigning values to variables" [@toalProgrammingParadigms] ↩︎

  13. "Functional programming is so called because a program consists entirely of functions. The main program itself is written as a function which recieves the program's input as its argument and delivers the program's output as its result. Typically the main function is defined in terms of other functions, which in turn are defined in terms of still more functions, until at the bottom level the functions are language primitives. These functions are much like ordinary mathematical functions, and in this paper will be defined by ordinary equations." [@hughesWhyFunctionalProgramming1989, p.1] ↩︎

  14. "En mathématiques et en informatique, les fonctions d'ordre supérieur sont des fonctions qui ont au moins une des propriétés suivantes : elles prennent une ou plusieurs fonctions en entrée ; elles renvoient une fonction." [@FonctionOrdreSuperieur2023] ↩︎

  15. La logique combinatoire est un système de calcul dans lequel toutes les fonctions sont pures (il n'y a que des fonctions d'ordre supérieur dans ce système) [@LogiqueCombinatoire2023] ↩︎

  16. "Structured programming is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by making extensive use of the structured control flow constructs of selection (if/then/else) and repetition (while and for), block structures, and subroutines." [@StructuredProgrammingWikipedia] ↩︎

  17. "'Selection'; one or a number of statements is executed depending on the state of the program. This is usually expressed with keywords such as if..then..else..endif. The conditional statement should have at least one true condition and each condition should have one exit point at max." [@StructuredProgrammingWikipedia] ↩︎

  18. "'Iteration'; a statement or block is executed until the program reaches a certain state, or operations have been applied to every element of a collection. This is usually expressed with keywords such as while, repeat, for or do..until. Often it is recommended that each loop should only have one entry point (and in the original structural programming, also only one exit point, and a few languages enforce this)." [@StructuredProgrammingWikipedia] ↩︎

  19. "The most important difference between structured and unstructured programs is that the former are designed in a modular way. Modular design brings great productivity improvements. First of all, small modules can be coded quickly and easily. Secondly, general purpose modules can be reused, leading to faster development of subsequent programs. Thirdly, the modules of a program can be tested independently, helping to reduce the time spent debugging." [@hughesWhyFunctionalProgramming1989, p.2] ↩︎

  20. "Prolog: The first paradigm is a logic programming engine based on unification and depth-first search. The second paradigm is imperative: the assert and retract operations which allow a program to add and remove program clauses." [@royProgrammingParadigmsDummies, p.18] ↩︎

  21. "Solving libraries (e.g., Gecode): The first paradigm is a solver library based on advanced search algorithms, such as Gecode. The second paradigm is added by the host language, e.g., C++ and Java support object-oriented programming." [@royProgrammingParadigmsDummies, p.18] ↩︎

  22. "In computer science, the expressive power (also called expressiveness or expressivity) of a language is the breadth of ideas that can be represented and communicated in that language." [@ExpressivePowerComputer2023] ↩︎

  23. "The more expressive a language is, the greater the variety and quantity of ideas it can be used to represent" [@ExpressivePowerComputer2023] ↩︎

  24. "The term expressive power may be used with a range of meaning. It may mean a measure of the ideas expressible in that language: regardless of ease (theoretical expressivity); concisely and readily (practical expressivity)" [@ExpressivePowerComputer2023] ↩︎

  25. "The first sense dominates in areas of mathematics and logic that deal with the formal description of languages and their meaning, such as formal language theory, mathematical logic and process algebra" [@ExpressivePowerComputer2023] ↩︎

  26. "For example, the Web Ontology Language expression language profile (OWL2 EL) lacks ideas (such as negation) that can be expressed in OWL2 RL (rule language). OWL2 EL may therefore be said to have less expressive power than OWL2 RL. These restrictions allow for more efficient (polynomial time) reasoning in OWL2 EL than in OWL2 RL. So OWL2 EL trades some expressive power for more efficient reasoning (processing of the knowledge representation language)." [@ExpressivePowerComputer2023] ↩︎

  27. "G-code began as a limited language that lacked constructs such as loops, conditional operators, and programmer-declared variables with natural-word-including names (or the expressions in which to use them). It was unable to encode logic but was just a way to "connect the dots" where the programmer figured out many of the dots' locations longhand." [@Gcode2023] ↩︎

  28. "G-code (also RS-274) is the most widely used computer numerical control (CNC) and 3D printing programming language. It is used mainly in computer-aided manufacturing to control automated machine tools, as well as for 3D-printer slicer applications. The G stands for geometry. G-code has many variants." [@Gcode2023] ↩︎

  29. "The design of languages and formalisms involves a trade-off between expressive power and analyzability. The more a formalism can express, the harder it becomes to understand what instances of the formalism say. Decision problems become harder to answer or completely undecidable." [@ExpressivePowerComputer2023] ↩︎

  30. "We conclude that observable nondeterminism should be supported only if its expressive power is needed." [@royProgrammingParadigmsDummies, p.14] ↩︎

  31. "[...] les langages algébriques, appelés aussi langages hors contexte, langages acontextuels, ou langages non contextuels. Ils sont reconnus par un automate à pile." [@HierarchieChomsky2023] ↩︎

  32. "Les langages [...] contextuels ou sensibles au contexte, sont exactement ceux reconnus par une machine de Turing non déterministe à mémoire linéairement bornée, appelés couramment automates linéairement bornés." [@HierarchieChomsky2023] ↩︎

  33. "La classe des langages contextuels (type 1) est incluse strictement dans la classe des langages récursivement énumérables (type 0). L'inclusion de la classe des langages algébriques (type 2) dans la classe des langages contextuels (type 1) doit être précisée car un langage contextuel ne contient jamais le mot vide ε. L'énoncé exact est : Un langage algébrique ne contenant pas le mot vide est un langage contextuel ou, de manière équivalente : Un langage algébrique est un langage contextuel éventuellement augmenté du mot vide." [@HierarchieChomsky2023] ↩︎

  34. "Le problème de l'appartenance d'un mot à un langage algébrique est décidable : il existe un algorithme qui, étant donnés la description d'une grammaire non contextuelle et un mot, répond en temps fini à la question de l'appartenance de ce mot au langage défini par cette grammaire (plus précisément, on peut le tester en un temps O(n^{3}) pour un mot de longueur n, grâce à l'algorithme CYK)." [@AutomatePile2021] ↩︎

  35. "Le problème de l'appartenance d'un mot à un langage de cette classe [la classe des langages récursivement énumérables] est indécidable." [@HierarchieChomsky2023] ↩︎

  36. "In computer science, one sees several such communities, each speaking its own language and using its own paradigms. In fact, programming languages typically encourage use of some paradigms and discourage others." [@floydParadigmsProgramming1979a, p.2] ↩︎

  37. "Furthermore, it is not at all clear how programming paradigms are to be characterised and differentiated. Indeed, on closer inspection, apparently disparate programming paradigms are very strongly connected. Rather, they should be viewed as different traditions of a unitary Computer Science paradigm composed of programming languages which are all Turing Complete, complemented by methodologies which may all be subsumed by Computational Thinking." [@michaelsonProgrammingParadigmsTuring2020, p.41] ↩︎