Archive for April, 2006

Nicht Offensichtliches über JavaScript - Eins

Tuesday, April 11th, 2006

In letzter Zeit ist es sehr still geworden in und um mein(em) Weblog. Gründe dafür gibt es mannigfaltige: Arbeiten (Programmieren), Klausuren, Semesterferien, Faulheit, Suchtspiele und so weiter und so fort. Zeit, dass sich das ändert. Im Strudel des Semesterneubeginns werden meine wachenden Stunden länger und damit auch die Zeit, die ich für Dinge wie mein Weblog verden kann.

In der Liste meiner vergangenen Aktivitäten steht ,,Programmieren”. Aus dem dort angebauten Erfahrungsschatz werde ich in den folgenden Wochen mein Blog füllen und fange gleich heute an, sonst verläuft das gleich alles im Sande. Vorwärts, also!

JavaScript ,,Back in Game”

Durch den Trend zu AJAX im Web 2.0 bekommt AJAX wieder eine wichtigere Stellung und entschlüpft seiner ,,hässliches Entlein” Stellung - Grund genug, dass auch ich dieser Programmiersprache ein paar Zeilen widme. (Wer eine kritischen Kommentar zum Hype ,,Web 2.0” und ,,AJAX” lesen möchte, dem sei Paul Grahams Kommentar ans Herz gelegt. Ich benutze die Worte hier so oft um Leser anzulo… ähm damit sie es besser verstehen, weil jeder diese Worte benutzt - mir ist klar, dass die Web 2.0 Blase genau so, wie die ,,Dot Com” Blase zerplatzen kann. Aber hey - ,,Dot Com” war doch recht spaßig, oder nicht?)

Folgende kleine Erklärung soll uns zu AJAX erst einmal genügen: Bei AJAX geht es haupsächlich darum, dass der Browser mit dem Server kommuniziert, ohne dass die Seite für den Benutzer sichtbar neu geladen wird. Das ganze geschieht mit Javascript und einem Objekt (bzw. eher wenigr auch einer ,,Klasse”, mehr dazu später) namens XmlHttpRequest. Diese wurde von Microsoft eingeführt und Klassen äquivalenter Funktionalität sind mittlerweile in allen großen Browsern verfügbar. Mit AJAX kann man nette Dinge machen, wie etwa Google Suggest oder Google Maps. Letztendlich ist AJAX jedoch nichts anderes als elegant eingesetztes Javascript, weswegen Paul Graham den Begriff sehr passend kommentierte: ,,Basically, what ,Ajax’ means is ,Javascript now works.”’.

Zurück zum heutigen Thema

Lassen wir nun die ganze Blase um Javascript, AJAX, XML, Web 2.0, überbezahlte Marketing-Leute und Manager hinter uns und wenden wir uns dem zu, was Javascript schon lange konnte, aber wahrscheinlich kaum einer wusste: Javascript hat weniger mit Java gemein als mit funktionalen Sprachen wie Lisp.

Das hätten wir geklärt und wir können aufhören. Nein? Ihr wollt wissen, was ich damit meine? Warum das zum Gutdünken der Programmierer ist? Wie ich ein funktionales Feature von Javascript schon zig mal einsetzte? Gut, überredet.

Funktionen als Werte

Ein tolles Feature von Javascript ist, dass Funktionen quasi Typen erster Ordnung sind. Das bedeutet, dass Funktionen genau so als Wert von Variablen gespeichert werden können wie auch Ganzzahlen oder Zeichenketten. Das ist anders als bei Java, wo Methoden (Objekt- bzw. Klassenfunktionen) an die Klassen oder Objekte gebunden sind, zu denen sie gehören.

So kann man etwa folgendes machen:

function sqr(x) {
  return x*x;
}

var c = sqr;  // => c ist Alias zu sqr
var d = c(4); // => d == 16

Das ist natürlich nur der Anfang. Jeder Informatikstudent, der eine funktionale Sprache erlernen musste, kennt bestimmt die map Funktion oder eine äquivalente Funktion. Die Funktion erwartet eine Liste list und eine Funktion f (als Wert, das geht in Java nicht und in C zwar mit Funktionszeigern aber nicht typsicher). map gibt dann eine Liste result zurück, für die gilt: result[i] = f(list[i]). Definieren wir einfach einmal map in Javascript:

function map(list, f) {
  var result = new Array();

  for (var i = 0; i < list.length; i++)
    result.push(f(list[i]));

  return result;
}

Anonyme Funktionen

Dass Funktionen Typen erster Ordnung sind wird dadurch noch netter, dass man auch anonyme Funktionen definieren kann (,,Lambdas” sozusagen):

var sqr = function(x){ return x * x; }

Damit können wir nun folgendes anstellen:

var list = [ 1, 2, 3, 4, 5, 6 ];
var squares = map(list, sqr);
var sqrs_of_sqrs = map(list, function(x) { return sqr(sqr(x)); })

Das ganze reicht natürlich nicht ganz an die Sprachfeatures von Haskell heran (dem Beweis dafür, dass ,,Design by Commitee” zu einer aufgeblähten Syntax führt), ist aber doch ganz nett. Zum Beispiel für Routinen zur Ereignisbehandlung.

Benutzen wir zum Beispiel Prototype für unsere revolutionäre, neue AJAX Anwendung, dann können wir zum Beispiel wie folgt auf die Nachricht onLoad des document Objektes (das Dokument wurde vollständig geladen) reagieren:

Event.observe(document, 'load',
  function() { alert('Dokument wurde geladen'); });

Oder wir kümmern uns um das Ergebnis eines asynchronen Aufrufes des Servers:

var req = new Ajax.Request(
  '/var/foo',
  {
    onFailure : function() { alert('Fehler!'); },
    onSuccess : function() { alert('Das hat funktioniert'); }
  });

Wie wir sehen können, ist es sehr nützlich, wenn Funktionen Typen erster Ordnung sind. Wenn Java etwa diese Fähigkeit hätte, dann wäre der Ereignisbehandlungscode für diese Sprache sehr viel eleganter. C# hat anonyme Funktionen und benutzt es an eben dieser Stelle.