Why are `1…2` and `1….2` not syntax errors?

Why are `1…2` and `1….2` not syntax errors?


6

use 5.016;
use warnings "all";
use Data::Dumper;

my @abc = (1, 2, 3);

my @bbb = @abc[1..2];
my @ccc = @abc[1...2];
my @ddd = @abc[1....2];

say Dumper "@bbb"; # output: '2 3'
say Dumper "@ccc"; # output: '2 3'
say Dumper "@ddd"; # output: ''

Why is there no syntax error in code above?

What do 1...2 (three dots) and 1....2 (four dots) mean here?

0

2 Answers
2


10

1..2 is tokenized as 1 .. 2, and parsed as a range operator with two integer constant operands. When evaluated, it is evaluated in list context, and it produces the integers from 1 to 2 inclusive.

1...2 is tokenized as 1 ... 2, and parsed as a range operator with two integer constant operands. ... is different than .. in scalar context, but they’re the same in list context.

1....2 is tokenized as 1 ... .2, and parsed as a range operator with two constant operands. When evaluated, it is evaluated in list context, and it produces the integers from 1 to 0.2 inclusive, which is to say it produces nothing.


A side note:

When tokenizing, Perl normally gobbles up as many characters as it can with no regard as to what follows. One exception is that a . will never be included in a numeric literal if followed by another ..

This means that 1..2 is always tokenized as 1, .., 2 and never 1. .2 or 1. . 2.

This means that 1...2 is always tokenized as 1, ..., 2 and never 1., .., 2 or 1, .., .2.

This also means that 1.....2 will never be tokenized as 1. ... .2 even though that would prevent the parser from throwing a syntax error.

(Thanks @Dada for helping me correct this.)


A side note:

At least some constant ranges are flattened into an array constant.

1..2 in list context and 1...2 in list context both compile to a two-element array constant, just like 1, 2.

1....2 in list context compiles to an empty array constant.

0


3

If you give Perl the option -MO=Deparse it will say how Perl parse your code.

The three-dot form (1...2) parses as (1..2). This is unexpected to me, but I assume it is a side effect of being able to parse both the two-dot and three-dot forms of the flip-flop operator.

The four-dot form parses as (1 .. .2). This is an empty range, so your array slice is also empty.

1

  • Re "The three-dot form (1…2) parses as (1..2).", No. They are parsed differently, but they compile to the same the thing in this case. Specifically, they compile to a constant array of two elements, just like 1, 2. /// Re "it will say how Perl parse your code.", Deparse is a decompiler. It can help show how Perl understand codes, but it doesn't actually show how code is parsed. That's why 1..2, 1...2 and 1, 2 all Deparse as 1, 2. (They don't Deparse as 1..2 as you claim.)

    – ikegami

    5 hours ago



Leave a Reply

Your email address will not be published. Required fields are marked *