Thank you, Brad. I think I've got it (let me know if below is incorrect): #### pseudocode: 1. eval(LHS --> $_) 2. eval($_ ~~ RHS) 3. overwrites(LHS <-- Step#2), except for S/// and TR///
[ When I first learned the "~~" smartmatch operator, I only thought it was for testing (e.g. with rx/// and m/// ). I thought it only returned TRUE/FALSE. But now I've gained a better understanding that s/// and S/// and tr/// and TR/// also work. As an aside, the ACCEPTS() notation is quite clear, while the smartmatch notation reminds me a little bit of 'gazinta' math: https://www.collinsdictionary.com/us/submission/18703/gazinta ] New question: Is there an explanation in the docs for the behavior I see below using square brackets instead of parentheses? It seems that square brackets in the "abc" series below gives a different result than parentheses, suggesting a different precedence level: mbook:~ homedir$ perl6 To exit type 'exit' or '^D' > > my $a = Q[<i>abc</i>] <i>abc</i> > [my $b = $a ] ~~ s/ <[cba]>+ // ; 「abc」 > say $/; say $_; say $a; say $b; 「abc」 (Any) <i>abc</i> <i>abc</i> > > my $x = Q[<b>xyz</b>] <b>xyz</b> > my $y = [ $x ~~ s/ <[zyx]>+ // ]; [「xyz」] > say $/; say $_; say $x; say $y; 「xyz」 (Any) <b></b> [「xyz」] > > say $*VM moar (2019.07.1) Best Regards, Bill. On Mon, Dec 9, 2019 at 6:04 PM Brad Gilbert <b2gi...@gmail.com> wrote: > > I meant that $_ is set to the left value while the right value is being > evaluated, and also while .ACCEPTS is called. > > LEFT ~~ RIGHT > > (Where LEFT and RIGHT represent some expression to be executed during > runtime.) > > Imagine that underneath the hood, something like this is happening: > > my $L-value = LEFT.evaluate(); > > given $L-value { > # $_ is temporarily the result of the LEFT expression > > my $R-value = RIGHT.evaluate(); > return $R-value.ACCEPTS($L-value); > } > > So this: > > « a b c ».join() ~~ S/b/y/ > > is functionally the same as: > > do given « a b c ».join() { > my $R-value = S/b/y/; > $R-value.ACCEPTS($_) > } > > Note that $R-value will be "ayc" > > "ayc".ACCEPTS("abc") == False > > --- > > > $_.say > (Any) > > > « a b c ».join() ~~ -> $a { say "\$a = $a\n\$_ = $_" } > $a = abc > $_ = abc > > > > « a b c ».join() ~~ ($_.say, -> $a { say "\$a = $a\n\$_ = $_" > }).tail > abc > $a = abc > $_ = abc > > > $_.say > (Any) > > > On Mon, Dec 9, 2019 at 7:34 PM William Michels <w...@caa.columbia.edu> wrote: >> >> Thank you Brad, for your in-depth reply. >> >> There are parts of your reply that make perfect sense to me, and also >> parts where I am still confused. I feel I understand your first three >> examples (1,2,3) explaining how the smartmatch operator relates to >> ACCEPTS(). However in the second three examples explaining "S///" >> (also numbered 1,2,3), I'm confused on Your Step 2. I've tried >> numerous examples, a few of which are reproduced below: >> >> mbook:~ homedir$ perl6 >> To exit type 'exit' or '^D' >> 1> my $a = « a b c ».join() >> abc >> 2> say $a ~~ s/b/y/ >> 「b」 >> 3> say $a >> ayc >> 4> my $probe = "AGCT" >> AGCT >> 5 > say $/ if $probe ~~ /"TCGA"/ ; >> () >> 6> say $/ if $probe ~~ /"AGCT"/ ; >> 「AGCT」 >> 7> say $/ if $probe ~~ s/"AGCT"/"TCGA"/ ; >> 「AGCT」 >> 8> say $probe >> "TCGA" >> 9> say $/ if $probe ~~ S/"TCGA"/"AGCT"/ ; >> Potential difficulties: >> Smartmatch with S/// is not useful. You can use given instead: >> S/// given $foo >> ------> say $/ if $probe ~~ S/"TCGA"/"AGCT"/ ; >> () >> 10> say $probe >> "TCGA" >> 11> say $_ >> abc >> 12> $*VM >> moar (2019.07.1) >> > >> >> For "S///" in your Step 1 the LHS is evaluated first (your Join >> example) and the LHS is temporarily set to $_. Then (your Step 2) the >> RHS is evaluated. Do you mean the RHS is evaluated in the context of >> $_ from the LHS?? Using your "abc" example I don't understand--if you >> **solely** look at the "S/b/./" operation--how the letters "a" and >> "c" show up in your Step 2 intermediate result. Of course, Raku/Perl6 >> may be far cleverer than I imagined--clever enough based on position >> and regex-rules (maybe) to simplify the two sides of the "S///" >> operator into a simple formula that can then be applied to the LHS. >> >> So in pseudocode, are you saying the following regarding "s///" >> (destructive-substitution) operation? >> >> 1. LHS: >> eval( "probe" ) --> $_ ; >> >> 2. RHS regex "target" between first two solidi of s/// or S/// : >> eval( "target".ACCEPTS( $_) ); >> >> 3. for s///, if above evaluates to TRUE match from above gets assigned >> to $/ and LHS "probe" gets overwritten with appropriate "substitution" >> characters between second two solidi of s/// or S/// : >> ( "match" --> $/ ) ; ( RHS_"substitution" --> "probe" ) ; >> >> [ 4. for S///, there is no possibility that Step 2 will evaluate to >> TRUE, so $/ is Nil and LHS "probe" remains as unchanged ]. >> >> If I'm close, please let me know. Meanwhile I will: 1) read over what >> you wrote again, and 2) play around with a little more example code, >> to gain a better understanding of what Raku/Perl6 is doing >> under-the-hood. >> >> Best Regards, Bill. >> >> >> >> On Sun, Dec 8, 2019 at 12:42 PM Brad Gilbert <b2gi...@gmail.com> wrote: >> > >> > 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 >> >> > >> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~