Süßwaren für JavaScript-Entwickler
Kommentare

Wiederholungen in Makros
Auf den ersten Blick wirkt dieser Ansatz schon einmal nicht schlecht. Ein kleines Problem existiert jedoch noch: Momentan findet nur eine Verarbeitung von class-Blöcken statt,

Wiederholungen in Makros

Auf den ersten Blick wirkt dieser Ansatz schon einmal nicht schlecht. Ein kleines Problem existiert jedoch noch: Momentan findet nur eine Verarbeitung von class-Blöcken statt, die genau eine Methode spezifizieren. Was jedoch, wenn wie in Listing 6 zwei Methoden definiert werden? Eine mögliche Lösung wäre die Zeile, die für das Methoden-Matching zuständig ist, zu kopieren und die Pattern entsprechend in $methodName2, $methodParams2 usw. umzubenennen. Natürlich wäre das für diesen speziellen Fall möglich, jedoch würde es das generelle Problem nicht lösen. Die Aufgabe war es, eine beliebige Anzahl von Methoden zu unterstützen. Aber auch dies ist kein Problem für Sweet.js.

Die Makrosprache erlaubt die Angabe von Wiederholungen durch die Verwendung von drei Punkten (…). Diese beziehen sich immer auf das direkt zuvor genannte Pattern:

$methodName:ident $methodParams $methodBody ...

Halt! Wenn sich die Wiederholung auf das zuvor genannte Pattern bezieht, dann würde es hier also lediglich Auswirkungen auf $methodBody besitzen. Es muss sich aber auf den Zusammenschluss aller drei Pattern beziehen. Für eben diesen Zweck besitzt Sweet.js die Möglichkeit, Gruppen von Pattern zu bilden. Diese werden in ein Konstrukt aus einem Dollarzeichen und Klammern eingeschlossen ($(…)). Angewendet auf das Klassenmakro sieht das Ganze wie folgt aus:

macro class {
  case $className:ident {
    constructor $con  structorParams $constructorBody
    $($methodName:ident $methodParams $methodBody) ...
  } => {}
}

Das Pattern für das Makro ist vollständig. Wird es derart auf Listing 6 losgelassen, kann eine korrekte Makrotransformation ausgeführt werden. Da das Transformationsergebnis aber hier noch leer ist, bedeutet dies, dass der class-Block bisher komplett entfernt wird. Listing 7 zeigt das vollständige Makro, um aus den gegebenen Informationen validen JavaScript-Code zu generieren.

Listing 7
macro class {
    case $className:ident {
        constructor $constructorParams $constructorBody
        $($methodName:ident $methodParams $methodBody) ...
    } => {
        var $className = (function(){
            var $className = function $constructorParams $constructorBody;
            $($className.prototype.$methodName = function $methodParams $methodBody;) ...
            return $className;
        })();
    }
}

Letztlich wird mithilfe der zuvor definierten Pattern lediglich der übliche, von vielen als unleserlich empfundene Quelltext erzeugt, der den zur Definition passenden Prototypen bereitstellt. Das Ergebnis nach erfolgter Transformation ist der Vollständigkeit halber in Listing 8 verfügbar.

Listing 8
var Greeter = function () {
        var Greeter$6 = function (name$2) {
            this.name = name$2;
        };
        Greeter$6.prototype.greet = function () {
            console.log('Hello ' + this.name + '!');
        };
        Greeter$6.prototype.getName = function () {
            return this.name;
        };
        return Greeter$6;
    }();
var world = new Greeter('World');
world.greet();
Lesbarer durch Makros

Wie das vorherige Beispiel zeigt, eignen sich Makros sehr gut, um einige Ecken und Kanten der Sprache auszubügeln, ohne auf Features oder Flexibilität verzichten zu müssen. Konsequent weiter gedacht, könnte man das demonstrierte Makro noch um Funktionalität für Instanzeigenschaften und Vererbung erweitern. Listing 9 zeigt, wie etwas Derartiges aussehen könnte.

Listing 9
macro class {
    case $className:ident extends $parentName:ident {
        $(property $propertyName:ident = $propertyAssignment) (,) ...
        constructor $constructorParams { $constructorBody ... }
        $($methodName:ident $methodParams $methodBody) ... } => {
        var $className = (function() {
            var $className = function $constructorParams {
               $(this.$propertyName = $propertyAssignment;) ...
                $constructorBody ...
            };
            __extend($className, $parentName);
            $($className.prototype.$methodName = function $methodParams $methodBody;) ...
            return $className;
        })();
    }
}

if (typeof __extend === "undefined") {
    __extend = function(child, parent) {
        var empty = function() {};
        empty.prototype = parent.prototype;
        child.prototype = new empty();
        child.prototype.__super__ = parent;
    }
}

class Tux extends Animal {
    property type = "Penguin"

    constructor(name) {
        this.__super__.call(this, name);
    }

    getType() {
        return this.type;
    }
}

Natürlich ist dies nur eine von vielen Umsetzungsmöglichkeiten. Hier zeigt sich die Schönheit von Makros: Gefällt einem etwas nicht, so ist es leicht, es den eigenen Wünschen anzupassen.

Liegt hier die Zukunft?

Hygienic Macros sind eine elegante Art, JavaScript um Features zu erweitern, die bisher fehlten. Sie ermöglichen nahezu jedem Entwickler, nach kurzer Einarbeitungszeit Spracherweiterungen zu schreiben, ohne sich zunächst mit Parser-Theorie, Abstract-Syntax-Trees und der damit verbundenen Komplexität auseinandersetzen zu müssen. Sweet.js befindet sich noch in einem sehr frühen Stadium, und trotzdem lassen sich damit bereits jetzt beeindruckende Ergebnisse erzielen. Es bleibt spannend zu beobachten, wie sich dieses Projekt in Zukunft entwickelt und welche Ideen andere Entwickler mittels Makros in die Tat umsetzen. Dies wird nicht das letzte Mal gewesen sein, dass die JavaScript-Community von Sweet.js gehört hat. Harren wir also gespannt und neugierig der Dinge, die da kommen.

Jakob Westhoff ist langjähriger JavaScript und PHP Professional. In seiner Tätigkeit als Consultant und Trainer bei der Qafoo GmbH unterstützt er Firmen dabei, hochqualitative Applikationen zu entwerfen und zu entwickeln. In seiner Freizeit beteiligt Jakob sich an diversen Open-Source-Projekten und ist begeisterter Pilot von Modellhelikoptern.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -