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 21:13
Subject:
Re: Learning the "ff" (flipflop) infix operator? (was Re: Rakuversion of "The top 10 tricks... .")
Message ID:
CAG2CFAb8LGhjOrE7g0VRJU7i1cb0y+W0sVWTRBBXoT+YexkK6w@mail.gmail.com
Issue golf, ff is always evaluating its RHS

$ raku -e 'say "With ff: ";say ( 1..5 ).grep({False ff .say}); say "With
fff: ";say ( 1..5 ).grep({False fff .say});'
With ff:
1
2
3
4
5
()
With fff:
()


-y


On Sun, Aug 2, 2020 at 2:16 PM yary <not.com@gmail.com> wrote:

> 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