A code transformation toolkit abusing some forgotten Erlang syntax.
Erlang
Latest commit 07b1254 May 22, 2012 @nox Rename henshin_suite:bgen/1
Failed to load latest commit information.
src
test
.gitignore Properly ignore BEAM test files May 13, 2012
Makefile
README.md
cover.spec
rebar.config

README.md

Henshin!

From Wikipedia:

Henshin (変身 henshin) is the Japanese word for "transformation," literally meaning, "to change or transform the body."

What is it?

Henshin is a parse transform using some forgotten syntax rules of Erlang to implement compile-time function calls, rules:

rule -> rule_clauses : build_rule('$1').

rule_clauses -> rule_clause : ['$1'].
rule_clauses -> rule_clause ';' rule_clauses : ['$1'|'$3'].

rule_clause -> atom clause_args clause_guard rule_body :
    {clause,?line('$1'),element(3, '$1'),'$2','$3','$4'}.

rule_body -> ':-' lc_exprs: '$2'.

These rules used to be used by Mnemosyne, the ancestor of QLC; you can find some references to it in erl_lint:

format_error({mnemosyne, What}) ->
    "mnemosyne " ++ What ++ ", missing transformation".

Henshin transforms every rule to an equivalent exported function, rejecting any binary generator and replacing any list generator with a match and a call to erl_syntax:concrete/1. It also exports a new function Mod:henshin_rules/0 which returns the list of rules defined by the module.

Let example be the following module:

-module(example).
-compile({parse_transform, henshin_module}).

add(XAST, YAST) :-
    X <- XAST,
    Y <- YAST,
    erl_syntax:abstract(X + Y).

This hypothetical module would be transformed to:

-module(example).
-export([henshin_rules/0, add/2]).

henshin_rules() ->
    [{add, 2}].

add(XAST, YAST) ->
    X = erl_syntax:concrete(XAST),
    Y = erl_syntax:concrete(YAST),
    erl_syntax:abstract(X + Y).

What is there to do?

  • Write better documentation.
  • Actually call the transformation rules used in modules thrown at henshin.