[erlang-questions] escript question

Chris Hicks <>
Mon Sep 19 17:33:25 CEST 2011


Thank you everyone for responding, the answers have been very informative. For my purposes, the method Ulf proposed looks to be the the optimal solution. It's going to make things so much easier than I had anticipated and now I just want this grind to end so I can get back to the fun stuff of writing my own code!

> Subject: Re: [erlang-questions] escript question
> From: 
> Date: Mon, 19 Sep 2011 16:37:53 +0200
> CC: ; 
> To: 
> 
> 
> 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
> 
> 
> 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110919/e0a10b4b/attachment.html>


More information about the erlang-questions mailing list