expr == Add(Value(var v1), Value(var v2)) <=> var foo = new $Foo$(); (expr as Add).deconstructor(foo::args1, foo::args2); (foo.args1 as Value).deconstructor(foo:args3); (foo args2 as Value).deconstructor(foo::args4); action(args3, args4); /* runtime */ class $Foo$ { Expr arg1; Expr arg2; int arg3; int arg4; } args1 args2 args3 args4