[erlang-questions] Dialyzer: Why do I get a 'will never return success typing error' with this recursive function?
Sat Feb 25 03:38:03 CET 2012
On 2012-02-24, at 3:51 PM, Kostis Sagonas wrote:
> On 02/24/12 19:36, Jeremy Raymond wrote:
>> On Fri, Feb 24, 2012 at 12:07 PM, Kostis Sagonas<> wrote:
>>> Lesson #2: do not spec function args with terms for which the function will
>>> not return any value.
>> So my case where I do want the atypical behaviour to loop with some
>> args and no with others, I should forgo the spec and ignore the
>> Dialyzer warning? There is no way I can state via aspecs that this is
>> indeed the intent of the function?
> If your function is indeed like the following one:
> test(noloop) ->
> test(loop) ->
> test(loop). % dialyzer warns about this call
> then there is a very simple thing that you can do: fold the argument in the function name and make two functions from it:
> test_noloop() ->
> test_loop() ->
> Dialyzer knows not to complain about calls to test_loop(), esp. so if you provide a spec that explicitly says that this function has indeed no_return(). To me, this is a more kosher program and expresses what you want better than a spec will do.
> PS. I understand of course that if your program is more involved than the above, you may need to refactor it a bit -- but dialyzer can guide you in this: when it complains that some call will never return, it is sure this call will always end up in the looping clause.
A simplified version of what I'm doing is
work(Type, Args) ->
spawn_link(fun() -> do_work(Type, Args) end).
do_work(type1, Args) ->
% do something once
do_work(type2, Args) ->
% do something else, then repeat
Some types of work are done once, others repeat. I could split the work into different functions, but then I need some other mechanism to select the type of work to do (case or if statements). Is there a better way I can do this?
The actual code is here: https://github.com/jeraymond/leader_cron/blob/master/src/leader_cron_task.erl, spawning work in init/1 and doing the work in run_task/3.
More information about the erlang-questions