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

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue May 17 14:13:09 AEST 2016



On Tue, 17 May 2016 13:26:40 +1000, Mark Brown <mark at mercurylang.org> wrote:
> I don't. For one thing, you've already convinced me that the
> flexibility of being able to use such symbols is of little value.

To me, and to you. To people who already use such symbols,
the answer is likely different, since it makes adapting to the
effective change in the language when we in effect reserve
some keywords is much easier.

> also don't like that I can be looking at a screenful of code while the
> declarations that tell me how to parse what I'm looking at could be
> thousands of lines away.

That wouldn't happen. You would parse syntactically correct code
exactly the same as now.

> How does it work with the module system? If you import a module with
> this pragma do you have to declare the pragma yourself to use the
> symbols?

That depends on exactly how we decide the pragma should work.
That is why I mentioned the question of imposing the requirement
that if the entity with the reserved name is exported, the pragma
must be exported too; then the importing module will get both,
and can adapt accordingly.

> Or do you lose good error messages?

The point of the pragma is to change how strict the parser is.

Traditionally, the parser operated like this:

   if 
       Term = functor(atom(Name), ArgTerms, _) and
       ArgTerms match the pattern we expect
       for the construct whose top functor is Name
   then
        consider Term to be that construct
   else
        consider Term to be call

This is errorprone, in that if there is a syntax errror somewhere
in ArgTerms, the parser considers Term to be a call, which yields
avalanche errors with misleading error messages.

I have been changing the parser to that it operates like this:

   if Term = functor(atom(Name), ArgTerms, _) then
       match ArgTerms against the pattern we expect
       for the construct whose top functor is Name
       if successful then
          consider Term to be that construct
       else
          generate an error message
   else
        consider Term to be call

The idea of the pragma is that normally, the parser operates
according to the second template above, which yields better
error messages for malformed code, but that if the pragma is
in effect, either for all names or just for Name, then we replace
"generate an error message" with "consider Term to be a call",
which effectively falls back to the first template.

Note that there should be minimal performance impact,
since we would look up the presence/absence of the pragma
only when we find a term that looks like it has a syntax error,
but which nevertheless may be correct code.

The reason why I think it is a good idea to make the pragma
specific about the names it applies to is that it allows us
to fall back to the template that generates worse error messages
only in the situations where the programmer, by using the pragma,
has implicitly stated that this buys them something they deem
worthwhile.

> That's not really an advantage, because prohibiting these names also
> tells people that their choice has consequences.

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.

And in some cases, the "them" is us. For example, replacing 
"=" as a function symbol in the comparison_result type would
NOT be trivial. Given that it has been several years since I had
a syntax error involving that function symbol, I would rather
not impose that work on myself, or on anyone else in the team.

Zoltan.





More information about the reviews mailing list