views:

93

answers:

4

Playing with Erlang, I've got a process-looping function like:

process_loop(...A long list of parameters here...) ->
    receive
        ...Message processing logic involving the function parameters...
    end,
    process_loop(...Same long list of parameters...)
end.

It looks quite ugly, so I tried a refactoring like that:

process_loop(...A long list of parameters...) ->
    Loop = fun() ->
        receive
            ...Message processing logic...
        end,
        Loop()
    end,
    Loop()
end.

But it turned out to be incorrect, as Loop variable is unbound inside the Loop function. So, I've arranged a workaround:

process_loop(...A long list of parameters...) ->
    Loop = fun(Next) ->
        receive
            ...Message processing logic...
        end,
        Next(Next)
    end,
    Loop(Loop)
end.

I have two questions:

  1. Is there a way to achieve the idea of snippet #2, but without such "Next(Next)" workarounds?

  2. Do snippets #1 and #3 differ significantly in terms of performance, or they're equivalent?

+2  A: 
  1. You might use tuples/records as named parameters instead of passing lots of parameters. You can just reuse the single parameter that the function is going to take.

  2. I guess (but I' not sure) that this syntax isn't supported by proper tail-recursion. If you refactor to use a single parameter I think that you will be again on the right track.

codecaster
+2  A: 
  1. No. Unfortunately anonymous function are just that. Anonymous, unless you give them a name.

  2. Snippet #3 is a little bit more expensive. Given that you do pattern matching on messages in the body, I wouldn't worry about it. Optimise for readability in this case. The difference is a very small constant factor.

Daniel Luna
A: 

The more conventional way of avoiding repeating the list of parameters in snippet #1 is to put all or most of them in a record that holds the loop state. Then you only have one or a few variables to pass around in the loop. That's easier to read and harder to screw up than playing around with recursive funs.

RichardC
A: 

I must say that in all cases where I do this type of recursion I don't think I have ever come across the case where exactly the same set of variables is passed around in the recursion. Usually variables will change reflecting state change in the process loop. It cannot be otherwise as you have to handle state explicitly. I usually group related parameters into records which cuts down the number of arguments and adds clarity.

You can of course use your solution and have some parameters implicit in the fun and some explicit in the recursive calls but I don't think this would improve clarity.

The same answer applies to "normal" recursion where you are stepping over data structures.

rvirding