Archiv für Juli 2008

Außer der Reihe: Abenteuer Lisp lernen

Freitag, 25. Juli 2008

Im Urlaub möchte man ja immer etwas schönes machen. Der eine geht Berge besteigen, eine andere lockt der Strand. Und ich will schon seit einiger Zeit endlich mal Lisp lernen. Verrückt, oder?

Aber wieso ausgerechnet Lisp???

Nun, was Lisp so interessant macht, ist die Tatsache, dass dessen Wurzeln bis in die 50er-Jahre des letzten Jahrhunderts zurückgehen und Lisp damit die zweitälteste heute noch verwendete Programmiersprache überhaupt ist. Die älteste ist Fortran. Dabei bilden Fortran und Lisp zwei gegensätzliche Pole bezüglich der programmiersprachlichen Ansätze, zwischen denen sich die heutigen Programmiersprachen bewegen. Während der Fortran-Ansatz eher maschinennah auf pure Rechenleistung ausgerichtet war, war Lisp problemorientierter, hochsprachlicher und in vielen Dingen seiner Zeit voraus. Z.B. wurden viele Innovationen wie das if/then/else-Konstrukt, rekursive Funktionsaufrufe, Garbage collection und Closures zuerst in Lisp eingeführt und fanden oder finden erst nach und nach Einzug in die Mainstream-Programmiersprachen.

Außerdem gibt es in Lisp keinen Unterschied zwischen Programm und Daten. Beides sind einfache Listen, die auf die gleiche Art programmatisch behandelt werden können. Damit kann man auf relativ natürliche Weise das Programm selbst anpassen, neuen Code erzeugen oder vorhandenen modifizieren. Das nennt man dann Makros, die aber nicht wie die C-Makros auf rein textueller Ebene arbeiten sondern auf Sprachebene. Deshalb nennt man Lisp auch die programmierbare Programmiersprache (“Lisp is a programmable programming language.”, John Foderaro, CACM, September 1991; siehe Lisp-Quotes von John Graham).

In Java gibt es ja auch so etwas ähnliches: Frameworks wie Spring und Hibernate erzeugen z.B. dynamisch (also während des Programmlaufs) Proxy-Klassen, die ein bestimmtes Interface implementieren und damit indirekt der Zielklasse neue Funktionalität einbauen. Das ganze funktioniert hier aber nicht mit Java-Sprachmitteln sondern auf Bytecode-Ebene (mit Bibliotheken wie cglib). In der Java-Welt ist das ein aktuelles Thema obwohl man dazu die Java-Ebene verlassen muss. Was mich an Lisp so fasziniert, ist die eingebaute Möglichkeit, genau so etwas mit Sprachmitteln bewerkstelligen zu können.

Mit dem Buch Practical Common Lisp von Peter Seibel gibt es sogar eine moderne und praxisnahe Einführung in Common Lisp. Das Buch ist unter dem obigen Link frei verfügbar im Netz als HTML-Version. Eine ebenfalls frei verfügbare PDF-Version gibt es direkt beim Verlag (links der Link Free eBook Download).

Gestern habe ich die ersten drei Kapitel durchgearbeitet. Neben dem der obligatorischen überblicksmäßigen Einführung des ersten Kapitels wird einem im zweiten Kapitel die Benutzung der klassischen Lisp-Arbeitsumgebung Emacs mit SLIME (Superior Lisp Interaction Mode for Emacs) näher gebracht. In einem Puffer hält man seine Lisp-Sourcecodedatei und in einem anderen läuft die Common-Lisp-Implentierung der Wahl (z.B. CLISP) im interaktiven Modus. Dann kann man z.B. eine Funktion, die man in der Lisp-Datei deklariert einzeln kompilieren und hat sie dann im interaktiven Puffer zum Testen zur Verfügung. Eine Arbeitsweise, die ich schon bei Python schätzen gelernt habe, nur dass man in Python nicht einzelne Funktionen neu in den interaktiven Modus laden kann, das geht hier nur Dateiweise.

Um gleich loslegen zu können, gibt es die ganze Programmierumgebung als leicht installierbares Paket Lispbox. Mit der Linux-Version hatte ich allerdings so meine Probleme. Das Start-Skript brach mit einer Fehlermeldung ab. Das kann man aber leicht beheben, wenn man das erste if in lispbox.sh auskommentiert bis auf den else-Zweig. Die Version mit Allegro Common Lisp konnte ich aber dennoch nicht zum Laufen überreden, da das Programm newlicence zum Download der Trial-Lizenz nicht mehr funktionert. Es gibt aber zum Lernen auch eine komplette Lisp-IDE zum freien Download (Express-Edition mit einigen Einschränkungen gegenüber der kommerziellen Version). Damit funktionierte auch der Download der Trial-Lizenz (die aber nicht mit der Lispbox-Version zusammenarbeitet).

Die CLISP-Version von Lispbox funktioniert aber nach der Behebung des Fehlers im Startskript problemlos. Unter Ubuntu ist es allerdings auch nicht viel komplizierter Emacs mit SLIME einzurichten. Zusätzlich zu den entsprechenden Paketen für Emacs, SLIME und z.B. CLISP, die man installieren muss, braucht man nur noch die ~/.emacs Datei anzupassen.

Das dritte Kapitel greift schon mal vor und gibt einem anhand eines etwas komplexeren Beispiels, einen Einblick, was mit Lisp möglich ist. Die Beispiele kann man leicht selber nachvollziehen, dadurch ergeben sich viele Aha-Momente, die richtig Lust auf mehr machen.

Leider muss ich meine weiteren Lisp-Abenteuer auf später verschieben, denn GDI-2 und Mathe warten ja auch noch auf weitere Bearbeitung.

Alles alte abgegeben in Mathe

Montag, 21. Juli 2008

Alle schon mal mit der alten Version des Moduls bearbeiteten Aufgaben hab ich jetzt nochmal abgegeben. Einige Einsendeaufgaben wurden allerdings bei der Überarbeitung zu reinen Übungsaufgaben degradiert. Mathematische Logik, Boolesche Netze und Expertensysteme, Beweisverfahren, Mengenlehre und die Hälfte von Relationen und Funktionen sind damit abgehandelt. Es stehen aber noch aus: Einführung in die Graphentheorie, algebraische Strukturen, Rekursivität, Fuzzy-Mengen und Fuzzy-Logik sowie Komplexität. Also noch ein ganz schöner Stiefel, den ich vor mir habe. Und das sind nur die Pflichtteile. Einige Unterkapitel gehören allerdings auch nur zum Erweiterungsprogramm.

Keine Mathe-Abgabe mehr mit OpenOffice

Montag, 21. Juli 2008

Meine alten Abgaben für Mathematisch-logische Grundlagen hatte ich immer mit OpenOffice erstellt. Nach meiner Umstellung auf Linux lassen sich meine alten Dokumente natürlich immer noch öffnen und bearbeiten und sehen auch mit allen mathematischen Formeln und Sonderzeichen immer noch genau so aus. Allerdings wurde mir jetzt erst bewusst, dass OpenOffice seine PDFs nicht ohne eingebettete Schriften erzeugt. Viele Sonderzeichen werden dann unter Linux einfach nicht angezeigt.

Da kommt es glücklicherweise ganz gelegen, dass ich mich in den letzten Tagen eh schon nach Alternativen für die Bearbeitung der Mathe-Aufgaben umgesehen habe. Der Formeleditor von OO ist zwar ganz passabel, aber Formeln in einem Satz werden oft nicht auf der gleichen Basislinie platziert. Aber besonders nervig ist das Zusammensuchen der ganzen Sonderzeichen aus den verschiedenen Zeichensätzen. Selbst wenn man sich die wichtigsten Sonderzeichen dann in einem separaten Dokument fürs Copy&Paste hält, ist das ganze doch eine ziemlich mühselige Angelegenheit.

Ich kenn mich zwar ein bisschen mit LaTeX aus, aber nicht so gut, dass ich das flüssig, ohne ständig nachschauen zu müssen, runterschreiben könnte. Ein guter Kompromiss scheint LyX zu sein. Das ist sozusagen ein LaTeX-Aufsatz mit einer hübschen GUI. LaTeX-Befehle, die man kennt, kann man direkt eingeben, ansonsten wählt man den entsprechenden Menüeintrag oder Toolbutton. Dabei erscheint der Text zwar nicht hundertprozentig so formatiert wie in der späteren Ausgabe, aber es reicht. Auch für Formeln gibt es eine ausreichende Vorschau direkt im Editor. LyX gefällt mir eigentlich ganz gut, auch wenn die z.B. die Tabellenunterstützung nicht ganz so gut ist. Man kann Standardtabellen ganz flott erstellen, aber um die Zellenhintergründe farbig zu gestalten, müsste man mit LaTeX-Befehlen arbeiten. Da aber meine Mathe-Abgaben nicht unbedingt so furchtbar schick sein müssen, wäre das zu verschmerzen.

Aber es sieht so aus, als gäbe es noch etwas passenderes für meine Zwecke: TeXmacs. Das ist im Prinzip eine Textverarbeitung speziell für mathematische Texte. Hier sieht man wie bei einer Textverarbeitung 1-zu-1 die spätere Ausgabe. Die GUI ist allerdings ein wenig gewöhnungsbedürftig. Das Programm ist mehr darauf ausgelegt, möglichst viel per Tastatur eingeben zu können. Viele Sonderzeichen, Klammern, Brüche usw. kann man zwar auch per Klicken einfügen, aber um eine Matrix einzufügen muss man Esc t N m hintereinander drücken (wenn man im Mathe-Modus ist). Das sind dann wohl die Emacs-Anleihen ;-) Dafür kann man dann ganz einfach mit Alt-Pfeil rechts bwz. Alt-Pfeil runter beliebig viele Spalten bwz. Zeilen in der Matrix einfügen.

Den Mathemodus innerhalb eines Fließtextes schaltet man wie in LaTeX mit dem $-Zeichen ein und wieder aus. Das hat den ungeheuren Vorteil, dass man im Tipp-Fluss bleibt, auch wenn man nur sowas wie “x > 0″ einfügt. Man kann auch viele Zeichen mit ihren LaTeX-Befehlen eingeben. Z.B. \in für das Element-Zeichen. Oder \frac für einen Bruch. Der Cursor ist dann im Zähler und mit Pfeil runter kommt man zum Nenner. (Einfacher ist dann aber die Abkürzung Alt-f). Auf einige sehr geniale Abkürzungen kommt man erst mit der Zeit. Wenn man z.B. im Mathemodus N eingibt, erhält man zunächst einfach ein großes kursives N. Drückt man nochmal N, dann verwandelt es sich in ein Mengen-N für die natürlichen Zahlen. Oder man gibt die Zeichen |–> ein und erhält einen Abbildungspfeil. Oder das Kaufmanns-Und &. Das kann man durch Drücken von Tab in das Und-Symbol verwandeln, das so aussieht, wie ein umgedrehtes kleines v. Nochmal Tab und man erhält das Symbol für Schnittmenge.

Jedenfalls sind viele Sachen ganz intuitiv. Daher hab ich mir meinen zweiseitigen Beweis zur Kombinatorik-Aufgabe vorgenommen und ihn nochmal mit TeXmacs neu geschrieben. Es hat gerade mal eine Stunde gedauert und sogar noch richtig Spaß gemacht. Mit OO hatte ich mich damals ziemlich abgerackert, zwei oder drei Stunden hat das schon gedauert. Das Resultat (übrigens mit eingebetteten Schriften) sieht sogar noch viel besser aus als mit OO. Aber das wichtigste ist die komfortable Eingabe. Das spart echt Zeit. Auch im Hinblick auf die Online-Abschlussklausur ein wichtiger Punkt.

TeXmacs ist auf jeden Fall einen zweiten Blick wert, man sollte sich nicht durch die etwas dröge GUI abschrecken lassen. Dafür bietet es gute integrierte Hilfetexte sogar auf deutsch.

Wieder Mathe

Sonntag, 20. Juli 2008

So langsam hab ich mich jetzt auch wieder mit Mathe angefreundet, genauer gesagt mit dem Modul Mathematisch-logische Grundlagen der Informatik. Meine ersten Bearbeitungen waren vom September 2007. Irgendwann um Weihnachten blieb ich dann bei ca. einem Drittel bearbeiteter Aufgaben hängen. Zwischenzeitlich wurde das Modul etwas überarbeitet (genauer gesagt: entschärft). Ein Teil des Kurses ist jetzt als Ergänzung gedacht. Gut finde ich dabei, dass nicht nur einmal im Einführungstext erläutert wird, welche Kapitel und Wissensbausteine Pflicht bzw. Ergänzung sind. Die Kapitel- / Wissensbausteinnamen sind alle entsprechend mit (P) oder (E) markiert, so dass man gleich im Navigationsbaum den Überblick hat.

Meine damaligen Aufgabenbearbeitungen werde ich natürlich wiederverwenden. Die ersten zum Kapitel mathematische Logik hab ich gerade abgegeben. Nur die ganzen Tests muss ich natürlich nochmal machen, wobei die teilweise ganz schön knackig sind. Aber das ist vielleicht eine gute Gelegenheit, den Stoff nochmal aufzufrischen.

Ereignisse

Donnerstag, 17. Juli 2008

Im Kapitel Ereignisverarbeitung im Detail werden die bei der GUI-Programmierung wichtigen Ereignisse behandelt. Z.B. wird unterschieden zwischen elemantaren und semantischen Ereignissen. Innere und anonyme Klassen werden ebenfalls erklärt, da diese oft bei der Ereignisverarbeitung verwendet werden.

Grafikprogrammierung

Donnerstag, 17. Juli 2008

Im Kapitel Grafikprogrammierung – eine Einführung werden die grundlegenen Möglichkeiten betrachtet, Text und einfache grafische Formen wie Linien und Rechtecke etc. in einen Grafikkontext zu zeichnen. Außerdem erfährt man, wie man Bilddateien lädt und anzeigt sowie die Unterschiede dabei zwischen Applets und normalen Anwendungen.

GDI-2: Ein Applet

Mittwoch, 16. Juli 2008

Das nächste Kapitel dreht sich um Applets. Applets sollten ja mal das Web revolutionieren; heutzutage begegnet man ihnen in freier Wildbahn aber nur noch selten. Aber Applets gehören einfach zu Java und es ist sicher gut zu wissen, wie man Applets programmiert. Hierzu gibt es auch eine Einsendeaufgabe, bei der man anhand eines kleinen Pflichtenheftes ein Applet entwickeln soll.

Wenn man mit Jigloo das Applet erzeugt, dann wird die Klasse gleich so erstellt, dass man sie sowohl als Applet als auch als normale Swing-Applikation starten kann. Allerdings sollte man hier etwas nacharbeiten, um die Vorgaben aus dem Kurs zu erfüllen und das Erzeugen der GUI-Elemente mit

SwingUtilities.invokeAndWait()

zu erledigen.

Die brandneue JavaFX Technologie findet leider noch keine Erwähnung im Kurs, das wäre aber wohl auch etwas zu viel verlangt, dazu ist das noch zu neu.

GDI-2: GUI-Editoren

Mittwoch, 16. Juli 2008

Das nächste Kapitel GUI-Grafikeditoren hat wieder eher einführenden Charakter (keine Tests, keine Aufgaben). Die Aufgabe besteht eher darin, den GUI-Editor Jigloo in Eclipse zu installieren und ein einfaches GUI-Programm, dessen Oberfläche im Schnelleinstieg manuell erstellt wurde, diesmal grafisch zusammenzuklicken.
Bei der Installations-Anleitung wird angegeben, man solle sich die ZIP-Datei des Jigloo-Plugins runterladen, ins Eclipse-Verzeichnis entpacken und Eclipse dann neu starten. Unter Eclipse Ganymede (3.4) funktioniert aber auch der Update-Mechanismus einwandfrei: Man muss nur im Menü unter Help auf Software-Updates… gehen und auf dem Reiter Available Software den Button Add Site… anklicken. Hier fügt man die Jigloo-Update-URL

http://cloudgarden1.com/update-site

hinzu und kann dann den Jigloo GUI Builder auswählen und installieren. Der Vorteil an dieser Methode ist, dass man so später auch installierte Plugins updaten kann.

GDI-2: Java-GUIs testen

Dienstag, 15. Juli 2008

Hab gerade das Kapitel Testen von GUIs durchgearbeitet. Dabei wird das Testframework Abbot verwendet, das eine Erweiterung von JUnit ist. Es wird erklärt, wie man die Abbot-JARs in ein Eclipse-Projekt einbindet, den Skript-Rekorder Costello startet und damit Benutzereingaben mitschneidet und wie man bei testgetriebener Entwicklung die Abbot-API direkt einsetzt.

Hierbei bin ich in einige Fallstricke geraten:

  • Das Abbot-Archiv der Version 1.0.1, wird in zwei Varianten zum Download angeboten: Als ZIP- oder als TGZ-Datei. Man sollte unbedingt die ZIP-Datei wählen, da in der TGZ-Datei die Datei costello.jar fehlt.
  • Bei Eclipse unter Linux ist die Standardzeichenkodierung der Sourcecodedateien UTF-8. Dies führt zu Problemen, wenn man die Beispielprojekte aus dem Kurs einbindet, da diese unter Windows erstellt wurden und dort Eclipse Cp1252 als Standardzeichenkodierung hat. Man kann aber in den Projekt- oder Dateieigenschaften die Zeichenkodierung umstellen (in der Auswahlliste ist Cp1252 nicht enthalten nur der ähnliche aber nicht identische ISO-8859-1; man muss es direkt reinschreiben)
  • Das Erzeugen eines JUnit-Tests aus einem aufgezeichneten Costello-Skript funktionierte bei mir nur mit absoluter Pfadangabe zum Skript. Den Beispielsourcecode, der nur eine relative Pfadangabe enthielt, musste ich anpassen. Die Dokumentation zum ScriptFixture-Konstruktor gibt aber nicht an, ob man nur absolute Pfade verwenden darf.

Ich finde es gut, dass dem auch in der Praxis so wichtigen Thema Testen Platz in einem eigenen kleinen Kapitel gegeben wird. Allerdings gibt es im gesamten Kapitel weder Aufgaben noch Tests. In GDI-1 wurde JUnit kurz eingeführt, dort allerdings die Version 4, die mit Annotationen arbeitet. Abbot basiert jedoch noch auf der 3er-Version, in der die einzelnen Tests nicht mit der Annotation @Test markiert werden sondern deren Methodenname mit “test” beginnen muss. Auf die Unterschiede hätte man hier vielleicht noch etwas näher eingehen können und vielleicht auch, wie man in Eclipse die eingebaute JUnit-Unterstützung verwendet.

Zwei Aufgaben GDI-2

Dienstag, 08. Juli 2008

Die ersten beiden Einsendeaufgaben von Grundlagen der Informatik 2 (GDI-2) sind korrigiert. Naja, es war auch nicht wirklich eine Herausforderung. Einmal sollte ein simples Begrüßungsfenster in Swing entwickelt werden. Die andere Aufgabe stammt aus dem Datenbankkapitel, das relativ unabhängig von den anderen ist. Hier sollte man in SQL eine Tabelle erzeugen, einen Datensatz einfügen und eine Abfrage ausführen. Gestählt durch das gerade abgeschlossene SQL-Modul war das natürlich ein Klacks ;-)