Thank you very much Brad!!

Let's redirect all conversation on this particular issue here:

https://github.com/rakudo/rakudo/issues/3221

Best Regards, Bill.

On Tue, Oct 8, 2019 at 10:53 AM Brad Gilbert <b2gi...@gmail.com> wrote:
>
> Most operations with Junctions produce Junctions.
>
>     > 1 + any(2, 3)
>     any(3, 4)
>
>     > any(1, 2) + 3
>     any(4, 5)
>
>     > any(<ab cd>) ~~ /./
>     any(「a」, 「c」)
>
> In the case of the following line, `$/` gets assigned a junction of the 
> results.
>
>     > if any(@genus) ~~ m/Hama/ { put "Matches at least one again"; };
>
> The `m/Hama/` is executing early in the smartmatch `~~`.
> Really you should have been using `rx/Hama/` or `/Hama/` instead.
>
>     > any(<ab cd>) ~~ m/./
>     False
>
> `m//` always executes against `$_`. While `rx//` always evaluates to the 
> regex itself.
> (`/…/` will do one or the other depending on context.)
> So there are some places where `m//` appears to wait to execute like the 
> following line.
>
>     > 'abc' ~~ m/b/
>
> It doesn't wait. It executes immediately.
>
>
> The reason is that smartmatch is actually a two step process.
> The above example is basically short for the following line:
>
>     > (do given 'abc' { m/b/ }).ACCEPTS('abc')
>
> Now I am going to simplify it.
> The `m/b/` executes immediately.
>
>     > (do given 'abc' { 「b」 }).ACCEPTS('abc')
>     > (                 「b」  ).ACCEPTS('abc')
>
> Since `.ACCEPTS` on an instance of Match always returns itself, the above 
> returns the Match object.
>
> It would operate differently, but come to the same result with `rx//`.
>
>     > (do given 'abc' { rx/b/ }).ACCEPTS('abc')
>     > (                 rx/b/  ).ACCEPTS('abc')
>
> Since `rx/b/` does indeed accept 'abc' the end result of the above line is 
> the Match object 「b」.
>
>
> In the case of a Junction, the `~~` applies to each part of the junction 
> separately, and then combines the results.
> So `$/` gets assigned a Junction rather than the normal Match.
> (Which means `m//` and `rx//` do not come to the same result.)
>
> If the book says that `@genus ~~ m/Hama/` and `any(@genus) ~~ m/Hama/` are 
> exactly the same, it is incorrect.
> The first sets $/ and returns the first value that returns a True value. 
> While the second returns True and sets $/ to a Junction of all the results.
>
>
> Then later when you do just `m//` it tries to assign to each value in the 
> Junction to the new result.
> Since the junction contains immutable values, that doesn't work.
>
>     > $_ = 'abc';
>     > $/ = any 'def', 'ghi';
>     > m/abc/
>     Cannot modify an immutable Str (def)
>       in block <unit> at <unknown file> line 1
>
> Basically when `m//` tries to do `$/ = …` it threads through the Junction 
> rather than just assigning directly to `$/`.
> It is a bug in the assignment code that m// uses.
>
>
> When submitting a bug report, it is best to reduce the problem to the 
> simplest example that still produces the error. The last example here does 
> just that.
> This is a compiler / runtime issue. The compiler's name is Rakudo, so the 
> appropriate repository would be https://github.com/rakudo/rakudo.
> Since you found the issue, I think you should create the issue in the bug 
> tracker.
> (Mainly because that is a common first stepping stone to getting involved.)
>
>
>
> On Tue, Oct 8, 2019 at 2:53 AM William Michels via perl6-users 
> <perl6-us...@perl.org> wrote:
>>
>> Greetings:
>>
>> I tried the following regular expression code, working generally from
>> "Learning Perl 6" by brian d foy (Chapter 15). Everything works fine
>> including the any() junction below, as long as the topic $_ variable
>> isn't defined beforehand. However specifically in combination with a
>> user-defined $_ topic variable, an any() junction returns the error,
>> "Cannot modify an immutable Match." See Perl6 REPL code below (also
>> checked with 6Pad (https://perl6.github.io/6pad/)) :
>>
>> mbook:~ homedir$ perl6
>> To exit type 'exit' or '^D'
>> > $_ = 'Hamadryas';
>> Hamadryas
>> > my @genus = < Hamadryas Sostrata Junonia >;
>> [Hamadryas Sostrata Junonia]
>> > say $_.WHAT, $/.WHAT;
>> (Str)Nil
>> > if @genus ~~ m/Hama/ { put "Matches at least one"; };
>> Matches at least one
>> > say $_.WHAT, $/.WHAT;
>> (Str)(Match)
>> > say m/Hama/;
>> 「Hama」
>> > say m/Hama/;
>> 「Hama」
>> > say $_.WHAT, $/.WHAT;
>> (Str)(Match)
>> > if any(@genus) ~~ m/Hama/ { put "Matches at least one again"; };
>> Matches at least one again
>> > say $_.WHAT, $/.WHAT;
>> (Str)(Junction)
>> > say m/Hama/;
>> Cannot modify an immutable Match (「Hama」)
>>   in block <unit> at <unknown file> line 1
>>
>> > say $*VM
>> moar (2019.07.1)
>> >
>>
>> I understood from the "Learning Perl 6" book that the two smart-match
>> lines of code are equivalent--the first one simply understands that
>> there is an 'implied' any() junction to check the array against the
>> match operator. But REPL reports back that in one case $/ returns a
>> match object type, while in the other case [with an explicit any()
>> junction], $/ returns a junction object type. So this feels
>> inconsistent, at the very least.
>>
>> Any explanation appreciated. If after triaging this issue, someone
>> would like me to open a Github issue, please point me towards the
>> correct repository.
>>
>> Thanks, Bill.
>>
>> W. Michels, Ph.D.

Reply via email to