[erlang-questions] Nested for-loops, there has to be a better way to do this

Zoltan Lajos Kis <>
Wed Jul 29 20:57:55 CEST 2009


And what do I gain using this for function compared to simply writing an 
"ad-hoc" recursive function whenever needed ?

for(
  fun(I) -> body(I) end,
  0,
  fun(I) -> I < 20 end,
  fun(I) -> I + 2 end
)

vs.

my_fun(20) -> ok;
my_fun(I) -> body(I), my_fun(I+2).

Z.

PS: seriously, is this what the original question was getting at?


Brentley Jones wrote:
> This is my take on it:
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> -module(for).
>
> -export([for/4, test_1/0, test_2/0]).
>
> for(BodyFun, Acc, ConditionFun, StepFun) ->
>   Done = ConditionFun(Acc),
>   if Done == false ->
>        Acc;
>      true ->
>        NewAcc = BodyFun(Acc),
>        LastAcc = StepFun(NewAcc),
>        for(BodyFun, LastAcc, ConditionFun, StepFun)
>   end.
>
> test_1() ->
>   Body = fun(I) ->
>            io:format("i=~p~n", [I]),
>            I
>          end,
>   for(Body, 0, fun(I) -> I < 10 end, fun(I) -> I + 1 end),
>   ok.
>
> test_2() ->
>   CondFun = fun(X) -> X < 5 end,
>   StepFun = fun(X) -> X + 1 end,
>   BodyInner = fun(J) ->
>                 io:format("~p", [J]),
>                 J
>               end,
>   BodyOuter = fun(I) ->
>                 for(BodyInner, 0, CondFun, StepFun),
>                 io:format("~n"),
>                 I
>              end,
>  for(BodyOuter, 0, CondFun, StepFun),
>  ok.
>
>
> %%%%% Output:
> 2> for:test_2().
> 01234
> 01234
> 01234
> 01234
> 01234
> ok
> 3> for:test_1().
> i=0
> i=1
> i=2
> i=3
> i=4
> i=5
> i=6
> i=7
> i=8
> i=9
> ok
>
> On Jul 29, 2009, at 11:25 AM, Cláudio Amaral wrote:
>
>> Used some of previous code...
>>
>> I tried to make a polymorphic function and coupled an example... this 
>> ended a little bit confusing, but as you can see, it makes all 
>> iterations (check the printed indexes, reversed).
>>
>> The body behaviour is the tricky stuff to code, but in exchange it is 
>> modular...
>>
>> Since I am an erlang newb, please correct anything you see as bad 
>> programming
>>
>> Cláudio
>>
>> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>> -module(for_loop).
>>
>> -export([for/4, show/0]).
>>
>>
>> for(BodyFunc, BodyArgs, StepFunc, {First, Last}) ->
>>   for_(BodyFunc, BodyArgs, StepFunc, {First, Last}, First).
>>
>>
>> for_(BodyFunc, BodyArgs, StepFunc, {_, LastTerm}, LastTerm) ->
>>   BodyFunc(BodyArgs, LastTerm);
>> for_(BodyFunc, BodyArgs, StepFunc, LimitsTuple, IndexTerm) ->
>>   NextArgs = BodyFunc(BodyArgs, IndexTerm),
>>   for_(BodyFunc, NextArgs, StepFunc, LimitsTuple, StepFunc(IndexTerm)).
>>
>>
>> show() ->
>>   for( fun(A1,A2)->body1(A1,A2) end,
>>    [{0,3}, [{1,0}], [{3,6},{1,2}]],
>>    fun(I) -> I+1 end,
>>    {0,3}
>>   ).
>>
>>
>> body1([ LimitsTuple, [{NLoop,II}|Rest], []],I) ->
>>   print([ I | lists:map(fun({_,Snd}) -> Snd end, Rest) ]),
>>   IndexInfo = [{NLoop,II}|Rest],
>>   [ LimitsTuple, IndexInfo, []];
>> body1([ LimitsTuple, [{NLoop,II}|Rest], [{X1,Xn}|XS]],I) ->
>>   for( fun (A1,A2)->body1(A1,A2) end,
>>    [ LimitsTuple, [ {NLoop+1,II}, {NLoop,I} | Rest ], XS],
>>    fun(K) -> K+1 end,
>>    {X1,Xn}
>>   ),
>>   IndexInfo = [{NLoop,II}|Rest],
>>   [ LimitsTuple, IndexInfo, [{X1,Xn}|XS] ].
>>
>> print(Numbers) ->
>>   io:format("indexes ~p~n", [Numbers]).
>>
>>
>>  escreveu:
>>> Regards,
>>> Z.
>>>
>>>
>>>> I was playing around with the idea of implementing a nested for-loop
>>>> like construct (I will concede, they are evil, but at rare times,
>>>> necessary.)  In non-functional programming languages, they are trivial
>>>> to do.  However, this has proved to be one of those simple things that
>>>> are a pain in the neck for me.  The idea was to be able to pass in a
>>>> list [5, 5, 10] (for example) and go through it all like 3 dimensional
>>>> array.  The below illustration is far from elegant (it's almost 23:00
>>>> where I live and need to go to work tomorrow early, so no time to come
>>>> up with something more sane :) ), but is there as an inquisitive
>>>> exercise.  Now, in my opinion, this implementation sucks (first time
>>>> I've ever gave such a problem a shot in Erlang.)
>>>>
>>>> Is there a better way to do this?  Anyone would like to demonstrate
>>>> it?
>>>>
>>>> Note: I've tested this code with the lists [2, 4] and [2, 4, 5].
>>>>
>>>> Compiled with:
>>>> Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.6.5
>>>>
>>>> My code:
>>>> ======================================
>>>> -module(loopWrapper).
>>>>
>>>> -export([runLoop/1]).
>>>>
>>>> runLoop(List) ->
>>>>  [FirstVal | RestList] = List,
>>>>  NextVal = FirstVal - 1,
>>>>  if (length(RestList) > 0) and (FirstVal > 0) ->
>>>>    io:format("~B~n~n", [FirstVal]),
>>>>    runLoop(RestList),
>>>>    io:format("~n~n"),
>>>>    runLoop([NextVal | RestList]);
>>>>  FirstVal > 0 ->
>>>>    io:format("~B", [FirstVal]),
>>>>    runLoop([NextVal]);
>>>>  true ->
>>>>    null
>>>>  end.
>>>>
>>>> ________________________________________________________________
>>>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>>>> erlang-questions (at) erlang.org
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>> ________________________________________________________________
>>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>>> erlang-questions (at) erlang.org
>>>
>>>
>>
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>



More information about the erlang-questions mailing list