Modulsystem für OOP-Sprache

8

Ich entwerfe eine einfache OO-Programmiersprache.

Es wird statisch typisiert, kompiliert und von einer VM ausgeführt - ähnlich wie Java.

Der Unterschied ist, dass ich OOP nicht so stark betonen möchte. Der Code selbst ähnelt größtenteils C ++ (Klassen, Funktionen und Variablen, die im Dateibereich zulässig sind).

Eines der Dinge, die ich haben muss, ist ein Modulsystem. Ich habe folgendes herausgefunden:

  1. Jede Datei ist ein Modul (einmal kompiliert) - wie Python
  2. Programmierer müssen ein Modul mit dem importSchlüsselwort importieren , wodurch der Compiler in Standardverzeichnissen und im Dateiverzeichnis nach Modulen sucht (die VM muss dies auch zur Laufzeit tun).

Und jetzt habe ich keine Ahnung, wie ich das Konzept der Submodule und der Modulhierarchie einführen soll.

Eine Möglichkeit besteht beispielsweise darin, von der Verzeichnishierarchie abhängig zu sein, sodass import engine.graphics.renderererwartet wird, dass im Arbeitsverzeichnis und in einem Verzeichnis mit dem Namen "Grafik" ein Verzeichnis mit dem Namen "Renderer" gefunden wird.

Was sind die Nachteile eines solchen Designs? Vermisse ich etwas

Aber Kled
quelle
1
Nun, es wäre nicht der erste. Sowohl Rust als auch OCaml behandeln Code in einer Datei implizit als Teil eines Moduls mit demselben Namen wie die Datei. Scheint dort gut genug zu funktionieren.
KChaloux
7
Und Haskell. Wenn Sie trotzdem OOP machen, würde ich Sie ermutigen, die Scala "Module sind spezielle Objekte" in Betracht zu ziehen. Beabsichtigen Sie auch, erstklassige Module zu unterstützen? Wenn ja, besteht eine Unklarheit zwischen foo.barfoo / bar.file oder einem Modul foomit dem Mitglied (auch ein Modul) bar. Etwas zu beachten
Daniel Gratzer
Wie wollen Sie mit der Versionierung umgehen? Viele Sprachen tun das überhaupt nicht, aber Sie können diesen Fehler genauso gut nicht im Voraus machen.
Donal Fellows
@DonalFellows Möchtest du das näher erläutern? Wie ist es die Verantwortung der Sprache, mit Versionen umzugehen? Trotzdem wollte ich @annotationszum Einbetten solcher Informationen einführen .
Aber Kled
@AberKled: Ich denke nicht, dass das Problem darin besteht, dass die Sprache für den "Umgang mit Versionen" verantwortlich ist, sondern dass Fred eine Version von Modul X hat, wenn er ein Modul Y schreibt, das damit funktioniert, und Joe eine Eine andere Version von X, wenn er das damit arbeitende Modul Z schreibt. Wenn keine unlösbaren Verhaltensunterschiede zwischen den verschiedenen Versionen von X bestehen, sollte es möglich sein, Y und Z zusammen zu verwenden, ohne dass sie neu kompiliert werden müssen.
Supercat

Antworten:

2

Werfen Sie einen Blick auf die Paket- / Modulhierarchie / -organisation von Python und insbesondere auf historische Aspekte, wichtige Ergänzungen im Laufe der Jahre, vor allem die neuesten. Wahrscheinlich macht es keinen Sinn, das Rad zu erfinden.

Ich weiß nicht, wie weit Sie mit Ihrer Sprache gehen wollen, z

  • Möchten Sie, dass der Bytecode des Moduls aus der Postleitzahl gelesen wird?
  • Wie trennt man Module / Bibliotheken für verschiedene Interpreter-Versionen?
  • Planen Sie, es mit Distributionen scheinbar harmlos zu machen?
  • Vergessen Sie nicht die Leichtigkeit der Sprachverteilung (denken Sie an distutils / pypi - jede Plattform / Sprache hat ihre eigene, nicht immer gute)

Ich denke, Java könnte ein weiteres interessantes Beispiel sein. Dinge können auch von Erlang gelernt werden (z . B. /programming/2968914/code-hot-swapping-in-erlang ).

Es gibt eine ganze Reihe von Designproblemen (einige davon wurden oben angesprochen), wenn Sie vorhaben, eines Tages Ihre Programmiersprache als Mainstream zu sehen. Glücklicherweise gibt es da draußen großartige Beispiele.

Einige Anweisungen für das Design von Programmiersprachenmodulen / Paketen / Bibliothekssystemen sollten Folgendes enthalten:

  • intuitiver Code zum Schreiben und Verwenden des Moduls
  • Modul- / Paketobjekte im Code
  • Introspektionsfunktionen für Module / Pakete
  • Modul- / Paketkapselung (wie kann man unnötige Details verbergen?)
  • Verwendung von Schnittstellen / Header-Dateien?
  • feinkörniges Dispatching-System, das sowohl spracheigene Distributions-Utils als auch Utils auf Systemebene verwenden können (vermeiden Sie "DLL-Hölle")
  • Speicherplätze für bytekompilierte Module
  • Setup-System, das das Kompilieren sowohl "reiner" Module als auch von Modulen / Abhängigkeiten automatisiert
  • kanonischer Ort des kompilierten Codes, Tests, Dokumentation, Assets in Ihrem Modul
Roman Susi
quelle
Dieser Beitrag ist ziemlich schwer zu lesen (Textwand). Hätten Sie etwas dagegen bearbeiten sie in eine bessere Form ing?
Mücke
1
" Es gibt eine Menge Designprobleme, wenn Sie vorhaben, Ihre Programmiersprache eines Tages als Mainstream zu sehen. " Ich nicht. Aber ich würde mich trotzdem
freuen,
1
@gnat Danke für den Hinweis. Hoffentlich jetzt besser.
Roman Susi
1
@AberKled Ich habe versucht, ein paar hinzuzufügen. Aber wie ich in der Antwort sagte, werfen Sie einen Blick auf die Geschichte der Entwicklung einer Mainstream-Sprache, besser, wenn sie eher von Programmierern als von Puristen / Elitisten angetrieben wird, um aus Fehlern Lehren zu ziehen, bevor Sie Ihre eigenen machen. Vergessen Sie natürlich nicht die wichtigsten Designziele für Ihre Sprache.
Roman Susi
2

Nehmen wir zunächst an, Sie ordnen Ihr Namespace-Modell einem anderen Namespace zu, z. B. dem Dateisystem, wie Sie vorgeschlagen haben. Zweitens gehe ich davon aus, dass Module andere Module importieren können. Mit anderen Worten, engine.graphics.rendererkönnte sehr gut eine Zeile wie enthalten import circle.arc. Das wirft zwei Fragen auf:

  • Wo würde die VM suchen circle.arc? Entsprechend dem erwähnten Dateisystem-Mappimg sollte es ein Verzeichnis wie /etc/mylang/modules/circle/arc ( /etc/mylang/modulesdas Stammverzeichnis Ihrer Modulstruktur) geben .

  • Wie würde eine Bewerbung verweisen circle.arc: durch importing circle.arcoder engine.graphics.render.circle.arc? Das erste würde die Hierarchie "verderben" (wenn nicht ruinieren), da circle.arces sich eindeutig um ein Submodul handelt engine.graphics.renderer, und das zweite würde bedeuten, dass sich /etc/mylang/modules/engine/graphics/renderer/circle/arcin Ihrem Dateisystem ein befinden sollte , das circle.arcgleichzeitig an zwei Orten platziert wird.

Allerdings scheint es mir zu restriktiv, ihn dem Dateisystem zuzuordnen, und sollten Sie sich für den Namespace-Ansatz entscheiden. Ich denke, Module können sich an allen möglichen Orten befinden (sogar Zip-Dateien, wie bereits erwähnt, sogar URLs). Die VM sucht zunächst nach einem Eintrag in einem Index (möglicherweise einer Konfigurationsdatei), der den Namespace den tatsächlichen Modulpositionen zuordnet.

Geomagas
quelle
1
Sie werden wahrscheinlich abgelehnt, weil Sie die spezifische Frage des OP nicht wirklich gut beantworten. Wenn Ihr Kommentar nicht vermitteln kann, was Sie sagen möchten, müssen Sie wahrscheinlich ein breiteres Gespräch mit dem OP offline führen. Unser Chatraum ist ein großartiger Ort, um dies zu tun.
maple_shaft
@maple_shaft: Was meinst du? Ist nicht die Frage "Was sind die Nachteile eines solchen Designs?" Mache ich nicht klar genug, dass meine Punkte potenzielle Nachteile der vom OP vorgeschlagenen Modularchitektur sind? Der Grund, warum ich nie gefragt habe, warum ich abgelehnt wurde, ist, dass ich von StackOverflow komme, wo die Leute es die ganze Zeit tun, ohne sich darum zu kümmern, einen Kommentar dazu zu hinterlassen - was frustrierend und vor allem nicht konstruktiv ist , aber ich bin es gewohnt es trotzdem und müde, nach einer Erklärung zu fragen.
Geomagas
1
Sie geben zu, dass Sie nicht beabsichtigen, die Frage zu beantworten, und Sie klären Ihre Gedanken mehr oder weniger anhand des Beispiels, das er zur Verfügung gestellt hat, was mit dem Renderer-Modul zu tun ist. Die Frage ist wirklich abstrakter als das und braucht eine breitere Antwort, denke ich. Ich habe eine Erklärung für Ihren Nutzen geliefert, weil ich denke, dass Sie gute Punkte ansprechen und es gut meinen, aber in der Tat werden die wichtigsten Teile der Frage nicht wirklich angesprochen.
maple_shaft
Nun, wenn der erste Satz das Problem war, habe ich ihn entfernt, da er sowieso nicht mit dem Rest der Antwort übereinstimmte - was bedeutet, dass er, obwohl ich ihn als "Gedanken" begann, die eigentliche Frage ansprach. Ich denke nicht, dass die Frage abstrakter ist, da sie sehr spezifisch ausgedrückt wird. Wenn ich falsch liege, erwarte ich, dass das OP angibt, was er impliziert, aber nicht in Worte gefasst hat. Ich weiß, dass Ihr Kommentar im Gegensatz zum anonymen Verhalten von Downvoter helfen sollte , und ich weiß das zu schätzen. Das tue ich wirklich.
Geomagas