Hacker News new | past | comments | ask | show | jobs | submit login

Common idiom in Erlang. Using message passing (untested code):

    do_something(N) ->
        Pid = self(),
        spawn(fun() -> find_x(Pid, N) end),
        receive
            {found, Item} -> ...;
            not_found -> ...
        end.
    
    find_x(Pid, N) -> find_x (Pid, N, [1, 3, 5]).
    find_x(Pid, _N, []) -> Pid ! not_found;
    find_x(Pid, N, [N|_T]) -> Pid ! {found, N};
    find_x(Pid, N, [_H|T]) -> find_x(Pid, N, T).
You can also handle timeouts and stuff.



Unless you specifically need a timer, I wouldn't use that and would simply return {ok, N} or {error, not_found}; that would avoid useless copying and message passing. Something like:

    find_x(N) -> find_x (N, [1, 3, 5]).
    find_x(N, []) -> {error, not_found};
    find_x(N, [N|_T]) -> {ok, N};
    find_x(N, [_H|T]) -> find_x(N, T).
If what you want is to get out of deep recursion and the above doesn't work especially well, that's what 'throw/1' is for:

    Res = try find_x(N) of
             Val -> {ok, Val}
          catch
             throw:not_found -> {error, not_found}
          end.
This will allow to avoid the stack, special cases for returning values and give you the code result you need.

The spawning of a process for a simple use case like this is only worth it if you need a timer to give a maximum execution time for a given request. Otherwise, it's not very useful, clear or efficient. I'd mark it as 'concurrency for the sake of it'.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: