Menschen zu coden ist schwieriger als Computer zu coden
(erikbern.com)- Entwicklerwerkzeuge sind schwieriger, weil sie nicht nur die Logik entwerfen müssen, die ein Computer ausführt, sondern auch das mentale Modell, das andere verstehen und nutzen sollen
- Schnelles Onboarding ist kein Zusatzfeature, sondern eher das Produkt selbst: Setup, API-Token und Reibung beim ersten Start müssen so weit reduziert werden, dass man es innerhalb weniger Minuten auf dem eigenen Laptop ausprobieren kann
- Nutzer lernen Muster eher, indem sie funktionierende Beispiele verändern, statt lange Erklärungen der Kernkonzepte zu lesen; je mehr Ausgangspunkte es gibt, die nah am eigenen Problem liegen, desto größer die Erfolgschance
- Fehlermeldungen, Anzahl der Konzepte, Benennung, Konfiguration, Defaults, Magic und Syntax Sugar verändern alle den Weg des Nutzers zum Erfolg; nötig ist daher ein lesbares und anpassbares Design
- Gute Developer Experience bedeutet nicht, Funktionen einfach zu reduzieren, sondern die Komplexität, die man kennen muss, stark zu senken, während der Umfang dessen, was man bauen kann, erhalten bleibt
Code für Menschen umfasst auch mentale Modelle
- Code für Computer bedeutet, große Geschäftsziele in logische Anweisungen zu zerlegen, denen ein Computer folgen kann
- Bei Code, den Menschen direkt handhaben — etwa Frameworks, Libraries, APIs, SDKs, DSLs, eingebettete DSLs und Programmiersprachen — reicht Ausführbarkeit allein nicht aus
- Solcher Code gibt dem Computer Anweisungen und muss zugleich berücksichtigen, wie Nutzer ihn lesen und verstehen
- Für das Design von Entwicklerwerkzeugen braucht es nicht nur Informatik, sondern auch psychologisches Verständnis dafür, wie Nutzer Schlussfolgerungen ziehen
Die Start-Erfahrung ist das Produkt
- Feedback zu Entwicklerwerkzeugen kommt meist von Power-Usern, die das Produkt häufig verwenden
- Nutzer, die schon am Anfang stecken bleiben, hinterlassen kein Feedback; dadurch entsteht ein Survivorship Bias
- So wie Consumer-Produkte ihren Onboarding-Funnel optimieren, sollten auch Entwicklerwerkzeuge den Weg bis zum ersten erfolgreichen Start als Kern des Produkts betrachten
- Für schnelles Onboarding lohnt es sich, die Produktstruktur selbst zu verändern
- Pflichtkonfiguration entfernen
- API-Token-Setup sehr einfach machen
- Reibung beim Start reduzieren
- Nutzer das Produkt innerhalb weniger Minuten auf dem eigenen Laptop ausprobieren lassen
- In einer Umgebung mit sehr vielen Entwicklerwerkzeugen haben Nutzer kaum die Energie oder Geduld, die Unterschiede eines bestimmten LRU-cache-NPM-Pakets im Detail zu verstehen
Beispiele lehren schneller als Kernkonzepte
- Menschen sind, anders als Computer, die strikte Befehle befolgen, gut in Pattern Matching
- Viele Dokumentationen zu Entwicklerwerkzeugen erklären zuerst das zentrale Datenmodell, Beziehungen, atomare Konzepte, Konfiguration und Ausführung; Menschen lernen jedoch besser, indem sie funktionierende Beispiele verändern und die Ergebnisse beobachten
- Mehrere Beispiele können nützlicher sein als eine 5.000 Wörter lange Erklärung der „core concepts“
- Nutzer lernen anhand von Beispielen, wie sich das Tool verhält
- Wer ein konkretes Problem lösen will, kann einen ausreichend nahen Ausgangspunkt finden
- Je mehr Ausgangspunkte es gibt, desto wahrscheinlicher ist ein Beispiel, das nahe an dem liegt, was man braucht
Nutzer in die Grube des Erfolgs schubsen
- Der Grundzustand des Programmierens besteht im Wesentlichen darin, immer wieder irgendeine Art von Fehler zu beheben
- Nutzer können den größten Teil ihrer Zeit mit einem Tool damit verbringen herauszufinden, „was nicht funktioniert“
- Wenn Entwickler schneller erfolgreich sind, mögen sie das Tool; wenn sie ständig an Fehlern hängen bleiben, geben sie dem Tool die Schuld
- Jeder Fehler ist eine Gelegenheit, Nutzer zurück auf den Happy Path zu bringen
- Code-Snippets in Exception-Meldungen aufnehmen
- Nützliche Warnungen ausgeben, wenn Nutzer wahrscheinlich etwas Ungewöhnliches tun
- Die nötigen Schritte bereitstellen, damit Nutzer erfolgreich werden
Konzeptuelle Überlastung reduzieren
- Jedes neue Konzept, das man verstehen muss, bevor man ein Tool nutzen kann, wird zu einem Reibungspunkt
- Zwei bis drei Konzepte sind akzeptabel, aber nicht viele Nutzer wollen acht neue Konzepte lernen
- Kubernetes benötigt beim Start nicht alle Konzepte, doch je mehr neue Konzepte hinzukommen, desto größer wird die Belastung
- Ein Framework, das mächtig ist und dennoch nur drei bis fünf Konzepte hat, besitzt Eleganz
- Wenn man React zum ersten Mal nutzt und nach ein bis zwei Stunden den konzeptuellen Hügel überwunden hat, kann es sich so anfühlen, als ließen sich mit wenigen einfachen Bausteinen große Strukturen bauen
- Ziel ist nicht, einfach die Zahl der Konzepte zu reduzieren, sondern die Konzepte zu reduzieren, die Nutzer kennen müssen, während der Umfang dessen, was sie bauen können, erhalten bleibt
- Hervorragende Tools können die Komplexität um 90 % reduzieren und die Fähigkeiten unverändert lassen
- Auch ein Tool, das die Komplexität um 90 % reduziert und die Fähigkeiten nur um 10 % senkt, ist nicht schlecht
Das konzeptuelle Entenprinzip
- Wenn es in einem Framework ein Element gibt, das einen Wert entgegennimmt und einen neuen Wert berechnet, ist es besser, es function zu nennen statt mit einem neuen Namen wie „compute node“, „valuator“ oder „frobniscator“
- Das Prinzip, dass etwas wahrscheinlich eine Ente ist, wenn es wie eine Ente läuft und wie eine Ente quakt, lässt sich auch auf Konzeptdesign anwenden
- Selbst wenn es feine Unterschiede gibt oder Werte gecacht werden, kann man es function nennen, wenn es einer function nahe genug kommt
- Bestehende Begriffe verbinden sich mit den mentalen Modellen, die Nutzer bereits haben, und reduzieren dadurch stark, wie viel erklärt werden muss
Programmierbar machen
- Nutzer tun mit Codebases unerwartete Dinge und können Framework-Elemente in for-loops, Funktionen oder andere Strukturen einbetten
- Deshalb sollte fast alles in einem Framework programmierbar sein
- Entsprechende Designrichtungen hängen miteinander zusammen
- Direkte Aufrufe aus Code ermöglichen, ohne den Umweg über die CLI
- Konfigurationsdateien reduzieren und durch SDKs oder APIs ersetzen
- Nicht nur eine einzige Instanz erlauben, sondern per Parametrisierung n Instanzen ermöglichen
- Solches Design kann Nutzer neue Anwendungsfälle entdecken lassen
- Wenn man den Wunsch nutzt, auf einem Framework „herumzuhacken“, kann das trotz etwas Chaos zu unerwarteten Entdeckungen führen
Magic, Defaults und Syntax Sugar mit Bedacht einsetzen
- Angenommen, es gibt eine Funktion
run_notebook, die ein Jupyter Notebook in der Cloud ausführt, und Nutzer müssen angeben, welches Container-Image verwendet werden soll - Es gibt mehrere mögliche Optionen
- Das Argument
image=...immer verpflichtend machen - Ein Default-Image mit den meisten Data-Science-Libraries bereitstellen und Nutzer es überschreiben lassen
- Den Code in den Zellen untersuchen und je nach benötigten Dependencies per „Magic“ ein Image auswählen
- Zusätzlich zur Magic-Methode Nutzer auch ein bestimmtes Image wählen lassen
- Das Argument
- Um die Eingabemenge zu reduzieren und die breitesten Anwendungsfälle zu unterstützen, kann die letzte Option gut aussehen
- Doch außer bei der ersten Option bleiben Probleme
- Magic bricht in manchen Situationen
- Nutzer, die Code lesen, der auf Defaults setzt, bemerken womöglich nicht, dass Anpassungen möglich sind
- Wenn Defaults nicht in über 97 % der Fälle passen und Magic nicht in über 99 % der Fälle richtig liegt, sollte man sehr vorsichtig sein
- Coding ist kein Golf, und die Aufgabe eines Tool-Anbieters besteht nicht nur darin, die Menge des von Nutzern geschriebenen Codes zu minimieren
- Perl war stark auf kurzen Code optimiert, aber Programme konnten wie eine Aneinanderreihung von Sonderzeichen aussehen; Python war selbst bei 50 % mehr Code lesbarer und leichter verständlich
- Menschen lesen Code zehnmal häufiger, als sie ihn schreiben, daher ist Lesbarkeit wichtig
- Syntax Sugar sollte nach demselben Maßstab bewertet werden
- Man kann versucht sein, für häufige Anwendungsfälle spezielle Syntax einzuführen
- Das kann jedoch Konsistenz verwässern und weniger klar machen, wie man Dinge anpasst
- Wenn Syntax Sugar nicht in über 99 % der Fälle passt, ist es womöglich besser, ihn nicht einzuführen
Designprinzipien für Erstnutzer
- Beim Schreiben von Code für Menschen bleiben noch viele Designprobleme
- Das meiste sollte immutable sein, aber nicht alles
- Scaffolding, also Codegenerierung, vermeiden
- Feedback-Loops sehr schnell machen
- Nutzern erleichtern, mit zur Entfernung vorgesehenen Funktionen umzugehen
- Automatisierte Tests für Code-Snippets in Dokumentation und Beispielen verwenden
- Die Gestaltung der Erfahrung für Erstnutzer ähnelt dem Schreiben eines Popsongs
- Selbst wenn ein Produzent einen Song tausendmal hört, muss er sich beim 999. Hören vorstellen, wie er für jemanden klingt, der ihn zum ersten Mal hört
- Auch bei Entwicklerwerkzeugen ist es sehr schwierig, dass jemand, der sie immer wieder gebaut hat, sich die Erfahrung eines Erstnutzers vorstellt
1 Kommentare
Hacker-News-Kommentare
Menschen lernen auf unterschiedliche Weise. Ich brauche zuerst die Kernkonzepte, bevor ich mit Beispielen einsteige. Umso mehr, wenn die Kernkonzepte nicht extrem einfach sind.
Viele Tutorials sind so, als würde man an die Hand genommen und Lego zusammenbauen. So nach dem Motto: „Hier sind die Lego-Steine, folge mir beim Bau eines kleinen Spielzeugprojekts, und am Ende des Tages kannst du Lego.“
Für mich funktioniert das nicht gut. Ich will wissen, wie und warum Entscheidungen getroffen werden, und die Perspektive des Autors verstehen. Ich möchte wissen, wie sich die einzelnen Lego-Steine anfühlen, wie sie zusammenpassen und wie man zu einem bestimmten Design kommt.
Ein Tutorial ohne wenigstens eine minimale Erklärung der Konzepte auf höherer Ebene zu verfolgen, fühlt sich an, als müsste ich etwas rückentwickeln, was eigentlich nicht nötig sein sollte. Wenn ich mir eine neue Library oder ein neues Framework ansehe, lese ich eher den Einführungsartikel und überspringe die „Getting Started“-Codebeispiele. Normalerweise gibt es in den „Advanced“-Abschnitten mehr konzeptionelle Diskussionen, also beginne ich dort, schaue mir dann die API-Referenz an, um die wichtigen Interfaces zu erfassen, und kehre erst am Ende zu den grundlegenden Codebeispielen am Anfang des Tutorials zurück
Heute springe ich viel öfter einfach hinein und arbeite direkt mit Beispielen, und ich habe das Gefühl, produktiver zu sein. Zum Teil ist das eine Frage des Vertrauens. Ich vertraue darauf, dass Leute, die hochwertige Software bauen, sich genug Gedanken gemacht haben, um Interfaces für typische Anwendungsfälle so verständlich zu gestalten, dass man nicht tief in die Interna einsteigen muss.
Natürlich stoße ich oft auf Hindernisse, bei denen ich tiefer graben muss. Aber das passiert gerade deshalb, weil es zehn andere Fälle gab, in denen ich allein mit einem oberflächlichen Eindruck erfolgreich weiterkam. Wenn ich dann tatsächlich tiefer einsteige, wirkt das deshalb meist auch nicht wie verschwendete Zeit
Solche Tools erzeugen eine bestimmte Ordnerstruktur, Template-Dateien und vorkonfigurierte Werkzeuge. Wenn ich nicht sofort auf einer höheren Ebene verstehe, was die generierten Dateien tun und warum sie so erstellt wurden, fühle ich mich unwohl, weil da zu viel unverstandene Magie ist.
Wenn etwas Neues dazukommt, brauche ich eine Einführung auf höherer Ebene, die seinen Zweck mit Konzepten verknüpft, die ich bereits kenne. Zumindest bis ich grob verstanden habe, was die Hauptschnittstellen dieser Blackbox sind, fühle ich mich im Umgang mit magischen Blackboxes nicht wohl. Wenn ich zum Beispiel create-react-app von Anfang an gelernt hätte, hätte ich wahrscheinlich sofort angefangen, den Zweck der von ihm konfigurierten Tools wie Babel oder ESLint zu untersuchen
Erst Jahre später, nachdem ich viele gute praktische Beispiele gesehen hatte, habe ich verstanden, worauf das Konzept hinauswill. Nach dieser Erkenntnis habe ich meine Lernweise verfeinert.
Zuerst überfliege ich die Kernkonzepte, dann probiere ich mehrere Beispiele aus, bis ich verstehe, warum das Konzept nötig ist, und anschließend lese ich die Kernkonzepte gründlich, um die Randfälle abzudecken, die in naiven Beispielen fehlen
Allerdings kann ein Start mit Beispielen auch zu gutem API-Design beitragen. Wenn man eine API nach dem Prinzip „Kernkonzepte zuerst“ entwirft, läuft es oft darauf hinaus, dass sie sich erst benutzen lässt, nachdem man die Kernkonzepte verstanden hat, und das ist für Nutzer, die sie nur gelegentlich verwenden, nicht ideal
Ganz im Hacker-Stil gab es keine Quellen. Ich kenne Pädagogik nur ein wenig, aber sie ist ein großes und ausgereiftes Fachgebiet, das moderne Prinzipien aus der Erfahrungspsychologie von Dewey und Piaget herleitet. Dazu gibt es weit mehr zu sagen, als in einen Blogpost, geschweige denn in einen einzelnen Abschnitt eines Blogposts passt.
Das größte Problem ist, wie du schon angemerkt hast, dass Menschen unterschiedlich sind. Das zweitgrößte Problem ist, dass wir nicht einmal sicher wissen, warum diese Unterschiede entstehen oder wie stabil sie über die Zeit bleiben. Der Text selbst ist gut geschrieben und untersucht die praktische Nutzbarkeit einer bestimmten Lehrstrategie gut, aber ich hätte mir etwas mehr Bescheidenheit gewünscht
Vor nicht einmal 2 Wochen gab es schon einen ähnlichen Beitrag: https://news.ycombinator.com/item?id=41566097
Schreiben für Menschen lässt sich am Ende auf zwei Fähigkeiten reduzieren: Empathie und Schreiben
Es gibt einen großen Unterschied zwischen ein bisschen Code zu schreiben und eine Anwendung oder ein Produkt zu schreiben. Dieser Beitrag sagt letztlich dasselbe, nur etwas weniger unverblümt. Empathie ist wichtig, weil sie den Unterschied zwischen Selbstbezogenheit und Außenorientierung ausmacht
Ein selbstbezogener Entwickler interessiert sich vor allem für Leichtigkeit, Bequemlichkeit, Code-Eitelkeit und andere subjektive Maßstäbe. Am Ende zählt er nur den eigenen Aufwand der Vermittlung. Ein außenorientierter Entwickler interessiert sich vor allem für Architektur und Dokumentation. Denn er sieht den Erfolg davon abhängig, wie andere sein Ergebnis aufnehmen
Einfachheit ist wichtiger als Leichtigkeit. Ein außenorientierter Entwickler kann keine Gedanken lesen und nicht wissen, was andere als leicht empfinden werden, aber er weiß, wie man die Zahl der Schritte reduziert und den Code klein hält
Aus Sicht des Gesamtprodukts ist das Schreiben einer Anwendung im Gehirn nichts anderes als das Schreiben eines Essays, eines Textes oder eines Buches. Entscheidend sind Organisation und Funktion. Der Code kommt später und ist wie die Wörter auf der Seite. Wer nur Codefragmente schreibt, entwickelt nicht die höherwertige Organisationsfähigkeit, die alles zu einem Ganzen verbindet
Deshalb hasse ich Frameworks so sehr. Frameworks nehmen Entwicklern die Übung, die sie brauchen, um originelle Software zu schreiben, und verhindern dadurch, dass sie organisatorische Fähigkeiten ausbilden. Die Betroffenen sehen es nicht, aber für diejenigen, die es sehen können, ist diese riesige Lücke völlig offensichtlich
Andere müssen nun aber ihre Abstraktionen lernen und entfernen sich dadurch entsprechend von den zugrunde liegenden Konzepten. Das kann es schwerer machen, die Kernfähigkeiten zu erwerben, die man braucht, um über das Framework hinauszugehen. So fühlte es sich für mich an, als ich Rails lernte; irgendwann merkte ich, dass es zu viel verbirgt, warf es weg und fing von vorn an
Dass das eine völlig andere Fähigkeit ist, war eine augenöffnende Erkenntnis. Sozusagen ist es jetzt ein bekanntes Unbekanntes
Wie sieht dieser Code für jemanden aus, dessen Chef ihm im Nacken sitzt, oder der um 2 Uhr nachts ein Produktionsproblem behebt? Man weiß erst, wie wertvoll diese Antwort ist, wenn man sie wirklich braucht. Und in dem Moment zahlt man viel Geld dafür. Falls man überhaupt jemanden findet, der so etwas kann. Solche Leute sind selten
Ich stimme der Aussage „Menschen lernen an Beispielen, nicht an Kernkonzepten“ nicht zu. Vielleicht ist das kleinlich, aber nicht alle Menschen funktionieren so
Menschen, die den Weg vom Allgemeinen zum Konkreten bevorzugen, werden im Schulunterricht meist schon ignoriert und finden oft erst in der Hochschulbildung etwas, das besser passt. Sie sind ohnehin schon genug an den Rand gedrängt; man muss ihre Existenz nicht auch noch abstreiten
Ich verstand nicht die Nuancen dessen, wann genau was zu tun war, was vollkommen gleichzeitig passieren musste und was direkt danach folgen sollte. Dann erklärte mir ihr Vater kurz, was die Kupplung tatsächlich macht und wie sich die Verbindung zwischen Rädern und Motor auf beide Seiten auswirkt
In diesem Moment verstand ich es sofort und brauchte keine Anweisungen mehr dazu, was in bestimmten Situationen zu tun war. Etwa 20 Minuten später konnte ich schon mit dem Handbremsstart an einer nach hinten abfallenden Steigung losfahren und den Wagen bewegen, was angeblich das Schwierigste am Schaltwagenfahren ist. Für manche Menschen ist es viel nützlicher, die Funktionsweise aus ersten Prinzipien zu verstehen, und unter Softwareingenieuren gibt es ziemlich viele von genau solchen Menschen
Wenn mich an einem Beispiel etwas überrascht, heißt das, dass mein Modell noch nicht vollständig ist. Oder dass das Beispiel falsch ist
Statt „Das wollen wir erreichen, so funktioniert das, und so machen wir es“ bekommen die Praktiker am Ende immer nur „So machen wir es“ zu sehen. Schon bei kleinsten Abweichungen kann man dann nicht mehr schlussfolgern, anpassen und Probleme lösen
Für häufige Aufgaben gibt es zwar ein gewisses Maß an Dokumentation, aber sie ist meist veraltet oder unvollständig. Es ist kein Wiki, also kann nicht jeder jederzeit etwas korrigieren, und um Dokumentation zu ändern, muss man ein nerviges Verfahren durchlaufen, sodass sie am Ende nicht aktualisiert wird. Wenn ich darüber nachdenke, ist das ziemlich ähnlich zu meiner Zeit beim Militär
Gerade jetzt erlebe ich das wieder, während ich mir Zeit nehme, Drizzle ORM zu lernen. Die ersten Materialien, die ich fand, bestanden nur aus „sechs Query-Beispielen“, und es frustrierte mich, dass nicht erklärt wurde, warum man diese Syntax verwendet und welche Alternativen es gibt. Ich schließe solche Sachen lieber, lese jede Seite der Dokumentation und mache dann etwas damit; diese Vorgehensweise ist für mich viel angenehmer
Ich weiß nicht, ob ich das heute noch in Echtzeit könnte. Diese Methode verbraucht ziemlich viele Denkschleifen, deshalb liegt mir inzwischen eher das Lesen eines Textes oder das Anhalten eines Videos, um das Ganze zu verarbeiten
Trotzdem bin ich oft in die Lage gekommen, anderen spontan etwas beizubringen, die es noch nicht verstanden hatten. Wenn man eine Theorie über ein System hat, kann man auch Fragen beantworten, an denen Mitschüler scheitern würden, die kaum über bloßes Auswendiglernen hinausgekommen sind
Ein Satz aus Code Complete: „Ein kleiner Teil der Programmierarbeit besteht darin, Programme so zu schreiben, dass Computer sie lesen können; der größere Teil besteht darin, sie so zu schreiben, dass andere Menschen sie lesen können.“ Seite 733
Ist mir seit fast 20 Jahren im Gedächtnis geblieben.
Das steht im Vorwort der ersten Auflage von Abelson und Sussmans Structure and Interpretation of Computer Programs und ist 10 Jahre älter als Code Complete.
Es ist ein Leitspruch, an den ich mich zu halten versuche, aber Arbeitgeber scheinen seltsamerweise immer auf dem Teil zu bestehen, den der Computer ausführt.
Das ist zwar ein kleiner Nebenast, aber als ich vor ein paar Tagen ein Unity-Spiel entwickelt habe, kam mir der Gedanke, dass sich IDEs in den letzten 10 bis 20 Jahren eigentlich kaum wirklich weiterentwickelt haben.
Das grundlegende IntelliSense ist definitiv viel besser geworden, aber abgesehen von ein paar kleineren Punkten wirkt das gesamte Konzept des Codierens fast noch genauso wie früher.
Die größte positive Veränderung liegt außerhalb des Editors. Auf Bibliotheken und Dokumentation lässt sich viel leichter zugreifen, es gibt enorm viele Fragen und Antworten von Nutzern, und neuerdings gibt es auch Werkzeuge wie ChatGPT, die diese Antworten gelegentlich zu einer brauchbar klingenden Antwort zusammenfassen.
Aber insgesamt scheint das eigentliche Schreiben von Code zu stagnieren. Deshalb pausiere ich die Arbeit am Spiel gerade kurz und mache ein paar Experimente. Ich will keine neue Sprache erschaffen, sondern möglichst alle lästigen Aufgaben an den Computer abgeben, um mich auf das Kreative konzentrieren zu können.
Die ersten drei Dinge, die ich testen möchte, sind diese: Warum muss ich mich selbst um kleine Sprachdetails wie Klammern oder Terminatoren kümmern, statt dass das Tool sie automatisch ergänzt? Könnte das Tool bei Modifikatoren wie einer private-public-Zugriffskette oder
unsafenicht auch automatisch die effizienteste Kombination bestimmen? Wenn ich mich auf etwa fünf miteinander interagierende Methoden konzentriere, möchte ich sie alle auf einem Bildschirm sehen können, ohne mehrere Fenster zu öffnen und mit den horizontalen/vertikalen Schiebereglern von VS zu kämpfen. Wenn ich ein HashSet erstellt habe und es später in ein Dictionary oder Tuple umgewandelt werden sollte, dann soll das Tool es einfach ändern und mir nur die Stellen zeigen, an denen eine Entscheidung nötig ist, damit ich sie bestätige oder selbst anpasse. In Unity wäre es außerdem schön, auf eine Methode oder einen Datensatz klicken und anweisen zu können, ihn in einen Burst Job samt zugehörigem NativeData-Satz umzuwandeln.Aber am Ende sind das alles nur Abstraktionen, und wir schreiben bloß Anweisungen, damit eine sehr dumme Maschine Daten verarbeitet.
Du sagst, Tools könnten Klammern oder Terminatoren doch einfach automatisch ergänzen, aber Computer sind wirklich simpel, und Programmiersprachen sind ein Kanal, um Gedanken aus dem Kopf zu übermitteln. Solche Trennzeichen sind genauso wichtig wie Sprach-Keywords. Sie sind Teil der Regeln. Um sie automatisch zu ergänzen, braucht man noch mehr Regeln und noch mehr Trennzeichen.
Wenn du mehrere miteinander interagierende Methoden auf einem Bildschirm sehen willst, gibt es Vim und Emacs oder Smalltalk-IDEs wie Pharo.
Datenumwandlungen lassen sich mit Vim- und Emacs-Makros erledigen. Aber die Wahrheit ist, dass Datenkodierung sehr wichtig ist. Für den Computer sind es alles nur Bits, und wir sind es, die diesen Bits Bedeutung geben und Regeln aufstellen, wie sie entsprechend dieser Bedeutung manipuliert werden. Um von einem Regelsatz in einen anderen überzugehen, braucht man noch mehr Regeln.
Ich würde empfehlen, Live-Programming-Umgebungen auszuprobieren. Dinge wie SLIME für Common Lisp, Pharo für Smalltalk oder die Web-Inspektoren von JavaScript. Das ist, als würde man nicht an Land ein Schiff bauen und sich vorstellen, wie Segeln wohl sein mag, sondern mitten auf dem Meer auf einem Schiff arbeiten.
Der schwierigste Teil beim Programmieren ist Denken und Lernen. Schneller tippen hilft da nicht besonders viel.
Wenn man zum Beispiel ein C-Programm schrieb, konnte man einstellen, dass „f“ zu
for (=; <=; ++) {;}oder zu einer bevorzugten Einrückungsform erweitert wird.Auch unter modernen Programmiereditoren gibt es viele, die ähnliche benutzerdefinierte Einstellungen unterstützen, aber leider ist der Ablauf dabei oft komplizierter als vor sehr langer Zeit.
Wenn eine Programmiersprache eine ausschweifende Syntax hat, halte ich es für nötig, sich die Zeit zu nehmen, Vorlagen zu definieren, mit denen sich in einem Editor jede beliebige Programmstruktur mit minimalen Tastenanschlägen schnell schreiben lässt.
Bei der Frage, ob man ein HashSet, Dictionary oder Tuple verwenden sollte, gibt es Performance-Auswirkungen, und abstrakt betrachtet ist nicht immer klar, welches davon richtig ist. In expliziten Sprachen wie Java, und vermutlich auch in C#, sollte man Methodenaufrufe so refaktorieren können, dass sie andere Typen akzeptieren. Dann ändert man eine Methode und refaktoriert alle ihre Aufrufe entsprechend.
Ich habe mit Gemini pro und ChatGPT o1 experimentiert, und beide sind wirklich schlecht beim Coden in Python und JavaScript. Sie schreiben fehlerhaften Code und bauen beim Beheben eines Fehlers oft einen anderen ein. Bei beiden hat man das Gefühl, dass sie lieber schnell eine Antwort liefern, als die Anforderungen wirklich zu durchdenken. Bis wir Werkzeuge haben, die auf die gewünschte Weise „Gedanken lesen“ oder verstehen, was wichtig und unwichtig ist, dürfte es also noch etwas dauern.
Noch problematischer könnten die Trainingsdaten sein. Der meiste Code stammt von unterdurchschnittlichen oder durchschnittlichen Entwicklern, also übernehmen solche Tools tendenziell die Denkmuster durchschnittlicher Entwickler. Selbst wenn man sie nur mit Code höchster Qualität trainieren würde, ist nicht klar, ob die meisten Entwickler überhaupt in der Lage wären, gute Prompts zu formulieren. Wenn man also seit 10 bis 20 Jahren programmiert, wird man von einem Tool, von dem man spontane Magie erwartet, wahrscheinlich immer ein wenig enttäuscht sein.
Trotzdem sind nicht-AI-statische Analysewerkzeuge schon seit Langem hervorragend und werden noch besser werden. Mit zusätzlicher AI könnten sie sich noch weiter verbessern. Wenn man ein Tool nicht als Künstler betrachtet, dem man eine Spezifikation zuwirft und von dem man ein ordentliches Ergebnis zurückbekommt, sondern als etwas, das mir dabei hilft, selbst der Künstler zu sein, kann das eine großartige Erfahrung sein.
Es könnte auch Spaß machen, der AI von Arbeiten zu erzählen, die der Editor stärker übernehmen sollte, und sie um Hilfe bei der Konfiguration zu bitten. Es gibt viele nicht-AI-Tools als Plugins. Ein Large Language Model zu verwenden, um die Plugins auszuwählen, die zum eigenen Arbeitsstil passen, könnte am effizientesten sein.
https://haystackeditor.com/
Ich habe es selbst noch nicht benutzt, plane aber, es auszuprobieren.
Der Titel des Beitrags ist diskutabel. Code wird ausschließlich für Menschen geschrieben. Computer brauchen keinen „Code“, und insbesondere High-Level-Code schon gar nicht. Für Computer reichen Maschinenbefehle völlig aus.
Wir schreiben Code, weil Maschinenbefehle für Menschen zu schwer zu schreiben und noch schwerer zu lesen sind.
Man sollte Code nicht als eine Art betrachten, mit dem Computer zu interagieren. Code ist eine Weise, menschliche Gedanken zu formalisieren, so dass sie so wenig mehrdeutig werden, dass sogar eine Maschine ihnen folgen kann.
Eigennützige Werbung für einen Blogbeitrag, den ich letzte Woche geschrieben und geteilt habe
Move Fast & Document Things [1]
Ich wollte keinen philosophischen Text schreiben, sondern praktische Tipps dazu teilen, wie unser kleines Team [2] für sich selbst und füreinander eine Kultur des Code-Schreibens etabliert – nicht durch Automatisierung oder AI, sondern durch gründliche und anspruchsvolle Reviews
Persönliche Freunde, die in anderen Organisationen Engineering-Leads sind, sagten alle: „Wir machen genau das Gleiche, aber du hast es tatsächlich aufgeschrieben.“ Wenn es für euch wertvoll war, freue ich mich über eine Empfehlung
[1] https://olshansky.substack.com/p/move-fast-and-document-thin...
[2] https://github.com/pokt-network/poktroll/graphs/contributors
„Zu viele Programmierbücher und Tutorials sind nach dem Motto: ‚Lass uns von Grund auf ein Haus Ziegel für Ziegel bauen‘, aber ich will eher: ‚Hier ist ein funktionierendes Haus, ändere etwas und schau, was passiert.‘“
So habe ich mir das Programmieren selbst beigebracht. Ich habe Jahre damit verbracht, kleine, einfache und eher mittelmäßige Programme gut zu schreiben
Später merkte ich, dass ich für bessere Jobs in der Softwareentwicklung nicht geeignet war. Ich hatte nämlich überhaupt keine Grundlagenkenntnisse in Softwaredesign, Programmiersprachen oder Computern. Weil ich nicht auf die langweilige Art gelernt hatte, war es eine demütigende Erfahrung, nach Vorstellungsgesprächen zu erkennen, wie viel ich nicht wusste
Man sollte immer die gesamte Dokumentation lesen und immer die Grundlagen lernen
Ich schreibe meinen gesamten Code für Menschen
Egal ob dieser Mensch ich selbst im höheren Alter ist oder irgendeine arme Person, die in ein paar Jahren meine Absichten verstehen muss
Das Schreiben von Code selbst halte ich nicht für schwer. Talent zeigt sich darin, Probleme ganzheitlich zu durchdenken, mit anderen Stakeholdern zusammenzuarbeiten, den besten Weg zu finden und sie dabei mitzunehmen, fachliche Spezialkenntnisse wie neue Mathematik oder Branchenkonventionen zu lernen, effiziente Algorithmen zu entwerfen und die Struktur und Muster eines Programms so zu vermitteln, dass sie klare und elegante Grenzen haben
Am Ende hängt vieles von Kommunikation und Klarheit ab
Ein großer Teil dieses Textes handelt von Dokumentation, und ein Verweis auf das 4doc-Modell wäre sehr hilfreich gewesen: https://docs.divio.com/documentation-system/
Im Grunde bedeutet es, dass man nicht nur Referenzdokumentation bereitstellen sollte, sondern auch Dokumentation zur Nutzung. Und dass man diese nach vorn stellen sollte, weil Nutzer diesen Teil der Gesamtdokumentation in der Regel zuerst sehen wollen
Natürlich gilt das nur im Allgemeinen; ich gehe meist direkt zur Referenz, aber nicht immer
Das heißt nicht, dass 4doc eine Universallösung oder ein Naturgesetz ist. Auch Hillel Wayne behandelt die Schwächen davon hier gut: https://www.hillelwayne.com/post/problems-with-the-4doc-mode...