Front page | perl.perl5.porters |
Postings from August 2021
Re: Pre-RFC: Real "boolean" SV type
Thread Previous
|
Thread Next
From:
Nicholas Clark
Date:
August 5, 2021 07:29
Subject:
Re: Pre-RFC: Real "boolean" SV type
Message ID:
20210805072915.GI11066@etla.org
On Thu, Aug 05, 2021 at 11:26:07AM +1000, Tony Cook wrote:
> On Wed, Aug 04, 2021 at 03:58:19PM +0100, Paul "LeoNerd" Evans wrote:
> > I propose the addition of a new SV type, of SVt_BOOL. Should I write an
> > RFC?
> >
> > This type will act much like the existing "booleans" of PL_sv_no and
> > PL_sv_yes, except its type will remain distinct, so it will be possible
> > to distinguish "that SV is a boolean". This is a requirement for
> > certain kinds of data serialisation - such as JSON or MsgPack - and may
> > be useful for many other purposes too.
>
> I think having some sort of boolean type will be useful for
> serialization, I'm not sure svtype is the right place to distinguish
> them.
>
> Like PV, PVNV etc (and unlike PVAV, PVIO etc) an SV will tend to get
> upgraded as more capabilities are needed from it.
>
> If SVt_BOOL is a small SV type like SVt_IV, can such an SV have magic,
> or be blessed?
>
> If SVt_BOOL is a large type like SVt_PVMG, simple booleans will be
> paying an extra cost they don't need.
>
> It may need a flag instead.
It can't be implemented as a type.
Much like the "was this originally an integer/was this originally a string"
problem can't also be implemented as a type.
In that, if you need to bless a boolean, then it has to be SVt_PVMG.
And for certain operations, the *value* needs to pass through a PVLV without
loosing it's "I'm a boolean"-ness. I think tied hashes; but certainly this;
#!/usr/bin/perl -w
use strict;
use Devel::Peek;
sub foo {
my $val = 3.14;
print STDERR "Here's it's NV\n\n";
Dump $val;
print STDERR "\n\nWhat comes in is *funky*;\n\n";
Dump($_[0]);
$_[0] = 3.14;
}
my %h;
foo($h{pi});
print STDERR "\n\nWhat you end up with is PVNV:\n\n";
Dump(\%h);
__END__
Here's it's NV
SV = NV(0x11007a8) at 0x11007b0
REFCNT = 1
FLAGS = (NOK,pNOK)
NV = 3.14
What comes in is *funky*;
SV = PVLV(0x1113f18) at 0x10dffb0
REFCNT = 1
FLAGS = (GMG,SMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x1101f18
MG_VIRTUAL = &PL_vtbl_defelem
MG_TYPE = PERL_MAGIC_defelem(y)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x10e0190
SV = PV(0x10e09a0) at 0x10e0190
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x11130b8 "pi"\0
CUR = 2
LEN = 10
TYPE = y
TARGOFF = 0
TARGLEN = 1
TARG = 0x11007e0
FLAGS = 0
SV = PVHV(0x10e6420) at 0x11007e0
REFCNT = 2
FLAGS = (SHAREKEYS)
ARRAY = 0x0
KEYS = 0
FILL = 0
MAX = 7
What you end up with is PVNV:
SV = IV(0x10dffb0) at 0x10dffb0
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x11007e0
SV = PVHV(0x10e6420) at 0x11007e0
REFCNT = 2
FLAGS = (SHAREKEYS)
ARRAY = 0x1108d58 (0:7, 1:1)
hash quality = 100.0%
KEYS = 1
FILL = 1
MAX = 7
Elt "pi" HASH = 0x694d4f73
SV = PVNV(0x10deb28) at 0x10fb130
REFCNT = 1
FLAGS = (NOK,pNOK)
IV = 0
NV = 3.14
PV = 0
So PVLVs also have to be able to hold booleans.
Types aren't the way to go. A flag might be, but it might also be possible to
implement it as
true: SvPOK(sv) && SvPVX(sv) == PL_Yes)
false: SvPOK(sv) && SvPVX(sv) == PL_No)
and have Perl_sv_setsv_flags() do SV copies like that for booleans.
(That's the *only* place that copies SVs. So it can be changed.)
Also
We need an API to say "how should I best serialise this SV?"
(This became apparent during the "IVs vs PVs" thread but I hadn't replied to
it there.)
Abstract all the "logic" about what flags might mean what into a clear API,
so that
1) We can change the internals in the future
2) We can add it to ppport.h to express the "best effort' for the past.
Pass a SV, return a value from an enumeration, which I think *starts*
* undef
* boolean
* integer
* float
* string
but needs at least one escape hatch for "clearly this is a dualvar"
and it's also not clear how to handle overloaded references.
Unless the rule is that anything passed in that's SvROK() returns "reference"
and the caller gets to figure it out.
(And before anyone starts to argue that string should be spit into "bytes" and
"text" - you *can't* know that based on just SVf_UTF8. This isn't what we
want, but it *is* the way it is currently.)
So yes, please, an RFC on booleans would be great. But the language level
semantics are what are important first - I don't think that the correct
implementation is obvious yet.
Nicholas Clark
Thread Previous
|
Thread Next