smartmatch is among the most complex parts of the language.

That complexity has to managed or it will be too complex to use effectively.

To that end, the rules and order of operations are never altered.

1. The left side is evaluated first, and the resulting value captured

        > say('left') ~~ say('right')
        left
        right

2. $_ is temporarily set to that value, and the right side is executed

        > 'ab' ~ 'c'   ~~ say($_)
        abc

3. The result of that execution is matched against the left value

        > 'abc' ~~ 'abb'.succ()
        True

    Specifically `.ACCEPTS` is called with the left value.
    So the following two lines are roughly equivalent.

        > 'abc'   ~~   'abb'.succ()
        > 'abb'.succ().ACCEPTS('abc')

So in the case of S/// and ~~ this is the order that things happen:

1. The left side is executed

        « a b c ».join()  ~~  S/b/./

        'abc' ~~ S/b/./

2. $_ is temporarily set to that value, and the right side is executed

        'abc' ~~ S/b/./

        'abc' ~~ 'a.c'

3. the result of the right side is matched against the left value

        'abc' ~~ 'a.c'

        'a.c'.ACCEPTS('abc') # False

So basically if S/// changes the value, the result is False.
If S/// doesn't change it, the result is True.

Which means the following two lines are functionally identical.

    'abc'   ~~  S/b/./
    'abc'  !~~   /b/

So the resulting value will never be the string you wanted!
It will be True or False.

---

The reason for the two stage execution is for the following.

    'abc' ~~   .contains('b')
    'abc' ~~ { .contains('b') }
    'abc' ~~ m / b /
    'abc' ~~ rx / b /

Those four lines work basically the same, but for two different reasons.

The first one works because $_ is set to the left value, and True.ACCEPTS()
always returns True

The second one works because CODE.ACCEPTS() always runs the code with the
same parameter list.

The third one works for the same reason as the first one

The fourth one works for the same reason as the second one

1. Left side executed

    'abc' ~~   .contains('b')
    'abc' ~~ { .contains('b') }
    'abc' ~~ m  / b /
    'abc' ~~ rx / b /

2. Right side executed

    'abc' ~~  True
    'abc' ~~ { .contains('b') }
    'abc' ~~ True
    'abc' ~~ rx / b /

3. R-VALUE  .ACCEPTS( L-VALUE )

    True.ACCEPTS('abc')
    { .contains('b') }.ACCEPTS('abc')
    True.ACCEPTS('abc')
    rx / b /.ACCEPTS('abc')

Note again that CODE.ACCEPTS(VALUE) is the same as CODE.(VALUE).
(Note also that a regex is a code object.)

    True.ACCEPTS('abc')
    { .contains('b') }.('abc')
    True.ACCEPTS('abc')
    rx / b /.('abc')

---

So then why does this work?

    'abc' ~~ { S/b/./ }

As I said CODE.ACCEPTS() always runs CODE with the same parameter list.

    { S/b/./ }  .ACCEPTS( 'abc' )

    { S/b/./ }  .( 'abc' )

---

So why does the warning tell you to use `given` instead of what I just
wrote?

The ~~ is intended mostly for resolving some sort of truthiness.
So I just misused the feature for something it was not intended for.

`given` is intended for temporarily setting $_, so it is the appropriate
tool for the job.

    S/b/./ given 'abc'

If you don't like `given`, then just use `.subst()`

    'abc'.subst( 'b', '.' )

On Sun, Dec 8, 2019 at 1:32 AM William Michels <w...@caa.columbia.edu>
wrote:

> Apologies, looks like the smartmatch operator is listed in the
> Operator Precedence table (15th row: under "Chaining infix"):
>
> https://docs.raku.org/language/operators#Assignment_operators
>
> However, am I correct in stating that the assignment operator ("=") is
> on the 19th row ("Item assignment")? Therefore in the absence of
> parentheses, etc., all smartmatch operations take precedence over
> assignment operations?
>
> Best Regards, Bill.
>
>
> On Sat, Dec 7, 2019 at 10:27 PM William Michels <w...@caa.columbia.edu>
> wrote:
> >
> > Wow Brad, that's interesting and informative.
> >
> > I haven't seen the S/// operator before, so I had to look it up. On
> > the first page I found the docs say (quite informatively): "S/// uses
> > the same semantics as the s/// operator, except it leaves the original
> > string intact and returns the resultant string instead of $/ ($/ still
> > being set to the same values as with s///)."
> >
> > https://docs.raku.org/syntax/S$SOLIDUS$SOLIDUS$SOLIDUS
> >
> > I was then able to find an overview on regexes, which more explicitly
> > names the "S///" operator as "Non-disruptive substitution". I suppose
> > I could quibble and request that the phrase "Non-disruptive
> > substitution" be added to the operator page (above), but no
> > matter--it's easy enough to find:
> >
> > https://docs.raku.org/language/regexes#S///_non-destructive_substitution
> >
> > So I think I understand that (as Brad has said): "smartmatch with S///
> > (or TR///) is not useful." Conversely, I've also found another
> > smartmatch construct that is useless (i.e. disallowed):
> >
> > > my $r = 'abc' ~~ { S/b/./ }
> > a.c
> > > my $s = 'abc' ~~ { s/b/./ }
> > Cannot modify an immutable Str (abc)
> >   in block <unit> at <unknown file> line 1
> > >
> >
> > No matter how "discouraged' a particular syntax is, people are going
> > to run into these disallowed syntaxes and wonder why. Could it be due
> > to precedence? These two prohibited operations beg the question: can a
> > definitive statement be made regarding the precedence of the
> > smartmatch operator relative to either lowercase-triple-solidus
> > operators such as s/// and tr/// , or relative to
> > uppercase-triple-solidus operators such as S/// and TR/// ?
> >
> > This really makes me wonder if anyone has plans to add "~~" (the
> > smartmatch operator) to the precedence table that can be found
> > below--and where in the table the smartmatch operator would precisely
> > sit:
> >
> > https://docs.raku.org/language/operators#Operator_precedence
> >
> > Best Regards, Bill.
> >
> >
> >
> >
> > On Sat, Dec 7, 2019 at 7:53 AM Brad Gilbert <b2gi...@gmail.com> wrote:
> > >
> > > The return value of s/// is the same as $/
> > >
> > > If you want the resulting string instead you can use S/// instead.
> > >
> > >     > $_ = 'abc'
> > >     > my $r = S/b/./
> > >     > say $r
> > >     a.c
> > >
> > > Note that it warns you try to use S/// with ~~
> > >
> > >     > my $r = 'abc' ~~ S/b/./
> > >     Potential difficulties:
> > >         Smartmatch with S/// is not useful. You can use given instead:
> S/// given $foo
> > >         ------> my $r = 'abc' ~~ S/b/./
> > >     False
> > >
> > > Which gives you an indicator of how to fix it
> > >
> > >     > my $r = S/b/./ given 'abc'
> > >     a.c
> > >
> > > Note that the `given` happens before the `=`
> > >
> > > So it works the same as
> > >
> > >     > my $r = ( S/b/./ given 'abc' )
> > >     a.c
> > >
> > > ---
> > >
> > > The reason ~~ doesn't work with S/// has to do with the dual pass
> nature of ~~.
> > >
> > > Without getting into details, you can avoid that by delaying the S///
> until the second pass.
> > >
> > >     > my $r = 'abc' ~~ { S/b/./ }
> > >     a.c
> > >
> > > Or you can just set $_ to the value.
> > > (Which is basically what the previous line is doing.)
> > >
> > >     > my $r = S/b/./ given 'abc'
> > >
> > >     > given 'abc' {
> > >     >   my $r = S/b/./
> > >     >   …
> > >     > }
> > >
> > >     > my $_ = 'abc'
> > >     > my $r = S/b/./
> > >
> > >     > my $r = 'abc' ~~ -> $_ { S/b/./ }
> > >
> > >     > my $r = 'abc' ~~ sub ( $_ ) { S/b/./ }
> > >
> > >     > my $r = 'abc' ~~ anon sub foo ( $_ ) { S/b/./ }
> > > ---
> > >
> > > One of design goals of Raku is to have as few special cases as
> possible.
> > > Which is why ~~ and S/// haven't been made to just work.
> > >
> > > (It could be argued that in this case an exception could be made. But
> I'm not going to argue for it.)
> > >
> > > On Fri, Dec 6, 2019 at 10:37 PM William Michels via perl6-users <
> perl6-us...@perl.org> wrote:
> > >>
> > >> Hello All,
> > >>
> > >> Todd put up some interesting code yesterday using the Raku/Perl6 REPL,
> > >> which I reproduced with no problem. Additionally I tried some
> > >> variations removing and/or moving parentheses to a different location,
> > >> and have numbered the relevant REPL lines 1 through 6:
> > >>
> > >> mbook:~ homedir$ perl6
> > >> To exit type 'exit' or '^D'
> > >> 1> my $x = Q[word</b><br>] ;
> > >> word</b><br>
> > >> 2> (my $y = $x) ~~ s/ '<' .* //; say $/; say $x; say $y;
> > >> 「</b><br>」
> > >> word</b><br>
> > >> word
> > >> 3> my $a = Q[word</b><br>] ;
> > >> word</b><br>
> > >> 4> my $b = ($a ~~ s/ '<' .* //); say $/; say $a; say $b;
> > >> 「</b><br>」
> > >> word
> > >> 「</b><br>」
> > >> > my $c = Q[word</b><br>] ;
> > >> word</b><br>
> > >> > my $d = $c ~~ s/ '<' .* //; say $/; say $c; say $d;
> > >> 「</b><br>」
> > >> word
> > >> 「</b><br>」
> > >> 7> $*VM
> > >> moar (2019.07.1)
> > >>
> > >> Working in groups of 2, lines 1 and 2 replicate the code Todd put up
> > >> (parenthesis surrounding everything to the left of the smartmatch
> > >> operator). I get the same result as Todd. What interests me are lines
> > >> 3 through 6. Lines 3 and 4 are the virtually the same code but with
> > >> parentheses surrounding everything to the right hand side (RHS) of the
> > >> assignment operator (" = "). As people will note, lines 2 and lines 4
> > >> give different results. Removing parentheses entirely in line 6 gives
> > >> the same result as in line 4. Because the results in line 4 and line 6
> > >> are the same, this says that as far as parentheses are concerned, the
> > >> smartmatch operator "~~" takes precedence over the assignment operator
> > >> "=".
> > >>
> > >> What's not clear to me in the code above (lines 4 and 6) is why
> > >> variables $b and $d get assigned to $/. I would have expected in line
> > >> 4 that $a would have been matched against the smartmatch, and the
> > >> result ("word") would have been simply copied into variable $b. Have I
> > >> misunderstood?
> > >>
> > >> Anyway, I'm just hoping to start a conversation on the topic of
> > >> precedence in general, and hopefully getting some feedback as to where
> > >> to look in the docs for further instruction.
> > >>
> > >> Best Regards, Bill.
> > >>
> > >>
> > >> On Fri, Dec 6, 2019 at 12:15 AM ToddAndMargo via perl6-users
> > >> <perl6-us...@perl.org> wrote:
> > >> >
> > >> > On 2019-12-05 23:19, ToddAndMargo via perl6-users wrote:
> > >> > > On 2019-12-05 03:09, William Michels via perl6-users wrote:
> > >> > >> What happens when you type "perl6" or "raku" at the bash command
> prompt?
> > >> > >
> > >> > > Hi William,
> > >> > >
> > >> > > On my shop machine, it jumps to the next line with an
> > >> > > empty flashing cursor
> > >> > >
> > >> > > On my office machine, it told me to install
> > >> > >      zef install Readline
> > >> > >
> > >> > > After that, I get:
> > >> > >
> > >> > > $ perl6
> > >> > > To exit type 'exit' or '^D'
> > >> > >  >
> > >> > >
> > >> > > and
> > >> > >
> > >> > >  > say "hello World"
> > >> > > hello World
> > >> > >  > say "B" ~ Q[:\] ~ " drive dismounted"
> > >> > > B:\ drive dismounted
> > >> > >  >
> > >> > >
> > >> > > and sticking an obvious booboo into it
> > >> > >
> > >> > >  > if 3 % 2 = 1 {say "odd"};
> > >> > > Cannot modify an immutable Int (1)
> > >> > >    in block <unit> at <unknown file> line 1
> > >> > >
> > >> > > Plus I can use the arrow keys to recall previous lines too.
> > >> > >
> > >> > > Time up update my Perl6 on my shop computer!
> > >> > >
> > >> > > No more hassling with `perl6 -e` !!!
> > >> > >
> > >> > > Dude!  THANK YOU !!!!!!
> > >> > >
> > >> > > -T
> > >> >
> > >> > You've created a monster!!
> > >> >
> > >> > perl6
> > >> > To exit type 'exit' or '^D'
> > >> >  > my $x = Q[</b><br>]
> > >> > </b><br>
> > >> >  > say $x
> > >> > </b><br>
> > >> >  > (my $y = $x ) ~~ s/ Q[<] .* //;
> > >> > ===SORRY!=== Error while compiling:
> > >> > Unrecognized regex metacharacter < (must be quoted to match
> literally)
> > >> > ------> (my $y = $x ) ~~ s/ Q[<] .* //;
> > >> >  > my $x = Q[abc</b><br>]
> > >> > abc</b><br>
> > >> >  > (my $y = $x ) ~~ s/ '<' .* //;
> > >> > 「</b><br>」
> > >> >  > (my $y = $x ) ~~ s/ '<' .* //; say $y
> > >> > abc
> > >> >  > (my $y = $x ) ~~ s/ '<' .* //; say $x; say $y
> > >> > abc</b><br>
> > >> > abc
> > >> >
> > >> >
> > >> > Thank you!
> > >> >
> > >> >
> > >> > --
> > >> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >> > Computers are like air conditioners.
> > >> > They malfunction when you open windows
> > >> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>

Reply via email to