Syntaxerweiterung von Pascal

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Syntaxerweiterung von Pascal

Beitrag von braunbär »

Hallo,

ich habe erfreut festgestellt, dass man im FPC einstellen kann, dass es die Operatoren +=, -= etc, versteht.
Zwei andere Syntaxerweiterungen, deren Impementierung sehr einfach sein dürfte, würde ich für sehr sinnvoll halten, und ich würde gerne wissen, was ihr davon haltet und ob eine Aussicht besteht, dass so etwas umgesetzt wird.

1. "with x:=object do" alternativ zu "with object do" - wobei x nicht extra an anderer Stelle deklariert werden müsste und der Gültigkeitsbereich sich auf den with-Block beschränken würde - würde die Probleme, die mit dem with-Statement in seiner jetzigen Form verbunden sind, auf einfache und elegante Art lösen.
2. Zuweisungen sollten generell als Teilexpressions erlaubt sein. Dann wären Konstrukte möglich wie: "while (l:=length(s)) < 10 do insert('x',s,l div 2)"

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Syntaxerweiterung von Pascal

Beitrag von Mathias »

Meinst du sowas in dieser Richtung, so wie es in C/C++ geht ?

Code: Alles auswählen

   for (int i; i = 0; i++) {
      machewas(i);
   }

So das i nur lokal ist ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Syntaxerweiterung von Pascal

Beitrag von Michl »

Mathias hat geschrieben:So das i nur lokal ist ?
Ganz klar lokal. Übrigens gibt es schon so einen Fall:

Code: Alles auswählen

  try
    raise Exception.Create('Huh, a exception');
  except
    on e: Exception do
      WriteLn(e.Message);
  end
"e" ist lokal ohne Deklaration erstellt.

Generell:
Ich, für meinen Teil, halte von solchen sich C annähernden Erweiterungen nicht viel. Schon der ganze Generic-Kram macht den Code nicht unbedingt leserlicher, geschweige denn debugfreundlicher. Die klare Struktur, auch mal etwas mit Umwegen verbunden, ist doch gerade das Schöne an Pascal.
Mit den Codetools fehlen mir solche Erweiterungen auch nicht, da beim Code schreiben mit einem einfachen <Ctrl> + <Shift> + <C> automatisch die entsprechende Variable in der Deklaration eingefügt wird. Sprich, ich bin genauso schnell, mit sauberen Code, der auch noch nach Jahren verständlich ist.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Syntaxerweiterung von Pascal

Beitrag von Mathias »

Auch das Create ist etwas komisch, normal heisst es:

Code: Alles auswählen

abc := Tabc.Create
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Syntaxerweiterung von Pascal

Beitrag von braunbär »

Ganz klar lokal.


Nein, 1. und 2. sind völlig verschiedene Sprachfeatures.

1.
Bei "With x:=object" sollte x nur lokal im Block vom with gelten (wie ja auch jetzt nur innerhalb des with-Block auf die Felder des with-Objekts zugegriffen werden kann). Der Sinn des konstrukts besteht darin, zu verhindern, dass spätere Änderungen an ganz anderen Stellen des Programms (in der record oder Klassendeklaration) unbemerkt das Verhalten des with-Blocks verändern können. Bei der normalen Pascal Implementierung droht diese Gefahr zumindest theoretisch immer, weshalb von der Verwendung von with ja generell abgeraten wird - einmal vor Langem ist mir das tatsächlich passiert, und ich habe den Fehler ziemlich lange gesucht, seither bin ich mit der Verwendung von with sehr zurückhaltend, obwohl es oft viel unnötige Schreibarbeit sparen würde.

2.
Die Variable, auf die hier zugewiesen wird, müsste vorher ganz normal deklariert werden. Der Zuweisungsoperator sollte in normalen "Expressions" als normaler Operator wie +, < oder *, mit niedrigster Bindungspriorität, verwendet werden können, dabei wird das Zwischenergebnis der Auswertung der rechten Seite der Zuweisung in der entsprechenden Variable gespeichert und die Auswertung normal fortgesetzt.
Also: (5+3) ist ein Ausdruck mit Ergebnis 8, der in einem beliebigen größeren Ausdruck verwendet werden kann.
Und : (a:=5+3) ist genau so ein Ausdruck mit Ergebnis 8, der in einem beliebigen größeren Ausdruck als Teilausdruck verwendet werden kann, bloß wird gleichzeitig dieses Zwischenergebnis in der (vorher normal deklarierten) Variable a gespeichert. Auch a:=b:=c:=10 wäre dann möglich und würde den Variablen a, b und c den Wert 10 zuweisen.

Mit den Codetools fehlen mir solche Erweiterungen auch nicht, da beim Code schreiben mit einem einfachen <Ctrl> + <Shift> + <C> automatisch die entsprechende Variable in der Deklaration eingefügt wird. Sprich, ich bin genauso schnell, mit sauberen Code, der auch noch nach Jahren verständlich ist.

Obwohl ich es hier gar nicht angesprochen habe: Variable, die nur lokal in einem Block gelten, tragen dazu bei, den Code verständlicher zu machen. Man weiß dann, dass es die Variable nur innerhalb dieses Blocks gibt und braucht sich keine Gedanken darüber zu machen, ob ein trickreicher Programmierer der Wert der Variablen vielleicht an anderer Stelle noch einmal verwendet hat.

Die klare Struktur, auch mal etwas mit Umwegen verbunden, ist doch gerade das Schöne an Pascal.

Meines Erachtens sind "Umwege" das exakte Gegenteil von "Klare Struktur".

Ich, für meinen Teil, halte von solchen sich C annähernden Erweiterungen nicht viel.

Die beiden von mir vorgeschlagenen Features gibt es meines Wissens beide in C nicht, C kennt ja überhaupt kein with. Die Zuweisungsoperatoren += etc. sind schlicht und einfach praktisch, das sehe ich nicht als "Annäherung an C". Ich mag C nicht und C++ schon gar nicht, das heißt aber doch nicht, dass ich gute Features ablehnen muss, bloß weil es sie in C gibt.


Zum Thema Exceptions: So wie die in Object Pascal definiert sind, fehlt ganz klar die "klare Struktur". Das haben Leute meines Erachtens im Husch-Pfusch-Verfahren definiert, leider wird Pascal diesen Schmarren jetzt wohl nicht mehr los werden...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Syntaxerweiterung von Pascal

Beitrag von mse »

braunbär hat geschrieben:Zwei andere Syntaxerweiterungen, deren Impementierung sehr einfach sein dürfte, würde ich für sehr sinnvoll halten, und ich würde gerne wissen, was ihr davon haltet und ob eine Aussicht besteht, dass so etwas umgesetzt wird.

MSElang hat die sichere "with" Version. Für Free Pascal wird es seit über zehn Jahren immer wieder diskutiert, mache dir keine Hoffnungen.
Es sei denn, Delphi führt es ein...

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Syntaxerweiterung von Pascal

Beitrag von mschnell »

braunbär hat geschrieben:1. "with x:=object do" alternativ zu "with object do"

Ich finde "with" allein schon deshalb furchtbar, weil man mehrere with ineinander verschachteln kann und dann eigentlich keiner mehr durchblickt. Kopiert man Codezeilen in/aus einem with-Block, ändern die Variablen ihre Bedeutung. Grauenhaft !

-Michael

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Syntaxerweiterung von Pascal

Beitrag von m.fuchs »

braunbär hat geschrieben:ich habe erfreut festgestellt, dass man im FPC einstellen kann, dass es die Operatoren +=, -= etc, versteht.

So etwas stelle ich nicht mit Freude fest und das ist einer der ersten Schalter den ich in neuen Projekte deaktiviere, Gleich nach $GOTO ON.

Was spricht denn an dieser Stelle dagegen auf eine Sprache auszuweichen in der man solche kürzere (und schlecht lesbaren) Statements verwenden kann? C wäre doch dann genau das Richtige.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Syntaxerweiterung von Pascal

Beitrag von mschnell »

Ich weiche gerne in eine Sprache aus, in der es kein "with" gibt (oder ich verwende es einfach nicht) :)

-Michael

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Syntaxerweiterung von Pascal

Beitrag von braunbär »

mschnell hat geschrieben:
braunbär hat geschrieben:1. "with x:=object do" alternativ zu "with object do"

Ich finde "with" allein schon deshalb furchtbar, weil man mehrere with ineinander verschachteln kann und dann eigentlich keiner mehr durchblickt. Kopiert man Codezeilen in/aus einem with-Block, ändern die Variablen ihre Bedeutung. Grauenhaft !

-Michael

Wenn du meinen Vorschlag überdacht hättest, dann hättest du bemerkt, dass er genau diese Probleme löst - also ein with ohne alle negativen Begleiterscheinungen. Jede Komponente des with-Objekts muss via "x." (oder so) dereferenziert werden, dann ist auch bei verschachtelten withs immer klar, zu welchem Objekt (das mit x., y. etc. quasi "abgekürzt" wird) die angesprochenen Felder gehören. Und kopiert man Codezeilen in einen/aus einem solchen with-Block, ändern die Variablen eben nicht ihre Bedeutung.

Wobei die beiden von dir genannten Punkte nicht wirklich das Killerargument sind. Das entscheidende Problem des normalen Pascal-with besteht darin, dass eine Änderung der Typdefinition an einer ganz anderen Stelle im Programm das Verhalten des Codes im with-Block ändern kann, ohne dass der Programmierer es bemerkt oder irgendwie darauf hingewiesen wird. Auch das wird durch meinen Vorschlag vermieden.

m.fuchs hat geschrieben:Was spricht denn an dieser Stelle dagegen auf eine Sprache auszuweichen in der man solche kürzere (und schlecht lesbaren) Statements verwenden kann? C wäre doch dann genau das Richtige.

Dass "Feld[3*i+5].Element[k]:=Feld[3*i+5].Element[k]+1" besser lesbar sein soll als "Feld[3*i+5].element[k]+=1" halte ich für ein Gerücht. In der ersten Version musst du drei mal kontrollieren, ob links und rechts vom Zuweisungsoperator das gleiche Element steht.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Syntaxerweiterung von Pascal

Beitrag von Timm Thaler »

braunbär hat geschrieben:Dass "Feld[3*i+5].Element[k]:=Feld[3*i+5].Element[k]+1" besser lesbar sein soll als "Feld[3*i+5].element[k]+=1" halte ich für ein Gerücht. In der ersten Version musst du drei mal kontrollieren, ob links und rechts vom Zuweisungsoperator das gleiche Element steht.


Inc() ist Dein Freund. https://www.freepascal.org/docs-html/rtl/system/inc.html

Nein, man muss nicht jeden Mist nachmachen, den C vormacht. Dann kann man gleich C verwenden, inklusive seiner ganzen fehlerträchtigen Spielereien.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Syntaxerweiterung von Pascal

Beitrag von Timm Thaler »

braunbär hat geschrieben:Wenn du meinen Vorschlag überdacht hättest, dann hättest du bemerkt, dass er genau diese Probleme löst - also ein with ohne alle negativen Begleiterscheinungen. Jede Komponente des with-Objekts muss via "x." (oder so) dereferenziert werden, dann ist auch bei verschachtelten withs immer klar, zu welchem Objekt (das mit x., y. etc. quasi "abgekürzt" wird) die angesprochenen Felder gehören.


Wenn Du Deinen Vorschlag mal genau überdenkst, merkst Du, dass er syntaktisch "unklug" ist.

Denn mit x := objekt wird üblicherweise dem x das objekt zugewiesen. Damit beziehen sich alle Änderungen an x.y im with-Teil - genau, auf x. Wenn der with-Teil fertig ist, hast Du also zwar x.y geändert, in objekt.y steht aber noch genau das Gleiche wie vor dem with-Teil. Du müsstest also zumindest am Ende wieder eine Rückzuweisung objekt := x machen.

Tja, wenn ich gern über solche Fehlerquellen stolpern und meine Zeit mit sinnlosem Debugging verschwenden will, kann ich auch gleich C nehmen.

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Syntaxerweiterung von Pascal

Beitrag von Mathias »

Ich finde "with" allein schon deshalb furchtbar, weil man mehrere with ineinander verschachteln kann und dann eigentlich keiner mehr durchblickt.

Ich verwende gerne with, wen man es richtig anwendet, wird der Code somit viel übersichtlicher.

Da kann man sich streiten, was übersichtlicher ist.

Code: Alles auswählen

    Button[i] := TButton.Create(Self);
    Button[i].Parent := Self;
    Button[i].Width := w;
    Button[i].Height := h;
    Button[i].Left := (i mod 16) * (w + 2);
    Button[i].Top := (i div 16) * (h + 2);
    Button[i].Caption := char(i + 32);
    Button[i].OnClick := @Button1Click;
   // -----
    Button[i] := TButton.Create(Self);
    with Button[i] do begin
      Parent := Self;
      Width := w;
      Height := h;
      Left := (i mod 16) * (w + 2);
      Top := (i div 16) * (h + 2);
      Caption := char(i + 32);
      OnClick := @Button1Click;
    end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Syntaxerweiterung von Pascal

Beitrag von m.fuchs »

braunbär hat geschrieben:Variable, die nur lokal in einem Block gelten, tragen dazu bei, den Code verständlicher zu machen. Man weiß dann, dass es die Variable nur innerhalb dieses Blocks gibt und braucht sich keine Gedanken darüber zu machen, ob ein trickreicher Programmierer der Wert der Variablen vielleicht an anderer Stelle noch einmal verwendet hat.

Einspruch Euer Ehren. Wenn du Variablen haben möchtest, die nur für einige Zeilen gültig sein sollen, dann lagere diese Zeilen in eine eigene Prozedur oder Funktion aus. Problem gelöst, schon mit jetzigen Bordmitteln.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: Syntaxerweiterung von Pascal

Beitrag von braunbär »

M.Fuchs hat geschrieben:Wenn du Variablen haben möchtest, die nur für einige Zeilen gültig sein sollen, dann lagere diese Zeilen in eine eigene Prozedur oder Funktion aus

Ein übertriebenes Aufsplittern des Codes in Zwerg-Unterprogramme trägt nicht zur Verbesserung der Lesbarkeit des Codes bei. Aber eine Möglichkeit, Variable lokal in einem Block zu deklarieren, wäre für die Lesbarkeit des Codes sicher nicht schädlich. Die Frage hat aber mit dem von mir angesprochenen Features ohnedies nichts zu tun.
Das Kriterium Lesbarkeit wird natürlich immer auch subjektiv interpretiert werden, dennoch sollte man "lesbar" nicht mit "ich bin es aber so gewohnt" verwechseln.

Timm Thaler hat geschrieben:Inc() ist Dein Freund. ... Nein, man muss nicht jeden Mist nachmachen, den C vormacht.

Und was soll an "inc()" BESSER sein als ein += Operator? Und nein, man muss auch nicht jedes Konstrukt als "Mist" bezeichnen, bloß weil es auch in C vorkommt.

Timm Thaler hat geschrieben:Denn mit x := objekt wird üblicherweise dem x das objekt zugewiesen.

Die Zuweisung ist hier natürlich als implizite Zeigerzuweisung mit anschließender impliziter Dereferenzierung im with-Block zu verstehen - so, wie es sonst bei Klassenvariablen der Fall ist.
Wobei aber meinetwegen das syntaktische Konstrukt ":=" auch durch irgend etwas anderes ersetzt werden könnte, gute Vorschläge sind immer willkommen. Im Prinzip wäre an der Stelle das Schlüsselwort "as" ja auch nett, geht aber nicht, weil das genau da mit anderer Bedeutung vorkommen kann, das wäre verwirrend.

Tja, wenn ich gern über solche Fehlerquellen stolpern und meine Zeit mit sinnlosem Debugging verschwenden will, kann ich auch gleich C nehmen.

Was diese Aggressivität bringen soll, kann ich nicht nachvollziehen.

Antworten