Ich interessiere mich für funktionale Programmierung und habe mich entschieden, mit Haskell in Kontakt zu treten. Mein Kopf tut weh ... aber irgendwann bekomme ich es ... Ich habe eine Kuriosität, warum ist die Syntax so kryptisch (in Ermangelung eines anderen Wortes)?
Gibt es einen Grund, warum es nicht ausdrucksvoller und menschlicher ist?
Ich verstehe, dass FP gut in der Modellierung mathematischer Konzepte ist und einige seiner prägnanten Ausdrucksmittel entlehnt hat, aber es ist immer noch keine Mathematik ... es ist eine Sprache.
Antworten:
Funktionssprachen wie Haskell und seine Vorgängerin Miranda sind aus dem mathematischen Konzept der Lambda-Rechnung hervorgegangen . Von der Wikipedia-Seite:
Aufgrund dieser Geschichte wird die Syntax dieser funktionalen Sprachen (und der funktionalen Elemente von imperativeren Sprachen) stark von der mathematischen Notation beeinflusst, die von der Lambda-Rechnung verwendet wird.
Die Genauigkeit, mit der sowohl mathematische Notationen als auch Computersprachen Anforderungen beschreiben können, und die Genauigkeit, mit der Computer ihre Anweisungen schreiben müssen, korrelieren gut miteinander. Die Ungenauigkeit der natürlichen Sprache stellt jedoch eine große Hürde für die Programmierung von Computern dar. Sogar die (wohl) erfolgreichsten Programmierumgebungen für natürliche Sprachen wie Wolfram Alpha benötigen eine beträchtliche Domänenerfahrung, um effektiv eingesetzt zu werden.
quelle
Die Haskell-Syntax ist der menschlichen Sprache sehr ähnlich. Es ist speziell so konzipiert, dass es der mathematischen Notation ähnelt. Dies ist eine Sprache, die von Menschen entworfen wurde (also eine menschliche Sprache ), um genau die Konzepte auszudrücken, auf denen Haskell aufbaut.
Sie können jedem Mathematiker oder Logiker einen Teil des Haskell-Codes zeigen, und er wird ihn verstehen können, auch wenn er noch nie von Haskell gehört hat und absolut nichts über Programmierung, Informatik oder sogar Computer weiß.
Auf der anderen Seite können Sie jedem Mathematiker oder Logiker einen Code wie diesen zeigen:
und er wird zutiefst verwirrt sein und sagen: "Das ergibt keinen Sinn, es gibt keinen
x
, derx
gleichx
plus ist1
."Ob eine bestimmte Notation "kryptisch" ist oder nicht, ist eine Frage der Meinung und Vertrautheit.
quelle
where
ermöglichen , den Kern zu kondensieren eine Funktion in einer Zeile.x = infinity
dies tatsächlich die Gleichung löst.Ich denke, eine Sache, auf die Sie wahrscheinlich stoßen, ist etwas, auf das ich beim Erlernen der funktionalen Programmierung gestoßen bin. Das heißt, dass Sie mit funktionaler Programmierung auf einer höheren Ebene denken / arbeiten können (und fast müssen) als mit imperativer Programmierung.
Was Sie finden , als weniger ausdrucksstark , ich denke , ist eigentlich mehr expressive: Sie müssen nicht jedes kleine Detail darzulegen, und kann mehr mit weniger Code in der funktionalen Programmierung tun - es gibt mehr Kraft auf das, was Sie schreiben.
Zum Beispiel könnte ich unbedingt schreiben:
was als Englisch total lesbar ist.
Eine Haskell-Version könnte sein (und dies ist keine gültige Haskell-Version, sondern nur zum syntaktischen Vergleich):
Das erfordert weniger Code und weniger Detail-Wrangling. Ich muss die Dinge nicht in eine Schleife und ihre Variablen () aufteilen.
for each (...)
Diemap
Funktion erledigt das für mich.Das Arbeiten auf diesem Niveau kann gewöhnungsbedürftig sein. Wenn es hilft, war Haskell wahrscheinlich die schwierigste Zeit, in der ich seit Beginn des Programmierens eine neue Sprache gelernt habe, und ich kenne> 10 Sprachen (einschließlich Lisp). Das Lernen hat sich gelohnt.
quelle
Momentan habe ich es mit Scala zu tun, damit ich mitfühlen kann. Zumindest mit Scala kann ich auf einen imperativen Stil zurückgreifen, wenn es zu schwierig wird.
Ich denke, dass hier mehrere Kräfte im Spiel sind:
Designer von funktionalen Sprachen haben notwendigerweise einen starken mathematischen Hintergrund, daher leihen sie sich eine mathematische Notation aus, die für sie selbstverständlich ist.
Eine größere Ausdruckskraft (dh Aussagekraft statt Nähe zum Englischen) einer Sprache hat (IMO) einen entsprechenden Preis für die Steilheit der Lernkurve. Knappheit hat in Scala einen hohen Stellenwert, viele Dinge sind optional.
Funktionale Sprachen verhalten sich einfach ganz anders, sodass die Grundoperationen nicht auf imperative Konstrukte abgebildet werden.
quelle
Wenn ich Ihren letzten Kommentar richtig verstanden habe, ist Ihre Frage, warum Haskell häufig symbolische Operatoren an Stellen verwendet, an denen auch alphanumerische Schlüsselwörter (oder Funktionsnamen) verwendet werden könnten.
In Bezug auf Stichwörter würde eine Antwort sein, dass Stichwörter verhindern, dass Sie bestimmte Wörter als Variablennamen verwenden. Zum Beispiel ärgere ich mich immer, wenn ich meine Variablen aufrufen möchte
from
undto
in einer Sprache, in der eines davon ein Schlüsselwort ist - wie in Python.Ein weiterer Grund für symbolische Operatoren im Allgemeinen ist die Prägnanz. Das trifft in Ihren spezifischen Beispielen für Listenverständnisse nicht wirklich zu (
<-
ist nicht kürzer alsin
), aber in vielen Fällen schon.Ein weiterer Grund ist die Lesbarkeit. Dies mag kontraintuitiv erscheinen, da symbolische Operatoren oft schwieriger zu erlernen sind, da ihre "Namen" nicht wirklich Aufschluss darüber geben, was sie tun (wie es der Name einer Funktion normalerweise tut), aber sobald Sie wissen, was ein bestimmter Operator tut, Ausdrücke mit symbolischen Infix-Operatoren sind für einen Menschen oft einfacher zu analysieren als für einen Menschen mit vielen alphanumerischen Präfix-Funktionsaufrufen, da die Operatoren auf diese Weise visuell leichter von den Operanden unterschieden werden können. Zum Beispiel würden die meisten Leute zustimmen, dass dies
2 * 3 + 4
leichter lesbar ist alsadd (mult 2 3) 4
oderadd(mult(2, 3), 4)
.quelle
Imperative Computersprachen kommen natürlichen Sprachen meist nicht näher als beispielsweise Haskell.
Einige sind jedoch so konzipiert, dass sie dem Englischen ähnlicher sind: zum Beispiel Cobol und Hypercard. Die Lehren, die ich aus diesen Beispielen ziehen würde, sind:
Die Perl-Computersprache wurde Berichten zufolge unter Berücksichtigung einiger subtilerer Aspekte der natürlichen Sprache entwickelt . Ich würde beurteilen, dass Perl in Bezug auf die allgemeine Benutzerfreundlichkeit besser abschneidet als Cobol oder Hypercard, aber die Leute haben unterschiedliche Meinungen über Perl.
quelle
Ich denke, Haskell wird der menschlichen Sprache so ähnlich, wie man es ohne eine verrückte Syntax erreichen kann. Das geht wirklich sehr weit, zum Beispiel mit der
where
Klausel, eine Definition aufzuschieben, und mit der Syntax des Listenverständnisses, die genau das ist, was ich an eine Tafel schreiben würde. Es vermeidet auch unnötige Zeichen wie geschweifte Klammern und verwendet Einrückungen großzügig. Das typische Beispiel ist Quicksort:Zugegeben, es ist ein einfaches Beispiel, aber ich kenne keine andere Sprache, die es so lesbar macht wie diese.
Kompliziertere Dinge zu tun kann in Haskell schwierig werden, aber das hat mit dem Typsystem, dem eingeschränkten IO und überhaupt nicht mit der Syntax zu tun.
Wenn überhaupt, würde ich sagen, dass Haskell syntaktische Einfachheit geopfert hat, um einer Syntax Rechnung zu tragen, die der menschlichen Sprache ähnlicher ist. Ein sprachähnliches Schema hat eine Syntax, die sehr weit von dem entfernt ist, was ein Mensch schreiben würde, aber es ist wirklich einfach, seine Regeln zu erklären.
quelle
++ [p] ++
?Ich denke, der Unterschied liegt in der Art und Weise, wie funktionale / deklarative Programmierung Aussagen über ein Problem macht, als wäre es ein mathematisches Problem, in dem imperative Programmierung einen Prozess beschreibt . In der Geschäftswelt umschließen oder ersetzen Computerprogramme physische Prozesse, sodass Sie möglicherweise eine Sprache finden, die dies als intuitiver erweist.
Es stellt sich heraus, dass sich der funktionale Stil dazu eignet, mehrere Prozessoren sicher zu verwenden (da er die Veränderlichkeit und die Nebenwirkungen minimiert) - etwas, von dem wir in Zukunft mehr sehen werden. Außerdem verfügen die meisten modernen funktionalen Sprachen über Sammlungen mit Iteratoren, an die Sie Funktionen übergeben können. Diese Methoden können ihre Arbeitslast sehr effizient auf mehrere Prozessoren aufteilen, ohne dass Sie davon etwas wissen.
quelle