Stilfrage? Oder gibt's Unterschiede?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Stilfrage? Oder gibt's Unterschiede?

Beitrag von photor »

Moin Forum,

mir sind die folgenden beiden Konstrukte bezüglich der Ergebnis-Übergabe einer function über den Weg gelaufen:

Code: Alles auswählen

 
function Factor1(blah1 : double; blub2 : integer) : double;
begin
[...]
  if x <= 1.0 then
    Result := blubber
  else
    Result := 1.0;
end;
 
function Factor2(blah1 : double; blub2 : integer) : double;
begin
[...]
  if x <= 1.0 then
    Factor2 := blubber
  else
    Factor2 := 1.0;
end;
 

Beide habe ich schon programmiert und beide scheine gleich zu funktionieren. Im ersten Fall nutze ich eine implizit(kommt sonst in Pascal nicht vor - glaube ich) definierte Standardvariable; im zweiten Fall weise ich immerhin dem Funktionsname (bzw. der entsprechenden "Speicherzelle" den Rückgabewert zu - so zumindest kann ich mir das jeweils plausibel machen.

Gibt es einen (technischen) Unterschied? Oder ist es eine reine Stilfrage (welcher ist der bessere :wink: )? Oder gar reine Geschmacksfrage (dann hat sich jede weitere Diskussion erledigt)?

Ciao,

Photor

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von mse »

Technisch gibt es keinen Unterschied.

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von braunbär »

Result ist ein neueres Sprachkonstrukt, im ursprünglichen Pascal gab es das nicht.
Der Vorteil von Result ist, dass du Result als normale Variable verwenden kannst, während die Verwendung des Funktionsnamens auf der rechten Seite einer Zuweisung oder als Parameter einer anderen Prozedur immer einen rekursiven Funktionsaufruf bedeutet.

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von photor »

D.h. ich könnte tatsächlich sowas schreiben?

Code: Alles auswählen

 function Factor1(blah1 : double; blub2 : integer) : double;
begin
  Result := 1.0;
  if x <= 1.0 then
    Result := blubber
end;


Ciao

Photor

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von braunbär »

Das kannst du auch, wenn du statt Result den Funktionsnamen verwendest.
Aber so kannst du sogar schreiben:

Code: Alles auswählen

 
function Factor1(blah1 : double; blub2 : integer) : double;
begin
  Result := 1.0;
  if x <= 1.0 then
    Result := Result+1;
end;
 

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von Timm Thaler »

braunbär hat geschrieben:Result ist ein neueres Sprachkonstrukt, im ursprünglichen Pascal gab es das nicht.


Neu? Ich bin mir ziemlich sicher, dass wir sowohl im Turbo Pascal als auch im Borland Pascal schon im letzten Jahrhundert result als Rückgabevariable für Funktionen hatten. Den Funktionsnamen selbst dagegen nie.

Leider habe ich von den alten Programmen aus der Schule nix mehr.

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von photor »

braunbär hat geschrieben:Das kannst du auch, wenn du statt Result den Funktionsnamen verwendest.
Aber so kannst du sogar schreiben:

Code: Alles auswählen

 
function Factor1(blah1 : double; blub2 : integer) : double;
begin
  Result := 1.0;
  if x <= 1.0 then
    Result := Result+1;
end;
 

Das ginge mit der Funktionsnamen-Variante nicht? Das klingt nach einem handfesten Vorteil (ob's immer gut ist, ist ne andere Frage).

Und wenn Tim Thaler sagt, das die Result-Formulierung die "ursprüngliche" ist, dann nutze ich fortan diese. Ich nehme mal an, das es beide Varianten auch in Delphi gibt,richtig?

Und [i]result[\i] ist automatisch von deklarierten Typ der Funktion, und es sind auch nur die generischen Typen (keine Objekte oder Records - allenfalls Pointer darauf) möglich, nehme ich an.

Ciao,

Photor

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von wp_xyz »

Nein, zu Turbo-Zeiten musste das Funktionsergebnis den Funktionsnamen haben, "Result" kam erst mit Delphi. Da kannst du heute noch im Mode TP nachvollziehen. Das folgende Beispielprogramm im Mode TP lässt sich nicht kompilieren, weil das Funktionsergebnis der Variablen "Result" zugewiesen wird; nimmt man stattdessen den Funktionsnamen, ist alles ok:

Code: Alles auswählen

program Project1;
 
{$mode TP}
 
function Add(x, y: Integer): Integer;
begin
  Result := x + y;     // <-- Fehler beim Kompilieren
//  Add := x + y;      // <-- ok
end;
 
begin
  WriteLn(Add(1, 2));
end.

P.S.
Allerdings meine ich, dass es auch den Doppelslash als einzeiligen Kommentar in Turbo noch nicht gab - was hier aber problemlos akzeptiert wird.

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von m.fuchs »

Timm Thaler hat geschrieben:Neu? Ich bin mir ziemlich sicher, dass wir sowohl im Turbo Pascal als auch im Borland Pascal schon im letzten Jahrhundert result als Rückgabevariable für Funktionen hatten. Den Funktionsnamen selbst dagegen nie.


Nö, wurde erst in Delphi eingeführt. Funktioniert auch unter FPC nicht, wenn man den TP-Mode aktiviert:

Code: Alles auswählen

{$MODE TP}
program ResultTest;
 
function Test: String;
begin
 Result := 'Bla';
end;
 
begin
end.


project1.lpr(6,2) Error: Identifier not found "Result"



Ein weitere wichtiger Grund der für die Benutzung von Result spricht: Man kann den Funktionsnamen einfacher ändern.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von Timm Thaler »

photor hat geschrieben:Und wenn Tim Thaler sagt, das die Result-Formulierung die "ursprüngliche" is...


Stopp! Ich nehm alles zurück und behaupte das Gegenteil. Ich habe tatsächlich noch ein paar alte TP-Programme gefunden, zwar nicht aus der Schulzeit, aber aus dem letzten Jahrhundert, und da erfolgte die Wertzuweisung auf den Funktionsnamen.

Code: Alles auswählen

Function Sgn(zhl:Real):Real;
  Begin
    If zhl>0 Then
      Sgn:=1
    Else
      If zhl<0 Then
        Sgn:=-1
      Else
        Sgn:=0;
  End;
 
Function Rad(wkl:Real):Real;
  Begin
    Rad:=wkl*Pi/180;
  End;
 
Function Grd(wkl:Real):Real;
  Begin
    Grd:=wkl*180/Pi;
  End;


Da habe ich mich tatsächlich falsch erinnert. So gehts los... Honig im Kopf.

Aber ja, der Vorteil von Result ist, dass man den Funktionsnamen unabhängig ändern kann. Und dass klar ist: Hier erfolgt die Übergabe, und es ist nicht irgend eine weitere Variable.

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von braunbär »

photor hat geschrieben:
braunbär hat geschrieben:Das kannst du auch, wenn du statt Result den Funktionsnamen verwendest.
Aber so kannst du sogar schreiben:

Code: Alles auswählen

 
function Factor1(blah1 : double; blub2 : integer) : double;
begin
  Result := 1.0;
  if x <= 1.0 then
    Result := Result+1;
end;
 

Das ginge mit der Funktionsnamen-Variante nicht? Das klingt nach einem handfesten Vorteil (ob's immer gut ist, ist ne andere Frage).

Ich wüsste nicht, was daran schlecht sein könnte.
Mit der Funktionsname-Variante geht es deshalb nicht, weil der Funktionsname auf der rechten Seite einer Zuweisung immer den Aufruf der Funktion bedeutet, auch im Funktionsrumpf selbst:

Code: Alles auswählen

 
function faktorielle  (n: integer): integer;
begin
if n<2
then result:=1
else result:=n*faktorielle(n-1);
end
 


Du kannst auch schreiben:

Code: Alles auswählen

 
function faktorielle  (n: integer): integer;
begin
if n<2
then faktorielle  := 1
else faktorielle  := n*faktorielle(n-1);
end
 

Aber an dem Beispiel siehst du sehr gut, warum die Verwendung von Result besser ist.
Steht Faktorielle links, dann wird ein Funktionsergebnis zugewiesen, steht es aber rechts vom Zuweisungsoperator, dann bedeutet es einen neuen (rekursiven) Funktionsaufruf. Das ist zwar nicht mißverständlich, weil es klar definiert ist, aber die Verwendung von Result macht das Programm meines Erachtens besser lesbar.


photor hat geschrieben:Und [i]result[\i] ist automatisch von deklarierten Typ der Funktion, und es sind auch nur die generischen Typen (keine Objekte oder Records - allenfalls Pointer darauf) möglich, nehme ich an.

Nein, warum sollte es so eine Einschränkung geben? Result ist vom Typ der deklarierten Funktion, das kann jeder Typ sein, den eine Funktion haben kann.

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: Stilfrage? Oder gibt's Unterschiede?

Beitrag von Timm Thaler »

braunbär hat geschrieben:Mit der Funktionsname-Variante geht es deshalb nicht, weil der Funktionsname auf der rechten Seite einer Zuweisung immer den Aufruf der Funktion bedeutet...


Ja, nenn man Rekursion. Damit konnte man früher innerhalb von Sekunden den 286er abschießen, wenn man keine Abbruchbedingung vorgesehen hat. ;-)

Jole
Beiträge: 114
Registriert: Fr 4. Jul 2014, 14:39
OS, Lazarus, FPC: Linux
CPU-Target: amd64

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von Jole »

@Timm Thaler: So ganz Trübt dich deine Erinnerung auch nicht, den in Turbo Pascal gab es das vordefinierte Symbol "@Result". Allerdings nur in Zusammenhang mit Assembler Code, Beispiel:

Code: Alles auswählen

 
function Test: Integer;
begin
  asm
    mov ax,99
    mov @result,ax
  end;
end;
 

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von photor »

Danke Forum,

Wieder was gelernt. :) Ich werde mich an die "result"-Variante halten; die Vorteile leuchten mir ein.

Ciao,

Photor

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

Re: Stilfrage? Oder gibt's Unterschiede?

Beitrag von Mathias »

Nein, zu Turbo-Zeiten musste das Funktionsergebnis den Funktionsnamen haben, "Result" kam erst mit Delphi.

Ich habe es gerade probiert, BP7 bringt einen Syntax-Fehler.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten