Parser/Grammatiken: Konstruktoren
-
Kellerautomat schrieb:
Ich beschaeftige mich in letzter Zeit ein bisschen mit dem Design von Programmiersprachen, Grammatiken und Parser. Dabei ist mir aufgefallen, dass alle mir bekannten Sprachen bei Konstruktoren einen Token, sei es der Klassenname, "this", "self" oder etwas aehnliches fordern. Hat das einen grammatikalischen Grund?
Es ist praktischer, wenn man beim Parsen auf ein eindeutiges, bzw. erwartbares Schlüsselwort trifft, dass man zuordnen kann und somit den Parser in einen eindeutigen Zustand ändern kann. this oder self bietet sich hier an. Klammern sind dabei eher unschön, denn Klammern priorisieren Ausdrücke und sobald man die öffnende Klammer sieht, könnten eine Vielzahl von Konstrukten folgen.
Mit dem Klassennamen oder der Tilde weiß direkt, wo man dran ist und was zu erwarten ist, entsprechend was man als Fehler werten darf.Stroustrup wollte in C++ zuerst den Konstruktor new( .. ) { ... } und delete() nennen. Da die operatoren new und delete aber überladbar sind, hat er davon wieder abstand genommen.
Aus Sicht der Machbarkeit spricht grundsätzlich spricht nichts gegen die von Dir vorgeschlagene Syntax, außer dass sie mit einem Editor schlecht suchen ist, aber das ist kein Problem der Programmiersprachenimplementation - wohl aber des Designs der Sprache.
-
Zeus schrieb:
Member sind benammt, außer Konstruktor und Dekonstruktur in deinen Beispiel. Ist das nicht Inkonsistent?
Konstruktoren und Destruktoren sind doch etwas besonderes, da finde ich eine besondere Syntax gar nicht verkehrt.
Xin schrieb:
Es ist praktischer, wenn man beim Parsen auf ein eindeutiges, bzw. erwartbares Schlüsselwort trifft, dass man zuordnen kann und somit den Parser in einen eindeutigen Zustand ändern kann. this oder self bietet sich hier an.
Und inwiefern ist '(' in diesem Kontext kein besonderes Schluesselwort bzw kein besonderer Token?
Xin schrieb:
Klammern sind dabei eher unschön, denn Klammern priorisieren Ausdrücke und sobald man die öffnende Klammer sieht, könnten eine Vielzahl von Konstrukten folgen.
Aber doch nicht in diesem Kontext. Klammern haben nur Priorisierungsfunktion in Ausdruecken.
Xin schrieb:
Mit dem Klassennamen oder der Tilde weiß direkt, wo man dran ist und was zu erwarten ist, entsprechend was man als Fehler werten darf.
Siehe oben, eine oeffnende Klammer ist doch genauso besonders?
Xin schrieb:
Aus Sicht der Machbarkeit spricht grundsätzlich spricht nichts gegen die von Dir vorgeschlagene Syntax, außer dass sie mit einem Editor schlecht suchen ist, aber das ist kein Problem der Programmiersprachenimplementation - wohl aber des Designs der Sprache.
Ich finde, diese Syntax sticht sehr stark aus dem Rest heraus. Insofern sehe ich das Problem nicht. Wie suchst du denn in einem C++-Programm nach einem Konstruktor? Eine Suche nach "<klassenname>" wird nicht besonders viel bringen. Entweder der Editor kann syntaktische Analyse - dann kommst du mit beiden Syntaxen zurecht - oder eben nicht - dann hast bei beiden ein Problem.
-
Kellerautomat schrieb:
Zeus schrieb:
Member sind benammt, außer Konstruktor und Dekonstruktur in deinen Beispiel. Ist das nicht Inkonsistent?
Konstruktoren und Destruktoren sind doch etwas besonderes, da finde ich eine besondere Syntax gar nicht verkehrt.
Wäre es da nicht positiv, wenn man diese Besonderheit auch im Quelltext herausstellt?
Kellerautomat schrieb:
Xin schrieb:
Es ist praktischer, wenn man beim Parsen auf ein eindeutiges, bzw. erwartbares Schlüsselwort trifft, dass man zuordnen kann und somit den Parser in einen eindeutigen Zustand ändern kann. this oder self bietet sich hier an.
Und inwiefern ist '(' in diesem Kontext kein besonderes Schluesselwort bzw kein besonderer Token?
'(' beginnt wie gesagt eine Priorisierung, das bedeutet, dass bis zu ')' alles zwischen '(' und ')' an einen Operator gehängt wird, der eine höhere Priorisierung als +, * usw. was auch immer hat.
Man kann den Parser so aufbauen, dass er reihenweise Zustände durchläuft, die jeweils klarstellen, wie ein Token verstanden werden sollte oder man lässt ihn etwas freier laufen.
In C++ sind die Funktionsdeklarationen keine Expressions, deswegen ist an dieser Stelle auch kein sonderliches Problem, diese Syntax zu übernehmen.
Kellerautomat schrieb:
Xin schrieb:
Klammern sind dabei eher unschön, denn Klammern priorisieren Ausdrücke und sobald man die öffnende Klammer sieht, könnten eine Vielzahl von Konstrukten folgen.
Aber doch nicht in diesem Kontext. Klammern haben nur Priorisierungsfunktion in Ausdruecken.
Es verwirrt den Entwickler aber evtl.
Wie gesagt - die Umsetzung ist kein Problem. Die Frage ist eher, ob man es umsetzen möchte. Mir wäre das als Auszeichnung zu knapp, zu schlecht suchbar.
Kellerautomat schrieb:
Xin schrieb:
Aus Sicht der Machbarkeit spricht grundsätzlich spricht nichts gegen die von Dir vorgeschlagene Syntax, außer dass sie mit einem Editor schlecht suchen ist, aber das ist kein Problem der Programmiersprachenimplementation - wohl aber des Designs der Sprache.
Ich finde, diese Syntax sticht sehr stark aus dem Rest heraus. Insofern sehe ich das Problem nicht. Wie suchst du denn in einem C++-Programm nach einem Konstruktor? Eine Suche nach "<klassenname>" wird nicht besonders viel bringen. Entweder der Editor kann syntaktische Analyse - dann kommst du mit beiden Syntaxen zurecht - oder eben nicht - dann hast bei beiden ein Problem.
Deswegen setze ich hier auf 'construct'. Es ist eindeutig suchbar und muss nicht angepasst werden, wenn sich der Name der Klasse ändert.
-
Xin schrieb:
Wäre es da nicht positiv, wenn man diese Besonderheit auch im Quelltext herausstellt?
Das versuche ich doch mit ().
Xin schrieb:
Deswegen setze ich hier auf 'construct'. Es ist eindeutig suchbar und muss nicht angepasst werden, wenn sich der Name der Klasse ändert.
Zuerst war ich bei "constructor", aber das war mir zu lang, also bin ich zunaechst bei "ctor" gelandet. Das schien mir aber zu kurz. Dann hab ich mich gefragt "Wozu ueberhaupt so ein Konstrukt?" und bin jetzt bei ().
Uebrigens danke fuer das Erwaehnen der Suchbarkeit. Ueber diesen Aspekt des Sprachdesigns habe ich noch gar nicht nachgedacht.
-
Kellerautomat schrieb:
Xin schrieb:
Wäre es da nicht positiv, wenn man diese Besonderheit auch im Quelltext herausstellt?
Das versuche ich doch mit ().
Ich bin sicher, dass das optisch schon herausragen kann.
Während ich allerdings dagegen ankämpfe nicht in Prosa zu verfallen, um einigen kryptischen Elementen entgegen zu wirken, erscheint mir das jedoch dann doch etwas einsam im Raum stehend, auch wenn ich es soweit gut nachvollziehen kann und auch in einer gewissen Weise als elegant empfinde.
Kellerautomat schrieb:
Xin schrieb:
Deswegen setze ich hier auf 'construct'. Es ist eindeutig suchbar und muss nicht angepasst werden, wenn sich der Name der Klasse ändert.
Zuerst war ich bei "constructor", aber das war mir zu lang, also bin ich zunaechst bei "ctor" gelandet. Das schien mir aber zu kurz. Dann hab ich mich gefragt "Wozu ueberhaupt so ein Konstrukt?" und bin jetzt bei ().
ctor und dtor sind zu nah zusammen, optisch wie auch auf den meisten Tastaturen. Man vertippt sich schnell. constructor ist zwar lang, aber eindeutig. Sogar so eindeutig, dass man es nicht wiederverwenden kann. So kam ich zu 'construct'.
Wobei das letzte Wort da noch nicht gesprochen ist, vielleicht wird es auch ein 'create', was sich allerdings vom üblichen Sprachgebrauch "Konstruktor" entfernen würde.Kellerautomat schrieb:
Uebrigens danke fuer das Erwaehnen der Suchbarkeit. Ueber diesen Aspekt des Sprachdesigns habe ich noch gar nicht nachgedacht.
Suchbarkeit und leichte Interpretierbarkeit von Sprachen sind relativ junge Probleme im Sprachdesign. Schließlich muss heutzutage nicht nur der Entwickler eine Sprache lesen, auch ein Editor wünscht sich da klare und möglichst einfach zu implementierende Regeln vorfinden.
-
Xin schrieb:
So kam ich zu 'construct'.
Wobei das letzte Wort da noch nicht gesprochen ist, vielleicht wird es auch ein 'create', was sich allerdings vom üblichen Sprachgebrauch "Konstruktor" entfernen würde.Ich fände ein eigenes Schlüsselwort bzw. einen speziellen Methodennamen für Konstruktoren/Destruktoren aufgrund der Konsistenz mit normalen Methodendefinitionen auch besser.
Mir gefallen
construct
/destruct
gut, denncreate
/destroy
benutzt man doch gerne für (unter Umständen statische) Factory- und Ressourcenmanager-Methoden. Außerdem ist es ja gemeinhin guter Stil, den Imperativ im Sinne vondoSomething()
für die Bennenung von Methoden zu verwenden (construct
vs.constructor
).
-
das Problem stammt letztendlich von inkonsequenter Auffassung von Objektorientierung.
bei konsequenter Anwendung der OO-Prinzipien stellt sich das Problem eigentlich gar nicht: Eine Klasse ist dann ein Objekt - Instanz der zugehörigen Metaklasse nämlich - und Instanzen werden erzeugt, indem eine Methode, sagen wir: "new", der Klasse aufgerufen wird: MyClass.new(...) oder MyClass new: ...
ruby und "new style classes" in python haben das auf syntaktischer Ebene mit myClass.new(...) bzw myClass.__new__(...)
-
buchstaben schrieb:
bei konsequenter Anwendung der OO-Prinzipien stellt sich das Problem eigentlich gar nicht: Eine Klasse ist dann ein Objekt - Instanz der zugehörigen Metaklasse nämlich
und metaklasse sind instanzen der zugehoerigen metametaklasse?
-
Shade Of Mine schrieb:
und metaklasse sind instanzen der zugehoerigen metametaklasse?
Nein, sie sind Instanzen von sich selbst.
-
Shade Of Mine schrieb:
und metaklasse sind instanzen der zugehoerigen metametaklasse?
ja.
und damit endet die Meta-Hierarchie auch schon, weil Meta-Metaklassen Instanzen von Metaklasse sind - d.h. weil "Metaclass class" eine Instanz von sich selbst ist
-
buchstaben schrieb:
Shade Of Mine schrieb:
und metaklasse sind instanzen der zugehoerigen metametaklasse?
ja.
und damit endet die Meta-Hierarchie auch schon, weil Meta-Metaklassen Instanzen von Metaklasse sind - d.h. weil "Metaclass class" eine Instanz von sich selbst ist
Wo genau brauchst du die Meta-Metaklasse?
-
Man könnte den ctor direkt an den Klassennamen heften und den dtor in den Klassenrumpf stopfen, z.B.:
class X protected (a: Int, b: Int) extends Y(a+b) { doSomething() doMore() dtor { ... } ... }
Alles im Klassenrumpf wird im ctor ausgeführt, bis auf den dtor natürlich.
-
Michael E. schrieb:
Wo genau brauchst du die Meta-Metaklasse?
weil bei konsequenter Auslegung des Objektprinzips Metaklassen ihrerseits Objekte sind, es also eine Klasse geben muß, deren Instanzen Metaklassen sind: die Meta-Metaklasse
-
buchstaben schrieb:
Michael E. schrieb:
Wo genau brauchst du die Meta-Metaklasse?
weil bei konsequenter Auslegung des Objektprinzips Metaklassen ihrerseits Objekte sind, es also eine Klasse geben muß, deren Instanzen Metaklassen sind: die Meta-Metaklasse
Und die Meta-Metaklasse identifizierst du dann mit der Metaklasse? OK, als theoretische Definition machts Sinn. Ich hatte gedacht, du wolltest in der tatsächlichen Implementierung eine eigene Meta-Metaklasse (ungleich der Metaklasse) einführen.
Edit: Ich bin etwas verwirrt von den Begriffen, um ehrlich zu sein
-
es gibt Programmiersprachen, in denen die Meta-Metaklasse tatsächlich vorkommt ("Metaclass class")
da funktioniert beispielsweise so was:
String class isMemberOf: Metaclass. "true" Metaclass class isMemberOf: Metaclass. "true"
letzteres ist der Zirkelschluß, der eine unendliche Meta-Hierarchie verhindert.
-
Wieso windest du dich eigentlich so darum, das Wort Smalltalk in den Mund zu nehmen? Weil "konsequente Auslegung des Objektprinzips" wissenschaftlicher klingt?
-
Bashar schrieb:
Wieso windest du dich eigentlich so darum, das Wort Smalltalk in den Mund zu nehmen? Weil "konsequente Auslegung des Objektprinzips" wissenschaftlicher klingt?
Weil er sich nicht als unsere alter Smalltalk-Lover outen will xD
-
Bashar schrieb:
Wieso windest du dich eigentlich so darum, das Wort Smalltalk in den Mund zu nehmen? Weil "konsequente Auslegung des Objektprinzips" wissenschaftlicher klingt?
Weil es z.B. in Ruby genauso ist wie in Smalltalk.
-
Michael E. logged out schrieb:
Bashar schrieb:
Wieso windest du dich eigentlich so darum, das Wort Smalltalk in den Mund zu nehmen? Weil "konsequente Auslegung des Objektprinzips" wissenschaftlicher klingt?
Weil es z.B. in Ruby genauso ist wie in Smalltalk.
Das ist kein Grund.