AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Störende Elemente der Delphi-Syntax / Vorschläge für neuen Dialekt
Thema durchsuchen
Ansicht
Themen-Optionen

Störende Elemente der Delphi-Syntax / Vorschläge für neuen Dialekt

Ein Thema von implementation · begonnen am 11. Jan 2012 · letzter Beitrag vom 24. Jan 2012
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    
Benutzerbild von implementation
implementation
Registriert seit: 5. Mai 2008
Hallo liebe Delphisten,

im Laufe der Zeit haben sich bei mir einige Dinge angehäuft, die mich an der aktuellen Syntax von Object Pascal stören.
Darunter sind folgende:
  • Es muss eine strikte Reihenfolge von interface->implementation eingehalten werden. Das heißt, ich kann keine globale Eigenschaft deklarieren, die auf eine private Variable zurückgreift.
  • Interfaces sind per se immer an Referenzzählung und COM-Kompatibilität gebunden. In meinem halbjährigen Ausflug nach C# habe ich erfahren, wie schön es sein kann, a) in Interfaces für Properties nicht gleich eine Getter/Setter-Methode angeben zu müssen, sondern dies der Implementierung zu überlassen, b) Objekt- und Interfacereferenzen mischen zu können
  • Methoden und nichtmethodische Routinen sind im implementation-Teil sprachlich nicht gruppiert (höchstens durch Kommentare)
  • Man kann zwar mehrere verschiedene benannte Destruktoren deklarieren, das hilft aber nichts, weil Free immer nur einen ganz bestimmten aufruft. Wozu haben wir denn unser schönes Benennungsfeature?

Daher habe ich mir mal einen Entwurf für einen neuen kleinen Dialekt überlegt, der diese Dinge besser machen soll, ich nenne ihn bisher "Thrym".

Hier mal ein Ausschnitt:
Delphi-Quellcode:
// Thrym

unit sample;

// Uses-Klausel außerhalb von public/private/implementation
uses
  ...

// public + private statt interface
public

  type
    TExample = class
    public
      procedure Sample;
    end;
    
    // Counted Interfaces:
    // Klassische COM-Interfaces, auf Methoden beschränkt,
    // Properties gehen den Weg über diese
    // (Referenzzählung!!)
    IExample = counted interface
      ['{GUID}']
      procedure SetTest(AValue: Integer);
      function GetTest: Integer;
      property Test: Integer read GetTest write SetTest;
    end;
    
    // Uncounted Interfaces:
    // Von COM komplett unabhängig, keine Referenzzählung
    // Properties müssen nicht direkt einen Getter/Setter
    // zugewiesen bekommen, dies ist Sache der Implementierung
    // Implementierende Klassen müssen nicht AddRef/Release/
    // QueryInterface unterstützen
    ISample = uncounted interface
      property Test: Integer read write;
    end;
    ...
  
  const
    ...
    
  var
    ...
    
private

  type
    // Schema-Typ, wie in GPC:
    TCharArray(start, length: Integer) = array [start..start+length] of char;
    TSample = TCharArray(0,6);
    ...
    
  const
    ...
    
  var
    ...
    FProp: Integer;
    
// können auch mehrere public/private sections sein
public

  // z.B. um global properties besser zum ermöglichen
  property Prop: Integer read FProp write FProp;
  
implementation // oh, it's me!

  // In den Implementation-Teil kommt
  // tatsächlich nur noch die Implementierung
  // der im public- und private-Teil deklarierten
  // Methoden und nichtmethodischen Routinen

  // Methoden gruppieren nach Klasse
  TExample: begin
  
    procedure Sample;
    var obj: TExampleObject;
    begin
      obj := TExampleObject.Create;
      try
        // Do Something
      finally
        // den Destruktor gefahrenlos direkt aufrufen können
        // damit benannte Destruktoren auch endlich wieder Sinn
        // machen - wozu kann man sonst mehrere Destruktoren
        // deklarieren, wenn man eh nur Destroy über Free verwenden
        // kann
        obj.Destroy;
        // schön wäre es jetzt noch, wenn obj gleich auf Nil gesetzt würde
        // dazu aber dick: Fragezeichen ?
      end
    end;
  
  end;

end.
Nun möchte ich das ganze aber nicht einfach verschlimmbessern, daher Frage an euch: Was haltet ihr von diesen Änderungen, insbesondere dem automatischen nil-setzen?

Je nach Feedback setze ich das ganze vllt. in Zukunft mal durch einen Präcompiler um, der dies dann in FreePascal-Code oder Delphi-Code umschreibt.

Verbesserungsvorschläge, Kritiken und Featurerequests sind gern willkommen (dazu mache ich den Thread ja auf )
 
Namenloser

 
FreePascal / Lazarus
 
#11
  Alt 12. Jan 2012, 09:05
- Class Helper Record Helper für einfache Basistypen, wie t.B. den Integer oder den String

- Interface Helper
Achja genau, das hatte ich noch vergessen. Ich wäre einfach für einen allgemeinen Helper , für jeden Typ, egal ob Klasse, Record oder primitiver Datentyp wie Integer. Diese Unterscheidung von class helpern und record helpern ist redundant, weil der Datentyp, auf den sich der Helper bezieht, ja ohnehin klar ist. Und falls man mal aus einem Record eine Klasse macht oder umgekehrt, müsste man nicht auch noch zusätzlich alle Helper-Definitionen anpassen.
Delphi-Quellcode:
type
  TFormHelper = helper for TForm
    procedure FadeOut();
  end;

  TRectHelper = helper for TRect
    procedure Normalize;
    function ContainsPoint(Pt: TPoint): Boolean;
  end;
  
  TIntHelper = helper for Integer
    function ToString: string;
  end;
Damit wären sehr moderne Konstrukte und modulare Programmierung möglich.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#12
  Alt 12. Jan 2012, 09:14
Wäre es nicht schön, einfach ein Helperkonstrukt für alle Typen zu haben, statt zwischen Class-, Record und Interface-Helpern zu unterscheiden?
Im Prinzip hast du ja Recht, denn über den Zieltüben ließe es sich ja unterscheiden.
Aber dann wäre es nicht mehr ganz kompatibel zum alten Code.

Zitat:
Bei Operatoren finde ich die FPC-/GPC-Syntax ganz schön, sie komplett aus der Klassendeklaration herauszunehmen. Dadurch wird jeder Typ operatorfähig,
Ein Operator Helper

Für Objekte sind Operatoren leider nicht möglich, der fehlenden automatischen Speicherverwaltung wegen,
aber wenn man die Copy/Create/Destroy-Ereignisse einführt, würde es dennoch einen Weg geben.
  Mit Zitat antworten Zitat
Medium

 
Delphi 2007 Enterprise
 
#13
  Alt 12. Jan 2012, 09:59
Mein Wunsch geht zwar über Syntax hinaus, und dafür würden mich sicher hier gerne einige vermöbeln, aber ein Delphi mit GC wäre schon sexy. Ich weiss, es gibt da diverse Fummelein mit Interfaces und Hacks, aber ein richtiger "ab Werk" GC ist einfach eine riesen Komfortsteigerung (wenn er vernünftig umgesetzt ist). Was ich in C# ab und an gern mache, und in Delphi ab und an wünschte, ist sowas wielokaleVarMitRückgabewert := TMyFooClass.Create(aParameter).SomeMethod(aNotherParameter); , und die Instanz dann einfach verpuffen lassen. (Ja, das sieht nach einem Designfehler aus, man meint die Methode hätte statisch sein sollen - aber so schlau sind leider nicht alle Fremdkomponentenhersteller.) Oder auch so Späße, bei denen Instanzen über mehrere Threads eher "locker umher geworfen" werden würden mit einem GC etwas weniger Kopfschmerzlastig.

Vielleicht sogar als alternativer Konstruktor, ggf. mit Einführung des new-Operators!
Delphi-Quellcode:
  bar := TMyFooClass.Create(); // <- normal ohne GC
  bar := new TMyFooClass(); // <- GC'ed
Mit etwas Unterstützung in der IDE (anderes Highlighting für GC'ed Instanzvariablen) wäre so ein Hybrid glaube ich sogar einigermaßen handlich.
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

 
FreePascal / Lazarus
 
#14
  Alt 12. Jan 2012, 10:19
@Medium:

Das ist eine verdammt gute Idee! Was mich an GC-Sprachen bisher insbesondere gestört hat, war, dass man den GC nicht einfach abstellen konnte. Ich habe über eine Hybridschiene schon nachgedacht, aber da bin ich immer zur Kollision gekommen.
Der Einfall, die Objekte einfach durch einen anderen Konstruktor zu erzeugen ist ein genialer Ansatz.

Das wäre allerdings ein Punkt, den ich allein nicht umsetzen könnte, weil ich a) von GC-Bau keinen Schimmer habe und b) auch keinen kenne, den man zu dem Zweck in die Ausgabedatei einfach automatisch einbinden könnte.
Die bisherigen Punkte würde ich mir zutrauen, aber ein Hybrid-GC ginge über meine Fähigkeiten hinaus.
Marvin
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#15
  Alt 12. Jan 2012, 10:30
Mit etwas Unterstützung in der IDE (anderes Highlighting für GC'ed Instanzvariablen) wäre so ein Hybrid glaube ich sogar einigermaßen handlich.
Wenn du jetzt noch sicherstellst, daß es nirgendwo "Altprogramme" gibt, wo z.B. "new" als Variable/Typ/Konstante/Parameter/Feld/... existiert, dann wäre das möglich.

Ansonsten hast du ein Problem, da plötzlich aus Diesem ein "reserviertes" Wort werden würde.
In Delphi also nicht möglich, obwohl es auch ohne GC technisch möglich wäre, wenn man den "new"-Operator auf die ".Create"-Constructoren umleitet.


Wenn man Klassen direkt als Interface markieren könnte, bei deren Deklaration, ohne vorher einen extra Interface-Typen manuell deklarieren zu müssen (der Compiler würde dann aus den Public/Published-Dingen dass Interface automatisch generieren), dann hätte man quasi auch einen GC für diese Objekte.
(über die Technik der Generics eventuell machbar, also wenn Emba das implementiert)

Über einen Precompiler könnte ich sowas auch selber nachrüsten.

Geändert von himitsu (12. Jan 2012 um 10:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

 
FreePascal / Lazarus
 
#16
  Alt 12. Jan 2012, 10:51
Mich würde jetzt auch mal genauer interessieren, was ihr von der Unit-Umstellung von Interface/Implementation auf Public/Private/Implementation haltet. Stimmt ihr mir zu oder haltet ihr das für überflüssig?
Was haltet ihr von der Methodengruppierung?
Marvin
  Mit Zitat antworten Zitat
Lemmy

 
Delphi 10.3 Rio
 
#17
  Alt 12. Jan 2012, 11:02
Mich würde jetzt auch mal genauer interessieren, was ihr von der Unit-Umstellung von Interface/Implementation auf Public/Private/Implementation haltet.
Nichts, zum einen weil Public/Private im OOP Bereich schlicht standard ist und es meiner Meinung nach wenig bringt hier Namen zu ändern - das auf was Du raus willst kannst Du auch mit Interface/Implementation machen (oder ich habe es nicht verstanden )

Was haltet ihr von der Methodengruppierung?
was sind für dich Methoden? Was sind für dich "nichtmethodische Routinen"? Und wie soll die Methodengruppierung aussehen? Oder habe ich da auch was nicht verstanden / übersehen?

Grüße
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#18
  Alt 12. Jan 2012, 11:06
Im Prinzip eigentlich nicht notwendig.

Interface = Public
Implementation = Private

Protected gibt's da nicht, bzw. es ist sinnlos, da die Vererbung fehlt und es somit dem Private entspricht.

Das Property ohne Klasse könnte nett sein, für globale Variablen oder Singletons.
Aber da man solche Globalen sowieso besser vermeiden sollte, bringt es eigentlich nicht viel.

Die Methodengruppierung finde ich unübersichtlich.

Seh ich irgendwo in der Implementation ein procedure irgendwas; , dann denke ich das wäre eine Prozedur und nicht daß sich da irgendwo noch ein begin verstecken könnte, welches dieses zu einer Methode macht.
Zwei Klassen, mit einer gleichnamigen Methode, dann stehen unten zwei Prozeduren, welche man nicht direkt einer der Klassen zuordnen kann, ohne vorher nach einem "begin" zu suchen, um zu sehn ob und wenn ja zu welcher Klasse es gehört.

Geändert von himitsu (12. Jan 2012 um 11:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

 
FreePascal / Lazarus
 
#19
  Alt 12. Jan 2012, 11:15
Nichts, zum einen weil Public/Private im OOP Bereich schlicht standard ist und es meiner Meinung nach wenig bringt hier Namen zu ändern - das auf was Du raus willst kannst Du auch mit Interface/Implementation machen (oder ich habe es nicht verstanden )
Der Punkt ist, dass momentan unitprivate Deklarationen alle im implementation-Teil liegen, wo dann Deklarationen und Implementierungen querbeet gemischt sind. In meinem Modell geht es darum, im implementation-Teil möglichst auch nur die implementation zu haben. Nicht exportierte Typen, Konstanten und Variablen kommen dann in den private-Teil. Die Reihenfolge der private- und public-Abschnitte ist nicht festgelegt, und es kann auch mehrere geben, um bspw. Global Properties zu ermöglichen, ohne den Getter/Setter auch veröffentlichen zu müssen.

Zitat:
was sind für dich Methoden? Was sind für dich "nichtmethodische Routinen"? Und wie soll die Methodengruppierung aussehen? Oder habe ich da auch was nicht verstanden / übersehen?
Methoden = Prozeduren und Funktionen von Klassen (und erweiterten Records)
nichtmethodische Routinen = Prozeduren und Funktionen, die keiner Klasse angehören
Delphi-Quellcode:
procedure TXyz.DoSmthng; // Methode
function IntToStr(AValue: Integer): string; // keine Methode
Wie die Gruppierung aussehen soll, steht nicht fest (wie allgemein noch nichts), im Entwurf im oberen Post sah sie so aus:
Delphi-Quellcode:
implementation

  TXyz: begin
    
    procedure Xyz;
    begin
      // Do something
    end;

  end;

end.
Im Prinzip eigentlich nicht notwendig.

Interface = Public
Implementation = Private
Da stört es mich aber, dass der implementation-Teil zugleich für unitprivate-Deklarationen und Implementierungen gleichzeitig benutzt wird. Schöner fände ich es, wenn man das trennen würde und im implementation-Teil keine Deklarationen mehr zugelassen würden.

Zitat:
Die Methodengruppierung finde ich unübersichtlich.

Seh ich irgendwo in der Implementation ein procedure irgendwas; , dann denke ich das wäre eine Prozedur und nicht daß sich da irgendwo noch ein begin verstecken könnte, welches dieses zu einer Methode macht.
Zwei Klassen, mit einer gleichnamigen Methode, dann stehen unten zwei Prozeduren, welche man nicht direkt einer der Klassen zuordnen kann, ohne vorher nach einem "begin" zu suchen, um zu sehn ob und wenn ja zu welcher Klasse es gehört.
Das stimmt natürlich, da ist sie kontraproduktiv. Schön wäre es, irgendwie eine Syntax zu finden, die dieses Problem nicht hat, aber das dürfte schwierig werden.

Zitat:
Aber da man solche Globalen sowieso besser vermeiden sollte, bringt es eigentlich nicht viel.
Stimmt durchaus, vllt. fliegen die Global Properties doch noch ausm Entwurf raus.
Marvin

Geändert von implementation (12. Jan 2012 um 11:18 Uhr)
  Mit Zitat antworten Zitat
Namenloser

 
FreePascal / Lazarus
 
#20
  Alt 12. Jan 2012, 12:26
Vielleicht sogar als alternativer Konstruktor, ggf. mit Einführung des new-Operators!
Delphi-Quellcode:
  bar := TMyFooClass.Create(); // <- normal ohne GC
  bar := new TMyFooClass(); // <- GC'ed
Bitte kein new-Operator!
Dieser Operator ist ein Makel, den fast alle Sprachen von C erben. Ich finde es semantisch viel schöner, wenn der Konstruktor wie eine klassenstatische Methode ist, die eine Instanz zurückliefert. Die Klasse selbst ist für die Erzeugung ihrer Instanzen zuständig. Ist das nicht wunderschön OO?

Geändert von Namenloser (12. Jan 2012 um 13:17 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz