2013-05-07 8 views
8

Ich habe mich immer gefragt, wie die Abhängigkeiten von einer Programmiersprache zu ihren Bibliotheken verwaltet werden. Nimm zum Beispiel C#. Als ich angefangen habe, etwas über Computer zu lernen, würde ich (fälschlicherweise) annehmen, dass die Sprache selbst unabhängig von den Klassenbibliotheken entwickelt wird, die schließlich für sie verfügbar werden. Das heißt, der Satz von Sprachschlüsselwörtern (wie for, oder throw) sowie die Syntax und die Semantik werden zuerst definiert, und Bibliotheken, die aus der Sprache verwendet werden können, werden separat entwickelt. Die spezifischen Klassen in diesen Bibliotheken, so dachte ich, sollten keinen Einfluss auf das Design der Sprache haben.Sind Sprachen wirklich abhängig von Bibliotheken?

Aber das funktioniert nicht, oder nicht die ganze Zeit. Betrachten Sie throw. Der C# -Compiler stellt sicher, dass der Ausdruck throw zu einem Ausnahmetyp aufgelöst wird. Exception ist eine Klasse in einer Bibliothek, und als solche sollte es überhaupt nicht speziell sein. Es wäre eine Klasse wie jede andere, außer dass der C# -Compiler ihr diese spezielle Semantik zuweist. Das ist sehr gut, aber meine Schlussfolgerung ist, dass das Design der Sprache von der Existenz und dem Verhalten bestimmter Elemente in den Klassenbibliotheken abhängt.

Darüber hinaus frage ich mich, wie diese Abhängigkeit verwaltet wird. Wenn ich eine neue Programmiersprache entwerfen würde, welche Techniken würde ich verwenden, um die Semantik von throw zu der ganz bestimmten Klasse zu mappen, die Exception ist?

So sind meine Fragen zwei:

  • Bin ich richtig, dass die Sprache Design im Denken fest an, dass der Basisklassenbibliotheken gekoppelt ist?
  • Wie werden diese Abhängigkeiten innerhalb des Compilers und der Laufzeit verwaltet? Welche Techniken werden verwendet?

Vielen Dank.

BEARBEITEN. Danke an diejenigen, die darauf hingewiesen haben, dass meine zweite Frage sehr vage ist. Ich stimme zu. Was ich versuche zu lernen, ist, welche Art von Referenzen der Compiler über die benötigten Typen speichert. Zum Beispiel findet es die Typen durch eine Art eindeutige ID? Was passiert, wenn eine neue Version des Compilers oder der Klassenbibliotheken freigegeben wird? Ich bin mir bewusst, dass dies immer noch ziemlich vage ist, und ich erwarte keine präzise Antwort in einem einzigen Absatz; vielmehr sind Hinweise auf Literatur oder Blogbeiträge sehr willkommen.

+0

See nicht tragbar ist http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/package-summary.html _ Bietet Klassen an, die für das Design von Die Java-Programmiersprache._ – flup

+0

Und http://msdn.microsoft.com/en-us/library/yxcx7skw(v=vs.71).aspx _Der System-Namespace enthält fundamentale Klassen und Basisklassen, die gemeinsam verwendeten Wert und definieren Referenzdatentypen, Ereignisse und Ereignishandler, Schnittstellen, Attribute und Verarbeitungsausnahmen. Andere Klassen bieten Dienste zur Unterstützung der Datentypkonvertierung, Methodenparametermanipulation, Mathematik, Remote- und lokaler Programmaufruf, Anwendungsumgebungsmanagement und Überwachung von verwalteten und nicht verwalteten Anwendungen. – flup

+0

Die Antwort auf die erste Frage lautet "Ja". Die zweite Frage ist so vage, dass ich keine Ahnung habe, wie ich überhaupt anfangen soll, darauf zu antworten. –

Antwort

11

Was ich versuche zu lernen ist, welche Art von Referenzen der Compiler über die Typen speichert, die er benötigt. Zum Beispiel findet es die Typen durch eine Art eindeutige ID?

Offensichtlich verwaltet der C# -Compiler eine interne Datenbank aller Typen, die sowohl im Quellcode als auch in den Metadaten zur Verfügung stehen. Deshalb wird ein Compiler als "Compiler" bezeichnet - er kompiliert eine Sammlung von Daten über die Quellen und Bibliotheken.

Wenn der C# Compiler muss, sagen wir, ob ein Ausdruck, der von oder identisch mit System.Exception abgeleitet wird geworfen es einen globalen Namespace-Lookup auf System zu tun vorgibt, und dann tut es einen Nachschlag auf Exception findet die Klasse und vergleicht dann die resultierenden Klasseninformationen mit dem Typ, der für den Ausdruck abgeleitet wurde.

Der Compiler-Team nutzt diese Technik, weil auf diese Weise es egal funktioniert, ob wir den Quellcode kompilieren und System.Exception ist in Metadaten oder wenn wir mscorlib selbst kompilieren und System.Exception ist in der Quelle.

Natürlich hat der Compiler als Performance-Optimierung tatsächlich eine Liste von "bekannten Typen" und füllt diese Liste so früh auf, dass sie nicht jedes Mal die Kosten für die Suche nachkommen muss. Wie Sie sich vorstellen können, müssen Sie die eingebauten Typen extrem groß nachschlagen. Sobald die Liste ausgefüllt ist, kann die Typinformation für System.Exception einfach aus der Liste ausgelesen werden, ohne die Suche durchführen zu müssen.

Was passiert, wenn eine neue Version des Compilers oder der Klassenbibliotheken freigegeben wird?

Was passiert ist: eine ganze Reihe von Entwickler, Tester, Manager, Designer, Autoren und Pädagogen zusammen bekommen und ein paar Millionen Mannstunden dafür, dass verbringen, dass der Compiler und die Klassenbibliotheken arbeiten alle, bevor sie sind freigegeben.

Diese Frage ist wiederum unmöglich vage. Was muss passieren, um einen neuen Compiler zu veröffentlichen? Eine Menge Arbeit, das muss passieren.

Ich bin mir bewusst, dass dies noch ziemlich vage ist, und ich erwarte keine präzise, ​​einteilige Antwort; vielmehr sind Hinweise auf Literatur oder Blogbeiträge sehr willkommen.

Ich schreibe einen Blog über, unter anderem, das Design der C# -Sprache und ihres Compilers.Es ist bei http://ericlippert.com.

+1

Danke für deine Antwort, Eric. Übrigens, ich folge deinem Blog. – CesarGon

3

Alle (praktischen) Programmiersprachen haben eine Mindestanzahl von erforderlichen Funktionen. Für moderne "OO" -Sprachen umfasst dies auch eine Mindestanzahl von erforderlichen Typen.

Wenn der Typ in der Language Specification erforderlich ist, dann ist es erforderlich - unabhängig davon, wie es verpackt ist.

Umgekehrt muss nicht alle des BCL eine gültige C# Implementierung haben. Dies liegt daran, dass nicht alle BCL-Typen von der Sprachspezifikation benötigt werden. Zum Beispiel sind System.Exception (siehe # 16.2) und NullReferenceException erforderlich, aber FileNotFoundException ist nicht erforderlich, um die C# -Sprache zu implementieren.

anzumerken, dass, obwohl die Spezifikation minimal Definitionen für Basistypen (z.B. System.String) bietet, ist es nicht die allgemein akzeptierten Methoden definieren (z.B. String.Replace).Das heißt, fast die gesamte BCL ist außerhalb der Anwendungsbereich der Sprachspezifikation .


.. aber meine Schlussfolgerung ist, dass die Gestaltung der Sprache über die Existenz und das Verhalten bestimmter Elemente in den Klassenbibliotheken abhängt.

Ich stimme zu und habe Beispiele (und Grenzen solcher Definitionen) oben enthalten.

.. Wenn ich eine neue Programmiersprache entwerfen sollte, welche Techniken würde ich verwenden, um die Semantik von "throw" auf die ganz bestimmte Klasse, die "Ausnahme" ist, abzubilden?

Ich würde nicht in erster Linie auf die C# -Spezifikation schauen, aber ich würde eher die Common Language Infrastructure Spezifikation betrachten. Diese neue Sprache sollte aus praktischen Gründen so konzipiert sein, dass sie mit bestehenden CLI/CLR-Sprachen zusammenarbeitet, muss aber nicht unbedingt "C#" sein.

Die CLI (und zugehörigen Referenzen) tun die Anforderungen einer minimalen BCL definieren. Wenn also angenommen wird, dass eine gültige C# -Implementierung der CLI entsprechen muss (oder davon ausgehen kann), dann gibt es viele andere zu berücksichtigende Typen, die in der C# -Spezifikation selbst nicht erwähnt werden.


Leider habe ich nicht ausreichende Kenntnisse der 2. (und interessanteren) Frage.

+1

Ich habe ausreichende Kenntnisse und ich weiß nicht, wie ich die zweite Frage beantworten soll; es ist völlig vage. –

5

Ich würde (vielleicht zu Unrecht) annehmen, dass die Sprache selbst unabhängig von den Klassenbibliotheken entwickelt wird, die schließlich dafür verfügbar werden würden.

Ihre Annahme ist im Fall von C# völlig falsch. C# 1.0, CLR 1.0 und .NET Framework 1.0 wurden zusammen entwickelt. Während sich Sprache, Laufzeit und Framework entwickelten, arbeiteten die Designer eng zusammen, um sicherzustellen, dass die richtigen Ressourcen zugewiesen wurden, so dass jeder neue Features pünktlich liefern konnte.

Ich verstehe nicht, wo Ihre völlig falsche Annahme herkommt; das klingt nach einer sehr ineffizienten Art, eine Hochsprache zu schreiben und eine gute Möglichkeit, Ihre Deadlines zu verpassen.

Ich kann schreiben, eine Sprache wie C, die im Grunde eine angenehmere Syntax für Assembler ist, ohne eine Bibliothek. Aber wie würdest du vielleicht schreiben, sagen wir async-await, ohne dass der Typ Task<T> im Raum mit dir gestaltet? Es scheint wie eine Übung in Frustration.

Bin ich der Meinung, dass Sprachdesign eng mit dem seiner Basisklassenbibliotheken gekoppelt ist?

Im Fall von C#, ja, absolut. Es gibt Dutzende von Typen, von denen die C# -Sprache annimmt, dass sie verfügbar und dokumentiert sind, um korrekt zu funktionieren.

Ich habe einmal eine sehr frustrierende Stunde mit einem Entwickler, der etwas völlig verrückt Problem mit einer foreach-Schleife aufweist, wurde, bevor ich entdecken, dass er seine eigenen IEnumerable<T> geschrieben hatte, die etwas andere Methoden als die realen IEnumerable<T> hatte. Die Lösung für sein Problem: Tu das nicht.

Wie werden diese Abhängigkeiten innerhalb des Compilers und der Laufzeit verwaltet?

Ich weiß nicht, wie man überhaupt anfängt, diese unmöglich vage Frage zu beantworten.

+0

Danke. Ich habe einige Details zur zweiten Frage hinzugefügt. – CesarGon

+0

Ich denke, das lässt die wichtige Tatsache aus, dass C# tatsächlich ohne .NET Framework und CLR-Laufzeit funktionieren kann. Mono ist das offensichtliche Beispiel. Außerdem, von dem, was ich verstehe, haben Sie (im C# -Team oder früher) große Anstrengungen unternommen, um Features wie 'async'-'await' von Pattern-Matching- anstelle von Hardcoding-Klassenabhängigkeiten abhängig zu machen. – MgSam

+1

@MgSam: Mono hängt von einer * genauen Kopie von .NET Framework und CLR * ab, daher bin ich mir nicht sicher, wie das relevant ist. Der Punkt ist, dass die Sprache von Typen im Rahmen abhängt; Welche Organisation eine Implementierung dieses Frameworks geschrieben hat, ist nicht relevant. Und ja, viele Features verwenden einen "pattern matching" -Ansatz für die Erweiterbarkeit, aber (1) Sie können keine asynchrone Methode erstellen, die 'MyTask ' zurückgibt - es muss der "echte" 'Task ' oder ein Typ sein so ähnlich, dass der Compiler den Unterschied nicht erkennen kann, und (2) mein Punkt ist, dass das TPL-Team und das C# -Team gemeinsam an dem Feature gearbeitet haben. –

0

mein Eindruck ist, dass

in Sprachen wie C# und Ada

Anwendungsquellcode tragbar ist

Standard-Bibliothek Quellcode

accross Compiler/Implementierungen