[erlang-questions] escript question
Ulf Wiger
ulf.wiger@REDACTED
Mon Sep 19 16:37:53 CEST 2011
On 19 Sep 2011, at 16:22, Garrett Smith wrote:
>
> E.g. store a function in your database that increments a number by 1:
>
> FStr = "fun(N) -> N + 1 end."
>
> When you're ready to use it:
>
> {ok, Tokens, _} = erl_scan:string(FStr),
> {ok, Exprs} = erl_parse:parse_exprs(Tokens),
> {value, F, []} = erl_eval:exprs(Exprs, []).
>
> Now:
>
> 2 = F(1).
I'd go one step further and store Exprs in the database directly, eliminating the parsing step.
To avoid having to learn the abstract form representation, you can use parse_trans_codegen.erl.
http://github.com/esl/parse_trans
Example:
-module(storefun).
-export([f/1]).
-include_lib("parse_trans/include/codegen.hrl").
f(1) ->
codegen:exprs(fun() ->
fun(N) ->
N + 1
end
end).
Compiling this with parse_trans/ebin in the path:
Eshell V5.8.4 (abort with ^G)
1> c(storefun).
{ok,storefun}
2> storefun:f(1).
[{'fun',8,
{clauses,[{clause,8,
[{var,8,'N'}],
[],
[{op,9,'+',{var,9,'N'},{integer,9,1}}]}]}}]
3> {value, F, []} = erl_eval:exprs(v(2),[]).
{value,#Fun<erl_eval.6.13229925>,[]}
4> F(2).
3
That is, codegen:exprs(fun() -> <Exprs> end) returns the abstract form list for <Exprs>. If you want the expressions to inherit variables, you can do that by defining those variables as arguments to the enclosing fun:
f(2) ->
codegen:exprs(fun(X) ->
fun(N) ->
N + X
end
end).
5> c(storefun).
{ok,storefun}
6> storefun:f(2).
[{'fun',14,
{clauses,[{clause,14,
[{var,14,'N'}],
[],
[{op,15,'+',{var,15,'N'},{var,15,'X'}}]}]}}]
7> {value, F2, []} = erl_eval:exprs(v(6),[]).
** exception error: {unbound_var,'X'}
8> {value, F2, []} = erl_eval:exprs(v(6),[{'X',17}]).
** exception error: no match of right hand side value
{value,#Fun<erl_eval.6.13229925>,[{'X',17}]}
9> {value, F2, _} = erl_eval:exprs(v(6),[{'X',17}]).
{value,#Fun<erl_eval.6.13229925>,[{'X',17}]}
10> F2(3).
20
The abstract code is generated at compile-time, so there is very little overhead.
BR,
Ulf W
Ulf Wiger, CTO, Erlang Solutions, Ltd.
http://erlang-solutions.com
More information about the erlang-questions
mailing list