Ich habe im Internet nach einer Definition für deklarative und imperative Programmierung gesucht, die etwas Licht für mich bringen würde. Die Sprache, die bei einigen der Ressourcen verwendet wird, die ich gefunden habe, ist jedoch entmutigend - zum Beispiel bei Wikipedia . Hat jemand ein reales Beispiel, das er mir zeigen könnte, um diesem Thema eine Perspektive zu geben (vielleicht in C #)?
541
Antworten:
Ein gutes C # -Beispiel für deklarative vs. imperative Programmierung ist LINQ.
Mit der imperativen Programmierung teilen Sie dem Compiler Schritt für Schritt mit, was passieren soll.
Beginnen wir zum Beispiel mit dieser Sammlung und wählen die ungeraden Zahlen:
Mit der imperativen Programmierung würden wir dies durchgehen und entscheiden, was wir wollen:
Hier sagen wir:
Bei der deklarativen Programmierung hingegen schreiben Sie Code, der beschreibt, was Sie wollen, aber nicht unbedingt, wie Sie es erhalten (deklarieren Sie Ihre gewünschten Ergebnisse, aber nicht Schritt für Schritt):
Hier sagen wir "Gib uns alles, wo es seltsam ist", nicht "Schritt durch die Sammlung. Überprüfen Sie dieses Element, wenn es seltsam ist, fügen Sie es einer Ergebnissammlung hinzu."
In vielen Fällen ist Code auch eine Mischung aus beiden Designs, sodass er nicht immer schwarzweiß ist.
quelle
collection.Where
verwendet nicht die deklarative Syntax, die Linq bereitstellt - siehe msdn.microsoft.com/en-us/library/bb397906.aspx für Beispiele,from item in collection where item%2 != 0 select item
wäre die deklarative Form. Das Aufrufen einer Funktion wird nicht zu einer deklarativen Programmierung, nur weil sich diese Funktion im System.Linq-Namespace befindet.Deklarative Programmierung ist, wenn Sie sagen, was Sie wollen, und imperative Sprache ist, wenn Sie sagen, wie Sie bekommen, was Sie wollen.
Ein einfaches Beispiel in Python:
Das erste Beispiel ist deklarativ, da wir keine "Implementierungsdetails" für die Erstellung der Liste angeben.
Wenn Sie ein C # -Beispiel einbinden, ergibt die Verwendung von LINQ im Allgemeinen einen deklarativen Stil, da Sie nicht sagen, wie Sie das erhalten, was Sie möchten. Sie sagen nur, was Sie wollen. Das Gleiche könnte man über SQL sagen.
Ein Vorteil der deklarativen Programmierung besteht darin, dass der Compiler Entscheidungen treffen kann, die zu besserem Code führen können als von Hand. Wird mit dem SQL-Beispiel ausgeführt, wenn Sie eine Abfrage wie hatten
Der SQL "Compiler" kann diese Abfrage "optimieren", da er weiß, dass
id
es sich um ein indiziertes Feld handelt - oder möglicherweise nicht indiziert. In diesem Fall muss er ohnehin über den gesamten Datensatz iterieren. Oder vielleicht weiß die SQL-Engine, dass dies der perfekte Zeitpunkt ist, um alle 8 Kerne für eine schnelle parallele Suche zu nutzen. Sie , als Programmierer, die nicht mit einer dieser Bedingungen betroffen, und Sie haben keinen Code zu schreiben , keinen besonderen Fall in dieser Art und Weise zu handhaben .quelle
filter(lambda x: x < 5, range(20))
, ist nur eine weitere Umgestaltung in eine kürzere Notation. Dies unterscheidet sich in keiner sinnvollen Weise von dem Listenverständnisausdruck (der klare Abschnitte "map" und "filter" enthält), der mit der ausdrücklichen Absicht erstellt wurde (siehe Seite 202 ), eine präzisere Notation zu erstellen. Und dieses Listenverständnis wäre in diesem Fall klarer / idiomatischer.Deklarativ vs. Imperativ
Ein Programmierparadigma ist ein grundlegender Stil der Computerprogrammierung. Es gibt vier Hauptparadigmen: imperativ, deklarativ, funktional (was als Teilmenge des deklarativen Paradigmas betrachtet wird) und objektorientiert.
Deklarative Programmierung : ist ein Programmierparadigma, das die Logik einer Berechnung ausdrückt (Was tun), ohne ihren Kontrollfluss zu beschreiben (Wie tun). Einige bekannte Beispiele für deklarative domänenspezifische Sprachen (DSLs) sind CSS, reguläre Ausdrücke und eine Teilmenge von SQL (z. B. SELECT-Abfragen). Viele Auszeichnungssprachen wie HTML, MXML, XAML, XSLT ... sind häufig deklarativ. Die deklarative Programmierung versucht, die Unterscheidung zwischen einem Programm als Befehlssatz und einem Programm als Aussage über die gewünschte Antwort zu verwischen.
Imperative Programmierung : ist ein Programmierparadigma, das die Berechnung anhand von Anweisungen beschreibt, die einen Programmstatus ändern. Die deklarativen Programme können doppelt als Programmierbefehle oder mathematische Aussagen angesehen werden.
Funktionale Programmierung: ist ein Programmierparadigma, das die Berechnung als Bewertung mathematischer Funktionen behandelt und Zustands- und veränderbare Daten vermeidet. Es betont die Anwendung von Funktionen im Gegensatz zum imperativen Programmierstil, der Zustandsänderungen betont. In einer reinen Funktionssprache wie Haskell sind alle Funktionen ohne Nebenwirkungen, und Zustandsänderungen werden nur als Funktionen dargestellt, die den Zustand transformieren.
Das folgende Beispiel für die imperative Programmierung in MSDN durchläuft die Zahlen 1 bis 10 und findet die geraden Zahlen.
Beide Beispiele liefern das gleiche Ergebnis, und eines ist weder besser noch schlechter als das andere. Das erste Beispiel erfordert mehr Code, aber der Code ist testbar, und der zwingende Ansatz gibt Ihnen die volle Kontrolle über die Implementierungsdetails. Im zweiten Beispiel ist der Code wahrscheinlich besser lesbar. Mit LINQ haben Sie jedoch keine Kontrolle darüber, was hinter den Kulissen passiert. Sie müssen darauf vertrauen, dass LINQ das angeforderte Ergebnis liefert.
quelle
Alle obigen Antworten und andere Online-Beiträge erwähnen Folgendes:
Was sie uns nicht gesagt haben, ist, wie wir es erreichen können . Damit ein Teil des Programms deklarativer ist, müssen andere Teile die Abstraktion bereitstellen , um die Implementierungsdetails (die die imperativen Codes sind) auszublenden .
list.Where()
eine neue gefilterte Liste abrufen. Damit dies funktioniert, hat Microsoft alle Anstrengungen unternommen, die hinter der LINQ-Abstraktion stehen.Tatsächlich ist einer der Gründe, warum funktionale Programmierung und funktionale Bibliotheken deklarativer sind, dass sie Schleifen und Listenerstellungen abstrahiert haben und alle Implementierungsdetails (höchstwahrscheinlich imperative Codes mit Schleifen) hinter den Kulissen verbergen.
In jedem Programm haben Sie immer sowohl imperative als auch deklarative Codes. Sie sollten darauf abzielen, alle imperativen Codes hinter den Abstraktionen zu verbergen , damit andere Teile des Programms sie deklarativ verwenden können .
Obwohl funktionale Programmierung und LINQ Ihr Programm deklarativer machen können, können Sie es immer noch deklarativer machen, indem Sie mehr Abstraktionen bereitstellen. Zum Beispiel:
PS Das Extrem der deklarativen Programmierung besteht darin, neue domänenspezifische Sprachen (DSL) zu erfinden:
quelle
debit
,deposit
usw. statt eigener Verantwortung Code des Wiederholensaccount.balance += depositAmount
Ich werde ein weiteres Beispiel hinzufügen, das in der deklarativen / imperativen Programmierdiskussion selten auftaucht: die Benutzeroberfläche!
In C # können Sie eine Benutzeroberfläche mit verschiedenen Technologien erstellen.
Am zwingenden Ende können Sie DirectX oder OpenGL verwenden, um Ihre Schaltflächen, Kontrollkästchen usw. unbedingt Zeile für Zeile (oder wirklich Dreieck für Dreieck) zu zeichnen. Es liegt an Ihnen zu sagen, wie die Benutzeroberfläche gezeichnet wird.
Am deklarativen Ende haben Sie WPF. Sie schreiben im Grunde etwas XML (ja, ja, "XAML" technisch) und das Framework erledigt die Arbeit für Sie. Sie sagen, wie die Benutzeroberfläche aussieht. Es ist Sache des Systems, herauszufinden, wie es geht.
Wie auch immer, nur eine andere Sache, über die man nachdenken sollte. Nur weil eine Sprache deklarativ oder imperativ ist, heißt das nicht, dass sie bestimmte Merkmale der anderen nicht aufweist.
Ein Vorteil der deklarativen Programmierung besteht auch darin, dass der Zweck beim Lesen des Codes normalerweise leichter zu verstehen ist, während der Imperativ Ihnen eine genauere Kontrolle über die Ausführung gibt.
Das Wesentliche von allem:
Deklarativ ->
what
Sie wollen fertig seinImperativ ->
how
Sie wollen es getan habenquelle
Ich mochte eine Erklärung aus einem Cambridge-Kurs + ihre Beispiele:
int x;
- was (deklarativ)x=x+1;
- Wiequelle
CSS
ist Imperativ dann?Der Unterschied hängt hauptsächlich mit der gesamten Abstraktionsebene zusammen. Mit deklarativ sind Sie irgendwann so weit von den einzelnen Schritten entfernt, dass das Programm viel Spielraum hat, wie Sie Ihr Ergebnis erzielen können.
Sie könnten jede Anweisung als irgendwo auf ein Kontinuum fallend betrachten:
Abstraktionsgrad:
Beispiel der deklarativen realen Welt:
Imperatives Beispiel aus der realen Welt:
quelle
Calvert, C. Kulkarni, D. (2009). Essentieller LINQ. Addison Wesley. 48.
quelle
Imperative Programmierung sagt dem Computer explizit, was zu tun ist und wie es zu tun ist, wie z. B. die Angabe der Reihenfolge und dergleichen
C #:
Deklarativ ist, wenn Sie dem Computer sagen, was zu tun ist, aber nicht wirklich, wie es zu tun ist. Datalog / Prolog ist die erste Sprache, die in dieser Hinsicht in den Sinn kommt. Grundsätzlich ist alles deklarativ. Sie können die Bestellung nicht wirklich garantieren.
C # ist eine viel wichtigere Programmiersprache, aber bestimmte C # -Funktionen sind deklarativer, wie z. B. Linq
Das Gleiche könnte zwingend geschrieben werden:
(Beispiel aus Wikipedia Linq)
quelle
Von http://en.wikipedia.org/wiki/Declarative_programming
Kurz gesagt, die deklarative Sprache ist einfacher, weil ihr die Komplexität des Kontrollflusses fehlt (Schleifen, if-Anweisungen usw.).
Ein guter Vergleich ist das ASP.Net-Code-Behind-Modell. Sie haben deklarative '.ASPX'-Dateien und dann die imperativen' ASPX.CS'-Codedateien. Ich stelle oft fest, dass, wenn ich in der deklarativen Hälfte des Skripts alles tun kann, was ich brauche, viel mehr Leute verfolgen können, was getan wird.
quelle
Hier von Philip Roberts stehlen :
Zwei Beispiele:
1. Verdoppeln Sie alle Zahlen in einem Array
Imperativ:
Deklarativ:
2. Summieren Sie alle Elemente in einer Liste
Imperativ
Deklarativ
Beachten Sie, wie in den imperativen Beispielen eine neue Variable erstellt, mutiert und dieser neue Wert zurückgegeben wird (dh wie etwas geschehen kann), während die deklarativen Beispiele für eine bestimmte Eingabe ausgeführt werden und den neuen Wert basierend auf der ursprünglichen Eingabe zurückgeben (d. H. , was wir passieren wollen).
quelle
Imperative Programmierung
Eine Programmiersprache, die Programmierdisziplin wie C / C ++, Java, COBOL, FORTRAN, Perl und JavaScript erfordert. Programmierer, die in solchen Sprachen schreiben, müssen eine geeignete Reihenfolge der Aktionen entwickeln, um das Problem zu lösen, basierend auf Kenntnissen in Datenverarbeitung und Programmierung.
Deklarative Programmierung
Eine Computersprache, für die keine herkömmliche Programmierlogik geschrieben werden muss. Benutzer konzentrieren sich eher auf die Definition der Eingabe und Ausgabe als auf die Programmschritte, die in einer prozeduralen Programmiersprache wie C ++ oder Java erforderlich sind.
Deklarative Programmierbeispiele sind CSS, HTML, XML, XSLT, RegX.
quelle
Das deklarative Programm ist nur ein Datenelement für seine mehr oder weniger "universelle" imperative Implementierung / vm.
Pluspunkte: Die Angabe nur von Daten in einem fest codierten (und überprüften) Format ist einfacher und weniger fehleranfällig als die direkte Angabe einer Variante eines imperativen Algorithmus. Einige komplexe Spezifikationen können nicht direkt geschrieben werden, sondern nur in einer DSL-Form. Best und Freq, die in DSLs Datenstrukturen verwendet werden, sind Mengen und Tabellen. weil Sie keine Abhängigkeiten zwischen Elementen / Zeilen haben. und wenn Sie keine Abhängigkeiten haben, haben Sie die Freiheit, Änderungen vorzunehmen und die Unterstützung zu vereinfachen. (Vergleichen Sie zum Beispiel Module mit Klassen - mit Modulen, die Sie zufrieden stellen, und mit Klassen, bei denen Sie ein fragiles Basisklassenproblem haben.) Alle Güter der Deklarativität und DSL ergeben sich unmittelbar aus den Vorteilen dieser Datenstrukturen (Tabellen und Mengen). Ein weiteres Plus: Sie können die Implementierung der deklarativen Sprache vm ändern, wenn DSL mehr oder weniger abstrakt ist (gut gestaltet). zum Beispiel parallel implementieren.
Minuspunkte: Sie raten richtig. Die Implementierung eines generischen (und durch DSL parametrisierten) imperativen Algorithmus / VM kann langsamer und / oder speicherhungrig sein als die spezifische. in manchen Fällen. Wenn diese Fälle selten sind - vergessen Sie es einfach, lassen Sie es langsam sein. Wenn es häufig ist, können Sie Ihr DSL / VM für diesen Fall jederzeit erweitern. Irgendwo, wo alle anderen Fälle langsamer werden, klar ...
PS Frameworks liegt auf halbem Weg zwischen DSL und Imperativ. und wie alle Halfway-Lösungen ... kombinieren sie Mängel, nicht Vorteile. Sie sind nicht so sicher UND nicht so schnell :) Schauen Sie sich das Alleskönner-Haskell an - es liegt auf halbem Weg zwischen starker einfacher ML und flexiblem Metaprog Prolog und ... was für ein Monster es ist. Sie können Prolog als Haskell mit nur booleschen Funktionen / Prädikaten betrachten. und wie einfach seine Flexibilität gegen Haskell ist ...
quelle
Ich frage mich nur, warum niemand Attributklassen als deklaratives Programmierwerkzeug in C # erwähnt hat. Die beliebte Antwort auf dieser Seite hat gerade über LINQ als deklaratives Programmierwerkzeug gesprochen.
Laut Wikipedia
Daher ist LINQ als funktionale Syntax definitiv eine deklarative Methode, aber Attributklassen in C # als Konfigurationstool sind auch deklarativ. Hier ist ein guter Ausgangspunkt, um mehr darüber zu erfahren: Kurzübersicht über die C # -Attributprogrammierung
quelle
Nur um ein weiteres Beispiel für die Entwicklung mobiler Apps hinzuzufügen. In iOS und Android haben wir Interface Builder, mit denen wir die Benutzeroberfläche der Apps definieren können.
Die mit diesen Buildern gezeichnete Benutzeroberfläche ist deklarativer Natur, wobei wir die Komponenten ziehen und ablegen. Die eigentliche Zeichnung erfolgt darunter und wird vom Framework und System ausgeführt.
Wir können aber auch die gesamten Komponenten im Code zeichnen, und das ist von Natur aus unerlässlich.
Einige neue Sprachen wie Angular JS konzentrieren sich darauf, Benutzeroberflächen deklarativ zu entwerfen, und wir sehen möglicherweise viele andere Sprachen, die dieselbe Unterstützung bieten. Wie Java hat keine gute deklarative Möglichkeit, native Desktop-Apps in Java Swing oder Java FX zu zeichnen, aber in naher Zukunft könnten sie es einfach.
quelle
Nach meinem Verständnis haben beide Begriffe Wurzeln in der Philosophie, es gibt deklarative und imperative Arten von Wissen. Deklaratives Wissen sind Aussagen über die Wahrheit, Aussagen über Tatsachen wie mathematische Axiome. Es sagt dir etwas. Imperatives oder prozedurales Wissen zeigt Ihnen Schritt für Schritt, wie Sie zu etwas gelangen. Das ist im Wesentlichen die Definition eines Algorithmus. Wenn Sie möchten, vergleichen Sie eine Computerprogrammiersprache mit der englischen Sprache. Deklarative Sätze geben etwas an. Ein langweiliges Beispiel, aber hier ist eine deklarative Methode, um anzuzeigen, ob zwei Zahlen in Java gleich sind:
Imperative Sätze auf Englisch geben dagegen einen Befehl oder stellen eine Anfrage. Imperative Programmierung ist also nur eine Liste von Befehlen (mach das, mach das). Hier ist eine zwingende Möglichkeit, in Java anzuzeigen, ob zwei Zahlen gleich sind oder nicht, während Benutzereingaben akzeptiert werden:
Im Wesentlichen überspringt deklaratives Wissen bestimmte Elemente, um eine Abstraktionsebene über diesen Elementen zu bilden. Die deklarative Programmierung macht dasselbe.
quelle