2009-04-30 8 views
2

Ich entwerfe eine hohe Ebene, objektorientierte, Garbage Collection Programmiersprache, und ich habe ein Problem mit Vorlagen. Ich plane, ein VM-System zu erstellen, ähnlich wie .NET oder JVM (aber LLVM wird unter der Haube verwendet). Das Problem ist, dass ich leistungsfähige, C++ - ähnliche Templates haben möchte, aber mit dynamischem Linking (damit ich die Template-Bibliothek ersetzen kann, ohne alles neu zu kompilieren, das es benutzt). Ich möchte in der Lage sein, eine Quelldatei zu kompilieren, ohne die Definition der Vorlagen zu haben. Die Codegenerierung zur JIT-Zeit sollte minimiert werden.Was ist der beste Weg, um Templates in einer Programmiersprache zu implementieren?

Hier sind die Optionen Ich denke an:

  • haben das Konzept einer Template-Bibliothek, die statisch in jede Übersetzungseinheit verbunden ist. Eine Vorlagenbibliothek wäre im Wesentlichen wie eine AST mit Leerzeichen, die ausgefüllt werden müssen, wenn die Vorlage instanziiert wird. Das Problem dabei ist, dass wenn zwei Dateien mit verschiedenen Versionen der Vorlagenbibliothek kompiliert werden, diese möglicherweise inkompatibel sind oder wenn die Vorlagenbibliothek fehlerhaft ist, muss alles neu kompiliert werden. So macht es C++.
  • Haben Sie Template-Bibliotheken, die zur JIT-Zeit verknüpft sind. Dies löst die meisten Probleme, erfordert jedoch, dass das IR im Wesentlichen ein AST ist. Ich möchte, dass die IR viel niedriger ist. Dies erfordert viel mehr Arbeit für JIT-in.
  • Haben Sie wimpy C# -ähnliche Generika mit nur Typen als Argumente. Dies ist ziemlich einschränkend, erlaubt jedoch eine einfache Codegenerierung und dynamische Verknüpfung.

Gibt es noch andere gute Möglichkeiten, an die ich nicht denke? Ich stehe auf die erste Option, aber ich mag keine der Optionen. Was denkst du ist die beste Option?

Antwort

1

Ich denke, es hängt von der Menge der Spezialisierung, die Sie wollen, d. H. Wie mächtig der Compiler von Templates sein muss.

Wenn man sich C++ anschaut, kann der Compiler alles Mögliche machen (wie zum Beispiel Unterklassen generieren durch Rekursion, wahrscheinlich ein fraktales Vererbungsdiagramm berechnen und die Zahlen von Pi on the fly berechnen).

Wenn Sie diese Leistung wollen, benötigen Sie wahrscheinlich eine leistungsstarke High-Level-JIT. FWIW, ich denke, das wäre cool. (Fügen Sie einfach den vollständigen Compiler in die Laufzeitumgebung ein.)

0

Hängt ein wenig vom Rest der Sprache ab ... wenn Sie Operatorüberladung, Werttypen usw. haben, dann machen Sie die Sache wirklich komplizierter (und verpassen möglicherweise großartig) Optimierungsmöglichkeiten), indem die C++ - Route nicht verwendet wird: Der Code, der die Vorlage verwendet, müsste auch als AST bis zur JIT-Zeit dargestellt werden, um eine maximale Spezialisierung zu ermöglichen.

Da C++ - Vorlagen im Wesentlichen eine Form von Makros sind, ermöglichen sie es, einen Großteil des durch Duplizierung erzeugten Aufblasens zu reduzieren, bevor Sie Code erzeugen.

Template-Typen (zumindest in C++) tendieren dazu, die meisten Kerntypen zu sein, die allen anderen Code zugrunde liegen, wenn sie sich ändern, vorausgesetzt, dass anderer Code immer noch damit kompatibel ist die kleinsten Änderungen.

0

Was Sie erreichen möchten, ist fast unmöglich. Sie müssen so gut wie die gesamte Repräsentation auf hoher Ebene Ihrer Sprache für die Vorlagen-Definitionen und den Code, der diese Vorlagen verwendet, zurücklassen und Ihre JIT-Kompilierung fast aus der Ebene des leicht verarbeiteten Quellcodes durchführen. Wenn Sie damit einverstanden sind, müssten Sie den Rest Ihres Compilers wirklich trivial halten und Sie werden keine der schwergewichtigen LLVM-Optimierungen verwenden können. Es gibt keine anderen Möglichkeiten, Template Metaprogrammierung beruht auf der Verfügbarkeit der High-Level-Informationen.

0

Denken Sie darüber nach, wie leistungsfähig diese Vorlagen sein werden. Sie müssen sich daran erinnern, dass eine Sprache, die Just In Time kompiliert wird, bedeutet, dass ein Großteil des schweren Hebens zur Ladezeit und zur Laufzeit durchgeführt werden muss. Je leistungsfähiger Sie Ihre Vorlagen erstellen, desto weniger Leistung erhalten Sie von ihnen.


Wenn Sie wirklich diesen Weg gehen werden, können Sie auch den Compiler in der Laufzeit als Macke suggested. Tatsächlich gibt es viele Sprachen, die das tun.

Indem Sie dies tun, machen Sie Ihre Implementierung der Sprache ein "interpretiert" oder teilweise "interpretiert". In diesem Sinne ist eine Vorlage nur ein Kostüm für match-replace-eval, und damit ist alles in Ordnung, Vorlagen funktionieren in dynamischen Sprachen oft so. Vergiss nicht, dass es am Ende Power versus Performance sein wird.


Hinweis: Bei dieser Art von Entscheidungen konfrontiert kann es sich lohnen, ein wenig zurück zu Schritt. Identifizieren Sie die Anwendungsfälle und priorisieren Sie sie, trennen Sie die Implementierung von dem Entwurf, sodass Sie das Design iterieren können, ohne dass die Implementierung ein Grund für Lähmung ist, und berücksichtigen Sie dies dennoch.

In jeder Iteration erweitern Sie das Design, um mehr Anwendungsfälle abzudecken, während Sie entscheiden, welches das beste Design ist. Wenn Sie ein Design erreichen, das Ihnen gefällt, können Sie es iterieren und dann können Sie auch die Implementierung durchlaufen. Mit dieser Methode können Sie zuerst die wichtigeren Fälle abdecken.

Ja, ich schlage eine iterative inkrementelle Methode vor. Und ich tue dies, weil es sich bei dieser Frage um das Design einer Sprache handelt, und es scheint mir sehr um die Implementierung besorgt zu sein. Es ist notwendig, die Ideen geerdet zu halten oder Sie werden in einem der Extreme enden (zu mächtig mit Mitleidsleistung oder überhaupt keine Vorlagen für eine Hochleistungslösung).

Verwandte Themen