[erlang-questions] Auto generated functions

John Webb <>
Wed Feb 6 12:58:09 CET 2008


Hi Attila,

How about the following for fun? (sorry, bad pun)...

%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(y).
-compile([export_all]).
-import(lists,[map/2,seq/2,foldl/3,reverse/1,append/1]).

y(F) when is_function(F) ->
     {arity,Arity} = erlang:fun_info(F(F),arity),
     Ps = mk_params(Arity),
     Func = append(["fun(H)->F(fun(",Ps,")->(H(H))(",Ps,")end)end."]),
     {ok,Tokens,_EndLine} = erl_scan:string(Func),
     {ok,[Expr]} = erl_parse:parse_exprs(Tokens),
     Bindings = erl_eval:add_binding('F',F,erl_eval:new_bindings()),
     {value,G,_NewBindings} = erl_eval:expr(Expr,Bindings),
     G(G);
	
y(_) -> erlang:error(not_function).

%% make a string of prameters "P1,P2...PN"
mk_params(0) -> "";
mk_params(N) ->
     MkPs = fun(X) -> [$P|integer_to_list(X)] end,
     [P1|Ps] = map(MkPs, lists:seq(1,N)),
     append(reverse(foldl(fun(P,Acc) -> [P,","|Acc] end, [P1], Ps))).

%% Examples
dots() ->
     (y:y(fun(F) -> fun() -> io:format("."),F() end end))().
			
len(I) when is_list(I) ->
     (y:y(fun(F) -> fun([],N) -> N; ([_|R],N) -> F(R,N+1) end end))(I, 
0).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

On Feb 5, 2008, at 7:39 AM, Attila Babo wrote:

> I wrote a simple Y combinator to deal with tail-recursive anonymous
> functions. There are several showcase implementations for Erlang
> already, but for practical purposes you need to deal with arity. Here
> is my code with examples, I'm looking for a way to avoid this
> boilerplate code. For practical reasons it's OK to generate it up to a
> point by hand or use a single tuple as a parameter, but I'm looking
> for "nicer" solution. Any suggestions?
>
> Attila
>
> %% Y Combinator
>
> y(F) ->
> 	{arity, Arity} = erlang:fun_info(F(F), arity),
> 	G = case Arity of
> 		0 -> fun(H) -> F(fun() -> (H(H))() end) end;
> 		1 -> fun(H) -> F(fun(A) -> (H(H))(A) end) end;
> 		2 -> fun(H) -> F(fun(A, B) -> (H(H))(A, B) end) end;
> 		3 -> fun(H) -> F(fun(A, B, C) -> (H(H))(A, B, C) end) end;
> 		4 -> fun(H) -> F(fun(A, B, C, D) -> (H(H))(A, B, C, D) end) end;
> 		5 -> fun(H) -> F(fun(A, B, C, D, E) -> (H(H))(A, B, C, D, E) end)  
> end
> 	end,
> 	G(G).
>
> %% Examples
>
> dots() ->
> 	(y:y(fun(F) -> fun() -> io:fwrite("."), F() end end))().
>
> len(I) when is_list(I) ->
> 	(y(fun(F) -> fun(X, N) -> case X of [] -> N; [_|R] -> F(R, N+1) end
> end end))(I, 0).
>
> %% End of code
>
> http://www.erlang.org/ml-archive/erlang-questions/200301/msg00053.html
> http://bc.tech.coop/blog/070611.html
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list