in reply to Why is Dumper returning "!!1" for true file test?

While 0 and 1 evaluate to false and true when tested, there is (was?) no real boolean type.

And !!0 is a special dual var, which is "" in string, and 0 in numeric context

Not having Booleans in Perl makes converting data from and to JSON problematic.

I seem to remember that Booleans were introduced with one of the last Perl releases.

So using !!0 and !!1 is both backwards and forward compatible.

Think of them as replacements for the keywords true and false found in languages like JS

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: Why is Dumper returning "!!1" for true file test?
by nysus (Parson) on Jan 20, 2024 at 17:58 UTC

    I just started using the latest version of Perl from version 5.32. I hadn't heard about the new booleans. Hadn't heard about !!0 and !!1 either.

    These are definitely a weird beast. When I did print Dumper !!1 I expected it to print 1 but in fact it printed $VAR 1= !!1. This must be the dual var nature you refer to.

    Is there a basic tutorial on all this?

    $PM = "Perl Monk's";
    $MC = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar Parson";
    $nysus = $PM . ' ' . $MC;
    Click here if you love Perl Monks

      I hadn't heard about the new booleans.

      They're not new. They've existed for a very long time. At least since Perl 5.6 in 2000, but probably long before that. What was missing were functions whose sole purpose was to return them. That's what was recently introduced. And that's why we used !!0 and !!1 to produce them before that.

        Perl 5.36 does have "new" booleans. Copies of the immortal &PL_sv_yes and &PL_sv_no values are still identifiable as booleans. This means they can be serialized more accurately. The latest versions of JSON::PP, Data::Dumper, and Storable all support this.

        Prior to perl 5.36 it was not possible to identify a boolean true value after it had been copied. The exact same SV type, flags, and values could be produced by normal usage of a string "1". A boolean false would be more identifiable as it would never be produced naturally, requiring dualvar to construct.

        > What was missing is a function whose sole purpose was to return them. That's what was recently introduced. And that's why we used !!0 and !!1 to produce them before that.

        Are you referring to builtin::true etc. in builtin? Nobody has mentioned them yet in this thread.

        Or are you talking about the internal &PL_sv_yes ?

        On a side note: shouldn't it be possible to activate true and false while silencing the warnings with just one pragma?

        use experimental qw/builtin/; use builtin qw/true false/; use Data::Dump; ddx $]; dd [true,false] __END__ # bool.pl:6: "5.036000" [1, ""]

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery

      > Hadn't heard about !!0 and !!1 either.

      I hope it's clear that ! is just the logical negation operator.

      Double negations are a very common idiom, you will find it in many languages, also in JS.

      !!$a is in the same idiomatic niche like 0+$a or "".$a of explicit casting to a certain type without altering the value. Just Boolean now instead of number or string.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        Ok, thanks, I wasn't sure. I thought maybe they adopted "!!0" and "!!1" and imbued it with some special meaning beyond double negation.

        $PM = "Perl Monk's";
        $MC = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar Parson";
        $nysus = $PM . ' ' . $MC;
        Click here if you love Perl Monks

      I'm not aware of a single perldoc discussing all details, like it's done in MDN for JS.

      (Especially as it's mostly internal stuff which could change and the effects are supposed to be DWIM. Like I said most problems arise when converting to other languages, esp. JS)

      But you can gather them from various places like perlop or perlglossary .

      FWIW and I don't think !!1 used to be dualvar (see Scalar::Util ) prior to 5.36.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        FWIW and I don't think !!1 used to be dualvar (see Scalar::Util ) prior to 5.36.

        It's actually a triplevar, and it has been so at least as far back as 5.6, but probably a lot further back.

        I don't have 5.6, but here's 5.8.9:

        $ 5.8.9/bin/perl -MDevel::Peek -e'Dump(!!1)' SV = PVNV(0x55e2de0d1348) at 0x55e2dd477310 REFCNT = 2147483647 FLAGS = (IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x55e2de0d2320 "1"\0 CUR = 1 LEN = 8 $ 5.8.9/bin/perl -MDevel::Peek -e'Dump(!!0)' SV = PVNV(0x55aeb71e8320) at 0x55aeb5e05da0 REFCNT = 2147483647 FLAGS = (IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x55aeb71e8300 ""\0 CUR = 0 LEN = 8
Re^2: Why is Dumper returning "!!1" for true file test?
by NERDVANA (Priest) on Jan 20, 2024 at 23:38 UTC
    The real question is why it returns "!!0" and "!!1" instead of "!1" and "!0". Saves a character and a runtime op...
      > Saves a character and a runtime op...

      And is confusing because you need to mentally negate it again, while !! is a common idiom.

      But the performance question occurred to me already I kind of expected constant folding to happen.

      update

      ha, indeed! :)

      DB<5> p B::Deparse->new()->coderef2text( sub{!!1} ) { use feature ... ; # shortened !0; } DB<6> p B::Deparse->new()->coderef2text( sub{!!0} ) { use feature ... ; # yadda !1; } DB<7> p $] 5.038002

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery