... und ist wahrscheinlich einer dieser Artikel, auf denen OOP basierte.
Nicht wirklich, aber es fügte sich in die Diskussion ein, insbesondere für Praktiker, die zu dieser Zeit darauf trainiert waren, Systeme anhand der ersten Kriterien zu zerlegen, die er in dem Artikel beschreibt.
Zuerst möchte ich wissen, ob meine Einschätzung korrekt ist. Stimmen das FP-Paradigma und dieser Artikel philosophisch nicht überein?
Nein. Außerdem unterscheidet sich Ihre Beschreibung, wie ein FP-Programm aussieht, aus meiner Sicht nicht von anderen, die Prozeduren oder Funktionen verwenden:
Daten werden von Funktion zu Funktion weitergegeben, wobei jede Funktion die Daten genau kennt und sie auf dem Weg "ändert".
... mit Ausnahme des Teils "Intimität", da Sie Funktionen haben können (und dies häufig tun), die mit abstrakten Daten arbeiten, um die Intimität zu vermeiden. Sie haben also eine gewisse Kontrolle über diese "Intimität" und können sie regulieren, wie Sie möchten, indem Sie Schnittstellen (dh Funktionen) für das einrichten, was Sie ausblenden möchten.
Daher sehe ich keinen Grund, warum wir Parnas Kriterien für das Verbergen von Informationen mithilfe der funktionalen Programmierung nicht folgen und eine Implementierung eines KWIC-Indexes mit ähnlichen Vorteilen wie seine zweite Implementierung erzielen könnten.
Vorausgesetzt, sie stimmen überein, würde ich gerne wissen, wie FPs das Verbergen von Daten implementieren. Es ist offensichtlich, dass dies in OOP zu sehen ist. Sie können ein privates Feld haben, auf das niemand außerhalb der Klasse zugreifen kann. Es gibt keine offensichtliche Analogie zu mir in FP.
In Bezug auf Daten können Sie mit FP Datenabstraktionen und Datentypabstraktionen erstellen. Alle diese verbergen konkrete Strukturen und Manipulationen dieser konkreten Strukturen unter Verwendung von Funktionen als Abstraktionen.
BEARBEITEN
Es gibt eine wachsende Anzahl von Behauptungen, wonach das "Verbergen von Daten" im Kontext von FP nicht so nützlich ist (oder OOP-ish (?)). Lassen Sie mich hier ein sehr einfaches und klares Beispiel von SICP stempeln:
Angenommen, Ihr System muss mit rationalen Zahlen arbeiten. Eine Möglichkeit, sie darzustellen, besteht darin, sie als Paar oder als Liste mit zwei Ganzzahlen darzustellen: dem Zähler und dem Nenner. Somit:
(define my-rat (cons 1 2)) ; here is my 1/2
Wenn Sie die Datenabstraktion ignorieren, erhalten Sie den Zähler und Nenner höchstwahrscheinlich mit car
und cdr
:
(... (car my-rat)) ; do something with the numerator
Nach diesem Ansatz wissen alle Teile des Systems, die rationale Zahlen manipulieren, dass eine rationale Zahl a ist cons
- sie cons
nummerieren, um rationale Zahlen zu erstellen und sie mit Hilfe von Listenoperatoren zu extrahieren.
Ein Problem, mit dem Sie möglicherweise konfrontiert sind, besteht darin, dass Sie eine reduzierte Form der rationalen Zahlen benötigen - Änderungen sind im gesamten System erforderlich. Wenn Sie sich zum Zeitpunkt der Erstellung für eine Reduzierung entscheiden, ist es möglicherweise später besser, auf einen der rationalen Begriffe zuzugreifen, was zu einer weiteren vollständigen Änderung führt.
Ein anderes Problem ist, wenn hypothetisch eine alternative Darstellung für sie bevorzugt wird und Sie beschließen, die cons
Darstellung aufzugeben - Änderung des vollen Maßstabs erneut.
Jeder vernünftige Versuch, mit diesen Situationen umzugehen, wird wahrscheinlich die Darstellung von Begriffen hinter Schnittstellen verbergen. Am Ende könnte es so aussehen:
(make-rat <n> <d>)
gibt die rationale Zahl zurück, deren Zähler die ganze Zahl <n>
und deren Nenner die ganze Zahl ist <d>
.
(numer <x>)
Gibt den Zähler der rationalen Zahl zurück <x>
.
(denom <x>)
gibt den Nenner der rationalen Zahl zurück <x>
.
und das System wird nicht länger wissen (und sollte nicht länger wissen), woraus Rationals bestehen. Dies liegt daran cons
, car
und cdr
ist nicht wesentlich für rationals, aber make-rat
, numer
und denom
ist . Natürlich könnte dies leicht ein FP-System sein. "Verstecken von Daten" (in diesem Fall besser bekannt als Datenabstraktion oder der Versuch, Repräsentationen und konkrete Strukturen zu kapseln) ist ein relevantes Konzept und eine Technik, die weit verbreitet und erforscht ist, sei es im Kontext von OO, funktionaler Programmierung oder wie auch immer.
Und der Punkt ist ... obwohl man versuchen kann zu unterscheiden, welche Art von "Verstecken" oder Kapselung sie tun (ob sie eine Entwurfsentscheidung oder Datenstrukturen oder Algorithmen verstecken - im Fall von prozeduralen Abstraktionen), Alle haben das gleiche Thema: Sie sind motiviert durch einen oder mehrere Punkte, die ausdrücklich erwähnt wurden. Das ist:
- Änderbarkeit: Gibt an, ob erforderliche Änderungen vor Ort vorgenommen oder über das System verteilt werden können.
- Unabhängige Entwicklung: Inwieweit können zwei Teile des Systems parallel entwickelt werden?
- Verständlichkeit: Wie viel des Systems muss bekannt sein, um einen seiner Teile zu verstehen.
Das obige Beispiel wurde aus dem SICP-Buch entnommen, daher empfehle ich dringend, Kapitel 2 zu lesen, um dieses Konzept vollständig zu diskutieren und darzustellen . Ich empfehle auch, sich im Kontext von FP mit abstrakten Datentypen vertraut zu machen, wodurch andere Probleme auf den Tisch kommen.