<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>Never mind - problem solved. Funs from erl_eval _can_ actually be abstracted using erl_eval:fun_data/1.</div><div><br></div><div>Too bad erl_parse:abstract/1 isn't aware of that…</div><div><br></div><div>As it happens, since the resulting data structure is in abstract form, funs in a dict will be compiled eventually anyway. :)</div><div><br></div><div>I leave it to you all to find remaining limitations or exciting uses.</div><div><br></div><div>BR,</div><div>Ulf W</div><br><div><div>On 28 Jan 2012, at 17:09, Ulf Wiger wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>I have made some improvements to ct_expand</div><div><br></div><div><a href="https://github.com/uwiger/parse_trans/blob/master/doc/ct_expand.md">https://github.com/uwiger/parse_trans/blob/master/doc/ct_expand.md</a></div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>In <a href="https://github.com/uwiger/parse_trans/blob/master/examples/ct_expand_test.erl#L15">https://github.com/uwiger/parse_trans/blob/master/examples/ct_expand_test.erl#L15</a>, an example is given of what kind of things can now be done with ct_expand.</div><div><br></div><div>I added a trace option, so that it would be easier to debug complex expansions:</div><div><br></div><div><div><div>Eshell V5.8.4  (abort with ^G)</div><div>1> c(ct_expand_test,[{ct_expand_trace,[r]}]).</div><div>ct_expand (27): call zip([1,2],[a,b])</div><div>ct_expand (27): call zip([2],[b])</div><div>ct_expand (27): call zip([],[])</div><div>ct_expand (27): returned from zip/2: []</div><div>ct_expand (27): returned from zip/2: [{{2},{b}}]</div><div>ct_expand (27): returned from zip/2: [{{1},{a}},{{2},{b}}]</div><div>Pretty-printed in "./ct_expand_test.xfm"</div></div></div><div><br></div><div>(Not perfect: the functions that were inlined don't show up in the trace.)</div><div><br></div><div>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).</div><div><br></div><div>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.</div><div><br></div><div>BR,</div><div>Ulf W</div><div><br></div><div><br></div></div>_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>http://erlang.org/mailman/listinfo/erlang-questions<br></blockquote></div><br></body></html>