O Mozilla Sweet.js permite enriquecer código JavaScript por meio do uso de macros. Com isso desenvolvedores pode customizar a sintaxe do JavaScript para o seu estilo, ou estendê-la para criar uma linguagem de domínio específico.
O Sweet.js possibilita a definição de "macros higiênicas", inspiradas em Scheme e Rust, com o uso da palavra-chave macro. Veja um exemplo simples, que substitui function por def:
macro def { case $name:ident $params $body => { function $name $params $body } }
Com isso, funções podem ser definidas usando def:
def add (a, b) { return a + b; }
Um exemplo mais complexo é a introdução da palavra chave class:
macro class { case $className:ident { constructor $constParam $constBody $($methodName:ident $methodParam $methodBody) ... } => { function $className $constParam $constBody $($className.prototype.$methodName = function $methodName $methodParam $methodBody; ) ... } }
Aqui está um exemplo de uso de class:
class Person { constructor(name) { this.name = name; } say(msg) { console.log(this.name + " says: " + msg); } } var bob = new Person("Bob"); bob.say("Macros are sweet!");
Outros exemplos de macros estão disponíveis no wiki do Mozilla e do Sweet.js. No GitHub, pode ser encontrado o código-fonte, sob licença BSD.
Os arquivos Sweet.js contêm macros que são compiladas pelo sjs em arquivos JavaScript puros, sem nenhuma sintaxe além do JavaScript. O require-sweet traz um AMD loader; já o SweetJS gem compila arquivos Sweet.js para Ruby.
Atualmente, o Sweet.js suporta apenas a definição declarativa de macros, mas de acordo com Tim Disney, da Mozilla Research, existem planos para suportar definições imperativas no futuro. Isso significa que macros poderão conter código JavaScript arbitrário para execução em tempo de compilação.