Qu'est-ce que la programmation déclarative? [fermé]

193

Je continue d'entendre ce terme ballotté dans plusieurs contextes différents. Qu'Est-ce que c'est?

Brian G
la source
7
La réponse que vous avez sélectionnée pour être la bonne (indiquée par la coche verte) est incorrecte. Il ne définit pas ce qui distingue la programmation déclarative de son antithèse - programmation impérative. Veuillez envisager de modifier votre sélection.
Shelby Moore III
3
Oui, la réponse marquée comme correcte n'est PAS correcte.
Dermot
4
@ShelbyMooreIII Précisez également quelle réponse est correcte pour que nous puissions la lire!
vivek.m
@ vivek.m J'ai fourni une nouvelle réponse aujourd'hui.
Shelby Moore III

Réponses:

148

La programmation déclarative, c'est quand vous écrivez votre code de telle manière qu'il décrit ce que vous voulez faire, et non comment vous voulez le faire. Il appartient au compilateur de comprendre comment.

SQL et Prolog sont des exemples de langages de programmation déclaratifs.

1800 INFORMATION
la source
29
Vous avez encore à comprendre "comment" dire à l'ordinateur "ce que" vous voulez :)
hasen
7
@hasenj this et les autres réponses ne définissent pas le seul attribut non partagé avec la programmation impérative - qui est l' immuabilité .
Shelby Moore III
3
Ce sera vraiment génial si vous pouvez mentionner en quoi elle diffère de la programmation impérative (langages comme C, C ++, C #), alors il sera plus facile pour les lecteurs de faire la différence.
RBT
1
programmeur : "Je veux voyager à Paris." déclarative (c) : "Comment aimeriez-vous vous y rendre? naviguer en bateau? ou voler dans un avion? peut-être, naviguer à mi-chemin puis voler jusqu'à la fin du trajet?" programmeur : "Je n'ai aucun intérêt à savoir comment c'est fait." impératif (sql) : "Ne vous inquiétez pas. Je peux demander ce dont vous avez besoin." ( c'est ainsi que je comprends la réponse )
Nate
Comment SQL peut-il être déclaratif s'il prend en charge des expressions qui ne sont pas référentiellement transparentes?
java-addict301
80

Les autres réponses font déjà un travail fantastique pour expliquer ce qu'est la programmation déclarative, donc je vais juste donner quelques exemples de pourquoi cela pourrait être utile.

Indépendance du contexte

Les programmes déclaratifs sont indépendants du contexte . Parce qu'ils déclarent uniquement quel est le but ultime, mais pas les étapes intermédiaires pour atteindre ce but, le même programme peut être utilisé dans différents contextes. Cela est difficile à faire avec les programmes impératifs , car ils dépendent souvent du contexte (par exemple, l'état caché).

Prenons yaccl'exemple. C'est un générateur d'analyseur aka. compilateur compilateur, un DSL déclaratif externe pour décrire la grammaire d'une langue, afin qu'un analyseur syntaxique pour cette langue puisse être généré automatiquement à partir de la description. En raison de son indépendance du contexte, vous pouvez faire beaucoup de choses différentes avec une telle grammaire:

  • Générez un analyseur C pour cette grammaire (le cas d'utilisation d'origine de yacc )
  • Générer un analyseur C ++ pour cette grammaire
  • Générer un analyseur Java pour cette grammaire (en utilisant Jay)
  • Générer un analyseur C # pour cette grammaire (en utilisant GPPG)
  • Générer un analyseur Ruby pour cette grammaire (en utilisant Racc)
  • Générer une visualisation arborescente pour cette grammaire (à l'aide de GraphViz)
  • il suffit de faire une jolie impression, un formatage sophistiqué et une mise en évidence de la syntaxe du fichier source yacc lui-même et de l'inclure dans votre manuel de référence en tant que spécification syntaxique de votre langue

Et beaucoup plus …

Optimisation

Parce que vous ne prescrivez pas à l'ordinateur les étapes à suivre et dans quel ordre, il peut réorganiser votre programme beaucoup plus librement, voire exécuter certaines tâches en parallèle. Un bon exemple est un planificateur de requêtes et un optimiseur de requêtes pour une base de données SQL. La plupart des bases de données SQL vous permettent d'afficher la requête qu'elles exécutent réellement par rapport à la requête que vous leur avez demandé d'exécuter. Souvent, ces requêtes semblent ne riencomme l'autre. Le planificateur de requêtes prend en compte des choses dont vous n'auriez même pas rêvé: latence de rotation du plateau de disque, par exemple ou le fait qu'une application complètement différente pour un utilisateur complètement différent vient d'exécuter une requête similaire et la table que vous êtes joindre avec et que vous avez travaillé si dur pour éviter le chargement est déjà en mémoire de toute façon.

Il y a un compromis intéressant ici: la machine doit travailler plus fort pour savoir comment faire quelque chose que ce serait dans un langage impératif, mais quand il fait comprendre, il a beaucoup plus de liberté et beaucoup plus d' informations pour l'optimisation étape.

Jörg W Mittag
la source
23

Librement:

La programmation déclarative tend vers: -

  • Ensembles de déclarations, ou déclarations déclaratives, chacune ayant un sens (souvent dans le domaine du problème) et pouvant être comprise indépendamment et isolément.

La programmation impérative tend vers: -

  • Séquences de commandes, chacune exécutant une action; mais qui peut ou non avoir un sens dans le domaine problématique.

En conséquence, un style impératif aide le lecteur à comprendre la mécanique de ce que le système fait réellement, mais peut donner peu de renseignements sur le problème qu'il est censé résoudre. D'un autre côté, un style déclaratif aide le lecteur à comprendre le domaine du problème et l'approche que le système adopte vers la solution du problème, mais est moins informatif en matière de mécanique.

Les vrais programmes (même ceux écrits dans des langages qui favorisent les extrémités du spectre, tels que ProLog ou C) ont tendance à avoir les deux styles présents à différents degrés à différents points, pour satisfaire les complexités et les besoins de communication variés de la pièce. Un style n'est pas supérieur à l'autre; ils servent simplement à des fins différentes et, comme pour beaucoup de choses dans la vie, la modération est la clé.

William Payne
la source
Voilà la bonne réponse. Aucun de ces marmonnements ci
Krzysztof Wende
Merci non seulement d'avoir répondu à la question, mais de l'avoir fait "Expliquez comme si j'étais 5" avec du contexte et de la praticité. Excellente réponse.
monsto
17

Voici un exemple.

En CSS (utilisé pour styliser les pages HTML), si vous voulez qu'un élément d'image fasse 100 pixels de haut et 100 pixels de large, vous «déclarez» simplement que c'est ce que vous voulez comme suit:

#myImageId {
height: 100px;
width: 100px;
}

Vous pouvez considérer CSS comme un langage déclaratif de "feuille de style".

Le moteur de navigation qui lit et interprète ce CSS est libre de faire apparaître l'image aussi haute et aussi large qu'elle le souhaite. Différents moteurs de navigateur (par exemple, le moteur pour IE, le moteur pour Chrome) implémenteront cette tâche différemment.

Leurs implémentations uniques ne sont bien sûr PAS écrites dans un langage déclaratif mais dans un langage procédural comme Assembly, C, C ++, Java, JavaScript ou Python. Ce code est un ensemble d'étapes à effectuer étape par étape (et peut inclure des appels de fonction). Cela peut faire des choses comme interpoler des valeurs de pixels et effectuer un rendu à l'écran.

Niko Bellic
la source
11

Je suis désolé, mais je dois être en désaccord avec bon nombre des autres réponses. Je voudrais mettre fin à ce malentendu confus de la définition de la programmation déclarative.

Définition

La transparence référentielle (RT) des sous-expressions est le seul attribut requis d'une expression de programmation déclarative , car c'est le seul attribut qui ne soit pas partagé avec la programmation impérative.

D'autres attributs cités de la programmation déclarative, dérivent de ce RT. Veuillez cliquer sur l'hyperlien ci-dessus pour l'explication détaillée.

Exemple de feuille de calcul

Deux réponses ont mentionné la programmation par tableur. Dans les cas où la programmation de feuille de calcul (alias formules) n'accède pas à l' état global mutable , il s'agit alors d'une programmation déclarative. Cela est dû au fait que les valeurs des cellules mutables sont les entrées et sorties monolithiques de main()(l'ensemble du programme). Les nouvelles valeurs ne sont pas écrites dans les cellules après l'exécution de chaque formule, elles ne sont donc pas modifiables pendant la durée de vie du programme déclaratif (exécution de toutes les formules dans la feuille de calcul). Ainsi, les unes par rapport aux autres, les formules considèrent ces cellules mutables comme immuables. Une fonction RT est autorisée à accéder à un état global immuable (et également à un état local mutable ).

Ainsi, la possibilité de muter les valeurs dans les cellules à la fin du programme (en tant que sortie de main()) ne fait pas d'elles des valeurs stockées mutables dans le contexte des règles. La principale distinction est que les valeurs des cellules ne sont pas mises à jour après l'exécution de chaque formule de feuille de calcul, donc l'ordre d'exécution des formules n'a pas d'importance. Les valeurs des cellules sont mises à jour une fois toutes les formules déclaratives exécutées.

Shelby Moore III
la source
1
Des effets secondaires imprévus peuvent détruire la relation entre ce qui a été déclaré et le comportement réel du programme. Je l'ai expliqué plus en détail dans une nouvelle réponse .
Shelby Moore III
8

La programmation déclarative est l'image, où la programmation impérative est des instructions pour peindre cette image.

Vous écrivez dans un style déclaratif si vous «dites ce que c'est» plutôt que de décrire les étapes que l'ordinateur doit suivre pour arriver là où vous le souhaitez.

Lorsque vous utilisez XML pour baliser des données, vous utilisez une programmation déclarative parce que vous dites "C'est une personne, c'est un anniversaire et là-bas il y a une adresse".

Quelques exemples où la programmation déclarative et impérative sont combinées pour un plus grand effet:

  • Windows Presentation Foundation utilise la syntaxe XML déclarative pour décrire à quoi ressemble une interface utilisateur et quelles sont les relations (liaisons) entre les contrôles et les structures de données sous-jacentes.

  • Les fichiers de configuration structurés utilisent une syntaxe déclarative (aussi simple que des paires "clé = valeur") pour identifier la signification d'une chaîne ou d'une valeur de données.

  • HTML marque le texte avec des balises qui décrivent le rôle de chaque morceau de texte par rapport à l'ensemble du document.

Chris Wenham
la source
2
Bien que XML soit déclaratif, je n'irais pas jusqu'à dire que c'est de la programmation déclarative simplement parce qu'il n'y a pas de sémantique active associée au balisage. Dire que quelque chose est une adresse n'aide pas à déterminer ce que vous voulez en faire.
HenryR
1
Il doit y avoir un contexte sous-jacent (domaine?) Dans lequel le programme déclaratif est utilisé. Ainsi, l'utilisation de XML combiné avec ANT peut être interprétée comme un programme déclaratif.
Gutzofter
7

La programmation déclarative est une programmation avec des déclarations, c'est-à-dire des phrases déclaratives. Les phrases déclaratives ont un certain nombre de propriétés qui les distinguent des phrases impératives. En particulier, les déclarations sont:

  • commutatif (peut être réorganisé)
  • associatif (peut être regroupé)
  • idempotent (peut se répéter sans changement de sens)
  • monotone (les déclarations ne soustraient pas les informations)

Un point pertinent est que ce sont toutes des propriétés structurelles et orthogonales au sujet. Le déclaratif ne concerne pas «quoi vs comment» . Nous pouvons déclarer (représenter et contraindre) un "comment" aussi facilement que nous déclarons un "quoi" . Le déclaratif concerne la structure, pas le contenu. La programmation déclarative a un impact significatif sur la façon dont nous résumons et refactorisons notre code, et comment nous le modularisons en sous-programmes, mais pas tellement sur le modèle de domaine.

Souvent, nous pouvons convertir l'impératif en déclaratif en ajoutant du contexte. Par exemple, "Tournez à gauche. (... attendez ...) Tournez à droite." à "Bob tournera à gauche à l'intersection de Foo et Bar à 11h01. Bob tournera à droite à l'intersection de Bar et Baz à 11h06." Notez que dans ce dernier cas, les phrases sont idempotentes et commutatives, alors que dans le premier cas, réorganiser ou répéter les phrases changerait gravement la signification du programme.

En ce qui concerne les monotones , les déclarations peuvent ajouter des contraintes qui soustraient les possibilités . Mais les contraintes ajoutent toujours des informations (plus précisément, les contraintes sont des informations). Si nous avons besoin de déclarations variant dans le temps, il est typique de modéliser cela avec une sémantique temporelle explicite - par exemple de "la balle est plate" à "la balle est plate au temps T". Si nous avons deux déclarations contradictoires, nous avons un système déclaratif incohérent, bien que cela puisse être résolu en introduisant des contraintes douces (priorités, probabilités, etc.) ou en utilisant une logique paraconsistante.

dmbarbour
la source
1
Les expressions déclaratives contribuent au comportement prévu du programme, l'impératif peut contribuer à l'intention ou non. Le déclaratif n'a pas besoin d'être commutatif et idempotent, s'il s'agit d'une sémantique intentionnelle.
Shelby Moore III
6

Décrire à un ordinateur ce que vous voulez, pas comment faire quelque chose.

denonde
la source
6

imaginez une page excel. Avec des colonnes remplies de formules pour calculer votre déclaration de revenus.

Toute la logique se fait déclarée dans les cellules, l'ordre du calcul est à déterminer par formule elle-même plutôt que procéduralement.

C'est en quelque sorte ce qu'est la programmation déclarative. Vous déclarez l'espace du problème et la solution plutôt que le flux du programme.

Prolog est le seul langage déclaratif que j'utilise. Cela nécessite un autre type de réflexion, mais il est bon d'apprendre, si ce n'est que pour vous exposer à autre chose que le langage de programmation procédural typique.

paan
la source
6

J'ai affiné ma compréhension de la programmation déclarative, depuis décembre 2011 lorsque j'ai fourni une réponse à cette question. Voici ma compréhension actuelle.

La version longue de ma compréhension (recherche) est détaillée sur ce lien , que vous devriez lire pour acquérir une compréhension approfondie du résumé que je fournirai ci-dessous.

La programmation impérative est l'endroit où l'état mutable est stocké et lu, ainsi l'ordre et / ou la duplication des instructions du programme peut modifier le comportement (sémantique) du programme (et même provoquer un bogue, c'est-à-dire un comportement involontaire).

Dans le sens le plus naïf et le plus extrême (ce que j'ai affirmé dans ma réponse précédente), la programmation déclarative (DP) évite tout état mutable stocké, donc la commande et / ou la duplication des instructions du programme ne peut PAS altérer le comportement (sémantique) du programme .

Cependant, une définition aussi extrême ne serait pas très utile dans le monde réel, car presque chaque programme implique un état mutable stocké. L' exemple de feuille de calcul est conforme à cette définition extrême de DP, car le code de programme entier est exécuté jusqu'à son terme avec une copie statique de l'état d'entrée, avant que les nouveaux états ne soient stockés. Ensuite, si un état est modifié, cela se répète. Mais la plupart des programmes du monde réel ne peuvent pas se limiter à un tel modèle monolithique de changements d'état.

Une définition plus utile de DP est que l'ordre et / ou la duplication des instructions de programmation ne modifie aucune sémantique opaque. En d'autres termes, il n'y a pas de changements aléatoires cachés dans la sémantique - tout changement dans l'ordre des instructions du programme et / ou la duplication ne provoque que des changements intentionnels et transparents du comportement du programme.

La prochaine étape serait de parler des modèles de programmation ou des paradigmes qui contribuent au DP, mais ce n'est pas la question ici.

Shelby Moore III
la source
Mise à jour: veuillez également vous référer à l'explication plus exhaustive de mon autre réponse sur la définition de la programmation déclarative.
Shelby Moore III
Functional programmingest un mot à la mode de nos jours qui est essentiellement un sous-ensemble de programmation déclarative. LINQ en langage C # est un élément de la programmation fonctionnelle lorsque le langage lui-même est impératif par nature. Donc C # devient une sorte d'hybride selon cette définition.
RBT
1
Le lien compute.com est mort.
Kedar Mhaswade
5

C'est une méthode de programmation basée sur la description de ce que quelque chose devrait faire ou être au lieu de décrire comment cela devrait fonctionner.

En d'autres termes, vous n'écrivez pas d'algorithmes faits d'expressions, vous mettez simplement en page la façon dont vous voulez que les choses soient. HTML et WPF sont deux bons exemples.

Cet article Wikipedia est un bon aperçu: http://en.wikipedia.org/wiki/Declarative_programming

Kevin Berridge
la source
1
Petit problème. WPF est une bibliothèque, pas vraiment un langage ou un paradigme. Je pense que vous vouliez vraiment dire que XAML est un exemple de langage déclaratif.
Nick
Et comment décririez-vous la programmation à l'aide d'une bibliothèque / d'un framework?
Gutzofter
Il est incorrect de déclarer que la programmation déclarative ne peut pas contenir d'expressions. La principale distinction est que les expressions ne peuvent pas muter les valeurs stockées .
Shelby Moore III
HTML n'est pas un langage de programmation
lud
5

Depuis que j'ai écrit ma réponse précédente, j'ai formulé une nouvelle définition de la propriété déclarative qui est citée ci-dessous. J'ai également défini la programmation impérative comme la double propriété.

Cette définition est supérieure à celle que j'ai fournie dans ma réponse précédente, car elle est succincte et elle est plus générale. Mais il peut être plus difficile à comprendre, car les implications des théorèmes d'incomplétude applicables à la programmation et à la vie en général sont difficiles à comprendre pour les humains.

L'explication citée de la définition discute du rôle que joue la programmation fonctionnelle pure dans la programmation déclarative.

Déclaratif vs impératif

La propriété déclarative est étrange, obtuse et difficile à saisir dans une définition techniquement précise qui reste générale et non ambiguë, car c'est une notion naïve que nous pouvons déclarer le sens (alias sémantique) du programme sans encourir d'effets secondaires involontaires. Il existe une tension inhérente entre l'expression du sens et l'évitement des effets involontaires, et cette tension dérive en fait des théorèmes d'incomplétude de la programmation et de notre univers.

Il est simpliste, techniquement imprécis et souvent ambigu de définir déclaratif comme « quoi faire » et impératif comme « comment faire » . Un cas ambigu est le « quoi » est le « comment » dans un programme qui produit un programme - un compilateur.

Évidemment, la récursion illimitée qui rend un langage de Turing complet , est également analogue dans la sémantique - pas seulement dans la structure syntaxique de l'évaluation (alias la sémantique opérationnelle). Il s'agit logiquement d'un exemple analogue au théorème de Gödel: « tout système complet d'axiomes est également incohérent ». Méditez sur l'étrangeté contradictoire de cette citation! C'est aussi un exemple qui montre comment l'expression de la sémantique n'a pas de limite prouvable, donc nous ne pouvons pas prouver 2 qu'un programme (et de façon analogue sa sémantique) stoppe alias le théorème de Halting.

Les théorèmes d'incomplétude dérivent de la nature fondamentale de notre univers qui, comme indiqué dans la deuxième loi de la thermodynamique, est « l'entropie (alias le # de possibilités indépendantes) tend à atteindre son maximum pour toujours ». Le codage et la conception d'un programme ne sont jamais terminés - il est vivant! - car il tente de répondre à un besoin du monde réel, et la sémantique du monde réel est en constante évolution et tend vers plus de possibilités. Les humains ne cessent de découvrir de nouvelles choses (y compris des erreurs dans les programmes ;-).

Pour capturer précisément et techniquement cette notion souhaitée susmentionnée au sein de cet univers étrange qui n'a pas de bord (réfléchissez à cela! Il n'y a pas «à l'extérieur» de notre univers), nécessite une définition laconique mais trompeusement pas simple qui sonnera incorrecte jusqu'à ce qu'elle soit expliquée profondément.

Définition:


La propriété déclarative est l'endroit où il ne peut exister qu'un seul ensemble d'instructions possible pouvant exprimer chaque sémantique modulaire spécifique.

La propriété impérative 3 est le duel, où la sémantique est incohérente dans la composition et / ou peut être exprimée avec des variations d'ensembles d'énoncés.


Cette définition du déclaratif est distinctement locale dans la portée sémantique, ce qui signifie qu'elle nécessite qu'une sémantique modulaire conserve sa signification cohérente, peu importe où et comment elle est instanciée et utilisée dans la portée globale . Ainsi, chaque sémantique modulaire déclarative doit être intrinsèquement orthogonale à toutes les autres possibles - et non un algorithme ou un modèle global impossible (en raison des théorèmes d'incomplétude) pour témoigner de la cohérence, ce qui est également le point de " Plus n'est pas toujours mieux » de Robert Harper, professeur d'informatique à l'Université Carnegie Mellon, l'un des concepteurs de Standard ML.

Des exemples de ces sémantiques déclaratives modulaires incluent les foncteurs de théorie des catégories, par exemple leApplicative typage nominal, les espaces de noms, les champs nommés et les écritures au niveau opérationnel de la sémantique, puis la programmation fonctionnelle pure.

Ainsi, des langages déclaratifs bien conçus peuvent exprimer plus clairement le sens , quoique avec une certaine perte de généralité dans ce qui peut être exprimé, mais un gain dans ce qui peut être exprimé avec une cohérence intrinsèque.

Un exemple de la définition susmentionnée est l'ensemble des formules dans les cellules d'un tableur - qui ne devraient pas donner la même signification lorsqu'elles sont déplacées vers différentes cellules de colonne et de ligne, c'est-à-dire que les identificateurs de cellule ont été modifiés. Les identifiants de cellule font partie de la signification voulue et n'en sont pas superflus. Ainsi, chaque résultat de feuille de calcul est unique par rapport aux identificateurs de cellule dans un ensemble de formules. La sémantique modulaire cohérente dans ce cas est l'utilisation d'identificateurs de cellules comme entrée et sortie de fonctions pures pour les formules de cellules (voir ci-dessous).

Hyper Text Markup Language aka HTML - le langage des pages Web statiques - est un exemple de langage hautement (mais pas parfaitement 3 ) déclaratif qui (au moins avant HTML 5) n'avait pas la capacité d'exprimer un comportement dynamique. Le HTML est peut-être la langue la plus facile à apprendre. Pour un comportement dynamique, un langage de script impératif tel que JavaScript était généralement combiné avec HTML. Le HTML sans JavaScript correspond à la définition déclarative car chaque type nominal (c'est-à-dire les balises) conserve sa signification cohérente sous composition dans les règles de la syntaxe.

Une définition concurrente du déclaratif est les propriétés commutatives et idempotentes des instructions sémantiques, c'est-à-dire que les instructions peuvent être réorganisées et dupliquées sans changer la signification. Par exemple, les instructions affectant des valeurs aux champs nommés peuvent être réorganisées et dupliquées sans changer la signification du programme, si ces noms sont modulaires par rapport à un ordre implicite. Les noms impliquent parfois un ordre, par exemple les identifiants de cellule incluent leur position de colonne et de ligne - déplacer un total sur une feuille de calcul change sa signification. Sinon, ces propriétés nécessitent implicitement une valeur globalecohérence de la sémantique. Il est généralement impossible de concevoir la sémantique des instructions afin qu'elles restent cohérentes si elles sont ordonnées ou dupliquées de manière aléatoire, car l'ordre et la duplication sont intrinsèques à la sémantique. Par exemple, les énoncés «Foo existe» (ou construction) et «Foo n'existe pas» (et destruction). Si l'on considère l'incohérence aléatoire endémique de la sémantique voulue, alors on accepte cette définition comme suffisamment générale pour la propriété déclarative. En substance, cette définition est vide en tant que définition généralisée car elle tente de rendre la cohérence orthogonale à la sémantique, c'est-à-dire de défier le fait que l'univers de la sémantique est dynamiquement illimité et ne peut pas être capturé dans un paradigme de cohérence globale .

Le fait d'exiger les propriétés commutatives et idempotentes pour (l'ordre d'évaluation structurelle de) la sémantique opérationnelle de niveau inférieur convertit la sémantique opérationnelle en une sémantique modulaire localisée déclarative , par exemple la programmation fonctionnelle pure (y compris la récursion au lieu des boucles impératives). Ensuite, l'ordre opérationnel des détails d'implémentation n'affecte pas (c'est-à-dire se propage globalement ) la cohérence de la sémantique de niveau supérieur. Par exemple, l'ordre d'évaluation (et théoriquement aussi la duplication des) formules de feuille de calcul n'a pas d'importance car les sorties ne sont copiées dans les entrées qu'après que toutes les sorties ont été calculées, c'est-à-dire de manière analogue aux fonctions pures.

C, Java, C ++, C #, PHP et JavaScript ne sont pas particulièrement déclaratifs. La syntaxe de Copute et la syntaxe de Python sont couplées de manière plus déclarative aux résultats escomptés , c'est-à-dire à une sémantique syntaxique cohérente qui élimine les étrangers afin que l'on puisse facilement comprendre le code après l'avoir oublié. Copute et Haskell imposent le déterminisme de la sémantique opérationnelle et encouragent « ne vous répétez pas » (SEC), car ils ne permettent que le pur paradigme fonctionnel.


2 Même lorsque nous pouvons prouver la sémantique d'un programme, par exemple avec le langage Coq, cela est limité à la sémantique qui est exprimée dans le typage , et le typage ne peut jamais capturer toute la sémantique d'un programme - pas même pour les langages qui sont pas Turing complet, par exemple avec HTML + CSS, il est possible d'exprimer des combinaisons incohérentes qui ont donc une sémantique non définie.

3 De nombreuses explications prétendent à tort que seule la programmation impérative a des instructions ordonnées syntaxiquement. J'ai clarifié cette confusion entre programmation impérative et programmation fonctionnelle . Par exemple, l'ordre des instructions HTML ne réduit pas la cohérence de leur signification.


Edit: J'ai posté le commentaire suivant sur le blog de Robert Harper:

en programmation fonctionnelle ... la plage de variation d'une variable est un type

Selon la façon dont on distingue la programmation fonctionnelle de la programmation impérative, votre «assignable» dans un programme impératif peut également avoir un type qui limite la variabilité.

La seule définition non confuse que j'apprécie actuellement pour la programmation fonctionnelle est a) les fonctions en tant qu'objets et types de première classe, b) la préférence pour la récursivité sur les boucles, et / ou c) les fonctions pures - c'est-à-dire les fonctions qui n'ont pas d'impact sur la sémantique souhaitée du programme lorsqu'il est mémorisé ( donc la programmation fonctionnelle parfaitement pure n'existe pas dans une sémantique dénotationnelle à usage général en raison des impacts de la sémantique opérationnelle, par exemple l'allocation de mémoire ).

La propriété idempotente d'une fonction pure signifie que l'appel de fonction sur ses variables peut être substitué par sa valeur, ce qui n'est généralement pas le cas pour les arguments d'une procédure impérative. Les fonctions pures semblent être déclaratives par rapport aux transitions d'état non composées entre les types d'entrée et de résultat.

Mais la composition des fonctions pures ne maintient pas une telle cohérence, car il est possible de modéliser un processus impératif d'effets secondaires (état global) dans un langage de programmation fonctionnel pur, par exemple IOMonad de Haskell et de plus il est tout à fait impossible d'empêcher de le faire dans tout langage de programmation purement fonctionnel Turing complet.

Comme je l'ai écrit en 2012, ce qui semble être le même consensus de commentaires dans votre récent blog , que la programmation déclarative est une tentative de capturer l'idée que la sémantique prévue n'est jamais opaque. Des exemples de sémantique opaque sont la dépendance à l'ordre, la dépendance à l'effacement de la sémantique de niveau supérieur au niveau de la couche sémantique opérationnelle (par exemple, les transtypages ne sont pas des conversions et les génériques réifiés limitent la sémantique de niveau supérieur ), et la dépendance à des valeurs variables qui ne peuvent pas être vérifiées (prouvées correct) par le langage de programmation.

J'ai donc conclu que seules les langues complètes non-Turing peuvent être déclaratives.

Ainsi, un attribut non ambigu et distinct d'un langage déclaratif pourrait être qu'il peut être prouvé que sa sortie obéit à un ensemble énumérable de règles génératives. Par exemple, pour tout programme HTML spécifique (en ignorant les différences de divergence entre les interprètes) qui n'est pas scripté (c'est-à-dire n'est pas Turing complet), sa variabilité de sortie peut être énumérable. Ou plus succinctement, un programme HTML est une fonction pure de sa variabilité. Idem un tableur est une fonction pure de ses variables d'entrée.

Il me semble donc que les langages déclaratifs sont l'antithèse de la récursion illimitée , c'est-à-dire que, selon le deuxième théorème d'incomplétude de Gödel, les théorèmes autoréférentiels ne peuvent pas être prouvés.

Lesie Lamport a écrit un conte de fées sur la façon dont Euclide aurait pu contourner les théorèmes d'incomplétude de Gödel appliqués aux preuves mathématiques dans le contexte du langage de programmation par la congruence entre les types et la logique (correspondance Curry-Howard, etc.).

Shelby Moore III
la source
4

La programmation déclarative est "l'acte de programmer dans des langages conformes au modèle mental du développeur plutôt qu'au modèle opérationnel de la machine".

La différence entre la programmation déclarative et impérative est bien illustrée par le problème de l'analyse des données structurées.

Un programme impératif utiliserait des fonctions mutuellement récursives pour consommer les entrées et générer des données. Un programme déclaratif exprimerait une grammaire qui définit la structure des données afin qu'elles puissent ensuite être analysées.

La différence entre ces deux approches est que le programme déclaratif crée un nouveau langage qui est plus étroitement associé au modèle mental du problème que son langage hôte.

dan_waterworth
la source
2

Cela peut sembler étrange, mais j'ajouterais Excel (ou n'importe quelle feuille de calcul vraiment) à la liste des systèmes déclaratifs. Un bon exemple de cela est donné ici .

Lunatik
la source
1

Je l'expliquerais car DP est un moyen d'exprimer

  • Une expression d'objectif , les conditions de - ce que nous recherchons. Y en a-t-il un, peut-être ou plusieurs?
  • Quelques faits connus
  • Des règles qui étendent les faits connus

... et où il existe un moteur de déduction qui travaille généralement avec un algorithme d' unification pour trouver les objectifs.

epatel
la source
-1

Pour autant que je sache, il a commencé à être utilisé pour décrire des systèmes de programmation comme Prolog, parce que prolog consiste (soi-disant) à déclarer des choses de manière abstraite.

Cela signifie de plus en plus très peu, car il a la définition donnée par les utilisateurs ci-dessus. Il devrait être clair qu'il existe un fossé entre la programmation déclarative de Haskell, par rapport à la programmation déclarative de HTML.

Marcin
la source
1
Il n'y a pas de "gouffre entre la programmation déclarative de Haskell, par rapport à la programmation déclarative de HTML", car l' attribut racine de la programmation déclarative est l'immuabilité des valeurs stockées.
Shelby Moore III
Quoi qu'il en soit, il y a une bonne différence entre un langage spécifique à un domaine qui est contraint même dans ses calculs implicites, par rapport à un système de programmation complet.
Marcin
D'accord. La complétude de Turing est orthogonale à l'immuabilité des valeurs stockées. Il ne faut donc pas confondre avec l'attribut déclaratif vs impératif. Merci d'avoir pensé à l'un des attributs (Turing-complétude) qui peuvent provoquer ce "gouffre".
Shelby Moore III
La rotation complète ne nécessite qu'une récursion illimitée . L'immuabilité des valeurs stockées n'exclut pas une récursion illimitée. Ce sont donc des attributs orthogonaux.
Shelby Moore III
-2

Quelques autres exemples de programmation déclarative:

  • Balisage ASP.Net pour la liaison de données. Il dit simplement "remplir cette grille avec cette source", par exemple, et laisse au système le soin de procéder.
  • Expressions Linq

La programmation déclarative est agréable car elle peut aider à simplifier votre modèle mental * de code, et parce qu'elle pourrait éventuellement être plus évolutive.

Par exemple, supposons que vous ayez une fonction qui fait quelque chose pour chaque élément d'un tableau ou d'une liste. Le code traditionnel ressemblerait à ceci:

foreach (object item in MyList)
{
   DoSomething(item);
}

Pas grand-chose là-bas. Mais que faire si vous utilisez la syntaxe plus déclarative et définissez à la place DoSomething () en tant qu'action? Ensuite, vous pouvez le dire de cette façon:

MyList.ForEach(DoSometing);

C'est, bien sûr, plus concis. Mais je suis sûr que vous avez plus de soucis que de simplement enregistrer deux lignes de code ici et là. Les performances, par exemple. À l'ancienne, le traitement devait se faire en séquence. Et si la méthode .ForEach () vous permettait de signaler qu'elle pouvait gérer le traitement en parallèle, automatiquement? Maintenant, tout d'un coup, vous avez rendu votre code multithread d'une manière très sûre et n'avez modifié qu'une seule ligne de code. Et, en fait, il existe une extension pour .Net qui vous permet de faire exactement cela.

  • Si vous suivez ce lien, il vous amène à un article de blog par un de mes amis. Le message entier est un peu long, mais vous pouvez faire défiler la page intitulée "Le problème" _et le récupérer là-bas sans problème. *
Joel Coehoorn
la source
1
Vous décrivez la programmation fonctionnelle, pas la programmation déclarative . La programmation déclarative a pour attribut de ne pas muter les valeurs stockées .
Shelby Moore III
La programmation déclarative peut muter les valeurs stockées ... c'est juste que vous spécifiez (déclarez) ce que vous voulez muter au lieu de savoir exactement comment procéder pour le muter. Que pensez-vous d'autre d'une instruction SQL INSERT ou UPDATE dans SQL?
Joel Coehoorn
Vous manquez le point que si vos fonctions ne sont pas pures, des effets secondaires non intentionnels peuvent détruire la relation entre ce que vous avez déclaré et le comportement réel du programme. Je l'ai expliqué plus en détail dans une nouvelle réponse .
Shelby Moore III
-3

Cela dépend de la façon dont vous soumettez la réponse au texte. Dans l'ensemble, vous pouvez regarder le programme sous une certaine vue, mais cela dépend de l'angle sous lequel vous regardez le problème. Je vais vous aider à démarrer avec le programme: Dim Bus, Car, Time, Height As Integr

Encore une fois, cela dépend de ce que le problème est global. Vous devrez peut-être le raccourcir en raison du programme. J'espère que cela vous aide et avez besoin des commentaires si ce n'est pas le cas. Merci.

Danny Darrie
la source