Sind alle Sprachen grundsätzlich gleich?

39

Vor kurzem musste ich das Design eines kleinen Programms verstehen, das in einer Sprache geschrieben war, von der ich keine Ahnung hatte ( ABAP , wenn Sie es wissen müssen). Ich konnte es ohne allzu große Schwierigkeiten herausfinden.

Mir ist klar, dass das Erlernen einer neuen Sprache ein völlig anderes Ballspiel ist, aber es ist einfach, die Absicht des Codes (insbesondere des Produktionsstandardcodes, der nicht unbedingt komplex ist) in jeder Sprache zu verstehen, wenn Sie bereits einige Sprachen beherrschen (am besten ein prozedurales / OO und ein funktionales).

Ist das allgemein wahr? Bestehen alle Programmiersprachen aus ähnlichen Konstrukten wie Schleifen, bedingten Anweisungen und Nachrichten, die zwischen Funktionen ausgetauscht werden? Gibt es nicht-esoterische Sprachen, für die ein typischer Java / Ruby / Haskell-Programmierer keinen Sinn hätte? Haben alle Sprachen einen gemeinsamen Ursprung?

Anirudh
quelle
4
Ich leite Sie zu Beating the Averages von Paul Graham. Vielleicht möchten Sie das Ganze lesen oder nicht, aber suchen Sie für den entsprechenden Teil nach der Überschrift "The Blub Paradox". Mr. Graham kann sich nicht die Mühe machen, Anker in seine Textwand zu setzen, daher kann ich keinen direkten Link dazu erstellen.
kwatford
4
Sprachen haben keinen gemeinsamen Ursprung. Aber alle Sprachen versuchen, ein Problem zu lösen. Ich denke, es ist etwas analog zur gesprochenen Sprache. Der Zweck ist, sich auszudrücken. Ich kann nicht sagen, dass es einfach ist, Sprachen zu verstehen, die auf den Kenntnissen von 1 Verfahren / OO / funktional basieren. Ich habe dies nicht getan, aber wenn ich diese Frage stellen würde, würde ich Perl oder Lisp mit vielen Klammern betrachten und ich könnte nicht sagen, dass es ausreichend ist, 1 Sprache aller Art zu kennen.
Shahkalpesh
1
In diesem Fall: Lambda-Kalkül. Vielleicht keine "echte" Sprache, aber sie ist in gewissem Sinne die Mutter aller Programmiersprachen. Ich musste einmal eine funktionale Sprache so implementieren, dass sie in Lambda-Ausdrücke kompiliert wurde (die dann direkt interpretiert wurden). Die Ergebnisse waren (zumindest für mich) unlesbar, obwohl alle relevanten Kennungen erhalten blieben. Besonders rekursive Funktionen mit dem Y-Kombinator. Die einzige praktische Möglichkeit, herauszufinden, was einige der Beispielausdrücke taten, bestand darin, sie von Hand auszuwerten. Einfache Dinge wie fibonnaci und merge sort waren nicht lesbar.
kwatford
2
Wenn Sie funktionale Sprachen beherrschen, sollten Sie wissen, dass Schleifen nicht in jeder Sprache möglich sind.
Jalf
Piet ist ziemlich anders. :)

Antworten:

88

Die Grundlagen der meisten prozeduralen Sprachen sind fast gleich.

Sie bieten an:

  • Skalare Datentypen: normalerweise Boolesche Werte, Ganzzahlen, Gleitkommazahlen und Zeichen
  • Zusammengesetzte Datentypen: Arrays (Zeichenfolgen sind Sonderfälle) und Strukturen
  • Grundlegende Codekonstrukte: Arithmetik über Skalare, Array- / Strukturzugriff, Zuweisungen
  • Einfache Kontrollstrukturen: if-then, if-then-else, while für Schleifen
  • Pakete von Codebausteinen: Funktionen, Prozeduren mit Parametern
  • Bereiche: Bereiche, in denen Bezeichner eine bestimmte Bedeutung haben

Wenn Sie das verstehen, haben Sie ein gutes Verständnis von 90% der Sprachen auf dem Planeten. Was diese Sprachen etwas schwieriger zu verstehen macht, ist die unglaubliche Vielfalt an ungeraden Syntaxformen, mit denen die Leute dieselben grundlegenden Dinge sagen. Einige verwenden eine knappe Notation mit ungerader Interpunktion (APL ist ein Extrem). Einige verwenden viele Schlüsselwörter (COBOL ist ein hervorragender Vertreter). Das macht nicht viel aus. Was wichtig ist, ist, dass die Sprache von sich aus vollständig genug ist, um komplexe Aufgaben zu erledigen, ohne dass Sie sich die Haare ausreißen müssen. (Versuchen Sie, ernsthaften String-Hacking im Windows-DOS-Shell-Skript zu programmieren: Es ist Turing-fähig, aber in allem sehr schlecht).

Weitere interessante Verfahrenssprachen bieten

  • Verschachtelte oder lexikalische Bereiche, Namespaces
  • Zeiger, mit denen eine Entität auf eine andere Entität verweisen kann, mit dynamischer Speicherzuweisung
  • Paketierung von verwandtem Code: Pakete, Objekte mit Methoden, Eigenschaften
  • Anspruchsvollere Steuerung: Rekursion, Fortsetzungen, Schließungen
  • Spezialisierte Operatoren: String- und Array-Operationen, mathematische Funktionen

Obwohl es sich technisch gesehen nicht um eine Eigenschaft der Sprache handelt, sondern um eine Eigenschaft des Ökosystems, in dem solche Sprachen leben, handelt es sich um Bibliotheken, die im Rahmen des Entwicklungswerkzeugs leicht zugänglich sind oder mit der Sprache versehen werden. Eine breite Palette von Bibliotheksfunktionen vereinfacht / beschleunigt das Schreiben von Anwendungen, weil man nicht neu erfinden muss, was die Bibliotheken tun. Java und C # gelten allgemein als gute Sprachen. Was sie jedoch wirklich nützlich macht, sind die großen Bibliotheken, die im Lieferumfang enthalten sind, und die leicht erhältlichen Erweiterungsbibliotheken.

Die Sprachen, die schwerer zu verstehen sind, sind die nicht prozeduralen:

  • Rein funktionale Sprachen, ohne Zuweisungen oder Nebenwirkungen
  • Logiksprachen wie Prolog, in denen symbolische Berechnung und Vereinheitlichung stattfinden
  • Pattern Matching-Sprachen, in denen Sie Formen angeben, die auf das Problem abgestimmt sind, und häufig Aktionen, die durch eine Übereinstimmung ausgelöst werden
  • Einschränkungssprachen, mit denen Sie Beziehungen angeben und Gleichungen automatisch lösen können
  • Hardware-Beschreibungssprachen, in denen alles parallel abläuft
  • Domänenspezifische Sprachen wie SQL, farbige Petri-Netze usw.

Es gibt zwei Hauptdarstellungsstile für Sprachen:

  • Textbasiert, in dem Bezeichner Entitäten und Informationsflüsse implizit in Formeln codieren, die die Bezeichner zur Benennung der Entitäten verwenden (Java, APL, ...)
  • Grafik, in der Entitäten als Knoten und Beziehungen zwischen Entitäten als explizite Bögen zwischen diesen Knoten gezeichnet werden (UML, Simulink, LabView)

Die grafischen Sprachen ermöglichen oftmals Textsprachen als Annotationen in Knoten und auf Bögen. Ungewöhnliche Grafiksprachen erlauben rekursiv Grafiken (mit Text :) in Knoten und auf Bögen. In sehr ungewöhnlichen Grafiksprachen können Anmerkungsdiagramme auf mit Anmerkungen versehene Diagramme verweisen.

Die meisten dieser Sprachen basieren auf einer sehr geringen Anzahl von Rechenmodellen:

  • Der Lambda-Kalkül (Basis für Lisp und alle funktionalen Sprachen)
  • Post-Systeme (oder Techniken zum Umschreiben von Strings / Bäumen / Graphen)
  • Turingmaschinen (Zustandsänderung und Auswahl neuer Speicherzellen)

Angesichts des Fokus der meisten Industriezweige auf prozedurale Sprachen und komplexe Kontrollstrukturen sind Sie gut bedient, wenn Sie eine der interessanteren Sprachen in dieser Kategorie gut lernen, insbesondere, wenn sie eine Art von Objektorientierung enthält.

Ich kann das Lernschema sehr empfehlen, insbesondere aus einem wirklich wunderbaren Buch: Struktur und Interpretation von Computerprogrammen . Dies beschreibt alle diese Grundkonzepte. Wenn Sie dieses Zeug kennen, werden andere Sprachen mit Ausnahme der doofen Syntax ziemlich einfach erscheinen.

Ira Baxter
quelle
3
Gute Antwort! Gibt es als Follow-up (gibt es eine Möglichkeit, eine Folgefrage in SO zu stellen?) Eine Sprache, die ich beherrschen und behaupten könnte, alle Konzepte in der Programmiersoftware zu verstehen? Wäre es Lisp (oder ein Dialekt wie Scheme)?
@ Anirudh: Es gibt keinen formellen Follow-up-Mechanismus, aber Sie könnten eine neue Frage eröffnen. Wenn es eine Begründung und einen Link zu dieser Frage enthält, kann es sein, dass es nicht einmal geschlossen ist. ;) Um Ihr Follow-up zu beantworten, glaube ich von ganzem Herzen, dass es nicht nur eine Sprache gibt, da die Paradigmen zu unterschiedlich sind.
@ Anirudh: In Übereinstimmung mit John Y gibt es nicht nur einen. Aber wenn Sie relativ neu in diesem Bereich sind, sollten Sie viel Energie investieren, um das prozedurale Paradigma zu meistern (ich betrachte OO nur als Spezialisierung). Es würde nicht schaden, andere Paradigmen (Logik, Einschränkung, Datenfluss) zu betrachten, um ein Gefühl dafür zu bekommen, wie sie funktionieren, aber für die alltägliche industrielle Arbeit sind prozedurale Sprachen so ziemlich König.
Ira Baxter
1
Genau wie bei natürlichen Sprachen ist "schwerer zu verstehen" subjektiv und von der ersten Sprache abhängig, die Sie lernen.
NullUserException
1
@NullUserException: Dies schlägt vor, dass Sie Ihre erste Sprache sorgfältig auswählen sollten, um das Verständnis anderer zu maximieren. Darum geht es bei Scheme und insbesondere beim SICP-Buch.
Ira Baxter
6

Hardwarebeschreibungssprachen sind Programmiersprachen, aber sie sind konzeptionell sehr unterschiedlich. Probieren Sie VHDL oder Verilog für die Größe an. Sie sind für die Programmierung von FPGAs üblich. (Ok, es handelt sich also nicht um Prozessoren, sondern um Allzweck-Computergeräte. Diese sollten als gültige Hardware für Informatik-Themen angesehen werden.) Sie müssen explizit dafür sorgen, dass die Dinge seriell ablaufen. Es ist ein ganz anderes Modell. Sie haben an Dinge gedacht, die in der Regel parallel ablaufen, nicht an die Ausnahme. Für Schleifen in Verilog erweitern Sie in parallele Hardware. Das "erwartete" Verhalten ist also möglicherweise nicht das, was Sie erwarten.

NoMoreZealots
quelle
Das ist ein guter Punkt. Ich werde Verilog / VHDL nachschlagen.
Ich habe immer gedacht, dass konventionelle Programmiersprachen nur sehr miese Wege sind, um natürlich parallele Programme wie VHDL zu programmieren. Wenn Sie als Hardware-Designer anfangen, wirkt dieses Stück über alles, was seriell geschieht, unglaublich ungeschickt. (Wir bringen den Leuten die falschen Programmiersprachen als erste Sprache bei: Es sollte Verilog sein!).
Ira Baxter
4

Kommt darauf an, was du mit "im Grunde" meinst. Alle Sprachen jeder Flexibilität sind Turing-komplett. In diesem Sinne: Ja, sie sind im Grunde alle gleich.

Auf einer niedrigen Ebene führen sie alle ähnliche Abläufe aus, und alle Windows-, Linux- und (aktuellen) OS X-Vorgänge werden auf Intel-kompatiblen Prozessoren mit denselben Befehlssätzen ausgeführt. Auf diese Weise sind sie im Grunde auch gleich.

Mir ist klar, dass Sie in Ihrer Frage "im Grunde" definiert haben, aber um das wirklich zu beantworten, muss diese Definition viel präziser sein. In vielerlei Hinsicht sind sie alle gleich. In vielerlei Hinsicht unterscheiden sie sich. Es ist alles zu einfach zu sagen, "es kommt darauf an." Wenn Sie eines der beiden Extreme wählen, wird die Frage wahrscheinlich nicht beantworten, was Sie beabsichtigen. Daher ist es entscheidend, wo diese Grenze gezogen wird, um Ihre Frage so zu beantworten, wie Sie es beabsichtigen.

Dinah
quelle
3

Ich würde sagen, dass eine Sprache Bedeutung codiert. Wenn die Bedeutung in einem bestimmten Kontext einen Sinn hat, können alle Sprachen, die die Bedeutung ausdrücken könnten, durch die Bedeutung und den Kontext als gleichwertig bezeichnet werden.

Wenn Sie diesen Kontext auf eine Standard-Von-Neumann-Maschine beschränken, könnte man sagen, dass die rechnerische Bedeutung der Änderung von Speicher und Rechenleistung in einer CPU der Ursprung ist - und möglicherweise die einzige Bedeutung, die alle Sprachen gemeinsam haben. Alle anderen Dinge sind Abstraktionen, die darauf aufbauen.

Preet Sangha
quelle
1
John von Neumann. Und es wird NICHT wie "newman" ausgesprochen, eher wie "noyman".
Vielen Dank für die Korrektur - ich spreche es aus, wie Sie gesagt haben.
Preet Sangha
Wenn jemand eine Korrektur vorschlägt, können Sie Ihren Beitrag einfach bearbeiten, um ihn wiederzugeben.
Phil Miller
2

Programmiersprachen sind auch Werkzeuge zum Denken. Mit einer anderen Denkperspektive verschwinden einige Probleme oder verwandeln sich in andere, besser handhabbare Muster (z. B. verschwinden viele Designmuster im C ++ - Stil, wenn Sie in Lisp denken (siehe z. B. die Präsentation von Peter Norvik ), und Erlang befreit Sie vom Denken Nebenläufigkeit auf niedriger Ebene oder verteilte Computerkonstrukte und Sie können sich nur auf die Anwendungslogik konzentrieren).

Es ist jedoch zu beachten, dass die "neuen" Paradigmen manchmal teilweise auf "ältere" Programmiersprachen angewendet werden können, was erklärt, warum wir beispielsweise Bücher haben, in denen funktionale Programmierung für Java-Programmierer unterrichtet wird . Die native Unterstützung und Integration eines mächtigeren Paradigmas in die Sprachebene ermöglicht jedoch eine natürlichere Anwendung des Paradigmas (und macht es folglich unmöglich, Programme in einer Sprache zu verstehen, die ein ungewohntes Paradigma unterstützt, wie andere Antworten andeuten - @Ira Baxter, in der nicht prozedurale Sprachen aufgelistet sind und @kwatford unter Bezugnahme auf Paul Graham ).

FooF
quelle
2
+++++++[>+++++++++++<-]>+.<+++++++++++[>+++<-]>.>>+++++++[>++++++<-]>++++.

Auf der untersten Ebene ist jede Programmiersprache die "gleiche", was jedoch nicht bedeutet, dass sie auf der Ebene, auf der Sie tatsächlich interagieren, identisch sind. Sie abstrahieren Probleme für Sie; das heißt nicht, dass sie die gleichen Probleme abstrahieren oder dass sie jedes Problem auf die gleiche Weise abstrahieren.

asthasr
quelle
1

Ältere Sprachen haben im Allgemeinen einige Ziele und machen Kompromisse, indem sie eine Sache für eine andere opfern. Eine Allzwecksprache kann für alles verwendet werden, aber keine Sprache kann jemals in jedem Bereich herausragende Leistungen erbringen. Einige Beispiele:

C versucht eine ideale Systemprogrammiersprache zu sein. Zu diesem Zweck werden die Lesbarkeit und die Sicherheit für die Kontrolle und Geschwindigkeit auf niedriger Ebene beeinträchtigt.

Python soll eine ideale Skriptsprache sein. Zu diesem Zweck werden Geschwindigkeit und Überprüfbarkeit für Produktivität und Portabilität geopfert.

Haskell versucht eine sichere, mathematisch reine Sprache zu sein. Zu diesem Zweck werden Lernfähigkeit und Konvention für Überprüfbarkeit und Zuverlässigkeit geopfert.

Diese Opfer und Vorteile machen einen großen Unterschied in der Sprache. Ja, die meisten Programmiersprachen können für alles verwendet werden, was von einem Computer ausgeführt werden kann, aber keine dieser Sprachen sollte für alles verwendet werden. Alle oben genannten Sprachen sind Sprachen, die ich für bestimmte Aufgaben auswählen würde, für andere jedoch nicht. Wenn ich ein Betriebssystem programmieren würde, würde ich C wählen. Wenn ich ein Backend für eine Website schreibe, würde ich Python verwenden. Und wenn ich ein Finanzsystem schreiben würde, würde ich Haskell benutzen.

Letztendlich ist Ihre Wahl als Programmierer das richtige Werkzeug für den Job.

Imagist
quelle