[m-rev.] for review: Enable non-tail-call warnings for?mutually-recursive code

Zoltan Somogyi zoltan.somogyi at runbox.com
Wed Mar 29 15:00:13 AEDT 2017



On Wed, 29 Mar 2017 14:41:44 +1100, Paul Bone <paul at bone.id.au> wrote:
> > >  :- type warn_non_tail_rec_calls_opt
> > >      --->    do_not_warn_non_tail_rec_calls_opt
> > > -    ;       warn_non_tail_rec_calls_opt.
> > > +    ;       warn_non_tail_rec_calls_self_opt
> > > +    ;       warn_non_tail_rec_calls_self_and_mut_opt.
> > 
> > I think having two separate flags, one for self and one for mutual
> > recursion, would be cleaner.
> 
> Normally yes, however I don't intend to support creating warnings for mutual
> recursion but not self recursion.  The issue is raised again below and I'll
> discuss it there.

What I am saying is that it is cleaner *internally* to have two separate flags.
I am *not* saying *anything* about what users see *externally*. Just because
the internals support a setting of "warn about mutual but not self recursive calls"
does not mean that this capability has to be visible to users.

> > > @@ -579,6 +615,8 @@ mark_tail_rec_calls_in_goal(Goal0, Goal, AtTail0, AtTail, !Info) :-
> > >      (
> > >          ( GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
> > >          ; GoalExpr0 = generic_call(_, _, _, _, _)
> > > +        % Note: we don't give tailcall warnings for negated goals, maybe we
> > > +        % should?
> > >          ; GoalExpr0 = negation(_)
> > >          ),
> > 
> > I don't think so. Any code in a negated scope *has* to be followed by the execution
> > of target language code that switches failure to success and vice versa, so any calls
> > in such scopes *inherently* cannot be tail recursive.
> 
> Yes.  I guess the question is, do people who use Mercury, but don't
> implement it, know this?  Many will once they give it some thought, but some
> won't.  Likewise I once surprised Peter Schachte with this:
> 
>     p(X::out, Y::out) :-
>         ...,
>         p(Y, X).
> 
> He assumed it was tail recursive, when it isn't.  This case is more subtle,
> and one that _is_ tail recursive in Prolog, but perhaps people could make
> a similar error with negation.

That sounds like it argues for another option to control what calls the compiler
should consider to be "obviously not tail calls", which it shouldn't warn about.
We already a "have we seen a recursive call in our backward traversal so far"
flag specifically for this purpose; maybe we should make its operation,
and the treatment of negated scopes and calls where the output args don't match up,
subject to this option. However, that is definitely a separate change.

Zoltan.




More information about the reviews mailing list