Entspricht die Programmierung in der UNIX-Philosophie der funktionalen Programmierung?


30

Die UNIX-Programmierumgebung (der klassische Text) besagt, dass der UNIX-Programmieransatz darin besteht, kleine, genau definierte Tools zu erstellen, die kombiniert werden können, um komplexere Probleme zu lösen. Beim Erlernen von C und der Bash-Shell habe ich festgestellt, dass dies ein leistungsstarkes Konzept ist, mit dem sich eine Vielzahl von Programmierproblemen lösen lassen.

Nur mit einer Linux-Plattform ist das Konzept ziemlich klar und wird die ganze Zeit verwendet. Jeder Ausdruck in der Befehlszeile, der E / A umleitet und Systemtools wie ls, grep usw. verknüpft, zeigt, wie leistungsfähig dieses Konzept ist.

Das, was mich verwirrt, ist, dass viele dieser Programme in C geschrieben sind und einen imperativen / prozeduralen Programmierstil verwenden. Die Art und Weise, wie sie in der Befehlszeile verwendet und zusammengefügt werden, scheint mir jedoch viel mehr eine funktionale Programmierung zu sein, in der sich jedes Programm befindet Eine isolierte Funktion, die nicht vom Status eines anderen Programms abhängt, mit dem sie verbunden sein könnte.

Ist dies zutreffend? Ist das Verständnis der UNIX-Programmierphilosophie im Grunde eine funktionale Programmierung mit Tools, die möglicherweise mit einem imperativen Programmierstil erstellt wurden?


5
Ich denke nicht, dass es wichtig ist, ob diese Analogie korrekt ist oder nicht. Die Frage ist, ist es eine nützliche Analogie für Sie? Hilft es Ihnen, Programme zu schreiben und Ihre Arbeit zu erledigen?

Antworten:


19

Ich glaube , Sie dort einen Punkt haben, aber cp, rm, cdund viele anderen Zustand zu ändern, so dass sie nicht wirklich funktioniert sind. In der UNIX-Philosophie geht es eher darum, nur eines zu tun, aber es gut zu machen. oft bedeutet es gut zu machen, funktionale Nutzung zuzulassen, aber nicht immer.


9

Die Antwort liegt in der "Monadic I / O- und UNIX-Shell-Programmierung" von Oleg Kiselyov.

Dies ist ein Aufsatz, der von Philip Wadlers Aufsatz "Wie man einen Imperativ deklariert" [ Wadler97 ] inspiriert wurde . Wir werden unheimliche Ähnlichkeiten zwischen monadischem I / O in Haskell und UNIX-Filterkompositionen auf der Basis von Pipes und Umleitungen aufzeigen. UNIX-Pipes (semantisch so behandelt, als würden sie in temporäre Dateien schreiben) ähneln Monaden. Darüber hinaus können auf der Ebene der UNIX-Programmierung alle E / A als ...


6

Nun, ich denke, Sie können es so sehen, wenn Sie das ganze Problem der Nebenwirkungen ignorieren. Unix-Befehle funktionieren häufig NICHT, wenn immer derselbe Datensatz mit den gleichen Eingaben zurückgegeben wird. Wie Sie bereits erwähnt haben, ähnelt der Piping-Aspekt der Funktionsprogrammierung.


1
Hast du wirklich ein Flugzeug? ;) (sorry für offtopic Kommentar)
BlackBear

@BlackBear Nicht mein persönlicher. Ich bin in einem Club, in dem ungefähr 50 von uns zusammen 4 Flugzeuge besitzen. Auf diese Weise ist es etwas erschwinglicher. :-)
Brian Knoblauch

@Brian Knoblauch: Ich hätte gerne ein Flugzeug in der Zukunft .. Geld erlaubt: P
BlackBear

5
Funktionale Programmierung impliziert nicht "keine Nebenwirkungen". Das Konzept, bei dem dieselbe Funktion immer dasselbe Ergebnis liefert, wird als "Idempotenz" bezeichnet und ist keine notwendige Bedingung für die Funktionsfähigkeit eines Programms. Dies wird auch als "rein funktional" bezeichnet.

2

Bis zu einem gewissen Grad kann man das sagen. Das ist aber nicht unbedingt wahr. Ich denke, Sie sollten dies eher als „Fähigkeit, mehr zu erreichen“ mit einem simplen Designansatz verstehen. Und um einfach zu sein, müssen Sie die Aufgabe in leicht verständliche und leicht zu montierende Teile unterteilen. Die UNIX-Philosophie, offen mit Ihnen umzugehen, kann anhand des folgenden Beispiels erläutert werden.

Alle Programmierung ist eine Art Datenmanipulation! Und in manchen Fällen ist Programmierung auch Programmmanipulation selbst (Metaprogrammierung). Nun funktioniert die UNIX-Philosophie wie folgt: Stellen Sie sich vor, Sie verarbeiten Text. Was ist Text? Text ist schließlich eine Art von Daten. Beim Zusammenfügen in eine organisierte Definition wird Text auch zu XML und JSON. Text kann auch eine Liste von Zahlen sein, Text kann auch CSV's, TSV's und was nicht! In anderen Fällen kann Text oder Zeichenfolge einen wirklich großen Bereich von Programmierdaten darstellen, nur weil sein Kontext sich verdrehen und in das verwandeln lässt, was wir wollen!

Die gesamte Programmierung erfordert eine Art Datenorganisation. Organisation erfordert Suche ...

ein. Da muss man einfach mit 'grep', 'fgrep' und seiner Familie das machen.

Sobald Sie suchen, müssen Sie etwas sortieren.

b. Jetzt haben wir den Befehl 'sort', um das zu tun.

Sie haben gerade zwei Dateien sortiert und möchten sie nun vergleichen.

c. Jetzt haben wir 'diff', 'cmp' und andere, um das zu tun.

Sie haben gerade festgestellt, dass es keinen Unterschied zwischen den Dateien gibt. Sie benötigen jetzt mehr organisierte Daten.

d. Sie haben 'cat', Pipes und Umleitungsoperatoren, um in eine Datei zu schreiben.

Sie benötigen eine genauere Analyse.

e. Sie haben Kopf, Schwanz, mehr, weniger, schneiden usw., um das zu tun ...

Alles zusammennähen mit dem '|' um einige Zeit wirklich mächtiges Zeug zu generieren, ohne überhaupt Code zu schreiben. Für mehr Suchen und Nähen haben Sie ..

f. awk, shell und sed.

awk, shell und sed geben Ihnen mehr Kontrolle über den Text, als Sie von diff et al. Haben Sie sich jemals über diesen Befehl gewundert1 | befehl2 | Die Serie command3 ... ist eine Art Workflow-Mechanismus. In Kombination mit If's wird dies leistungsfähiger.

Jetzt kommt noch mehr Spaß.

Haben Sie jemals von einem Hilfsprogramm namens 'Perl' gehört , das so leistungsstark ist, dass Sie praktisch jede Aufgabe mit so wenig Arbeit erledigen können, wie Sie es sich vorstellen können? In Verbindung mit einem Dienstprogramm wie DBM können Sie selbst geringe Anforderungen an die Zeitbeständigkeit Ihrer Anwendung erfüllen. Denken Sie daran, wir sind noch nicht einmal aus der Textwelt herausgetreten, haben es jedoch geschafft, die meisten Aspekte einer Programmierumgebung abzudecken.

Ich denke also, UNIX ist mehr als ein Betriebssystem. Es handelt sich um eine Sammlung von Tools und Umgebungen, mit denen die Probleme auf einfachste Weise gelöst werden können. Ein einfacher Weg impliziert nicht unbedingt eine einfache Implementierung der Lösung. Aber die Einfachheit selbst bringt Sie nicht weit.

Ich habe dies einige wo auf reddit gelesen.

"Wenn Ihr einziges Konstruktionsziel die Einfachheit ist, erhalten Sie so viele Benutzer wie Plan9."


1

Die Art und Weise, wie sie in der Befehlszeile zusammengefügt werden und miteinander interagieren, ist sehr funktional. Ich würde jedoch sagen, dass dies mehr mit dem Design der Shell zu tun hat und weniger damit, ob diese zugrunde liegenden Programme zwingend oder funktional geschrieben sind. Die meisten guten funktionalen Sprachen unterstützen imperative / prozedurale Konzepte, obwohl sich ihr Gesamtdesign für die funktionale Programmierung eignet. Ja, viele der UNIX-Shell-Features verwenden Funktionskonzepte, aber auch dies liegt mehr am Design der Shell als an der speziellen Implementierung der zugrunde liegenden Programme.

Hoffe das hilft,

-tjw

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.