Was sind Beispiele für Inkonsistenz und Unvollständigkeit in Unix / C?


20

In Richard Gabriels berühmtem Aufsatz The Rise of Worse is Better stellt er karikaturisierte Versionen der Designphilosophien MIT / Stanford (Lisp) und New Jersey (C / Unix) in Bezug auf Einfachheit, Korrektheit, Konsistenz und Vollständigkeit gegenüber. Er führt das Beispiel des "PC-Verlierer-Problems" an ( das an anderer Stelle von Josh Haberman erörtert wurde ), um zu argumentieren, dass Unix der Einfachheit der Implementierung Vorrang vor der Einfachheit der Schnittstelle einräumt.

Ein anderes Beispiel, das ich mir ausgedacht habe, sind die unterschiedlichen Herangehensweisen an Zahlen. Lisp kann beliebig große Zahlen darstellen (bis zur Größe des Speichers), während C Zahlen auf eine feste Anzahl von Bits begrenzt (normalerweise 32-64). Ich denke, das zeigt die Richtigkeitsachse.

Was sind einige Beispiele für Konsistenz und Vollständigkeit? Hier sind alle Beschreibungen von Gabriel (die er zugibt, dass es sich um Karikaturen handelt):

Der MIT / Stanford-Ansatz

  • Einfachheit - Das Design muss sowohl in der Implementierung als auch in der Benutzeroberfläche einfach sein. Es ist wichtiger, dass die Schnittstelle einfach ist als die Implementierung.
  • Korrektheit - Das Design muss in allen beobachtbaren Aspekten korrekt sein. Falschheit ist einfach nicht erlaubt.
  • Konsistenz - Das Design darf nicht inkonsistent sein. Ein Design darf etwas weniger einfach und weniger vollständig sein, um Inkonsistenzen zu vermeiden. Konsistenz ist ebenso wichtig wie Korrektheit.
  • Vollständigkeit - das Design muss so viele wichtige Situationen abdecken, wie es praktisch ist. Alle vernünftigerweise erwarteten Fälle müssen abgedeckt werden. Einfachheit darf die Vollständigkeit nicht übermäßig beeinträchtigen.

Der New Jersey-Ansatz

  • Einfachheit - Das Design muss sowohl in der Implementierung als auch in der Benutzeroberfläche einfach sein. Es ist wichtiger, dass die Implementierung einfach ist als die Schnittstelle. Einfachheit ist die wichtigste Überlegung in einem Design.
  • Korrektheit - Das Design muss in allen beobachtbaren Aspekten korrekt sein. Es ist etwas besser, einfach als richtig zu sein.
  • Konsistenz - Das Design darf nicht zu inkonsistent sein. In einigen Fällen kann die Konsistenz der Einfachheit halber geopfert werden. Es ist jedoch besser, diejenigen Teile des Designs zu löschen, die mit weniger häufigen Umständen zu tun haben, als entweder Komplexität der Implementierung oder Inkonsistenz einzuführen.
  • Vollständigkeit - das Design muss so viele wichtige Situationen abdecken, wie es praktisch ist. Alle vernünftigerweise erwarteten Fälle sollten abgedeckt werden. Die Vollständigkeit kann zugunsten einer anderen Qualität geopfert werden. Tatsächlich muss die Vollständigkeit geopfert werden, wenn die Einfachheit der Implementierung gefährdet wird. Konsistenz kann geopfert werden, um Vollständigkeit zu erreichen, wenn die Einfachheit beibehalten wird; Besonders wertlos ist die Konsistenz der Schnittstelle.

Bitte beachte, dass ich nicht frage, ob Gabriel Recht hat (eine Frage, die für StackExchange nicht geeignet ist), sondern nach Beispielen, auf die er sich möglicherweise bezogen hat.


6
Falls Sie neugierig sind, ist dies kein Problem mit den Hausaufgaben. Ich bin der Lehrer. :-) Beim zweiten Gedanken, vielleicht ist das meine Hausaufgabe.
Ellen Spertus

4
Ich habe Schwierigkeiten zu verstehen, warum diese Frage nicht unter Unix & Linux (oder vielleicht Software Engineering ?) Gestellt wird . Können Sie erläutern, inwiefern Sie eine CS-Perspektive in dieser Angelegenheit benötigen? Bitte klären Sie auch, ob Sie positive oder negative Beispiele wünschen.
Raphael

Passt diese Frage nicht besser zu programmers.stackexchange.com ?
Basile Starynkevitch

Ich habe dies auf CS gepostet, weil ich das Sprachdesign als einen der grundlegendsten Bereiche der Informatik betrachte, der Berechenbarkeit, Komplexität, Architektur, Benutzerfreundlichkeit usw. umfasst Aussicht. Was Programmierer angeht, sind die Leute mir fast immer feindlich gesonnen, wenn ich dort poste, auch wenn ich denke, dass ich mich mit Themen befasse, also halte ich mich von diesen fern.
Ellen Spertus

Antworten:


15

Der Titel der Frage deutet darauf hin, dass Sie einige grundlegende Inkonsistenzen in der Benutzeroberfläche interessieren könnten:

Unix-Befehle folgen keiner bestimmten Syntax für die Angabe von Optionen und Flags. Zum Beispiel verwenden die meisten Befehle einzelne Buchstaben, denen ein '-' als Flag vorangestellt ist cat -n some_file, aber Ausnahmen wie tar tf some_file.tarund dd in=some_file out=some_other_file count=2existieren in häufig verwendeten Befehlen.

Unix und seine Nachkommen und Verwandten haben mehrere leicht unterschiedliche Syntaxen für reguläre Ausdrücke. Shells verwenden "*", während andere Programme (grep, egrep, vi) ". *" Verwenden. egrep hat '+' und '|' grep als betreiber nicht.

Die grundlegende Systemaufrufschnittstelle "Alles ist eine Datei" könnte als unvollständig angesehen werden: Lesen / Schreiben / Suchen / Schließen passt nicht zu jedem E / A-Gerät. Die dringend benötigten Ausnahmen werden in "ioctl" -Aufrufe zusammengefasst, aber Geräte wie Soundkarten passen nicht einmal so gut.


Gute Antwort. Als ich den Titel sah, dachte ich sofort "ioctl" (und fcntl), aber jetzt muss ich keine Antwort eingeben.
Louis

1
Glob-Muster sind keine regulären Ausdrücke
jk.

8

Konsistenz

Lisp hat eine sehr konsistente Syntax, alle Spracherweiterungen können natürlich über Makros und dergleichen eingebettet werden. C hat andererseits eine ziemlich Code-Syntax, die es einem erlaubt, einige "Abkürzungen" zu nehmen, so dass C-Code in einigen Fällen tatsächlich einfacher aussieht.

Vollständigkeit

Wenn Sie in Lisp kein bestimmtes Sprachfeature benötigen, können Sie es selbst mit Makros implementieren. C hat auch Präprozessor, aber es ist ziemlich verwirrend.


8

Die Zeichenfolgen von C dürfen kein Zeichen 0 enthalten, und die Bibliotheksfunktionen sind nicht für den Umgang mit Binärdaten geeignet.

Dateinamen auf Unix-Systemen dürfen weder Zeichen 0 noch Zeichen 47 (Schrägstrich) enthalten.

In der ursprünglichen Implementierung von Unix waren die Dateinamen auf 14 Zeichen beschränkt. In späteren Versionen wurde diese Einschränkung nur gelockert. sie haben es nicht beseitigt.

Hinzugefügt : Die E2BIGSystemfehlerbedingung, wenn versucht wurde, execmit einer Argumentliste zu arbeiten, die zu viele Argumente enthält, oder wenn zu viel Speicher belegt ist oder wenn die Umgebung zu groß ist.

Unix ist für diese Art von willkürlicher Einschränkung berüchtigt. Bis zum Aufkommen von Perl im Jahr 1987 war der Umgang mit großen Datenmengen oder Datenmengen mit langen Datensätzen oder Binärdaten äußerst unzuverlässig.


Nichtzulassen /ist nicht willkürlich, es ist notwendig (?), Mehrdeutigkeiten aufzulösen, ebenso /wie das Pfadtrennzeichen. Ich habe gerade eine Datei erstellt 000, anscheinend ist diese spezifische Einschränkung in den Tagen eines modernen GNU / Linux weg.
Raphael

Ich wollte damit nicht sagen, dass das Verbot von /willkürlich war, sondern nur, dass die Begrenzungen für Zeilenlänge und Dateigröße willkürlich waren. Der Punkt ist jedoch, dass ein anderes Design erlaubt hätte, dass Dateinamen Schrägstriche enthalten, was die Designer von Unix jedoch nicht taten halte es für wichtig.
Mark Dominus

Ich bin mir sicher, dass diese Grenzwerte zu diesem Zeitpunkt aufgrund von Leistungsüberlegungen eingeführt wurden. Auch unentwickelte Techniken können dazu beitragen. Aus heutiger Sicht scheinen sie fragwürdig, das ist sicher. Was /mich betrifft , bin ich neugierig: Wenn ein Pfad als Zeichenfolge codiert werden soll, wie geht das ohne ein reserviertes Zeichen für die Pfadtrennung?
Raphael

Ich verstehe nicht, was du meinst. Die Frage fragt nach "Beispielen für Inkonsistenz und Unvollständigkeit in Unix / C". es wird keine Leistung erwähnt.
Mark Dominus

1
@Raphael: Sie beseitigen dumme Trennzeichenprobleme, indem Sie einen pathabstrakten Datentyp definieren , und verwenden diesen in Ihren Schnittstellen, anstatt eine bestimmte Implementierung (nullterminierte ASCII-Zeichenfolgen) verfügbar zu machen.
Wandering Logic

4

IIRC mein Lehrer sagte, dass die Unfähigkeit, char *Variablen in switchAnweisungen in C zu verwenden, eine Sache der Inkonsistenz ist, aber für mich war das eine Frage der Allgemeinheit (Vollständigkeit). Ich denke, es ist besser, "Konsistenz" nur in Ihren Algorithmen oder im Software-Design zu verwenden, nicht in der Programmiersprache selbst (zumindest nicht in Sprachen wie C. Vielleicht hat eine fehlerhafte Sprache Konsistenzprobleme), weil die Programmiersprachen solide Standards haben, die den Bereich der Regeln definieren und arbeiten, indem Sie Eingaben auf Regeln anwenden. Also, wenn etwas in der Sprache nicht erlaubt ist, ist es geplant , nicht erlaubt zu sein und ist keine Inkonsistenz in der Sprache, IMHO.


  1. Ich habe Allgemeingültigkeit als Vollständigkeit verwendet. Ich denke, sie sind dasselbe. vielleicht bin ich falsch.
  2. Dies ist keine Antwort. vielleicht vorschlag oder meine meinung.

3

Das beste Beispiel, das ich habe, ist der arme Benutzer, der eine Datei mit dem Namen .. -rund Namen eingegeben hat rm *.

Ob diese Geschichte wahr ist oder nicht, sie ist zum Klassiker eines Unix-Haters geworden.

Siehe Das Unix-Haters Handbook , die eine Einführung von Dennis Ritchie hat sich, für viele dieser Beispiele.

Ich füge hinzu, dass das Vermeiden dieser Art von Problemen eine wichtige Rolle bei der Entwicklung von Microsofts Power Shell gespielt hat.


Ich habe den Aufsatz von Richard Gabriel am Ende des Handbuchs der Unix-Hasser gelesen. :-)
Ellen Spertus

3
  • Die unzähligen Bedeutungen derselben (kurzen) Flags für Befehle sind sicherlich inkonsistent.
  • Jedes Programm, das reguläre Ausdrücke verwendet, hat eine eigene Syntax
  • Konfigurationsdateien für Dienste haben alle unterschiedliche Syntax (dies kann zum Teil verzeiht werden, Ihr Mailer-Daemon hat wenig mit Ihrem Webserver oder dem Systemstart zu tun, aber immer noch)
  • Es gibt verschiedene Editoren! Benutzer verwenden verschiedene Muscheln !! Warum gibt es so viele Desktop-Umgebungen?!?

OTOH, die Tatsache, dass die Shell die Globs erweitert und nicht das Programm, beseitigt viele irritierende Inkonsistenzen, die in anderen Systemen vorhanden sind. Dies gilt auch für die Tatsache, dass Sie mit demselben Befehl eine Datei von einem Ort zum anderen im Dateisystem, auf eine Diskette oder von einer Zip-Diskette auf Band kopieren können.

Also ja, Unix ist inkonsistent. So sind die anderen Systeme, nur anders ;-)


2

LISP, das Zahlen mit unendlicher Genauigkeit unterstützt, im Vergleich zu C, das nur Maschinen-Ganzzahlen unterstützt, ist kein Beispiel für die 'Richtigkeit' der Sprache. Es ist eine einfache Sache, die sich aus der Tatsache ergibt, dass die Sprachen sehr unterschiedliche Designziele hatten.

Der Punkt von C sollte eine Sprache in der Nähe des Computers sein, mit der Betriebssysteme implementiert werden können. Maschinen unterstützen (meistens) keine unendlich genauen Dezimalzahlen. Maschinen haben (meistens) ganze Zahlen mit festen Bitlängen.

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.