GOTO (aus Digitaluhr, Hilfe !)

Bitte aktiviere JavaScript!
Dann ist aber auch gar nichts erlaubt, denn Sprünge (GOTO) sind ja generell das, was am Ende die CPU macht. Also wenn man die Trennung zwischen erstelltem Code und dem daraus generierten Code nicht hat, dann wird man nur noch einfache, gradlinige Software entwickeln können fürchte ich.
(Selbst ein Funktionsaufruf ist ja nur ein pushen von Werten auf den Stack gefolgt von einem Sprung. Und am Ende dann das herunternehmen von Werten vom Stack und dann ein Sprung zu der Rücksprungadresse....)
Na so war das nicht gemeint :p
 
Ersetz das break einfach durch ein return, dann ist er sicher zufriedengestellt :p
Ach ja: Und bei Methoden gibt es ja für manch einen auch die Regel, dass man nur ein return Statement am Ende haben darf. Also nichts mit return vorher oder so ... Wer das break; so massiv ablehnt, der wird dies wohl auch ablehnen.

Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.

Aber das ist dann auch ein anderes Thema.

Außerdem meinte ich damit, dass man nichtmehr irdische Personen schwer fragen kann, wie sie etwas gemeint haben. (Es sei denn, jemand versteht hier etwas von Okkultismus, aber das ist jetzt wirklich am Thema vorbei...)
Also DU hast lediglich mit dem Namen eines Toten etwas begründen wollen. Und Du kannst das jetzt nicht begründen, weil die Person tot ist? Aber Du musst doch irgendwas von der Person wissen, wenn Du der Meinung warst, dass dies ein Argument für diese Sache ist.

Ach bitte, schlechter Verlierer würd ich mal sagen. ;) @Blender3D
Ihm geht es ja nur um eine Erläuterung der Kritik. Nur weil Du Deine Kritik nicht belegen / erläutern kannst, ist @Blender3D nun der schlechte Verlierer?

Kann man mir diese Logik evtl. etwas erläutern?
 
Ach ja: Und bei Methoden gibt es ja für manch einen auch die Regel, dass man nur ein return Statement am Ende haben darf. Also nichts mit return vorher oder so ... Wer das break; so massiv ablehnt, der wird dies wohl auch ablehnen.

Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.

Aber das ist dann auch ein anderes Thema.
In Clean Code steht doch auch, dass mehrere returns durchaus besser sein können?

Some programmers follow Edsger Dijkstra’s rules of structured programming. Dijkstra said that every function, and every block within a function, should have one entry and one exit. Following these rules means that there should only be one return statement in a function, no break or continue statements in a loop, and never, ever, any goto statements.

While we are sympathetic to the goals and disciplines of structured programming, those rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefit.

So if you keep your functions small, then the occasional multiple return, break, orcontinue statement does no harm and can sometimes even be more expressive than the single-entry, single-exit rule. On the other hand, goto only makes sense in large functions, so it should be avoided.
(Bezieht sich sogar auf goto :p)
 
(Im Byte-Code entspricht ein break btw einem goto. Die Punkte von Dijkstra dürften für breaks in Verbindung mit Labeln genauso gelten)
Da ich auch Assemblerprogramme schreibe, weiß ich natürlich auch dass im Byte Code dort ein Sprung stattfindet.
Dasselbe passiert aber auch bei einer abweisenden while Schleife im Byte Code oder wenn man return verwendet.
Der Punkt ist, dass BREAK <> GOTO ist. Warum?
Ich kann mittels break nicht an eine beliebige Stelle Springen. Also Logik:
A hat Eigenschaft 1 und 2.
B hat Eigenschaft 1.
--> A <> B
Und Dijkstra spricht in seinem Link von GOTO.
 
@Blender3D Spulen wir nochmal zurück bitte. Ich wollte damit nicht schreiben, Dein Code sei schlecht oder Ähnliches, aber eben auch nicht "fehlerfrei", bzw an der ein oder anderen Stelle hätte man ihn, zB in einem Review, anders schreiben können.

@ all : Ich kann nicht genau begründen, wie Dijkstra das evtl gemeint haben könnte. Aber @mrBrown hat ja bereits ein paar relevante Stellen herausgesucht...
 
Der Punkt ist, dass BREAK <> GOTO ist.
[...]
Und Dijkstra spricht in seinem Link von GOTO.
Ich hab nirgends das Gegenteil behauptet.

Wenn man jedes GOTO ablehnt (was Dijkstra nicht getan hat) - auch die, die nur für Vorwärtssprünge genutzt werden - muss man den gleichen Maßstab aber auch für break ansetzen.

Setzt man einen sinnvollen Maßstab an (und weicht auch von single-entry/single-exit ab, weclhes für return, break & continue ebenso gilt), sind breaks völlig Okay, aber sowas wie Vorwärtssprünge mit Goto als Ersatz für finally aber auch. (Als reines Sprachfeature ist es mMn besser als goto, da begrenztere Nutzungsmöglichkeiten)

Das die Aussage von @Tobias-nrw so wie sie da stand dämlich ist, ist völlig klar. Aber je nachdem, wie hart man Dinge auslegt, sprechen die Dinge, die gegen goto sprechen, auch gegen breaks.

Ich kann mittels break nicht an eine beliebige Stelle Springen
Wenn man Blöcke sehr missbraucht, kann man immerhin an fast jede Stelle springen, nur z.B. nicht in andere, fremde Blöcke... Ist dann allerdings noch schlimmer als goto für sowas zu benutzen...
 
Zuletzt bearbeitet:
Ich staune darüber, auf welche Abwege eine recht einfache Anfängeraufgabe führen kann.

Und welch ein Trubel um ein Statement, daß es im Hauptthemenbereich des Forums nicht gibt. ;)
 
Danke @mrBrown für Deine Unterstützung. Das Zitat oder der Beleg zeigt ja das ich nicht unrecht hatte mit meinen "Kritik"punkten. ;)

Hier gab es nur ein break; aber besonders, wenn sich die break;s häufen, tut das dem Lesefluss nicht gut...

An dem Beispiel sieht man auch, dass seine Thesen keinesfalls "in die Jahre gekommen", vielmehr aktueller denn je sind.
 
Wobei ich diese Clean Code Regel ablehne und für nicht konstruktiv halte. Das führt dann zu schlecht lesbarem Code, weil man ständig if (..) { ... } else { ... } Blöcke bekommt.
Grundsätzlich versuche ich, mich schon daran zu halten, habe aber kein Problem mit Ausnahmen. Typisches Beispiel:

Java:
public boolean equals(Object o) {
    if (o == null || o == this || !(o instanceof MeineKlasse)) {
        return o == this;
    }

    MeineKlasse k = (MeineKlasse) o;
    return Objects.equals(this.value, k.value);
}
ist für mich am angenehmsten zu lesen. Andererseits schreibe ich for-each-Schleifen in der Regel nicht, wenn dies zu einem return/break führen würde (Ausnahmen gibt es immer).
 
Grundsätzlich versuche ich, mich schon daran zu halten, habe aber kein Problem mit Ausnahmen. Typisches Beispiel:

Java:
public boolean equals(Object o) {
    if (o == null || o == this || !(o instanceof MeineKlasse)) {
        return o == this;
    }

    MeineKlasse k = (MeineKlasse) o;
    return Objects.equals(this.value, k.value);
}
ist für mich am angenehmsten zu lesen. Andererseits schreibe ich for-each-Schleifen in der Regel nicht, wenn dies zu einem return/break führen würde (Ausnahmen gibt es immer).
Also es ist schon oft so, dass man bei Funktionen am Ende das Ergebnis zurück gibt, aber ich denke, dass es nicht selten vorkommt, dass man eben aus einer Menge etwas heraus suchen muss und dann natürlich die Suche abbricht.

Und da sehe ich nun als einzige Alternative, eben auf das for statement zu verzichten und es generell per while Schleife ablaufen zu lassen. Aus dem Code
Code:
for(SomeType elment: elements) { 
    ...
    if (someCondition) return someExpression;
}
wird dann halt etwas wie (Pseudocode im Browser hier entstanden
Code:
Iterator<SomeType> iterator = elements.getIterator();
SomeType result = null;
while (result==null && iterator.hasNext()) {
    SomeType element = iterator.next();
    ...
    if (someCondition) result=someExpression;
}
return result;
Oder man schwenkt natürlich auf streams um mit elements.stream().filter(...).First(); was bei halbwegs aktuellem Java (Java 8 Minimum) gehen würde. Nur bei komplexerem Filter bin ich mir jetzt nur nicht sicher, ob dies lesbar bleibt. (Aber vermutlich schon. Complexe Dinge würde ich in den anderen Varianten ja auch nicht in der Schleife ablaufen lassen sondern eben verlagern. Das wird da ja auch gelten...

Habe ich da jetzt etwas übersehen? Das mit der While Schleife würde ich erst einmal als schwerer lesbarer ablehnen. Das mit der Streams API sieht aber tatsächlich gut aus und zeigt, dass meine bisherige Haltung diesbezüglich evtl. durch die Einführung der Streams API anzupassen ist.
 
Das mit der While Schleife würde ich erst einmal als schwerer lesbarer ablehnen.
Jein. Es ist zweifelsohne mehr Code, der aus Sicht von Anfängern zunächst schwerer zu begreifen ist (Iterator-Konzept). Tatsächlich ist das aber alles Standard-Boilerplate-Code. Dieses Muster findet man also so gut wie immer, wenn mit Iteratoren gearbeitet wird.

Tatsächlich sagt das while aber wesentlich präziser, worum es geht: iteriere so lange, bis result != null ist. Das for-Each lügt mir dagegen ins Gesicht: es tut so, als ob über alle Elemente iteriert würde, tatsächlich bricht es irgendwann ab und springt auch noch aus der Methode.

Wenn man die Blöcke einklappt, wird deutlicher, was ich meine:
Java:
for (SomeType element : elements) { ... }
return null;
vs
Java:
while (result == null && it.hasNext()) { ... }
return result;
Für so etwas würde ich heute allerdings auch Streams verwenden :)

(EDIT: Schleifenbedingung korrigiert)
 
Zuletzt bearbeitet:
Jein. Es ist zweifelsohne mehr Code, der aus Sicht von Anfängern zunächst schwerer zu begreifen ist (Iterator-Konzept). Tatsächlich ist das aber alles Standard-Boilerplate-Code. Dieses Muster findet man also so gut wie immer, wenn mit Iteratoren gearbeitet wird.

Tatsächlich sagt das while aber wesentlich präziser, worum es geht: iteriere so lange, bis result != null ist. Das for-Each lügt mir dagegen ins Gesicht: es tut so, als ob über alle Elemente iteriert würde, tatsächlich bricht es irgendwann ab und springt auch noch aus der Methode.
Diese Argumentation kann ich nachvollziehen, aber wirklich überzeugt bin ich nicht. :)
Im Augenblick empfinde ich die While Scheife auf Grund des Boilerplate Codes eher als unleserlicher. Aber auch der logische Ablauf ist bei der while schleife deutlicher, da hier eine Bedingung ist. Bei der for Schleife hat man das ja unterteilt in einmal die Definition über was iteriert werden soll + einer if Abfrage innen drin. (if (Bedingung) return result; ist ja existenziell.

Aber ich werde auf jeden Fall einmal in der Praxis schauen, ob die while schleife deutlicher wird (Ist ja auch eine Frage der Gewöhnung) und ich werde auch einmal den Smalltalk im Team darauf lenken. (Akzeptiert sind da beide Wege.)
 
Du vergleichst Äpfel und Birnen... Es ging nicht um ein return; sondern um das noch schädlichere break;.

Und naja, da bleibt nur zu hoffen, dass Du nicht etwas ablehnen kannst...
Bitte lies einen Thread, ehe Du antwortest. In den letzten Beiträgen (ab #33) ging es eben nicht mehr um das "break;" oder "return" sondern um die Konsequenzen. Und da gab es im Thread drei Optionen für die Implementierung: for-each, while und Streams.

Und genau die wurden bewertet. Da kannst Du auch gerne Deine Sicht sagen.

@mihe7 Interessant ist, wenn "null" ein mögliches Resultat wird und bei nicht Vorhandensein eines Resultates eine Exception geworfen werden soll. Das verkompliziert die while-Lösung etwas. Da wäre mein Ansatz dann, Optional<ResultTyp> zu verwenden. Dann kann man halt result.isPresent in der while Bedingung und ein abschließendes if nach der while schleife...

Da wird das mit der Stream API doch deutlich einfacher und übersichtlicher.
 
Diese Argumentation kann ich nachvollziehen, aber wirklich überzeugt bin ich nicht.
Das sind ja auch nur persönliche Präferenzen - und die sind nun einmal individuell verschieden :)

Interessant ist, wenn "null" ein mögliches Resultat wird und bei nicht Vorhandensein eines Resultates eine Exception geworfen werden soll. Das verkompliziert die while-Lösung etwas.
Darin unterscheiden sich while und for-each aber nicht - oder ich habe Dich falsch verstanden.
 
Darin unterscheiden sich while und for-each aber nicht - oder ich habe Dich falsch verstanden.
Das Problem, welches ich meine ist: Angenommen es kann auch null als Ergebnis heraus kommen. Also ich habe etwas wie:
Code:
for (Element element: elements) {
  if (someCheck(element)) return element.getValue();
}
// Hier ist klar: element wurde nicht gefunden - kann also Exception werfen oder default Wert zurück geben oder oder oder ...
Die 1:1 Übersetzung hinkt aber:
Code:
while (result == null && it.hasNext()) {
  Element element = it.next();
  if (someCheck(element)) result = element.getValue();
}
Aber da bricht dann ja auch noch nicht einmal die Schleife ab, wenn getValue() auch null liefern kann/darf.

Aber das war ein Denkfehler bei mir. Denn wenn man es aufschreibt, dann wird klar: ich kann ja einfach der element in result speichern. Das ist dann nicht null und ich kann am Ende auch schauen: Wenn result == null, dann gebe ich default Wert zurück oder werfe eine Exception ... also gar kein Thema, das zu diskutieren wäre und auch nichts, das neue Argumente in die Diskussion einbringt. Also an der Stelle sorry für evtl. Verwirrungen.
 
Passende Stellenanzeigen aus deiner Region:

Oben