develooper Front page | perl.perl6.users | Postings from August 2020

Re: Learning the "ff" (flipflop) infix operator? (was Re: Rakuversion of "The top 10 tricks... .")

Thread Previous | Thread Next
From:
yary
Date:
August 2, 2020 18:16
Subject:
Re: Learning the "ff" (flipflop) infix operator? (was Re: Rakuversion of "The top 10 tricks... .")
Message ID:
CAG2CFAbvCkwwRQAYF4Z9ZQ0vSw1PGg+H+-h12oEafB5=Nd_6Hg@mail.gmail.com
tl;dr: is this a Rakudo issue?

ooh a puzzle 😀 why do 'ff' and 'fff' give different results in this case?
The start & end are disjoint, the $++ should only run when the string test
is true, so I expect 'ff' and 'fff' to behave the same also.

Golfing a little

$ raku -e 'my @input=qw<nope + B C D - 1 - no + E F - 2 3 - never never + G
- 4 5 - hide>; \
say "With ff:  ",@input.grep({($_ eq "+" && $++ < 2) ff  ($_ eq "-" && $++
< 2)}); \
say "With fff: ",@input.grep({($_ eq "+" && $++ < 2) fff ($_ eq "-" && $++
< 2)});'

With ff:  (+ B C D - + E F - 2 3 - never never + G - 4 5 - hide)
With fff: (+ B C D - + E F -)

With both of these, the flip-flop turns on with the first '+' and turns off
with the first '-'
With both of these, the 2nd '+' turns on the flip-flop.
WIth 'ff', the flip-flop never turns off, with 'fff' the flip-flop turns
off when it encounters the next '-'

I wonder... let's have the end of the flip-flop say every time it runs

raku -e 'my @input=qw<nope + B C D - ?? - no + E F - !! ## - never never +
G - %% && - hide>; \
say "With ff: ";say @input.grep({($_ eq "+" && $++ < 2) ff  ("checking
$_".say && $_ eq "-" && say "increment to " ~ ++$ )}); \
say "With fff:";say @input.grep({($_ eq "+" && $++ < 2) fff ("checking
$_".say && $_ eq "-" && say "increment to " ~ ++$ )});'

With ff:
checking nope
checking +
checking B
checking C
checking D
checking -
increment to 1
checking ??
checking -
increment to 2
checking no
checking +
checking E
checking F
checking -
increment to 3
checking !!
checking ##
checking -
increment to 4
checking never
checking never
checking +
checking G
checking -
increment to 5
checking %%
checking &&
checking -
increment to 6
checking hide
(+ B C D - + E F -)
With fff:
checking B
checking C
checking D
checking -
increment to 1
checking E
checking F
checking -
increment to 2
(+ B C D - + E F -)

Hey gurus, why is the end check in 'ff' running so much more often than the
end check of 'fff' ?

ps. I had many weird errors, due to having "rake" installed, and having
something autocorrect my "raku" command-line to "rake"!!!

-y


On Sat, Aug 1, 2020 at 10:06 PM William Michels <wjm1@caa.columbia.edu>
wrote:

> Hi Yary, Nice code!
>
> The general approach of using an anonymous counter is useful to me. Below
> are  examples when I only want to recover the first one or two blocks of
> text starting with "Start" and ending with "Mark" (nota bene: I took your
> example text and deleted the blank lines):
>
> user@book:~$ raku -ne ' say $_ if ($_ eq "Start" && $++ < 1) fff ($_ eq
> "Mark" && $++ < 1);' yary_ff_example2.txt
> Start
> hi print me
> yes!
> Mark
> user@mbook:~$ raku -ne ' say $_ if ($_ eq "Start" && $++ < 1) ff ($_ eq
> "Mark" && $++ < 1);' yary_ff_example2.txt
> Start
> hi print me
> yes!
> Mark
> user@mbook:~$ raku -ne ' say $_ if ($_ eq "Start" && $++ < 2) fff ($_ eq
> "Mark" && $++ < 2);' yary_ff_example2.txt
> Start
> hi print me
> yes!
> Mark
> Start
> We're back!
> Mark
> user@mbook:~$ raku -ne ' say $_ if ($_ eq "Start" && $++ < 2) ff ($_ eq
> "Mark" && $++ < 2);' yary_ff_example2.txt
> Start
> hi print me
> yes!
> Mark
> Start
> We're back!
> Mark
> Still here!
> Start
> haha that Start does nothing
> going to end it now
> Mark
> !bye bye don't see me!
> user@mbook:~$
>
> I guess I have to say--I'm still a little surprised by the last result
> using the "ff" infix operator. I'd appreciate knowing why "ff" and "fff"
> behave differently in the last two examples, since the beginning marker
> doesn't look anything like the end marker (suggesting they should act
> identically). Also, is there a simpler way to write the conditional?
>
> Thx, Bill.
>
>
>
> On Sat, Aug 1, 2020 at 4:04 PM yary <not.com@gmail.com> wrote:
> >
> > This made me want to try a contrived puzzle, use 'fff' to show things
> between a "start" and 2nd "mark" line. That is, print any line below not
> marked with "!" at the start
> >
> > $ cat example.txt
> >
> > !ignore me
> >
> > Start
> >
> > hi print me
> >
> > yes!
> >
> > Mark
> >
> > still print me
> >
> > Mark
> >
> > !ignore this line
> >
> > !this line too
> >
> > Start
> >
> > We're back!
> >
> > Mark
> >
> > Still here!
> >
> > Start
> >
> > haha that Start does nothing
> >
> > going to end it now
> >
> > Mark
> >
> > !bye bye don't see me!
> >
> >
> > Let's see...ooh that was easy!!
> >
> > raku -ne '.say if "Start" ff ($_ eq "Mark" && ++$ %% 2)' example.txt
> >
> >
> > That increments the anonymous state variable $ and then checks if it is
> divisible by 2, so that only every 2nd Mark returns True
> >
> > Don't know if I'll ever need it, fun to have it.
> >
> > -y
> >
> >
> > On Tue, Jul 28, 2020 at 7:09 PM Brad Gilbert <b2gills@gmail.com> wrote:
> >>
> >> A regex doesn't have to match the entire string.
> >>
> >>     'abcd' ~~ / bc /
> >>     # 「bc」
> >>
> >> A string has to match exactly with the smart-match. (`ff` and `fff` do
> smart-match)
> >>
> >>     'abcd' ~~ 'bc' # False
> >>     'abcd' ~~ 'abcd' # True
> >>
> >> A string inside of a regex only makes that a single atom, it does not
> make it match like just a string.
> >>
> >>     'abcd' ~~ / 'bc' /
> >>     # 「bc」
> >>
> >>      'aBaBaB' ~~ / aB+ /
> >>     「aB」
> >>
> >>      'aBaBaB' ~~ / "aB"+ /
> >>     「aBaBaB」
> >>
> >> In fact a string inside of a regex doesn't do much more than square
> brackets.
> >>
> >>      'aBaBaB' ~~ / [aB]+ /
> >>     「aBaBaB」
> >>
> >> If you want the regex to match fully, add a beginning of string and end
> of string marker.
> >>
> >>     'abcd' ~~ / ^ bc $ /
> >>     # Nil
> >>
> >>     'abcd' ~~ / ^ abcd $ /
> >>     # 「abcd」
> >>
> >> ---
> >>
> >> Since `ff` can begin and end at the same time, the following is turning
> on and off at almost every iteration of the loop after it starts.
> >>
> >>     $ raku -ne '.put if /star {print q[on ]}/ ff /start {print q[off
> ]}/ ;' startling.txt
> >>     on star
> >>     on off start
> >>     on off startl
> >>     on off startli
> >>     on off startlin
> >>     on off startling
> >>
> >> On Tue, Jul 28, 2020 at 1:43 PM William Michels <wjm1@caa.columbia.edu>
> wrote:
> >>>
> >>> Thank you, Brad and Larry, for explaining the "ff" and "fff" infix
> >>> operators in Raku to me!
> >>>
> >>> I have to admit that I'm still fuzzy on the particulars between "ff"
> >>> and "fff", since I am not familiar with the sed function. I can
> >>> certainly understand how useful these functions could be to 'pull out
> >>> all PGP signatures' from a file (which was the Perl5 example given in
> >>> the Oracle Linux Blog). So I can now  pull out the html "head" section
> >>> from the page _ https://raku.org/fun/ _ (saved locally as file
> >>> "fun.txt") using the following Raku code:
> >>>
> >>> user@mbook:~$ raku -ne '.put if Q[<head>] ff Q[</head>]' fun.txt
> >>> <head>
> >>>     <meta charset="utf-8">
> >>>     <meta http-equiv="X-UA-Compatible" content="IE=edge">
> >>>     <meta name="viewport" content="width=device-width,
> initial-scale=1">
> >>>     <title>Raku is optimized for fun!</title>
> >>>
> >>>
> >>>     <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon">
> >>>     <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
> >>>     <link href="/bootstrap/css/bootstrap-theme.min.css"
> rel="stylesheet">
> >>>     <link href="/style.css?v=1" rel="stylesheet">
> >>>
> >>> </head>
> >>> user@mbook:~$
> >>>
> >>> What I'm less clear on is how the code below is functioning. I first
> >>> print out file named "startling.txt" with 'cat':  it's supposed to
> >>> stand in for a text delimited linewise by "header 1", "header 2", etc.
> >>> After the 'cat' example, I show three examples with Perl(v5.26.3) and
> >>> three examples with Raku(2020.06), generally comparing literal vs
> >>> regex arguments.
> >>>
> >>> The first two Perl5 examples returns nothing; the third Perl5 example
> >>> returns everything after the "star" line. For the Raku code, the
> >>> 'DWIMmiest' output below is the first Raku example, which returns two
> >>> lines, "star" and "start". This is what I expected/desired. But I'm
> >>> not really understanding what's happening with the other 2 Raku
> >>> examples (which return everything after the "star" line):
> >>>
> >>> user@mbook:~$ cat startling.txt
> >>> s
> >>> st
> >>> sta
> >>> star
> >>> start
> >>> startl
> >>> startli
> >>> startlin
> >>> startling
> >>>
> >>> user@mbook:~$ perl -nE 'print if "star" .. "start" ;' startling.txt
> >>> user@mbook:~$ perl -nE 'print if /"star"/ .. /"start"/ ;'
> startling.txt
> >>> user@mbook:~$ perl -nE 'print if /star/ .. /start/ ;' startling.txt
> >>> star
> >>> start
> >>> startl
> >>> startli
> >>> startlin
> >>> startling
> >>> user@mbook:~$ raku -ne '.put if "star" ff "start" ;' startling.txt
> >>> star
> >>> start
> >>> user@mbook:~$ raku -ne '.put if /"star"/ ff /"start"/ ;' startling.txt
> >>> star
> >>> start
> >>> startl
> >>> startli
> >>> startlin
> >>> startling
> >>> user@mbook:~$ raku -ne '.put if /star/ ff /start/ ;' startling.txt
> >>> star
> >>> start
> >>> startl
> >>> startli
> >>> startlin
> >>> startling
> >>> user@mbook:~$
> >>>
> >>> I'm all in favor of improving the "ff" and "fff" functions in Raku
> >>> over their Perl5 counterparts, but I'm hoping to gain a better
> >>> (mnemonic?) way of remembering the expected return values with literal
> >>> vs regex arguments.
> >>>
> >>> Any assistance appreciated, Bill.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> On Sun, Jul 26, 2020 at 10:04 AM Larry Wall <larry@wall.org> wrote:
> >>> >
> >>> > On Sat, Jul 25, 2020 at 04:32:02PM -0500, Brad Gilbert wrote:
> >>> > : In the above two cases ff and fff would behave identically.
> >>> > :
> >>> > : The difference shines when the beginning marker can look like the
> end
> >>> > : marker.
> >>> >
> >>> > The way I think of it is this:  You come to the end of "ff" sooner,
> so you
> >>> > do the end test immediately after passing the start test.  You come
> to the
> >>> > end of "fff" later, so the end test is delayed to the next iteration
> from
> >>> > the start test.  (Same mnemonic for .. and ... in Perl, by the way,
> since
> >>> > ff and fff were modeled on .. and ... (in their scalar form), but we
> stole
> >>> > .. and ... in Raku for ranges and sequences so we needed something
> else.)
> >>> >
> >>> > I suppose if you're musical you can come up with mnemonics based on
> "fff"
> >>> > being louder than "ff", so it echoes longer before it stops...  :)
> >>> >
> >>> > Larry
>

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About