Dave Thomas und Andy Hunt sind die Autoren von "The Pragmatic Programmer" und des ersten englischsprachigen Rubybuches "Programming Ruby".
(Beide) Nach Wichtigkeit geordnet:
In einer wirklichen produktiven Umgebung sind diese drei gut ausgewogen: alle steuern einen Beitrag zum Erfolg eines Projektes bei. Letztlich sind alle drei auf verschiedene Formen von Kommunikation zurückzuführen. Das ist es was programmieren so interessant macht.
Programmiersprachen sind in keinem Gebiet ein Wundermittel. Keine momentane Programmiersprache erlaubt es, zu erkennen, was zum Beispiel im Kopf eines Users vorgeht.
Wenn man zu Beginn nach Anforderungen sucht, glaubt man, den User verstanden zu haben, aber wie will man das wissen? Dicke Dokumentationen und hektarweise UML-Diagramme helfen nicht, denn der User wird oder kann sie nicht lesen. Die beste Kontrolle ist die Präsentation eines Prototyps oder der Einsatz kurzer Iterationen, die frühzeitig Geschäftwerte enthalten. Die User sollen mit dem richtigen System arbeiten können. Damit wird nicht nur unser Verständnis überprüft, normalerweise verschwinden auch Unklarheiten beim User.
Um das zu erreichen, braucht man Umgebungen und Sprachen, mit denen Applikationen schnell erzeugt werden können: Es macht keinen Sinn, einen Prototypen zu erzeugen, wenn es genau so lange dauert, wie das richtige System. Man benötigt auch Sprachen und Umgebungen, die einem die größtmögliche Freiheit geben, nachdem der Code geschrieben ist: Der User sagt, "Was, wenn ..." und wir machen einfach die Änderung. Sprachen wie C++ und Java sind hier schwach, sie sind zu zeremoniell auch bei einfachen Dingen. Dynamische Sprachen bieten die notwendige Flexibilität.
Wenn man Code schreibt, konzentriert man sich auf etwas anderes. Natürlich will man dem Kunden jeden Tag etwas brauchbares liefern, aber die low-level Funktionalität des Codes wird immer wichtiger. Als Programmierer suchen wir nach Sprachen, die uns saubere und transparente Ausdrucksmöglichkeiten bieten. Je kleiner der Sprung zwischen Gehirn und Tastatur ist, um so effizienter wird die Kommunikation.
Zum einen ist das Niveau der Sprache von Bedeutung. Normalerweise muss man sich bei abstrakteren Sprachen weniger anstrengen, um Code zu erzeugen. Aber - und das ist ein großes Aber - neigen abstrakte Sprachen auch dazu, sich querzustellen und die Vorstellungen des Sprachdesigners, wie man etwas richtig macht, auf den eigenen Code zu übertragen. Dann wird Programmieren wieder schwierig. Obwohl Java hinreichend abstrakt ist, braucht praktisch alles, vom Erzeugen von Closures für Callbacks bis zum Iterieren über Collections, ein bisschen zu viel Arbeit: der Arbeitsfluss wird unterbrochen, wenn man das ganze Blabla eintippt, das Java und die Bibliotheken erfordern. Das ist mit ein Grund dafür, warum das gute, alte C immer noch populär ist: Wenn man einmal die Idiome verstanden hat, tritt die Sprache bei Seite und lässt einen arbeiten.
Zum anderen bleibt das Thema Verifikation: hat man den richtigen Code geschrieben? Sprachen helfen dem (oder behindern den) Programmierer hier. Da gibt es einmal Hilfen für typische Fehler während der Übersetzung und der Laufzeit. Die Proponenten statisch typisierter Sprachen werten dies als großen Vorteil ihrer Umgebungen, wir kommen gleich darauf zurück.
Wenn der Code geschrieben ist, muss er getestet werden. Wie hilft uns die Sprache hier? Bevor man eine einzelne Zeile JUnit-Testcode schreiben kann, braucht man 40--50 Zeilen Supportcode. In Ruby ist das Äquivalent require 'rubyunit'. Vielleicht ist das ein Grund, warum mehr Rubyprogrammierer wirklich Tests schreiben.
Schließlich zeigen Studien, dass Code-Inspektionen die effektivste Methode sind, um Bugs und Designfehler auszumerzen. Wie einfach ist es für andere, die Absicht hinter deinem Code zu erkennen? Oder sieht der Leser nur die Verpackung?
Wir glauben, dass man die Frage so nicht beantworten kann. Trotzdem ...
(Dave) Ich habe keine einzelne Lieblingssprache. Für low-level Arbeit gibt es nichts besseres als C (sicherlich nicht C++). Ich habe immer die deklarative "pic" Sprache in DWB gemocht: es ist sehr reizvoll, komplexe Diagramme zu zeichnen ohne eine einzige Koordinate anzugeben. (Und für diese Art von Constraint-basierter Programmierung habe ich auch eine Schwäche für eine numerische Kontrollsprache namens APT: es macht irgendwie das Programmieren wirklich, wenn Gleichungen in deinem Code direkt in die Bewegung von Schneideköpfen umgesetzt werden.) Für allgemeines Programmieren verwende ich im Moment erst einmal Ruby. Es lässt mich produktiv sein, und ich kann mich ausdrücken. Es lenkt mich nicht ab. Nach zwei ziemlich aktiven Jahren mit Ruby, empfinde ich die Benutzung von Ruby immer noch als Spass.
(Andy) Für was? Die größte Gefahr bei einer Lieblingssprache oder -methodologie oder jedem anderen Lieblingshammer ist, dass alles anfängt, wie ein Nagel auszusehen. Man setzt seine Lieblingssprache für alles ein -- unabhängig davon, ob die Situation es erfordert. Ich benutze viele Programmiersprachen und irgendwie sind sie alle nicht perfekt. Für systemnahes Programmieren, oder jegliche Aufgabe bei der Geschwindigkeit und Größe entscheidend sind, ist C die beste Wahl, aber C kann kryptisch sein und die Suche nach Speicherlöchern kann sehr viel Zeit kosten. Wenn es um verständliche Formulierungen geht, ist Eiffel die Sprache der Wahl, aber nichts kann sich mit der Flexibilität von Ruby messen.
(Dave) Andy hat recht, dass es gefährlich ist, einen einzigen Favoriten für irgendetwas zu haben. Ich denke, das ist der Grund, wieso wir uns gegen diese Frage auflehnen. Ich denke, wir haben beide Vorlieben für bestimmte Sprachen, aber wenn es darauf ankommt, sind Sprachen Werkzeug: wähle das richtige für die anstehende Aufgabe.
(Beide) Transparenz, Transparenz, Transparenz. Mit Transparenz meinen wir Sprachen, Bibliotheken und Betriebssysteme, die einen nicht behindern oder dazu zwingen, die Arbeit eines anderen zu erledigen. C++ ist hier wahrscheinlich das schlimmste Beispiel, aber auch Java hat viele Schwächen. Als Programmierer wollen wir mit Integer-Objekten arbeiten. Immer. Es ist uns egal, ob sie der Compiler intern besonders behandelt; wir sollten es nicht. Nach 40 Jahren Programmiersprachenentwicklung sollten wir von diesen maschinennahen Implementationsdetails wegkommen und nicht um sie herumcoden müssen.
Früher war Rechenzeit teuer und Arbeitszeit billig. Deine Lochkarten durften nur einmal am Tag kompiliert werden, und jeder einzelne Befehl hat gezählt. Daher machte es wirtschaftlich Sinn, dass Menschen etwas härter arbeiten mußten. Die Zeiten haben sich jedoch deutlich geändert, und Programmierer sind weit teuerer und wertvoller als die austauschbaren Kisten, die wir im Supermarkt kaufen können. Und trotzdem zeigen viele Programmiersprachen noch immer dieses archaische Verhalten, das uns zwingt, uns Tausende von Implementationsdetails zu merken, wenn wir eigentlich nur das Problem des Kunden lösen wollen.
(Beide) Da gibt es zwei. Der erste ist Hast. Programmierer stehen oft unter einem enormen Zeitdruck; manchmal von der Verwaltung oder von Kunden, aber oft durch uns selbst. Dieser deplazierte Wagemut bringt einen schnell in Schwierigkeiten: man hat keine Zeit es richtig zu machen, und hofft, es später noch erledigen zu können. Es gibt kein später. Gute Programmiertechniken und Disziplin werden in Angesicht einer Deadline schnell aufgegeben. Die Folge? Mehr Bugs und Probleme, die in noch weniger Zeit gelöst werden müssen, was zu einem Teufelskreis führt. Keine Programmiersprache oder Technik wird uns helfen, bis wir alle lernen innezuhalten und zu "DENKEN!"
Das zweite Problem ist, dass wir oft denken, die richtige Lösung zu kennen, ohne unser Wissen zu überprüfen. Wir denken, dass wir korrekten Code geschrieben haben, aber wir halten uns nicht mit Unit-Tests auf und überprüfen unsere Annahmen nicht. Wir erfinden andauernd das Rad neu, und ignorieren Jahre von Forschung und brauchbare Techniken, die andere erarbeitet haben. Als Industrie sind wir gegenüber der aktuellen Forschung auch erstaunlich indifferent.
Wenn sich der Programmierberuf weiterentwickeln soll, muss dieser Trend umgekehrt werden. Wir plädieren für einen Programmierstil, den wir Pragmatisches Programmieren nennen, der Programmierer dazu anhält, die Fehlkalkulationen gedankenloser Hast abzulehnen und über Feedback in allen Bereichen Annahmen zu überprüfen, sei es beim Schreiben von Code oder beim Umgang mit Kunden und Usern. Wir müssen die Informationsflüsse zwischen Forschung und Industrie sowie zwischen Programmierern, Akademikern und Verkäufern wiederbeleben, damit wir nicht immer wieder die alten Fehler wiederholen und den Rost aus 30 Jahre alten Sprachen und Techniken herausklopfen müssen.
(Beide) Wir haben seit vielen Jahren für generatives Programmieren geworben (ohne den Begriff generatives Programmieren zu benutzen). Die Idee, zu einem deklarativen Programmierstil zu kommen, bei dem sich der Code selbst selbst um die einfachen Details im Verborgenen kümmert, scheint einfach gesunder Menschenverstand zu sein.
(Dave) Gleichzeitig habe ich Angst vor den Komplexitäten, die man durch solche Techniken in Sprachen wie C++ erzeugt, die dafür überhaupt keine Unterstützung bieten. C++ Templates sind ein Hack, und sie als komplexe Codegeneratoren zu benutzen, kann keine gute Lösung sein, wenn zukünftige Generationen von Programmierern das System weiterentwicklen sollen. Wenn generatives Programmieren gut sein soll (und es ist gut), dann sollte man einmal Entwickler fragen, wieso sie nicht Sprachen benutzen, die es von Haus aus unterstützen.
(Andy) Ich stimme Dave zu. Die Industrie muss lernen, weiter zu gehen, als nur einen hässlichen Hack auf einen weiteren hässlichen Hack zu packen, und muss wirklich neue Paradigmen von Null auf akzeptieren. Wieso nicht ein Betriebssystem, mit wirklich objektorientierten Systemaufrufen? Wieso bleiben wir bei GUI-Systemen, die für eine Apple Lisa passend sind? Wieso entwickeln wir die kompliziertesten Systeme immer noch in schwarz-weissen, zwei-dimensionalen Kästen? Es ist an der Zeit weiter zu gehen und die Revolution anzuführen, die hier ansteht. erreicht haben.
Zurück zur Produktiver Programmieren Seite Zurück zur Approximity Hauptseite Bei Amazon.de kaufen