Kompatibilität vs. Feature in neuen Sprachversionen

Ist bei einer neuen Sprachversion die Kompatibilität (zu vorher) wichtiger als neue Feature ?


  • Umfrageteilnehmer
    14

Micke

Lt. Junior Grade
Registriert
Nov. 2020
Beiträge
480
Verfolgt man die Pläne der Teams welche Sprachen weiterentwickeln, nennen diese als eine Bremse von neuer Funktionalität oftmals die Wahrung der Kompatibilität zu vorherigen Versionen. siehe auch "breaking changes".
Das heißt die Annahme ist, daß Konsumenten die Kompatibilität gegenüber Neuerungen vorziehen. Mich überrascht es jedesmal das zu hören, deswegen dieser Realitätscheck.

Das Kritische an einem "breaking change" ist m.M.n. nicht der Umstiegsaufwand auf die neue Version, weil man auch mit der bisherigen weiterarbeiten kann. Sondern der Umstand, dass die Sprache offensichtlich in einer problematischen Sackgasse gelandet ist, aus der sie sich nicht anderes befreien kann. Und in Folge auch der eigene Code.

Danke schonmal für die Teilnahme.
 
Breaking changes verursachen Arbeit und damit Kosten. Allg. Planungsunsicherheit bei Updates.

Demgegenüber steht dass ich Zugriff auf irgendwelche Features bekomme die ich erstmal gar nicht zwingend brauche (mein Programm funktioniert ja schon!) und kurzfristig will ich auch gar nicht alle meine Projekte umschreiben um neues Feature XY zu verwenden (-> Regressions). Ich will auch nicht ohne Grund auf eine höhere Mindestversion springen weil mich das im Deployment einschränkt bzw. ich dann ggf. auch meine Systeme häufiger Updaten muss (-> steigert Ausfallrisiko, kostet noch mehr Zeit).

Bei einer populären Sprache oder Bibliothek sind tausende von Projekten von einem BC break betroffen. Rechtfertigt die Änderung diese Kosten bzw. kann Feature XY diese verlorene Zeit in den nächsten Jahren auch wieder einsparen? Mit Folgekosten (Ausfälle, Regressions) reden wir vielleicht von zehntausenden Stunden Arbeitszeit. Und jeder BC break birgt die Gefahr dass die Entwickler nicht bereit sind die Kosten zu tragen oder einfach nicht die Zeit haben und für Ewigkeiten auf einer alten Version mit Sicherheitslücken bleiben.
Es ist also fast immer vorzuziehen eine potentielle Neuerung solange abzumildern bzw. zu bearbeiten bis diese mit bestehendem Code kompatibel ist. Auch wenn die Endlösung dann ein bisschen weniger elegant ist oder den Entwicklern der Sprache zusätzliche Arbeit verursacht.

Bei einer Neuentwicklung oder wenn größere Umbauten anstehen nehme ich neue Features gerne mit bzw. wechsle auf modernere Schnittstellen. Aber das passiert eben nach Bedarf, nicht nach Schedule der Sprache.
 
  • Gefällt mir
Reaktionen: BeBur, TomH22 und Maviapril2
Micke schrieb:
Apropos Funktionalität und Features. Aus meiner Sicht sollte es bei einer Sprache auch gar nicht darum gehen, das man viele Features hat. Weil das führt nur zu Verwirrungen. Besser man hat weniger die sinnvoll einander ergänzen und auch einfach zu benutzen sind. Bei einer gut designten Sprache gibts auch viel weniger die Notwendigkeit für "breaking changes".

Allerdings ist in der Praxis oftmals ist ja auch gar nicht unbedingt die Sprache selbst ein Problem, sondern Bibliotheken.
 
  • Gefällt mir
Reaktionen: jb_alvarado und TomH22
Ich kann @Marco01_809 nur zu 100% zustimmen.

Ausserdem ist der Startbeitrag ohne konkretes Beispiel auch nicht besonders nützlich.

Micke schrieb:
Sondern der Umstand, dass die Sprache offensichtlich in einer problematischen Sackgasse gelandet ist, aus der sie sich nicht anderes befreien kann.
Hast Du ein Beispiel wo eine Sprache in einer "problematischen Sackgasse" ist, die nur durch ein Redesign zu lösen ist?

Was ist in Deiner Definition überhaupt ein Breaking Change?
Streng genommen kann schon die Einführung eines neuen Keywords (z.B. "async" und "await") ein breaking change sein, weil es in existierendem Code Bezeichner mit genau diesem Namen geben kann. Andererseits werden diese Konflikte selten sein und lassen sich relativ leicht beseitigen. Ändert man aber z.B. die Semantik von Datentypen (so geschehen z.B. in Lua wo der Typ "Number" seit Lua 5.3 zwischen Integer und Double "Subtypen" unterscheidet) kann das erhebliche Seiteneffekte haben, die auch nicht immer offensichtlich in existierendem Code zu finden sind.

Für mich ist das abschreckende Beispiel von Breaking Changes immer noch der Wechsel von Python 2.x auf Python 3.x. Python ist eine Sprache deren Wert vor allem im großen Ecosystem an Libraries liegt, und der Übergang von Python 2.x nach 3.x hat in fast jedem Python Projekt über viele Jahre für erheblichen Mehraufwand geführt, und der Übergang ist noch immer nicht abgeschlossen. Mittlerweile ist zwar jedes relevante Python Paket kompatibel mit Python 3, aber viele Projekte fangen nun an, alte Python 2 Abhängigkeiten/Workarounds auszubauen.

Bei Python hat es sich vermutlich am Ende trotzdem gelohnt, Python 3 ist in vieler Hinsicht besser und zukunftstauglicher als Python 2.

Natürlich entwickeln sich Sprachen weiter (die meisten heutigen C-Programmierer werden ein "K&R Style" C Programm kaum noch lesen können), es gibt aber viele Wege das "verträglich" zu lösen.
Eine Möglichkeit ist z.B. neue Versionen der Sprache auf Modulebene zu aktivieren.

Z.B:

HTML:
<script type="module">
        import {mq_start} from './mqclient.js';
        await mq_start();

 </script>

Lade ich hiermit ein ES6 Modul. Da sich ES6 Module und "klassiches" Javascript einen globalen Namensraum teilen kann ich trotzdem in Kontrollfluss zwischen den Welten umherspringen.

In C/C++ ist das ABI (Application Binary Interface) zwischen verschiedenen Versionen der Sprache kompatibel, d.h. Calling Conventions, Registerbelegung, etc. bleiben gleich. Daher kann man über Compilerdirektiven (z.B. -std=c99 beim GCC) den verwendeten Sprachstandard bestimmen und trotzdem die Module später noch miteinander linken.

Über solche Mechanismen können sie Sprachen weiterentwickeln ohne dass man existierende Codebasen zwingend überarbeiten muss.

Nur erfordert dass viel Planung und z.B. bei Sprachen wie C/C++ auch Abstimmung in Standard Gremien. Man kann also nicht einfach mal so "Ad-hoc" ein neues Feature einführen.
 
  • Gefällt mir
Reaktionen: Maviapril2
Micke schrieb:
Das Kritische an einem "breaking change" ist m.M.n. nicht der Umstiegsaufwand auf die neue Version, weil man auch mit der bisherigen weiterarbeiten kann.
Man kann nicht immer damit weiterarbeiten. Außer man bleibt im abgeschotteten, stillem Kämmerlein, bei dem einem die Sicherheit der zwingend zur Sprache gehörenden Frameworks egal ist.

Viele mögen PHP nicht als Programmiersprache bezeichnen, aber mir graut jedesmal, wenn mein Webservice-Provider wieder eine Nachricht verschickt, dass er es aufgibt, die alte Version zu unterstützen. Das hat (zum Glück nur für mein Hobbyprojekt) jedesmal zu hohem, aus meiner Sicht völlig unnötigem Test- und Entwicklungsaufwand geführt.

Wie TomH22 richtig schreibt, besteht eine Programmiersprache nicht nur aus der Sprachdefinition, sondern mind. auch aus dem zugehörigen Framework. Man müsste glatt mal ermitteln, wie oft die (g)libc durch inkompatibele Nachfolger ersetzt wurde.

Nachdem ich mir das "Spiel" mit .NET einige Zeit angesehen habe, bin ich heilfroh, immer noch beim Framework 4.8 geblieben zu sein. Warum soll ich alle 2-3 Jahre meine komplette Software umschreiben (und dabei natürlich auch neu testen), weil es für die alte Runtime keine weitern Security-Updates gibt, ich die neuen Features aber nicht benötige. Die SW hat sich, bis auf ein paar Bugfixes, die letzten 9 Jahre nicht geändert und so lange MS oder Wine das alte Framework noch unterstützten, wird das vermutlich auch so bleiben.
 
  • Gefällt mir
Reaktionen: Maviapril2
Es geht auch nicht nur um den eigenen Code. Bei breaking changes müssen ggf. auch die Abhängigkeiten (irgendwann) umstellen. Wenn die das nicht alle machen, dann hat man ggf. nochmal mehr Extraaufwand oder auch ein großes Problem.

TomH22 schrieb:
In C/C++ ist das ABI (Application Binary Interface) zwischen verschiedenen Versionen der Sprache kompatibel, d.h. Calling Conventions, Registerbelegung, etc. bleiben gleich. Daher kann man über Compilerdirektiven (z.B. -std=c99 beim GCC) den verwendeten Sprachstandard bestimmen und trotzdem die Module später noch miteinander linken.
Ist das so? Soweit ich weiß ist die ABI bei C++ nicht stabil (jdfs. im Vergleich zu C).

Micke schrieb:
Das Kritische an einem "breaking change" ist m.M.n. nicht der Umstiegsaufwand auf die neue Version, weil man auch mit der bisherigen weiterarbeiten kann. Sondern der Umstand, dass die Sprache offensichtlich in einer problematischen Sackgasse gelandet ist, aus der sie sich nicht anderes befreien kann. Und in Folge auch der eigene Code.
Es hat leider noch niemand eine perfekte Sprache erfunden, von daher wird das auch so bleiben.
 
  • Gefällt mir
Reaktionen: Maviapril2
ok, zusammenfassend Kompatibilität vor Fortschritt. Ist eine Antwort, danke.

d.h. lieber 5 / 2 = 2 als 2.5 (Python)
TomH22 schrieb:
Eine Möglichkeit ist z.B. neue Versionen der Sprache auf Modulebene zu aktivieren. ....... [oder] das ABI
Eben und andere Sprachen bieten vergleichbares. Sind damit eigentlich Optionen die die Abneigung senken sollten.
TomH22 schrieb:
Streng genommen kann schon die Einführung eines neuen Keywords ein breaking change sein,
Das wird vermutlich der verbreitetste Fall sein. Ist aber gleichzeitig trivial zu bewältigen.

ok, unerwartet aber interessant.
 
Zuletzt bearbeitet:
Mit so einer passiv-aggressiven Art wirst du jedenfalls nichts dazu lernen.
 
  • Gefällt mir
Reaktionen: Maviapril2 und TomH22
Ein Hauptproblem bei Breaking Changes ist halt der Zeitinvest. Wenn ich jedes Jahr oder alle paar Jahre je nach Umfang der Programme Tage bis Monate bis Jahre investieren muss, um sie am Laufen zu halten, dann ist es eher unschön, weil man dann für die eigentliche Weiterentwicklung (also neue Features einbauen, absichern etc.) keine Zeit mehr hat.

Klar kann einem eine neue Version das vereinfachen, bzw. unsichere Codekonstrukte direkt verhindern.

Meiner Meinung nach ist es am besten, wenn neue Features parallel zu alten Features verwendet werden können. Dann muss man den Code nicht umstellen, man kann es aber. Und man kann externe Abhängigkeiten auch erstmal weiter nutzen

Und wenn man den Code eh aus anderen Gründen anfassen muss, dann kann man es auch umstellen, wenn es einfach möglich ist. Aber nach dem eigenen Zeitplan, nicht einem von außen vorgegebenen ;)
 
  • Gefällt mir
Reaktionen: TomH22
Zurück
Oben