[erlang-questions] Auto generated functions
John Webb
jwebb@REDACTED
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
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
More information about the erlang-questions
mailing list