Einträge mit dem Tag ‘Programmieren’

Actually, I have known this for some time, but today, it has bitten me again: Interpreted languages[1] are not suited for application development. Period. Use them for quick hacks, or for prototyping, or in lieu of a shell script. But never for real applications.

People tend to say Computers are so fast today the overhead does not really matter, and if it does for a few inner loops, no problem: our language can interface with C. But that is beside the point. The real disadvantage of these languages is not their (somewhat inferior) execution speed, but their lack of static checking. If you write bogus in a compiled language, chances are the compiler will catch it. Some stricter languages[2] will catch more kinds of bogus than more lenient ones[3], but there are surprisingly many ways to write bogus that every compiler will catch. Interpreted languages do not have a compile phase, they just throw an exception when encountering bogus at runtime. If they encounter it: There are many execution paths through a program, and some may not be followed very often, making it easy to write, install, and use completely broken software. You may say Well, write tests then, but as useful tests are, they come with large disadvantages when relied upon as the only means of detecting errors: Firstly, they have to be written. A compiler knows about the language, but the developer has to write all necessary testcases by hand. It is easy to overlook something, and it is also very easy to be lazy and write too few tests (or none at all). Secondly, executing tests takes machine time (probably more than what was saved by not compiling), and writing tests takes developer time (lots of it). Finally, the static analysis a compiler provides tends to catch different errors than tests do, so combining the two will simply catch more problems than either method on its own.

Oh, and then there is the problem of external code. Libraries, modules, whatever. APIs should not change (needlessly), but sometimes they do. With ordinary binary code, there is an established way to keep around different versions of a given library, so older programs using an older API can still function. I am not aware of a similar mechanism for Python, so getting ImportErrors from a module that installed just fine is not that unusual. In fact, implementing such a method for an interpreted language would be somewhat more involved than for a compiled one: When a programmer links to a shared library, the linker will take that to mean the latest installed version of that library. The version number is then encoded into the application binary, so the correct library will be used whenever the application is started. However, the very nature of an interpreted language means that the program is not touched by anyone but the developer. So if the developer does not demand a particular version, nothing else does, either. Seriously: use a tool that fits the job rather than clutching a hammer and trying to see nails everywhere.

  1. like Python
  2. like Ada
  3. like C
Kein Kommentardeutsch

Ja, da war ich wohl ein wenig voreilig, das Verständnis des Buildsystems anzunehmen. Das stellte sich heraus, als ich den erfolgreich kompilierten gcc unter einem Debugger[1] betreiben wollte. Wer schon einmal versucht hat, ein Kompilat mit eingeschalteter Optimierung zu debuggen, weiß, was ich meine: Variablen lassen sich nicht mehr auslesen, das Programm scheint im Code wirr vor und zurück zu springen — selbst ein sehr einfaches, selbst geschriebenes Programm ist kaum noch nachvollziehbar. Nicht so schlimm, dachte ich mir, und habe mit CFLAGS='-g -O0' configure gleich den nächsten Build angestoßen. Die Ernüchterung folgte allerdings auf dem Fuße:[2] die Flags waren irgendwo unterwegs verlorengegangen, und das Resultat kein bißchen brauchbarer als beim ersten Versuch.

Dabei bin ich eigentlich froh und dankbar, daß der gcc als Buildsystem die GNU Autotools verwendet. Sie werden zwar manchmal als veraltet und zu kompliziert abgetan, aber ich komme mit ihnen immer noch weit besser klar als mit CMake, Python Distutils und allem anderen, das ich bislang gesehen habe. Die Probleme beim gcc rühren allein daher, daß es mit dem bloßen Kompilieren nicht getan ist; stattdessen wird der dabei erzeugte Compiler dazu verwendet, aus dem Sourcecode noch einen Compiler (Stage2) zu erzeugen, und dieser wiederum erzeugt dann das fertige Kompilat (Stage3).[3] Of will man in verschiedenen Stadien verschiedene Optionen verwenden, und deshalb gibt es auch einen ganzen Zoo von Umgebungsvariablen, deren Zweck nicht immer ohne weiteres klar ist.

Ach so, die Lösung: nach dem Konfigurieren einfach make BOOT_CFLAGS='-g -O0' bootstrap eingeben, und schon klappt es.

  1. Für den Fall, daß noch nicht alle des Programmierens nicht mächtigen Leser aufgegeben haben, sei gesagt: Ein Debugger ist ein Programm, mit dem man den Ablauf und den Zustand eines anderen — möglicherweise fehlerhaften — Programmen schrittweise verfolgen kann.
  2. Jedenfalls halbwegs — so ein Notebook ist nicht gerade die schnellste aller Entwicklungsmaschinen
  3. Dieser Bootstrap genannte Zauber dient dazu, den fertigen Compiler mit sich selbst zu kompilieren, was ein guter Test für seine Zuverlässigkeit ist.
Kein Kommentar

Eine kurze Statusmeldung: Inzwischen läuft der Build durch, und ein passendes Problemchen zur Analyse habe ich auch schon gefunden. Am Anfang ist es immer ratsam, sich einen weniger drängenden Bug zu suchen, weil es sonst leicht passiert, daß jemand mit mehr Erfahrung und Überblick schneller ist…

1 Kommentar

Es war vor ein paar Tagen, da saß ich in meinem Lieblingssessel, es war etwas früher als üblich, und es sollte ein schöner Abend werden. Endlich die Gelegenheit, etwas zu tun, zu dem mir sonst die Zeit fehlt — doch was nur? Lesen mochte ich aus irgendeinem Grund nicht, und der Vokabelkasten neben mir wirkte auch nicht gerade verlockend. Ein Computerspiel vielleicht, dachte ich mir, wenn die Monster zur Tür hereinkommen und du die Taschenlampen und Bumerangs strategisch ums Bett herum verteilst ist das sehr befriedigend, weil die Kiste dir mit jeder Monsterwelle eine neue Herausforderung vorwirft aber du löst sie jedesmal und die Lösung ist so einfach und so elegant wenn du nur die Taschenlampen hinten in die Kurven und die Shuriken vorne an die Geraden stellst, aber nein irgendwie ist das ja auch alles repetitiv und ein bißchen langeweilig, und dann wußte ich du brauchst Code code CODE und es ist völlig egal daß du jeden Tag acht Stunden am Rechner verbringst du mußt jetzt und gerade den Compiler anwerfen und ein programmieren und jedes Problem ist eine Herausforderung aber das Programm löst sie und der Code ist so elegant nur ist es gar nicht repetitiv wenn du nur das richtige Problem hast und hinterher können tatsächlich Leute dein Programm benutzen und…

Nun ja, ich habe dann ein bißchen nach einem passenden Projekt gesucht. Vielleicht ein schönes buntes Mac-Programm? Aber bald fiel mir wieder ein, daß ich vor fünf oder sechs Jahren schonmal ein bißchen im gcc herumgefuhrwerkt hatte, und das hat mir eigentlich von allen Projekten immer noch am meisten Spaß gemacht: einerseits ist der Compilerbau schon soetwas wie die Königsdisziplin der angewandten Informatik, und andererseits gibt es beim gcc unglaublich viele kleine Nischen und Unterprojekte, in denen man sich nicht gegenseitig auf die Füße tritt, man aber auch Chancen hat, daß der eigene Code hinterher im fertigen Produkt Verwendung findet. Naja, und dann hat der gcc natürlich eine sehr zentrale Rolle im GNU-Projekt und eine unglaublich breite Nutzerschaft, und das schmeichelt dem Ego dann auch irgendwie.

Für’s erste ist aber statt Blood, Sweat & Code noch der Kampf mit dem Buildsystem angesagt, damit ich den ersten Bootstrap hinbekomme.

3 Kommentare

This is again an entry bound to be uninteresting to most…

If you use Jim Rogers’ Pipe Commands for Ada, and the linker complains about an
undefined reference to `c_constant_eof',
try
pragma Import (C, c_constant_EOF, "__gnat_constant_eof");
instead of
pragma Import (C, c_constant_EOF);

[via Usenet]

Kein Kommentardeutsch

Es war einmal eine Zeit, in der für jeden neuen Computer alle Programme neu geschrieben werden mußten. Die Menschen kannten es nicht anders, und so erfanden sie tagein, tagaus das Rad neu. Doch dann kam Dennis und sagte: wäre es nicht schön, wenn wir dem Computer einfach erklären könnten, was die Programme tun sollen? Dann könnte der Computer das Programm selber schreiben; und wenn wir einen neuen bauen, dann geben wir ihm einfach die gleiche Erklärung, und er baut sich das Programm so, wie er mag.

So hat Dennis die Programmiersprache C erfunden. Außerdem hat er noch einen guten Teil von Unix erfunden, aber das ist eine andere Geschichte. Ein paar Jahre später hat Bjarne C++ erfunden. C++ ist ein bißchen seltsam: einerseits ist es ein einfaches Werkzeug für Leute, die sich beim Arbeiten die Hände dreckig machen (low level, sagt der Programmierer), wie C es ist: so etwas wie ein Hammer oder eine Zange; andererseits bringt es eine Menge fortschrittliches Zeugs mit: wie ein Industrieroboter vielleicht.

Kein Wunder, daß es da Ungereimtheiten gibt. Wer sich mit C++ auskennt, der findet bei yosefk eine sehr unterhaltsame Zusammenstellung dieser Ungereimtheiten.

[Edit: Typo]

Kein Kommentar

Software is hard

hat Donald Knuth, graue Eminenz der Informatik, einmal gesagt. Warum das so ist, versucht Scott Rosenberg in seinem Buch Dreaming In Code zu ergründen.
Er tut das in einer Form, die mich sehr an ein Blog erinnert: die Kapitel bestehen nicht aus einem durchgehenden Erzählstrang, sondern aus oft nur lose zusammenhängenden, kurzen Abschnitten; dabei springt Rosenberg oft zwischen den Anfängen der Computertechnik und der Gegenwart hin und her, und man merkt, daß Hoffnungen und Probleme sich doch über die Zeiten kaum verändert haben.

… Bugs are called “defects,” and defects are “injected” by workers–as if the product begins in some Platonic state of perfection and is then corrupted by mad-eyed workers shooting bug-filled syringes into its bloodstream.�

Ein weiteres Merkmal von Blogs ist das Verlinken auf Quellen oder verwandte Themen. Hyperlinks funktionieren in einem Buch natürlich nicht, aber dafür gibt es fast dreißig Seiten Fußnoten mit Referenzen, viele sogar mit URL.

Eine eindeutige Antwort kann der Autor letztlich nicht liefern, aber er zeigt doch eine Menge Aspekte auf, die Softwareprojekten zusetzen. Der für mich wichtigste Punkt betrifft die Frage, warum Brückenbauten in der Regel problemlos über die Bühne gehen, das Erstellen von Programmen aber nicht:

Software development is often compared to the construction industry, but the analogy breaks down in one respect. Even after we have learned how to build structures so solve particular problems … we still need to keep building more of those structures. However much I may like your house, I can’t have it myself.�

Abschließend möchte ich noch hinzufügen, daß Rosenberg ausdrücklich Nichtprogrammierer als Zielgruppe anspricht. Er verzichtet weitgehend auf technische Details, und erklärt diese, wenn er sie trotzdem anspricht. Gerade diesen Lesern bietet Dreaming In Code die Möglichkeit, zu erfahren, wie Softwareentwicklung funktioniert — welche Probleme sich auftun, wie die Entwickler zusammenarbeiten, was sie motiviert.

Politischer Aktivismus ist übrigens auch schwierig. Wolfgang Stieler beschreibt das recht witzig (natürlich aus der Sicht eines Softwareentwicklers), aber das Thema und sein Fazit sind durchaus ernst:

Die meisten politischen Angelegenheiten werden außerhalb des Netzes verhandelt.

Da nimmt es nicht wunder, wenn auch monatelanger Aktivismus (natürlich zum großen Teil online quer durch die Blogosphäre) in der Bundespolitik kaum Wirkung entfaltet.

2 Kommentare