[m-rev.] for review: better error messages for lambda exprs

Mark Brown mark at mercurylang.org
Wed May 18 02:56:44 AEST 2016


On Tue, May 17, 2016 at 6:53 PM, Zoltan Somogyi
<zoltan.somogyi at runbox.com> wrote:
> On Tue, 17 May 2016 17:59:03 +1000, Mark Brown <mark at mercurylang.org> wrote:
>> Granted, it's not as nasty as being able to change the operator
>> precedence table mid-module. But there's some important cues that I'd
>> like to be able to rely on, such as that the right operand of infix
>> ':-' is a goal, or that the first operand of 'trace' is a list of
>> trace paramaters, even though these may superficially resemble data
>> terms. I don't think I can rely on that if there may be a pragma or
>> import_module somewhere that changes the rules.
>>
>> Part of the reason I support the changes you've been making is that
>> restricting the language can on its own help readers of the code, over
>> and above the error messages which benefit writers. The availability
>> of this pragma undermines that advantage, even, I would argue, when it
>> is not being used.
>
> I agree on both points, but I am not the one who you must convince
> on this point.

Put it this way: if there's a case for people to be using keywords as
names then I don't support prohibiting them at all.

>
>> > Yes, it does that. It also gives them significant work to do.
>> > I would prefer to impose such work on Mercury users
>> > only when it buys them something they are likely to value
>> > more than better error messages for syntax errors
>> > that may be rare in their experience.
>>
>> Then why pester them at all?
>
> I don't want to pester anyone. Adding the pragma would make the
> error go away.
>
> I also don't want to bother the people who know what they are doing.
> I just want to nudge people who choose keywords as the names of things
> without making a conscious choice to do so. Without something like this
> pragma, I don't see how we can separate the two kinds of cases.

Okay, I see. It's essentially a warning not an error.

For some users this warning would be superfluous because, as you said,
the syntax errors may be rare in their experience.

>> Then I think we should revisit Peter's question of whether we can
>> improve error messages another way. What if the parser did something
>> like:
>>
>>    if
>>        Term = functor(atom(Name), ArgTerms, _) and
>>        ( ArgTerms match the pattern we expect
>>        for the construct whose top functor is Name or
>>        Name is not defined )
>>    then
>>         consider Term to be that construct, possibly
>>         generating an error message
>>    else
>>         consider Term to be call
>
> Regardless of how desirable that proposal may be, it cannot be
> implemented without huge pain, because the "possibly generating
> an error message" is a task that belongs to the typechecker,
> the rest of that code belongs to the parser, and the two cannot
> be combined without huge pain.

That step is the same one that appears in your second template. So for
this lambda expression where the mode is missing:

   (pred(Y) is semidet :- X > Y)

If ':-'/2 is not defined by the user then you get the message your
above diff would generate. If ':-'/2 is defined but 'is'/2 isn't, you
get a similar error but it would be reported as coming from the first
argument to ':-'/2. If both ':-'/2 and 'is'/2 are defined, then both
pred/N and semidet/0 could still be recognised as part of a lambda
construct.

Getting back to your diff:

> This diff changes things so that when the top function symbol on
> the RHS of a unification is a Mercury "keyword" used only in one kind
> of construct, we commit to parsing its arguments as part of that construct.
> (If it the keyword can be part of more than one construct, we look deeper
> into its structure, and commit to parsing it as a given construct only
> when we have seen enough of the structure to rule out the other possible
> constructs it could be a part of.) If the parsing fails, we now generate
> an error message that describes the problem *directly*.

I'd like to propose that the commits only occur if the keyword is not
also defined by the user. If it's defined by the user, terms that
don't match the special data-term should be treated as calls.

Mark


More information about the reviews mailing list