Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusion in precedence with <<$foo>>[0] #6371

Closed
p6rt opened this issue Jul 3, 2017 · 12 comments
Closed

Confusion in precedence with <<$foo>>[0] #6371

p6rt opened this issue Jul 3, 2017 · 12 comments
Labels
LTA Less Than Awesome; typically an error message that could be better

Comments

@p6rt
Copy link

p6rt commented Jul 3, 2017

Migrated from rt.perl.org#131695 (status was 'resolved')

Searchable as RT131695$

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

From @briandfoy

It seems that term precedence with << >> gets confused.

I also asked this on StackOverflow​: https://stackoverflow.com/q/44872419/2766176

  my $string = '5+8i';

  {
  my $number = val $string;
  put "Type​: " ~ $number.^name;
  put "Elems​: " ~ $number.elems;
  put "First​: " ~ $number.[0];
  }

  {
  my $number = <<$string>>;
  put "Type​: " ~ $number.^name;
  put "Elems​: " ~ $number.elems;
  put "First​: " ~ $number.[0];
  }

  {
  my $number = <<$string>>[0];
  put "Type​: " ~ $number;
#`(
===SORRY!=== Error while compiling ...
Cannot use variable $number in declaration to initialize itself
------> put "Type​: " ~ $⏏number;
  expecting any of​:
  double quotes
  statement end
  statement modifier
  statement modifier loop
  term
)
  }

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

From @jnthn

On Mon, 03 Jul 2017 05​:46​:46 -0700, comdog wrote​:

It seems that term precedence with << >> gets confused.

The << >> quoting construct interpolates. The rule for interpolation of method calls, indexing, etc. after a scalar is that there may be one, but it may only end with a ], ), } or >.

{
my $number = <<$string>>[0];

When the variable is encountered inside of the interpolating quoting construct, which is being parsed by the quoting parser, it calls back into the Perl 6 main language parser. This parses a variable and optionally a postfix. The >>[0] is a valid postfix, where >> is the hyper-operator and [0] is the indexer. Therefore the $string>>[0] is taken as the thing to interpolate. It then hands back control to the quoting parser.

put "Type​: " ~ $number;
#`(
===SORRY!=== Error while compiling ...
Cannot use variable $number in declaration to initialize itself
------> put "Type​: " ~ $⏏number;

This is complaining that $number was used before its declaration was complete, which is indeed the case because at we are still inside of the quoting construct.

I can see the potential for a human reader to be confused, but the Perl 6 parser is not in the least bit confused. There isn't any question as to what will parse the >>​: if the main language parser understands it and wants it, then it gets it, because the quoting parser doesn't get a say again until the main language parser has done its bit. This is the same reason that you can do stuff like​:

say "Foos​: @​foo.join("bar")"

And there isn't a bit of confusion so far as Perl 6 is concerned that the inner " is opening a new string, not closing the one we were already in. Granted it's maybe kinder to the reader to write it with single quotes inside of the string. But nestings of main language => quote parser => main language => quote parser will Just Work, each eating as much as it understands (or until seeing its terminator) before giving up control.

/jnthn

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

@jnthn - Status changed from 'open' to 'rejected'

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

From @briandfoy

On Mon, Jul 3, 2017 at 11​:09 AM, jnthn@​jnthn.net via RT
<perl6-bugs-followup@​perl.org> wrote​:

I can see the potential for a human reader to be confused,

I think there are two improvements here​:

* a better explanation of interpolation and what's allowed there (such
as "only postfix...") with plenty of examples.

* a better explanation of the process. I wouldn't have expected
something to eat that much inside the string. Not everything in the
main language is going to interpolate, so how is it making its
decision which thing it wants to parse?

* perhaps a better error message. We know we are inside a quoting
thing, so we might be able to guess that the quoting thing is not
terminated.

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

From @geekosaur

Perhaps this example should be provided somewhere as a 'gotcha'.

On Mon, Jul 3, 2017 at 11​:09 AM, jnthn@​jnthn.net via RT <
perl6-bugs-followup@​perl.org> wrote​:

On Mon, 03 Jul 2017 05​:46​:46 -0700, comdog wrote​:

It seems that term precedence with << >> gets confused.

The << >> quoting construct interpolates. The rule for interpolation of
method calls, indexing, etc. after a scalar is that there may be one, but
it may only end with a ], ), } or >.

{
my $number = <<$string>>[0];

When the variable is encountered inside of the interpolating quoting
construct, which is being parsed by the quoting parser, it calls back into
the Perl 6 main language parser. This parses a variable and optionally a
postfix. The >>[0] is a valid postfix, where >> is the hyper-operator and
[0] is the indexer. Therefore the $string>>[0] is taken as the thing to
interpolate. It then hands back control to the quoting parser.

put "Type​: " ~ $number;
#`(
===SORRY!=== Error while compiling ...
Cannot use variable $number in declaration to initialize itself
------> put "Type​: " ~ $⏏number;

This is complaining that $number was used before its declaration was
complete, which is indeed the case because at we are still inside of the
quoting construct.

I can see the potential for a human reader to be confused, but the Perl 6
parser is not in the least bit confused. There isn't any question as to
what will parse the >>​: if the main language parser understands it and
wants it, then it gets it, because the quoting parser doesn't get a say
again until the main language parser has done its bit. This is the same
reason that you can do stuff like​:

say "Foos​: @​foo.join("bar")"

And there isn't a bit of confusion so far as Perl 6 is concerned that the
inner " is opening a new string, not closing the one we were already in.
Granted it's maybe kinder to the reader to write it with single quotes
inside of the string. But nestings of main language => quote parser => main
language => quote parser will Just Work, each eating as much as it
understands (or until seeing its terminator) before giving up control.

/jnthn

--
brandon s allbery kf8nh sine nomine associates
allbery.b@​gmail.com ballbery@​sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

From @AlexDaniel

I don't really want to start another ticket for what I'm about to suggest, therefore I'll reopen this one.

Not so long ago I filed this ticket​:
https://rt-archive.perl.org/perl6/Ticket/Display.html?id=131640

The underlying issue is exactly the same. And it has actually happened during whateverable development, so it is not some kind of a thought exercise.

Therefore, I think that we should actually try to improve the error message somehow. And here's my idea. What if the error message said something like this​:

===SORRY!=== Error while compiling -e
Cannot use variable $number in declaration to initialize itself
(while parsing shell-quote words started at line 2)
at -e​:3
------> put "Type​: " ~ $⏏number;
    expecting any of​:
        double quotes
        statement end
        statement modifier
        statement modifier loop
        term

Please suggest a better way to put it, but the idea is quite simple​: if we are inside another language that was started on a different line, why not say where exactly it was started? There may be cases when this additional line will not give anything useful, but generally it will make the error message Truly Awesome™.

On 2017-07-03 10​:59​:54, allbery.b@​gmail.com wrote​:

Perhaps this example should be provided somewhere as a 'gotcha'.

On Mon, Jul 3, 2017 at 11​:09 AM, jnthn@​jnthn.net via RT <
perl6-bugs-followup@​perl.org> wrote​:

On Mon, 03 Jul 2017 05​:46​:46 -0700, comdog wrote​:

It seems that term precedence with << >> gets confused.

The << >> quoting construct interpolates. The rule for interpolation
of
method calls, indexing, etc. after a scalar is that there may be one,
but
it may only end with a ], ), } or >.

{
my $number = <<$string>>[0];

When the variable is encountered inside of the interpolating quoting
construct, which is being parsed by the quoting parser, it calls back
into
the Perl 6 main language parser. This parses a variable and
optionally a
postfix. The >>[0] is a valid postfix, where >> is the hyper-operator
and
[0] is the indexer. Therefore the $string>>[0] is taken as the thing
to
interpolate. It then hands back control to the quoting parser.

put "Type​: " ~ $number;
#`(
===SORRY!=== Error while compiling ...
Cannot use variable $number in declaration to initialize itself
------> put "Type​: " ~ $⏏number;

This is complaining that $number was used before its declaration was
complete, which is indeed the case because at we are still inside of
the
quoting construct.

I can see the potential for a human reader to be confused, but the
Perl 6
parser is not in the least bit confused. There isn't any question as
to
what will parse the >>​: if the main language parser understands it
and
wants it, then it gets it, because the quoting parser doesn't get a
say
again until the main language parser has done its bit. This is the
same
reason that you can do stuff like​:

say "Foos​: @​foo.join("bar")"

And there isn't a bit of confusion so far as Perl 6 is concerned that
the
inner " is opening a new string, not closing the one we were already
in.
Granted it's maybe kinder to the reader to write it with single
quotes
inside of the string. But nestings of main language => quote parser
=> main
language => quote parser will Just Work, each eating as much as it
understands (or until seeing its terminator) before giving up
control.

/jnthn

@p6rt
Copy link
Author

p6rt commented Jul 3, 2017

@AlexDaniel - Status changed from 'rejected' to 'open'

@p6rt
Copy link
Author

p6rt commented Jul 4, 2017

From @TimToady

We now warn on the ambiguity of >> or » when used where it could easily be intended as either a hyper or the quotewords terminator. While we could, in theory, do some lookahead to try to suppress this warning in some cases, it will be brittle in the face of languages that mutate the postfix space, so I think it's better to just warn outright and let people disambiguate with whitespace or a suitable change to the hyper or quote delims.

(As for retargeting this ticket to the more general case of multiline quote errors, please note that a runaway hyper is not a kind of quote, and that we already warning on runaway quotes that cross line boundaries. Also, the problem here is essentially independent of multi-line-ness. So I've changed the title of this bug back to the original, since that's the problem we're fixing.)

1 similar comment
@p6rt
Copy link
Author

p6rt commented Jul 4, 2017

From @TimToady

We now warn on the ambiguity of >> or » when used where it could easily be intended as either a hyper or the quotewords terminator. While we could, in theory, do some lookahead to try to suppress this warning in some cases, it will be brittle in the face of languages that mutate the postfix space, so I think it's better to just warn outright and let people disambiguate with whitespace or a suitable change to the hyper or quote delims.

(As for retargeting this ticket to the more general case of multiline quote errors, please note that a runaway hyper is not a kind of quote, and that we already warning on runaway quotes that cross line boundaries. Also, the problem here is essentially independent of multi-line-ness. So I've changed the title of this bug back to the original, since that's the problem we're fixing.)

@p6rt
Copy link
Author

p6rt commented Jul 4, 2017

@TimToady - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Jul 4, 2017
@p6rt
Copy link
Author

p6rt commented Jul 5, 2017

From @zoffixznet

On Tue, 04 Jul 2017 10​:29​:50 -0700, larry wrote​:

While we could, in theory, do some lookahead to try to suppress this
warning in some cases

I moved[^1] the warning to the point when we parsed a hyper and are
making AST for it rather than just where we matched the potential end quoter.

So now it still warns for stuff like​:

  my $number = <<$string>>[0]; put "Type​: " ~ $number;

But no longer warns for cases like​:

  my $number = <<$string>>;

Which I think are far more common (e.g. `run «cal $year»`) and there's no hyper intended there,
so the warning was fairly annoying.

[1] rakudo/rakudo@d39f7b9aff

@p6rt p6rt added the LTA Less Than Awesome; typically an error message that could be better label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LTA Less Than Awesome; typically an error message that could be better
Projects
None yet
Development

No branches or pull requests

1 participant