I have made some improvements to ct_expand
It used to be that it could only expand simple expressions. Now, it can handle calls to local functions, which are then interpreted. It also handles things like fun foo/1, by fetching the function definition and inlining it as a "regular" fun.
Unfortunately, I failed to bring it up to the level that I aspired to, namely to improve some of Tony Rogvall's code (not yet released). The problem there was that his code called functions that stored funs in a dict. Doing this at compile-time, the funs would - at best - end up being interpreted. As it was, I didn't even get that far, since funs created by one interpreted function couldn't be passed as arguments to another interpreted function.
The culprits are erl_eval, which unconditionally converts the return values into regular terms, and erl_parse:abstract/1, which fails to create abstract expressions from funs. Thus, the conversion to regular terms is not reversible in this case.
I added a trace option, so that it would be easier to debug complex expansions:
Eshell V5.8.4 (abort with ^G)
1> c(ct_expand_test,[{ct_expand_trace,[r]}]).
ct_expand (27): call zip([1,2],[a,b])
ct_expand (27): call zip([2],[b])
ct_expand (27): call zip([],[])
ct_expand (27): returned from zip/2: []
ct_expand (27): returned from zip/2: [{{2},{b}}]
ct_expand (27): returned from zip/2: [{{1},{a}},{{2},{b}}]
Pretty-printed in "./ct_expand_test.xfm"
(Not perfect: the functions that were inlined don't show up in the trace.)
I welcome ideas on how to get around the above limitation with reasonable effort (I know I could make my own evaluator, but that seems like too high a price).
Oh, the error reporting from parse_trans has been greatly improved. It now detects parse_errors immediately, and aborts the transform, and also reports transform errors in a less noisy way. Let me know if you have issues with it.
BR,
Ulf W