3 Punkte von GN⁺ 2023-12-29 | 1 Kommentare | Auf WhatsApp teilen
  • Manche Softwareprojekte sind warmblütig und müssen durch kontinuierliche Entwicklungsaktivität am Leben gehalten werden; wenn die Arbeit zwar unterbrochen wird, später aber wieder aufgenommen werden kann, sind sie eher kaltblütig
  • Kaltblütige Projekte wählen langweilige Technik, damit Build und Tests auch nach langer Pause nicht kaputtgehen, und vermeiden Abhängigkeiten von externen Diensten, die sich ändern oder verschwinden können
  • Die Übernahme oder Schließung abhängiger Dienste, Compiler-Upgrades und eingestellter Paket-Support schlagen beim Wiederanlaufen wenig aktiver Projekte als Wartungskosten zu Buche
  • Code, den man wie bei persönlichen Projekten 1, 2 oder 3 Jahre lang nicht anfasst, kann nur schwer kontinuierliche Wärme erzeugen; deshalb sollte man ihn von Anfang an unter der Annahme einer niedrigen Änderungsrate entwerfen
  • Der statische Site-Generator für diesen Blog läuft seit dem ersten Commit im Jahr 2012 mit Python 2, vier im Repository enthaltenen Drittanbieter-Modulen, lokaler Ausführung und Deployment per rsync over ssh bis heute fast ohne Änderungen weiter

Projektpflege im Bild kaltblütiger Tiere

  • In einer naturkundlichen Vorlesung im Jahr 2004 legte der Professor ein aus dem Gefrierfach geholtes painted turtle Jungtier unter die Kamera und hielt damit die Vorlesung
  • Das Jungtier der painted turtle war eine von nur wenigen Arten, die selbst im gefrorenen Zustand überleben konnten
  • Innerhalb einer Stunde begann die Schildkröte mit kaum sichtbaren Bewegungen und hatte sich am Ende etwa über die Hälfte des Bildschirms bewegt
  • Warmblütige Tiere müssen ihre Körpertemperatur in einem engen Bereich halten; beim Menschen wird es problematisch, wenn man sich von etwa 37°C entfernt
  • Kaltblütige Tiere regulieren ihren Stoffwechsel passend zur Umgebungstemperatur, sind bei Wärme aktiv und bewegen sich immer langsamer, je kälter Körper und Umwelt werden
  • Softwareprojekte lassen sich ähnlich einteilen
    • Warmblütige Software funktioniert gut, wenn im Projekt kontinuierlich Bewegung und Wärme vorhanden sind
    • Lässt man sie 6 Monate ruhen, kann sie beim erneuten Hervorholen wie ein totes Projekt wirken

Bedingungen und Beispiele für kaltblütige Software

  • Dass warmblütige Projekte sich nur schwer wieder starten lassen, liegt daran, dass sich externe Veränderungen ansammeln
    • Dienste, von denen die CI abhängt, können übernommen worden sein oder aus Geldmangel nicht mehr funktionieren
    • Beim Hinzufügen neuer Abhängigkeiten kann ein Compiler-Upgrade nötig werden
    • Andere Pakete werden womöglich nicht mehr gepflegt und funktionieren mit dem neuesten Compiler nicht mehr
  • Projekte, an denen man allein arbeitet, nur bei Inspiration Änderungen vornimmt und dann länger als ein Jahr nicht mehr anfasst, lassen sich schwer als warmblütige Projekte betreiben
  • Ein kaltblütiges Projekt sollte wie das gefrorene Jungtier der painted turtle auch nach einem Jahr noch genau an der Stelle wieder starten können, an der es angehalten wurde
  • Dafür verwendet man boring technology und vermeidet Abhängigkeiten von externen Diensten, bei denen Build- und Testskripte sich ändern, kaputtgehen oder ganz verschwinden können
  • Abhängigkeiten werden wie bei vendored dependencies direkt im Projekt-Repository mitgeführt
  • Die Software, die diesen Blog betreibt, ist ein Beispiel für ein kaltblütiges Projekt
    • Der erste Commit stammt vom 8. Januar 2012; es war ein kleiner statischer Site-Generator, der eine alte Wordpress-Installation ersetzen sollte
    • Er wurde in Python 2 geschrieben, hängt von vier Drittanbieter-Modulen ab, die alle ins Projekt-Repository eingecheckt sind
    • Alle Schritte laufen lokal, und die Ergebnisse werden per rsync over ssh deployt
    • Abgesehen von einigen kleinen Verbesserungen läuft er seitdem ohne Änderungen weiter, und es wird erwartet, dass er auch in 12 Jahren noch funktioniert

1 Kommentare

 
GN⁺ 2023-12-29
Hacker-News-Meinungen
  • Das Web-Framework Express aus dem Node- und JavaScript-Ökosystem wird aktuell in der Hauptversion 4.x.x seit über 10 Jahren gepflegt https://www.npmjs.com/package/express?activeTab=versions
    Trotzdem wird es mit über 17 Millionen Downloads pro Woche sehr häufig genutzt https://www.npmjs.com/package/express, und auch wenn ihm Funktionen fehlen oder die Performance nicht die beste ist https://fastify.dev/benchmarks/, ist es gut, weil es schnelle und stabile Entwicklung sowie langfristige Planung ermöglicht
    Man muss sich keine Sorgen machen, dass Sicherheits-Patches für ältere Versionen eingestellt werden oder sich APIs drastisch ändern; Go ist dank seiner umfangreichen Standardbibliothek und des Kompatibilitätsversprechens noch stabiler, sodass auch über 10 Jahre alte Programme noch laufen können https://go.dev/doc/go1compat

    • Es hat mich angenehm überrascht, dass Express schon 13 Jahre alt ist
      Als es erstmals erschien, wurde es oft allein deshalb, weil es in JavaScript geschrieben war, als Schrott für minderwertige Pseudo-Programmierer abgetan; seitdem hat es aber in mehreren Unternehmen geholfen, großartige Services zu bauen, die mit Express echtes Geld verdienen, und heute verarbeitet es vermutlich enorme Mengen an Requests
      Heutzutage schreibe ich auch viel in Go, bin aber weiterhin vollkommen zufrieden damit, Services mit Express zu bauen, und halte es insgesamt für gute Software
    • Express v5 soll in naher Zukunft erscheinen (https://github.com/expressjs/express/issues/4920)
    • CakePHP bietet ebenfalls diese Art von Stabilität, und deshalb schrecke ich vor RoR zurück
      Nicht, dass ich es wirklich ablehne; ich würde es wohl eher wegen des endlosen Hamsterrads ständiger Versions-Upgrades nicht wählen
  • Python ist ein sehr schlechtes Beispiel für kaltblütige Software
    Sowohl bei der Runtime als auch bei den Tools gibt es ständig Breaking Changes, und der Autor ist offenbar in einer Situation, in der er weiterhin Python 2 verwenden muss, dessen Support schon vor langer Zeit eingestellt wurde
    Bessere Beispiele wären Sprachen wie Go oder Java, bei denen 10 Jahre alter Code auch mit modernen Tools gut läuft; noch extremer wäre Perl, wo sogar 30 Jahre alter Code noch gut funktioniert

    • Stimmt
      Beim Entwickeln von Software macht man Fehler, durch die Nutzer Dinge auf eine nicht beabsichtigte Weise tun können; in der Java-Welt löst man das, indem man neuere, sicherere und klarer intendierte Funktionen hinzufügt und Nutzer zur Migration ermutigt
      Python ist ähnlich, nur kommt dort noch ein „und bald schalten wir die alte Funktion ab“ dazu, während Java das nicht tut
      Zum Beispiel gilt die equals-Methode von java.net.URL als kaputtes Design und wird stark abgeraten, wird aber seit über 20 Jahren weiter unterstützt
      Der leere Operator in Python Airflow unterstützte eine Zeit lang den Namen DummyOperator, aber weil „dummy“ historisch und kulturell auch als abwertender Begriff verwendet wurde, änderten die Maintainer ihn so, dass EmptyOperator genutzt werden sollte, und brachen den alten Namen
      Nach einem Upgrade gab es beim Laden des Codes Fehler, bis man die Referenznamen änderte; persönlich würde ich Nutzer nicht auf diese Weise brechen
      In der Java-Welt hätte man eine bloße Namensänderung mit einer Textersetzung ausreichend bewältigen können, also hätte man sie wohl weiter unterstützt, bis es einen wirklich zwingenden Grund gegeben hätte, das nicht mehr zu tun
      Deshalb denke ich insgesamt, dass sich Java und Java-Library-Abhängigkeiten deutlich freier upgraden lassen als Python
    • Maven ist großartig
      Wenn man eine Java-LTS-Version nutzt und gute Abhängigkeiten auswählt, kann man es jederzeit wieder lauffähig machen
      In Python gab es in einem Machine-Learning-Kurs einmal den Fall, dass eine Abhängigkeit über Nacht eine API-Änderung einführte, die alles kaputt machte; der Dozent nutzte noch die neueste Version von vor einigen Wochen, als er mit der Vorbereitung des Kurses begonnen hatte, und hatte es deshalb nicht bemerkt
    • Ich bin mir nicht sicher, was mit „es gibt ständig Breaking Changes“ gemeint ist
      Der Wechsel von Python 2 zu 3 war ein Breaking Change, aber das war eine einmalige Änderung und keine „fortlaufenden Breaking Changes“
      Wenn man bei derselben Hauptversion bleibt, wird alter Code durch neue Minor-Versionen nicht kaputt gemacht; alter 2.x-Code läuft zum Beispiel gut auf 2.7, und alter 3.x-Code läuft auch auf 3.12 gut
      Minor-Versionsänderungen können neue Funktionen hinzufügen, aber alter 3.x-Code geht nicht kaputt, nur weil er das Schlüsselwort async oder Type Hints nicht verwendet
    • Zustimmung
      Das ist einer der Gründe, warum ich Python nach Möglichkeit meide
      Ich habe das Gefühl, dass Python-Code, den ich heute schreibe, in ein paar Jahren mit eher geringer Wahrscheinlichkeit noch funktioniert, und halte das für ein ziemlich großes Problem
    • Bei der Aussage „10 Jahre alter Java-Code läuft auch mit modernen Tools gut“ bin ich mir nicht sicher
      Selbst wenn ich versucht habe, 3 Jahre alten Java-Code mit einem neuen SDK auszuführen, war immer irgendwo etwas kaputt
  • Ich arbeite auf IBM-Mainframes (z/OS), und bei der Wahrung der Abwärtskompatibilität habe ich kaum jemanden gesehen, der IBM nahekommt
    Microsoft Windows sehe ich auf Platz 2, das Linux-Kernel-ABI vielleicht auf Platz 3, aber im gesamten Linux-Ökosystem ist das nur ein kleiner Teil
    Das meiste andere ist eher Churn, und in Open Source scheint es nur wenige Leute zu geben, die ihre Freizeit in Abwärtskompatibilität stecken wollen
    Ökonomisch wirkt das wie ein Gefangenendilemma: Alle schieben die Kosten für Kompatibilität auf andere ab, und am Ende erzeugen sie für alle mehr nutzlose Arbeit

    • In Open Source gibt es zwar eine starke Tendenz, dem Neuen und Glänzenden hinterherzulaufen, aber das gilt schwerlich für alle
      Schaut man sich zum Beispiel die Retro-Computing-Community an, ist es gar nicht so selten, dass Treiber geschrieben werden, damit neue Hardware auf alten Betriebssystemen läuft
    • Es hilft definitiv enorm, wenn man für Wartung bezahlt wird
      Wenn es keine Vergütung gibt, hängt es letztlich davon ab, wie sehr man die Plattform liebt, die man baut; ich habe mich wegen des bewährten Commitments zur ABI-Stabilität entschieden, den Linux-Kernel direkt über Systemaufrufe anzusprechen
      Bei meiner eigenen Programmiersprache hingegen möchte ich sie so „perfekt“ wie möglich machen und habe ständig das Bedürfnis, sie zu ändern
      Für den Fall, dass jemand auf die wahnsinnige Idee kommt, sie ernsthaft zu nutzen, habe ich in der README einen Hinweis platziert, dass sie noch in einer frühen Entwicklungsphase und instabil ist
      Ich vermute, die Leute, die Ruby oder Python entwickeln, empfinden ähnlich: Eine Sprache fühlt sich wie ein eigenes Kind an, man will, dass sie Erfolg hat, und hält es daher für nötig, Fehler wie damals, als print ein Keyword war, zu korrigieren
    • Es geht nicht nur um Abwärtskompatibilität; wenn man etwas kurz nicht pflegt, ist auch die Wahrscheinlichkeit hoch, dass es aus zufälligen Gründen kaputtgeht
      Oft gehen sogar genau die Teile kaputt, die für Abwärtskompatibilität gedacht sind
      Bei einem früheren Arbeitgeber bauten wir containerisierte Node-Apps, und CI erstellte Images aus dem Node-Quellcode; nach einer Weile begannen Deployments von Services, die niemand angerührt hatte, plötzlich zu scheitern
      Es stellte sich heraus, dass das Dockerfile auf einem Ubuntu-Image basierte, dessen Supportzeitraum abgelaufen war; die Update-Repositories waren in ein Archiv-Repository verschoben worden, sodass ohne Anpassung des Dockerfiles kein Image mehr gebaut werden konnte
      Das ist ein Beispiel dafür, dass unangetastete Software kaputtgeht, und deshalb bevorzuge ich Go und Single Binaries
      Wenn man sie als Release paketiert, muss man sie nicht erneut bauen, und in einem Distroless-Docker-Image gibt es außer meinem Binary keine Abhängigkeiten
      Ich nutze Go seit Langem, hatte aber nie das Problem, dass Software mit dem Alter kaputtgeht; viele Arten von Problemen, die ich mit Node oder PHP hatte, sind verschwunden
      Das zweitgrößte Problem bei Node sind die Indirektionsmuster der Frameworks, das größte ist das Paketmanagement
      Peer-Dependency-Probleme wie „Ich habe Version X installiert, aber Modul Y braucht Version Z“ tauchen ständig auf
  • Viele Engineers prüfen auf GitHub beim Suchen nach Libraries den Zeitpunkt des letzten Commits
    Sie neigen dazu, eine Library mit jüngeren Commits für besser unterstützt zu halten
    Aber ein archiviertes Projekt, das genau das tut, was man braucht, 0 Bugs hat und seit Jahren stabil ist, ist wie ein verstecktes Juwel im Secondhandladen
    Heutzutage verwerfen viele Engineers Libraries automatisch, wenn sie nicht „ständig“ aktualisiert werden, und scheinen das für etwas Gutes zu halten

    • Damit eine Library statisch bleiben kann, muss auch die Umgebung, in der sie genutzt wird, statisch sein
      Moderne Softwareentwicklungsumgebungen sind das oft nicht, und Web-Frontends sind ein typisches Beispiel für häufige Änderungen
      Bei einer vollständig eigenständigen Library können ausbleibende Updates in Ordnung sein, aber eine Library, die von einem Web-Frontend-Framework abhängt, verursacht Probleme, wenn sie nicht an Veränderungen im Ökosystem angepasst wird
    • Streng genommen stimmt es nicht immer, aber auf aktuelle Updates zu schauen, ist eine hervorragende Heuristik
      Die genauen Zahlen kenne ich nicht, aber in der überwältigenden Mehrheit der Fälle bedeutet fehlende aktuelle Aktivität meiner Ansicht nach nicht „fertig und bugfrei“, sondern „aufgegeben“
    • Ich habe einmal Diagramme gesehen, die zeigten, wie sich Programmiersprachen im Lauf der Zeit verändert haben und wie viel vom ursprünglichen Code noch übrig ist
      Manche Sprachen sahen kaum noch wie Version 1.0 aus, andere hatten den Großteil des geschriebenen Codes beibehalten und nur oben drauf ergänzt
      Am Ende scheint sich diese Haltung auch in Community und Ökosystem widerzuspiegeln
      Clojure war, soweit ich mich erinnere, weit oben auf der Liste, weil es kaum Breaking Changes macht; eine Library, die zuletzt vor fünf Jahren geändert wurde, läuft auch mit der aktuellen Sprachversion einwandfrei
      Dass es zur Lisp-Familie gehört und man den Sprachkern ohne Upstream-Änderungen erweitern kann, hilft vermutlich ebenfalls, auch wenn das natürlich seine eigenen Macken hat
      Trotzdem fand ich es gut, dass es mir den Gedanken ausgetrieben hat, „frisch“ sei gleichbedeutend mit „gut“
      Heute nutze ich häufiger Libraries, die sich seit einigen Jahren kaum verändert haben, als Libraries, die erst letztes Jahr neu entstanden sind, und habe damit keine großen Probleme
    • Es hängt von der Sprache ab
      Manche Sprachen erscheinen alle ein bis zwei Jahre und fügen neue, elegante Syntax oder abstrakte Datentypen in der Standardbibliothek hinzu, die häufig genutzte, aber unbeholfene Muster ersetzen
      Die Community dieser Sprache betrachtet die neue Syntax fast sofort als „idiomatisch“ und findet, dass Code, der noch auf die alten, schwerfälligen Arten geschrieben ist, überarbeitet werden sollte
      Der Grund, eine bestimmte Codebasis zu ändern, ist meist, dass die bisherige Vorgehensweise im Vergleich zur neuen Syntax weniger transparent ist und Wartung sowie Code-Reviews erschwert
      Die Logik lautet: Hätte es die neue Syntax von Anfang an gegeben, hätte niemand die alte Vorgehensweise für guten Code gehalten; also sollte man den Code aktualisieren, um die Lesbarkeit für neue Entwickler und die Einstiegshürde für Beiträge zu senken
      Wenn eine in einer solchen Sprache implementierte Library seit mehr als 3 Jahren nicht aktualisiert wurde, ist das oft ein schlechtes Zeichen
      Es kann bedeuten, dass die Entwickler nicht mehr ausreichend mit der Community verbunden sind, um sie in idiomatischem Code zu pflegen, der für andere Entwickler, die die aktuelle Form der Sprache gelernt haben, leicht lesbar ist, und dass sie womöglich auch kein Interesse an externen PRs haben
    • Wenn „0 Bugs“ bedeutet, dass es 0 GitHub-Issues gibt, sollte man vorsichtig sein
      Es könnte schlicht niemand etwas melden, weil das Projekt als aufgegeben gilt, und es könnten Sicherheitslücken vorhanden sein
  • Software, mit der man ohne Updates auskommen kann, ist nur Software, die von Anfang an richtig gebaut wurde
    Bei Software nur für sich selbst ist das vergleichsweise einfach: Die eigenen Vorlieben ändern sich wahrscheinlich auch nach 10 Jahren nicht stark, und weil n klein ist, kann man bei kleinen Problemen ignorieren, ob es eine O(n)-Funktion gibt, und stattdessen eine O(n^2)-Funktion verwenden
    Bei Software, die andere nutzen sollen, sind die Anforderungen jedoch anders, und bei ausreichend großem N entstehen Probleme, weil eine O(n)-Funktion wertvoll wird
    Ob man sie für sich selbst oder für andere schreibt: Es können unvorhergesehene Probleme auftreten
    Zum Beispiel kann die Software beim Verarbeiten von Dateien über 1 GB abstürzen, aber weil man normalerweise nur Dateien unter 100 KB verwendet, hat man sich nie darum gekümmert; wenn man es dann beheben will, muss man vielleicht die Hälfte neu schreiben
    Genau darin liegt der stärkste Einwand gegen die Vorstellung, unveränderliche Software sei grundsätzlich besser als Software, die sich häufig ändert
    Unveränderte Software kann von Anfang an perfekt gewesen sein, aber es kann auch tief im Inneren ein Schrecken lauern, und das lässt sich im Voraus schwer unterscheiden
    Das heißt auch nicht, dass schnell aktualisierte Software grundsätzlich besser ist als langsam aktualisierte; neben der Update-Geschwindigkeit gibt es viele weitere Faktoren

    • Ich glaube nicht, dass das bedeutet, Software dürfe sich niemals ändern
      Wenn sich Anforderungen ändern, muss sich natürlich auch die Software ändern
      Aber in 10 Jahren kann vieles passieren, das nichts mit geänderten Anforderungen zu tun hat
      Open-Source-Projekte werden aufgegeben oder ändern ihre Richtung, kommerzielle Software wird eingestellt, Firmen werden übernommen, Regeln im App Store oder Play Store ändern sich, APIs verschwinden oder ihre Preise ändern sich, sodass die Wirtschaftlichkeit eines Projekts zusammenbricht
      Auch Toolchains, Frameworks, Programmiersprachen, Paradigmen und Best Practices ändern sich
      Der Kern ist meiner Ansicht nach, zu verhindern, dass externe Veränderungen, die nichts mit den Anforderungen zu tun haben, mir Änderungen aufzwingen
      Das ist ein gutes Prinzip, aber wie immer gibt es Kompromisse
      Stabil zu sein ist etwas anderes als veraltet zu sein, und die Grenze verläuft oft bei der Sicherheit
      Was tut man, wenn eine wichtige neue Anforderung leicht zu erfüllen wäre, man dafür aber eine vendored Library um sieben Hauptversionen anheben müsste und dadurch jede Menge sachfremde Brüche entstünden?
      Was tut man, wenn es nicht mehr genug Leute gibt, die mit einem eingefrorenen Toolset vertraut sind, und niemand es lernen will?
      Abhängigkeiten sorgfältig und konservativ auszuwählen ist gut, aber selbst mit den so klein gehaltenen Änderungen an Abhängigkeiten nicht Schritt zu halten, geht meiner Meinung nach einen Schritt zu weit
  • Die Stimmung des Textes kann ich gut nachvollziehen
    Ich hasse es wirklich, dass selbst eine Mobile-App, die erst vor ein paar Jahren gebaut wurde, inzwischen Dutzende Stunden braucht, nur um sie zu patchen und ein Update einzureichen
    Interessant ist auch der letzte Teil, in dem der Autor seinen statischen Site-Generator kaltblütige Software nennt und sagt, er laufe unter Python 2
    Python 2 wird heutzutage immer schwieriger zu installieren, und am Ende wird auch dieses Projekt ein warmblütiges Projekt werden

    • Ich habe ein kleines Hobbyprojekt (iOS und macOS), an dem ich nicht regelmäßig entwickle, das ich aber als Nutzer häufig verwende, und ich halte es so, dass es auf dem neuesten OS kompiliert und läuft
      Jedes Mal, wenn ich Xcode aktualisiere, muss ich Kleinigkeiten reparieren, damit das Projekt sauber kompiliert und funktioniert; das ist extrem nervig und sollte eigentlich völlig inakzeptabel sein
      Die jüngsten git-Commit-Messages sind alle Varianten von „für das neueste Xcode lauffähig gemacht“
      Wenn solche Änderungen an untergeordneten SDKs oder am OS wegen Sicherheitsbedrohungen nötig wären, könnte ich es bis zu einem gewissen Grad verstehen, aber das ist fast nie der Fall
      Meistens sind es dumme Änderungen wie APIs zu deprecaten, Standardwarnungen hinzuzufügen oder nun dieses Framework statt jenes Frameworks verwenden zu sollen
      Plattformen und Frameworks müssen aufhören, absichtlich bewegliche Ziele zu sein, besonders wenn es sich inzwischen um sehr stabile und zuverlässige Betriebssysteme handelt
      Man sollte ein 10 Jahre altes Projekt aus dem Gefrierschrank holen können und es sollte genauso sauber kompilieren und laufen wie vor 10 Jahren
      Diese Betriebssystemanbieter sind Billionenunternehmen, also will ich keine Ausreden hören, dass Abwärtskompatibilität viel Engineering-Aufwand erfordert
  • Ich pflege weiterhin ein persönliches Nebenprojekt
    Es begann vor 12 bis 13 Jahren in reinem PHP, später schrieb ich es mit Laravel neu und um 2017 herum noch einmal mit Symfony
    Weil ich als Freelancer Vollzeit arbeitete und keine Energie hatte, gab es auch Phasen von 6 bis 18 Monaten, in denen ich nur zwei oder drei sehr kleine Commits machte; wenn ich Zeit hatte, fügte ich Funktionen hinzu, aktualisierte, experimentierte und lernte
    Es war sehr nützlich, um zu lernen, wie man ein Projekt langfristig pflegt
    Ich lernte Dinge wie Dependency-Updates, Unnötiges zu entfernen, Sicherheitsupdates zu prüfen und Gelegenheiten zur Vereinfachung zu finden (von Vagrant zu Docker, von Vue + Axios + Webpack usw. zu Htmx), und ich lernte auch, was man vermeiden sollte
    Persönlich meide ich inzwischen frisch entwickelte Abhängigkeiten, Microservices und komplexe Infrastruktur wie Kubernetes
    Zuletzt habe ich mehrere Funktionen gebaut, auf PHP 8.2 und Symfony 7 aktualisiert und auch ChatGPT-basierte Funktionen integriert, sodass ich wohl 1 bis 3 Jahre pausieren könnte, wenn ich wollte
    In den letzten 4 bis 5 Jahren hat dieses Projekt ungefähr so viel Umsatz gemacht wie ein durchschnittliches Jahreseinkommen als Freelancer, es ist also auch kein schlafendes, unbekanntes Nebenprojekt

    • PHP fühlt sich furchtbar an, wenn man zurückkehrt, aber ich sehe es als Beispiel dafür, wirklich Abwärtskompatibilität zu wahren, sogar zum eigenen Nachteil
      Als ich nach ein paar Jahren zurückkam, waren dieselben furchtbaren Bildbearbeitungsfunktionen noch da wie vor 8 Jahren, als ich gegangen war
    • Ich überlege, Symfony nativer zu lernen, und bin neugierig, warum du von etwas wie Laravel zu Symfony gewechselt bist
  • Neben dem, was im Artikel gesagt wird, ist auch ein inhärent sicheres Threat Model wichtig
    Eine vollständige Website zum Beispiel muss sich ständig mit Angreifern und Spam-Bots auseinandersetzen und ist daher im Kern eher warmblütig
    Statische Seiten wie TiddlyWiki hingegen muss man nicht einmal ins Web stellen, und der Browser ist eine enorm stabile Plattform, also ist das deutlich besser

  • Der Unterschied in der Präferenz für kaltblütige und warmblütige Projekte dürfte mit dem Buxton Index aus https://www.cs.utexas.edu/users/EWD/transcriptions/EWD11xx/EWD1175.html zusammenhängen

    • Beim Lesen des verlinkten Textes stellt sich heraus: Der Buxton Index bezeichnet den Zeitraum, in dem ein Akteur wie eine Person oder Organisation in Jahren plant.
      Ein kleiner Lebensmittelladen in der Nachbarschaft liegt bei etwa 0,5 Jahren, ein wahrer Christ bei unendlich, ein durchschnittlicher Politiker, der wiedergewählt werden will, bei etwa 4 Jahren, die meisten Industrien etwas darüber, und Manager, die Quartalsberichte schreiben müssen, deutlich darunter.
      Wichtig ist der Buxton Index, weil enge Zusammenarbeit zwischen Akteuren mit sehr unterschiedlichen Buxton Indizes zwangsläufig scheitert und in moralischen Vorwürfen endet.
      Die Seite mit dem kürzeren Horizont wird als oberflächlich und kurzsichtig kritisiert, die mit dem längeren als pflichtvergessen, verantwortungsscheu oder als Trittbrettfahrer.
      Am Ende hält man sich gegenseitig auch für dumm.
      Der Vorteil des Buxton Index liegt darin, dass er als einfaches Zahlenkonzept moralisch neutral ist und Unterschiede über moralische Debatten hebt.
      Das ist besonders wichtig, wenn man über Zusammenarbeit zwischen Wissenschaft und Industrie nachdenkt.
    • Klingt sehr ähnlich wie Zeitpräferenz: https://en.wikipedia.org/wiki/Time_preference
  • Dieser Name ist wirklich schlecht.
    Kaltblüter sind stark von ihrer Umgebung abhängig, während Warmblüter durch ihren Stoffwechsel die Abhängigkeit von der Außentemperatur verringern.
    So oder so ist das unnötig mehrdeutig.
    Man könnte einfach „Software ohne externe Abhängigkeiten“ sagen und sich den langen erklärenden Absatz sparen.

    • Das ist die einzige Antwort, die den Kern des Problems des Artikels wirklich trifft, aber natürlich hat sie hier niemand empfohlen.
      Ich mag schon Softwareentwicklungsartikel nicht, die mit unpassenden Metaphern aus der Natur zu oberflächlichen Schlussfolgerungen springen; noch weniger mag ich solche Artikel, wenn sie dabei das natürliche Phänomen, auf das sich die Metapher bezieht, völlig falsch verstehen.
      Dass einige Arten, darunter die Zierschildkröte, das Einfrieren überleben, liegt nicht an Kaltblütigkeit, sondern an speziellen Frostschutzproteinen.
      Andere Eidechsen oder Kaltblüter würden beim Auftauen ihre eigenen Gewebe zerreißen.
    • Es gibt auch jemanden, der die biologische Deutung großzügiger gelesen hat.
      https://lobste.rs/s/hitos3/cold_blooded_software#c_mxjzwh