Zitat von
alienous:
alles klar, habs verstanden! vielen dank.
wieder etwas gelernt!
Das ist gut (wirklich!)
Zitat von
negaH:
Zitat:
Ich seh ehrlich gesagt noch nicht den sachlichen Vorteil darin, dass ich eine Funktion innerhalb einer Funktion verwende. Als Nachteile sehe ich weiterhin, dass die Lesbarkeit reduziert wird. Man sieht meiner Meinung nach nicht sofort, wo was herkommt.
Siehst du und da meine ich arbeitest du ineffizient.
Interessante
Meinung
Zitat von
negaH:
Warum willst du ALLES im Kopf haben, jedes kleine Detail eine Implementierung, das ist utopisch. Konsequenz ist also das man im BlackBox-Prinzip denkt und auch einen Source liest.
Was genau möchtest du mir denn hier unterstellen?! Mir wäre nicht klar, dass man alle Details einer Implementierung im Kopf finden könnte (oder alle Programme bestehen nur aus einem Kopf). Dass Delphi seine Variablen/Methoden immer schon vor ihrer Implementierung bekannt macht ist keineswegs ein Feature das ich beführworte. Finde das andere Sprachen, wie Java, die Dinge erst einführen wenn sie wirklich verwendet werden sehr viel besser.
Aber zur Blackbox, da fahre ich mit einer z.B. abstrakten Klasse oder einem Interface um einiges Schwarzer. Da brauche ich dann gar kein Wissen über die Implementierung! (Stimmt wenn man noch Factory-Pattern und Dependency Injection hinzunimmt, dann kann es Klassen geben die nur die Schnittstelle kennen).
Da seh ich jetzt einen sehr einfachen Weg um austauschbare Lösungen bereit zu stellen. Die habe ich durch die Mittel der
OOP gegeben. Ich sehe also für Delphi Programme die OO programmiert werden keine Notwendigkeit der nested Functions.
Zitat von
negaH:
Was ist den das Gegenteil der Funktionen, und eben nested Funktionen ? Spaghetti-code !
Von welchen Funktionen redest du denn bitte? Erstmal ist Spaghetti-Code auch innerhalb von Funktionen ohne weiteres Möglich und auch in einer nested Function kann ich sicherlich welchen unterbringen. Das hat doch nichts mit Alternativen zu tun. Ich (und kein anderer hier) habe doch nie behauptet, dass man keine Funktionen verwenden soll. Bleib doch einfach erstmal bei dem was hier gesagt wurde!
Es geht um so genannte nested Functions! Und wo ist jetzt der gut leserliche Vorteil zwischen :
Delphi-Quellcode:
function Convert(K: Integer): String;
begin
Result := '';
while K <> 0 do
begin
Result := Result + Char(Ord('0') + K mod 10)
K := K div 10;
end;
end;
begin
for I := 0 to x do
begin
Array[i] := Convert(I*2);
Array[i*2] := Convert(I*3);
Array[i*12] := Convert(I*12);
end;
und dem was ich wirklich propagiere!
Delphi-Quellcode:
type
TConverter = class(TObject)
private
function Convert(K : Integer): String;
public
doFoo;
end;
....
function Convert(K: Integer): String;
begin
Result := '';
while K <> 0 do
begin
Result := Result + Char(Ord('0') + K mod 10)
K := K div 10;
end;
end;
procedure doFoo;
...
for I := 0 to x do
begin
Array[i] := Convert(I*2);
Array[i*2] := Convert(I*3);
Array[i*12] := Convert(I*12);
end;
end;
Zitat von
negaH:
Zitat von
negaH:
1.) man sieht wohl den Unterschied in der Lesbarkeit
Klar, finde die Klasse ist sehr leicht lesbar. Ich sehe dass es sich hier um zwei Methoden handelt und kann die sehr leicht getrennt voneinander betrachten.
Von aussen ist es eine Black-Box, nur die Methode doFoo ist sichtbar. Ich habe alle Vorteile der
OOP offen gehalten. Klar, könnte ich auch mit einer nested Function machen, würde für mich aber immer noch die Lesbarkeit senken (kommen wir noch darauf zurück).
Zitat von
negaH:
2.) Convert() als Funktion wird ausschließlich nur in dieser Funktion benötigt und um Namens Kollisionen zu vermeiden machen wird sie nested
Was natürlich ein weiterer Nachteil ist. Was ist denn wenn ich eine äussere Funktion habe, die auch convert heißt? Jetzt merke ich mir nicht alle nested Functions und komme schnell zu dem Punkt, an dem ich zwei Funktionen verwechsel (und mir Ergebnisse nicht erklären kann).
Jetzt frage ich mich aber, wie wahrscheinlich in einer Klasse (die man sauber designt) Namenskonflikte sind. Tragen die dann nicht zu einer für sich selbst sprechende Bennenung bei? Ich meine klar, convert konvertiert wohl etwas, keiner weiß jetzt was (und jeder muss in die Implementierung schauen), mir entgeht da der Vorteil.
Zitat von
negaH:
3.) Convert() benötigt in EAX den Parameter K, und noch ein Register um Result aufzunehmen. Mehr benötigt man an registern auch nicht, dh. Convert() sollte durch den Compiler in einen Maschionencode umgewandelt werden der ohne STack auskommt.
4.) in der Funktion selber werden I,X und @Array benötigt, also 3 CPU Register. Also auch diese Funktion sollte durch den Compiler vollständig in Registern optimiert werden
Ok, darüber habe ich mir keine Gedanken gemacht, aber wieviel bringt das ganze? Ich meine klar die Relationen sind hier schon klar, doch der erste Cache-Miss könnte die Vorteile hier schon deutlich dominieren (was so pauschal auch falsch ist, aber egal).
Zitat von
negaH:
Gibt es eine procedurale Modularisierung in einer Programmiersprache so gibt es dort auch konsequenter Weise die nested Funktionen als stärkste Abstraktionsebene.
Dazu kann ich nur nochmal sagen, dass es nie darum ging. Alles was ich sagte ist, dass es andere Mittel gibt (da stimmen wir ja völlig überein) um Abstraktion zu erreichen. Ich finde einfach, dass die Lesbarkeit vom Code durch nested-Functions eingeschränkt wird. Der Vorteil (den ich nicht kannte und jetzt dazu gelernt habe) liegt in dem Perfomanteren übergeben von Parametern an die nested Function.
Aber auch ich möchte es noch mal deutlich machen, zerlegt man ein Problem nur innerhalb von einer Funktion in einzelne Teilprobleme und verwendet dazu nested Funktions, würde das in letzter Konsequenz zu Konstrukte führen wie
Delphi-Quellcode:
procedure doA;
var x : Integer;
procedure doB;
var y : Integer;
procedure doC;
var z : Integer;
begin
//....
end;
begin
// ....
end;
begin
// ...
end;
Wobei hier in doB redundante Teile aus doA auftauchen und in doC solche aus B, natürlich kann man hier noch beliebig weiterschachteln (wieviele Register bleiben da dann übrig?). Klar, ist jetzt auch ein konstruiertes Beispiel, aber die habe ich bisher hier gesehen.
Auch hier möchte ich nur sagen, dass es Konsequent fortgeführtes Verwenden von nested Functions wäre. Ihr Einsatz lässt sich vermeiden und würde die Lesbarkeit solcher Beispiele mit Sicherheit erhöhen!
Weder nested Functions noch
OOP oder ein anderes Mittel der Strukturierung und Abstraktion ersetzen also ein sinnvolles Design und ich möchte nocheinmal sagen, 500 Zeilen mit allen nested Functions zusammen klingt nach einem Design, dass man verbessern könnte.
Da von xaromz auch gesagt wurde, dass es hier Unterprozeduren gibt, würde ich sagen, dass man einen Teil von ihnen anders auslagern sollte (in eine eigene
Unit, die diese Klasse von Problemen löst (auch ohne
OOP!)).
Gruß Der Unwissende