Sonntag, 20. März 2011

Monaden in Scala

Am vergangenen Wochenende habe ich beim MATHEMA Campus 2011 einen Vortrag über Monaden in Scala gehalten (Folien hier).

Monaden sind ein etwas sperriges Konzept, das in rein funktionalen Sprachen wie Haskell u.a. für eine vernünftige Ein-/Ausgabeprogrammierung notwendig ist. Für Scala sind Monaden vielleicht nicht ganz so wichtig, aber auch mit Scala kann man sinnvoll monadisch programmieren – und das Schöne daran: Über die ganze komplizierte mathematische Theorie dahinter muss man sich keine Gedanken machen. Im Gegenteil, wer schonmal ein bisschen Scala programmiert hat, wird dabei vermutlich (unbewusst) auch Monaden genutzt haben.

Was sind diese Monaden? Ein abstrakter Datentyp für verkettbare Berechnungen mit folgenden Eigenschaften:
  • Ein Typkonstruktor wie List[A] (mit z.B. List[Int] als Ausprägung).
  • Eine Funktion, um einen Wert im Typ "einzuwickeln". Das kann der Konstruktor sein, z.B. new List(1) bzw. List(1), aber häufig wird diese Funktion return, unit, lift oder pure genannt.
  • Eine Funktion, um die enthaltenen Werte zu verrechnen, aber nach der Berechnung im Typ verpackt zu lassen. Übliche Namen sind bind oder (in Scala) flatMap.
Die Monadengesetze müssen von den Funktionen eingehalten werden, aber das lassen wir mal außen vor. Klingt kompliziert? Schauen wir uns das in der Praxis an:
case class MiniMonade[A](wert:A) {

def flatMap[B](f: A => MiniMonade[B]) = f(wert)

def map[B](f: A => B): MiniMonade[B]
= MiniMonade(f(wert))
}
Die Mini-Monade soll also genau einen Wert des generischen Typs "A" speichern und verarbeiten können. Listen sind auch Monaden und können entsprechend beliebig viele Werte verarbeiten. In unserer Monade ist zusätzlich noch die Funktion map implementiert, damit wir Objekte dieser Klasse in den for-Comprehensions von Scala einsetzen können. Und genau das ist auch der häufigste Anwendungsfall für Monaden in Scala:
val m1 = MiniMonade(2)
val m2 = MiniMonade(3)

val erg = for { x <- m1; y <- m2 } yield x*y;

println( erg )
In dieser for-Comprehension werden alle Werte aus den beiden Monaden-Objekten miteinander mit x*y verrechnet und landen anschließend (durch die Magie der Monaden-Funktionen) wieder in einem Monaden-Objekt. Da unsere Objekte jeweils nur einen Wert speichern, wird nur 2*3 berechnet:
HeartOfGold:~ much$ scala MiniMonade.scala
MiniMonade(6)
Das scheint unnötig viel Aufwand für eine simple Multiplikation zu sein... Aber folgendes Beispiel dürfte – so oder in ähnlicher Form – jeder schonmal programmiert haben, und das ergibt sicher mehr Sinn:
val zeilen = List(10,20)
val spalten = List(1,2)

val summen = for {z <- zeilen; s <- spalten} yield z+s;

println( summen )
// List(11, 12, 21, 22)
Andere gebräuchliche monadische Typen sind (neben vielen weiteren) Map und Option, und alle diese Klassen können in einer for-Comprehension kombiniert werden.

Die Verwendbarkeit in for-Comprehensions ist in Scala sicherlich der wichtigste Grund, warum man geeignete eigene Klassen monadisch machen sollte. Würden wir noch withFilter und foreach implementieren, könnten wir unsere Monade außerdem in weiteren for-Varianten einsetzen.

Beim diesjährigen Herbstcampus werde ich einen Einsteiger-Vortrag (OO-Vorkenntnisse reichen) zu diesem Thema halten.

Mittwoch, 9. Februar 2011

Freie Icons für Web-Oberflächen

Gute Web-Oberflächen zeichnen sich nicht nur durch durchdachte, einfach zu verstehende HTML-Formulare aus. Sie sollten auch ansprechend – "schön" – aussehen, weil die Benutzer dann garantiert lieber mit der Web-Anwendung arbeiten als mit lieblos gestalteten Seiten.

Ein wichtiger Aspekt dabei sind klar gestaltete Symbolgrafiken (Icons) – sei es für Status-Anzeigen oder für Schaltflächen. Wenn man künstlerisch nur eingeschränkt begabt ist, greift man besser auf fertige Grafiken zurück, als langweilige und schlecht zu erkennende Symbole selber zusammenzupixeln.

Seit langer Zeit nutze ich daher immer wieder gerne die famfamfam-Icons von Mark James. Die Mini- und Flaggen-Icons sind dabei komplett Public Domain, können also beliebig verwendet werden. Und auch die 1000 Silk-Icons stehen kostenfrei selbst für kommerzielle Anwendungen zur Verfügung. Der Autor bietet sie unter der Creative Commons Attribution 2.5-Lizenz an (wahlweise auch unter der Lizenz-Version 3.0) und verlangt lediglich einen Link auf seine Web-Seite.

Vielen Dank für die Blumen – äh – Icons!

Freitag, 14. Januar 2011

OpenJDK 7 für Mac OS X

Nachdem Apple vor knapp zwei Monaten Unterstützung für das OpenJDK-Projekt angekündigt hatte, wurde die Mac OS X-Portierung am Montag dieser Woche als offizielles OpenJDK-Projekt angenommen – und nur einen Tag später hat Apple den ersten offenen Code in das Projekt eingebracht. Im Wesentlichen entspricht diese erste Veröffentlichung der BSD-Portierung. Apple hat derzeit nur den Build-Prozess verändert, um ein Universal Binary mit einem .jdk-Bundle zu erzeugen, das zur neuen Java-Verzeichnisstruktur von Mac OS X passt (und entsprechend nach der Installation automatisch erkannt wird).

Jeder kann nun zum Mac OS X-Port beitragen und sich das aktuellste OpenJDK aus den Quelltexten bauen. Voraussetzung dafür sind u.a. Mac OS X ab Version 10.6.5 sowie Xcode ab Version 3.2.5. Genaueres ist im Wiki beschrieben; dort kann man auch den aktuellen Projekt-Status einsehen.

Wer das JDK 7 einfach ausprobieren möchte, ohne es selber bauen zu müssen, kann sich ein fertiges DMG von Google Code herunterladen. Der Installer für den Mac OS X-Branch enthält sowohl eine 32- als auch eine 64-Bit-JVM. Nach der schnellen und vollkommen unproblematischen Installation kann man das JDK 7 mit den üblichen Kommandos im Terminal testen:

much$ /usr/libexec/java_home --version 1.7
/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home

much$ export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
much$ $JAVA_HOME/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-b00)
OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)

much$ /usr/libexec/java_home -v 1.7 --exec java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-b00)
OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)

Für grafische Frontends wird noch kein Cocoa, sondern nur X11 unterstützt. Zum Ausprobieren der neuen Sprachfeaturen (Strings im switch etc.) reicht das aber vollkommen aus.

Wie bereits erwähnt wird das OpenJDK 7 automatisch von den Java-Einstellungen in Mac OS X erkannt. Wegen der noch unvollständigen Cocoa- bzw. Mac OS X-Integration sollte man die neue Version aber noch nicht als Default setzen, d.h. besser am Ende der Liste belassen.

Dienstag, 30. November 2010

VisualVM 1.3.x statt Eclipse TPTP?

Vor zwei Wochen wurde bekannt gegeben, dass das Eclipse-Projekt für Test- und Performance-Werkzeuge – TPTP – nach dem kommenden Update auf Version 4.7.2 (geplant für Februar 2011) nicht mehr weiterentwickelt wird.

Einer der Aspekte, die mir an TPTP gefallen haben, war das Probekit, mit dem man kleine Java-Schnipsel an bestimmte Stellen einer Java-Klasse (Methoden-Ein- und -Ausgang etc.) einweben lassen konnte, um die Klassen zur Laufzeit genauer zu untersuchen.

Ein möglicher Ersatz steht schon in den Startlöchern. Mitte des Jahres wurde VisualVM 1.3 veröffentlicht, das mittlerweile in der Version 1.3.1 verfügbar ist. Darin enthalten ist das Tracer-Plugin, mit dem sich diverse "Probes" für eine laufende Anwendung aktivieren lassen, die dann synchron untereinander auf einer Zeitleiste dargestellt werden:

Derzeit gibt es nur vordefinierte Probes für Swing, JavaFX sowie für diverse weitere Pakete der Standard-Klassenbibliothek (Collections, I/O etc.). Das Tracer-Framework soll sich aber einfach mit eigenen Probes erweitern lassen (auch wenn ich noch keinen Link zu einer aktuellen Entwickler-Dokumentation gefunden habe) – und vielleicht gibt es ja in absehbarer Zeit eine Probe zum AOP-mäßigen Einweben von kleinen Code-Stücken? Dieser Wunsch muss erlaubt sein, schließlich ist ja bald Weihnachten :-)

Ob man VisualVM separat herunterladen muss oder ob es im installierten JDK bereits enthalten ist, kann man auf der Release-Übersicht herausfinden. Das aktuelle Java 6 Update 22 bringt leider immer noch die ältere VisualVM-Version 1.2.2 mit.

Montag, 15. November 2010

Oracle bringt Java SE 7 für Mac OS X

... und Apple wird auch in Mac OS X 10.7 "Lion" noch die eigene Java SE 6-Implementation bereitstellen. Das sind kurz zusammengefasst die Ergebnisse der letzten Tage.

Nachdem es vor drei Wochen recht düster für die Zukunft von Java auf Mac OS X ausgesehen hatte, weil Apple die eigene Java-Implementierung abgekündigt, aber keinen Ersatz als Perspektive geboten hatte, sieht es nun so aus, als ob wir genau die Lösung bekommen, die von vielen favorisiert wurde: Apple bringt die meisten Teile seiner Java-Implementation als Open Source in das OpenJDK-Projekt ein, und Oracle wird daraus – beginnend mit Java SE 7 – offizielle Java-Releases für Mac OS X bauen.

Es ist noch nicht ganz klar, wann Java SE 7 für Mac OS X verfügbar sein wird und wie die Quelltexte im Detail zur Verfügung gestellt werden. Aber die Zukunft für Java auf Mac OS X dürfte damit sichergestellt sein.

Nebenbei hat Apple in der Pressemitteilung bekannt gegeben, dass auch das im nächsten Jahr erscheinende Mac OS X 10.7 "Lion" noch die eigene Java SE 6-Implementation enthalten wird, so dass für die Übergangszeit auf Oracles Mac-Java-Implementation eine klare Perspektive besteht.

Na also. Warum denn nicht gleich so?

Donnerstag, 11. November 2010

Scala 2.8.1

Vorgestern wurde mit nur wenigen Tagen Verspätung Scala 2.8.1 freigegeben.

Neben zahlreichen Bugfixes enthält das Update vor allem eine verbesserte Version von Scaladoc. Ein Ergebnis dieses Werkzeugs ist beispielsweise die API-Dokumentation der Scala-Standard-Bibliothek.

Scala 2.8.1 ist vollständig binärkompatibel mit der vorangegangenen Version 2.8.0 (was davor durchaus nicht selbstverständlich war, nun aber erklärtes Ziel zur Stabilisierung der Softwareentwicklung mit Scala ist).

Seit heute liegt außerdem die Scala IDE für Eclipse in einer aktualisierten Version vor. Durch die Binärkompatibilität der Scala 2.8.x-Versionen kann man erstmalig die neueste Scala IDE einsetzen und damit bestehende Projekte wahlweise weiterhin mit Scala 2.8.0 übersetzen, bis eine Umstellung auf 2.8.1 geeignet erscheint.

Donnerstag, 21. Oktober 2010

@Deprecated Java für Mac OS X

Es musste ja irgendwann passieren: Nachdem schon Flash in Ungnade gefallen war, hat Apple nun keine Lust mehr auf Java...

In den Release Notes zum gestern erschienenen "Java for Mac OS X 10.6 Update 3", das Java SE 6 auf Version 1.6.0_22 aktualisiert, findet sich an prominenter Stelle der Hinweis, dass Apples eigene Java-Implementation ab sofort als veraltete Technologie gilt und in künftigen Mac OS X-Versionen fehlen könnte.

Auch wenn direkt unter dieser Ankündigung beschrieben ist, dass und wie mit diesem Update Java Virtual Machines (JVMs) anderer Hersteller leichter ins System eingebunden werden können (was ich in einem folgenden Blog-Eintrag beschreibe) und auch die exakte Wortwahl der Apple-Java-Abkündigung fast impliziert, dass ein anderer Hersteller in die Bresche springen wird – gesichert ist dies nicht.

Bis also Oracle oder IBM oder irgendwer sonst (Google?) offiziell bekannt gibt, dass sie eine Java-Implementierung für Mac OS X anbieten werden, müssen wir leider davon ausgehen, dass Java auf dem Mac tot ist.

Dies dürfte extrem negative Auswirkungen auf den Einsatz von Macs in Unternehmen haben, da dort Java-Anwendungen häufig in der einen oder anderen Form benötigt werden. Ebenso wird der Mac damit für Bildungseinrichtungen und insbesondere Hochschulen uninteressant, da dort oft Java als Lehrsprache eingesetzt wird. Und die Java-Entwickler-Gemeinde, in der sich (zumindest gefühlt) überdurchschnittlich viele Mac-Anwender befinden, wird sich neue Hardware-Investitionen und Upgrades auf kommende Mac OS X-Versionen gut überlegen.

Zu hoffen bleibt, dass die Ankündigung nur eine Kommunikations-Katastrophe mit schlechtem Timing war. Andererseite werden, sofern man diversen Internet-Quellen glauben darf, Java-Anwendungen für den kommende "Mac App Store" nicht akzeptiert werden, da es sich um veraltete Technologie handelt. Und das sieht dann schon eher nach Absicht aus...

Abwarten und Kaffee trinken.