[erlang-questions] Dialyzer: Why do I get a 'will never return success typing error' with this recursive function?
Jeremy Raymond
jeraymond@REDACTED
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<kostis@REDACTED> 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) ->
> ok;
> 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() ->
> ok.
>
> test_loop() ->
> 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.
>
> Kostis
>
> 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
ok;
do_work(type2, Args) ->
% do something else, then repeat
work(loop, Args).
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
mailing list