Einträge mit dem Tag ‘Code’

Der Webcomic xkcd behandelt nach eigener Aussage romance, sarcasm, math, and language. Es hat einige Zeit gedauert, bis ich mich an die etwas kruden Strichmännchen gewöhnt habe, aber inzwischen hat er seinen Platz in meiner Bookmarkliste an der Seite von Dilbert und UserFriendly verdient.

Heute gibt es ein Diagramm über die Schwierigkeit, die Computer mit diversen Spielen haben. Angefangen von vollständig gelösten Spielen wie Tic-Tac-Toe über solche, bei denen selbst Weltmeister gegen Programme keine Chance haben (Reversi, seit einiger Zeit auch Schach) geht die Liste hoch zu Spielen, bei denen Menschen immer noch die Oberhand haben. Daß Go weit oben stehen würde, hatte ich erwartet; daß Snakes and Ladders1 ein besonders kompliziertes Spiel sei, war mir dagegen neu, und so habe ich ein wenig Recherche den vier Einträgen oberhalb von Go betrieben. Das Ergebnis:

  • Snakes and Ladders ist ein reines Glücksspiel, das man weder gut noch schlecht spielen kann
  • Mao muß man spielen, ohne die Regeln zu kennen
  • Seven Minutes in Heaven -- ähem
  • Calvinball gibt es gar nicht

Romance, sarcasm, math, and language, indeed.

  1. oberhalb von Go eingeordnet []
Kommentare deaktiviert für Sieben Minuten

Eigentlich weiß ich das ja schon länger, aber heute ist es mir wieder schmerzhaft bewußt geworden: Interpretierte Sprachen1 sind zur Entwicklung ernsthafter Programme ungeeignet. Für Prototypen, einen schnellen Hack, oder als Shell-Skript-Ersatz sind sie eine feine Sache, aber nicht für echte Programme.

Man hört oft, Computer sind heutzutage so schnell, daß das schlechtere Laufzeitverhalten nicht ins Gewicht fällt, und falls doch ein paar Stellen kritisch sind, so ist das auch kein Problem: die Sprache kann C-Routinen aufrufen. Aber darum geht es nicht. Die echten Nachteile liegen nicht in der Ausführungsgeschwindigkeit, sondern in der fehlenden statischen Prüfung des Codes. Wenn man in einer kompilierten Sprache Quatsch schreibt, dann kann man darauf hoffen, daß der Compiler das bemerkt. In manchen strengeren Sprachen2 läßt der Compiler weniger Quatsch durchgehen als in nachgiebigeren3, aber es gibt erstaunliche viele Sorten Quatsch, die jeder Compiler findet. Interpretierte Sprachen kennen keinen Compiler, deswegen finden sie den Quatsch erst zur Laufzeit. Wenn sie ihn finden: Es gibt viele Pfade durch ein Programm, und einige davon werden nur selten benutz; deshalb ist es einfach, völlig vergurkte Programme zu schreiben, zu installieren, und zu benutzen. Es heißt dann oft Deshalb brauchen wir Tests, aber so nützlich Tests auch sind, so haben sie doch gewichtige Nachteile (jedenfalls wenn sie die einzige Möglichkeit sind, Fehler zu finden: Zuerst müssen sie überhaupt geschrieben werden. Ein Compiler versteht die Sprache, aber der Entwickler muß alle nötigen Testcases von Hand schreiben. Dabei kann man leicht etwas übersehen, und noch leichter aus Bequemlichkeit zu wenige (oder gar keine) Tests schreiben. Zweitens braucht das Abarbeiten der Tests Rechenzeit -- wahrscheinlich mehr, als man durch den fehlenden Compilerlauf gespart hat; und das Schreiben kosts Entwicklerzeit, und zwar eine Menge. Schließlich findet der Compiler oft einfach andere Fehler als Tests, und wenn man beides einsetzt, findet man mehr Fehler.

Ja, und dann gibt es noch das Problem mit externem Code. Bibliotheken, Module, oder wie man ihn auch nennen will. APIs sollten sich nicht ändern (jedenfalls nicht ohne guten Grund), aber manchmal tun sie es eben doch. Für gewöhnliche, binäre Programme gibt es wohldefinierte Mechanismen, um verschiedene Versionen einer Bibliothek gleichzeitig vorzuhalten, damit ältere Programme immer noch laufen. Einen entsprechenden Mechanismus für Python kenne ich nicht, und so ungewöhnlich ist es nicht, wenn ein sauber installiertes Modul mit ImportErrors um sich wirft. Wenn man eine solche Methode entwickeln wollte, hätte man auch mit einem zusätzlichen Problem zu kämpfen: Wenn ein Programmierer eine shared library verlinkt, dann nimmt der Linker automatisch die neueste installierte Version dieser Bibliothek. Die Versionsnummer wird dann in dem kompilierten Programm verewigt, und wenn man es irgendwann später startet, wird die richtige Bibliothek benutzt. Es liegt aber gerade im Wesen einer interpretierten Sprache, daß der Programmcode nur vom Programmierer verändert wird. Wenn dieser also nicht von Hand eine bestimmte Bibliotheksversion anfordert, dann tut das auch keine andere Instanz.

Im Ernst: man sollte Werkzeuge verwenden, die für die Aufgabe geeignet sind, anstatt sich verzweifelt an seinen Hammer zu klammern und überall Nägel zu sehen.

  1. z.B. Python []
  2. z.B. Ada []
  3. z.B. C []
Kommentare deaktiviert für Lessons learnedenglish

Linux und die Speicherverwaltung -- das ist gar kein einfaches Thema. Wenn man dann noch versucht, seine User mittels ulimit im Zaume zu halten, wird es nur schwieriger. Gerade habe ich etwas sehr erhellendes gefunden: die meisten Sachen funktionieren einfach nicht.

Kommentare deaktiviert für Linux, Ltd

Ärgerlich, wenn der Rechner allnächtlich den mühsam zurechtgezimmerten Code löscht. Praktisch, wenn alle Änderungen in der Code-Datenbank gespeichert sind und man zu jedem beliebigen Zeitpunkt zurückgehen kann. Wunderlich, wenn zusammen mit dem Code auch alle seine Spuren in der Vergangenheit verschwunden sind.

Jetzt habe ich über Monate immer mal wieder ein, zwei Stündchen darauf verwendet, das Leck zu finden. Heute war ich endlich erfolgreich:

In the normal fast-forward case the behavior remains unchanged. However, now local modifications and commits will be erased, and upstream rewrites are handled smoothly.  This ensures that the upstream
branch is tested as expected.

Argh! Was soll das denn? Was ich teste, möchte ich bitteschön selbst entscheiden. Und wenn ich wirklich Upstream testen will, dann lege ich schon einen passenden Branch an. Aber es kann doch nicht sein, daß die Software das für mich entscheidet, und dann auch noch meinen Code aus der Datenbank löscht!

Kommentare deaktiviert für Erasedenglish

Was ist denn heute los? Da standen doch tatsächlich kurz nacheinander zwei Leute mit Daten auf Disketten in der Tür.

1 Kommentar

Gerade gefunden: Ein Link für alle, die wissen, was eine Turingmaschine ist.

Kommentare deaktiviert für Maschine

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 Debugger1 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. []
Kommentare deaktiviert für Suboptimal

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

Heute habe ich mal wieder eine Notiz, die für die meisten Leser wohl weniger interessant sein dürfte.

Wer Jim Rogers' Pipe Commands für Ada verwendet und über den Linkerfehler
undefined reference to `c_constant_eof'
stolpert, der möge es einmal mit
pragma Import (C, c_constant_EOF, "__gnat_constant_eof");
anstelle von
pragma Import (C, c_constant_EOF);
probieren.

[via Usenet]

Kommentare deaktiviert für End Of Fileenglish