- John Carmack hat seine persönliche Sicht auf die Verwendung veränderlicher Variablen (mutable variables) geteilt
- Er sagte, dass er beim Arbeiten mit Python das Prinzip der „einmaligen Zuweisung“ (single assignment) vernachlässigt habe und sich selbst davor warnen müsse
- Er betonte, dass man außer bei iterativen Berechnungen in Schleifen Neuzuweisungen oder Aktualisierungen von Variablen vermeiden sollte
- Wenn alle Zwischenschritte der Berechnung erhalten bleiben, hilft das beim Debugging, und beim Verschieben von Codeblöcken kann es verhindern, dass unbeabsichtigt frühere Werte verwendet werden
- In C/C++ sei es eine gute Gewohnheit, fast alle Variablen bereits bei der Initialisierung als
const zu deklarieren
- Abschließend betonte er mit den Worten „Ich wünschte,
mutable wäre ein Keyword“, dass Unveränderlichkeit der Standard sein sollte
1 Kommentare
Hacker-News-Kommentare
Nachdem ich 2 Jahre lang Clojure verwendet habe, wurde mir klar, wie schwer es ist, anderen Entwicklern die Klarheit zu vermitteln, die Unveränderlichkeit bringt
Wer daran gewöhnt ist, Effekte durch Zustandsänderungen zu erzeugen, versteht das meist erst, wenn er es selbst erlebt
Wenn man zum Beispiel
x = 7; x = x + 3; x = x / 2schreibt, gibt es beim Vertauschen der Reihenfolge keinen Fehler, aber das Ergebnis ändert sichVerwendet man dagegen neue Variablen wie
x1undx2, führt eine falsche Reihenfolge zu einem Fehler und macht das Problem klar sichtbarLetztlich ist Single Assignment eine Möglichkeit, solche Abhängigkeiten explizit auszudrücken
Selbst wenn ich Kollegen ohne Erfahrung mit funktionalen Sprachen erklärt habe, wie leicht zu testen und sauber funktionszentriertes Denken ist, kam das kaum an
In Python lässt sich ein funktionaler Stil nur schwer lesbar schreiben, und JS wirkt dafür sogar besser geeignet
Am Ende probieren nur neugierige Entwickler Sprachen wie Clojure aus
Die Funktion muss keinen externen Zustand kennen, und außen muss niemand das Innere der Funktion kennen
Man kann eine bestimmte Funktion unabhängig testen oder debuggen, ohne den Gesamtzustand des Programms zu kennen
Es ist interessant zu sehen, wie die Haskell-Community am Ende versucht, Veränderlichkeit innerhalb des Typsystems neu zu erfinden
Entscheidend ist, Nebenwirkungen mit minimalen Kosten unter Kontrolle zu halten
Haskell hatte wegen seines Typsystems eine hohe Einstiegshürde, und F# war zu kompromissbereit, sodass man am Ende in C#-Syntax codiert
Dank der Homoikonizität von Clojure und seiner mächtigen Datenstrukturen wurde mir das Konzept, „mit Werten zu arbeiten“, zum ersten Mal wirklich klar
Beruflich würde ich es wohl nicht einsetzen, aber Menschen ohne Erfahrung mit funktionalen Sprachen oder Lisp würde ich es unbedingt empfehlen
Ich wünschte, Variablen wären standardmäßig unveränderlich und alles wäre ein Ausdruck (expression)
Aber als Clojure-Entwickler leide ich in der Realität unter der Invasion von Python
Inzwischen leide ich unter der Invasion von TypeScript, daher kann ich das nachvollziehen
Dieser Ansatz ist wirklich nützlich, um den Umfang von Änderungen zu begrenzen
Du musst dich nicht in Stammeskriege zwischen Sprachen hineinziehen lassen
In einer Zeit steigender Produktivität sind solche Grenzen bedeutungslos
Ich empfehle den Artikel Don’t Call Yourself a Programmer
Ich versuche Neuzuweisungen von Variablen zu minimieren, nutze aber oft Variablenschattening
Ich mag Muster wie
result = result.process(), weil sie knapp sindWenn
process()zum Beispiel eine Validierungsfunktion ist, kann unklar werden, an welchem Punkt der verarbeitete Wert stehtDeshalb ist es besser, Zustände im Namen klar voneinander zu unterscheiden
Beispiel:
result = x |> foo |> bar |> bazoder(-> x foo bar baz)result.process()? Was für ein result und was für ein process soll das sein?“Wer den Code später liest, wird verwirrt sein
Schon der Begriff „Variable“ fühlt sich für mich seltsam an
Wenn sie unveränderlich ist, warum nennt man sie dann Variable?
In Rust muss Veränderbarkeit mit
mutexplizit angegeben werdenIn C muss man dagegen den Präprozessor verwenden, um Konstanten zu erstellen, was verwirrend ist
xerhält bei jedem Aufruf einen anderen Wert und ist damit selbst ein variierender WertAuch ohne Neuzuweisung kann man es also Variable nennen
Die Programmierung hat dieses Konzept direkt übernommen
Eine Konstante hat in allen Ausführungen denselben Wert
Siehe Variable (mathematics)
Es wäre gut, wenn die IDE visuell markieren würde, ob eine Variable verändert wurde
Zum Beispiel durch eine leichte Kennzeichnung geänderter Variablen
Wenn man möglichst oft
finalverwendet, wird Code leichter lesbar und wartbarerDie IDE sollte warnen und Änderungen nur dann zulassen, wenn sie wirklich nötig sind
Wie in Rich Hickeys Geschichte über set vs list sollte man Strukturen wählen, die Bedeutung klar ausdrücken
Früher habe ich an einem Projekt gearbeitet, das Unveränderlichkeit aus Gründen der Thread-Sicherheit strikt durchgesetzt hat
Dadurch wurde der Code leichter lesbar, und es war einfacher nachzuvollziehen, was sich ändern kann
Seitdem bin ich ein glühender Fan von Unveränderlichkeit
Nachdem ich in einer großen Haskell-Codebasis gearbeitet hatte und dann wieder zu C zurückkehrte, dachte ich, Unveränderlichkeit sollte der Standard sein
constreicht dafür nicht ausUm etwas zu verändern, braucht man Zeiger, und in C++ können schon Funktionsaufrufe Argumente verändern, was undurchsichtig ist
Ich stimme der Aussage zu, dass man „fast alle Variablen als const deklarieren“ sollte
Da sollte Rust erwähnt werden
Ich stelle mir eine Syntax vor, bei der Unveränderlichkeit der Standard ist und mutable nur innerhalb eines bestimmten Blocks erlaubt ist
Zum Beispiel wie ein
with-Block in PythonSobald man den Block verlässt, wäre wieder alles unveränderlich
Am Borrow Checker von Rust sieht man, wie komplex dieses Konzept ist
Es gibt den Satz: „State is the enemy“
Je mehr Zustand es gibt, desto exponentiell mehr Bedingungen müssen getestet werden
Unveränderlichkeit ist ein Weg, diese Zustandsexplosion zu verhindern
Separation of Church and State