Front page | perl.perl5.porters |
Postings from May 2023
More on adding data checks in Perl
Thread Next
From:
Ovid
Date:
May 21, 2023 09:08
Subject:
More on adding data checks in Perl
Message ID:
CA+M4CHuDiBoXP3N_QHzBfHC6mTOT6emPuOV_O==gNXjehvFkdQ@mail.gmail.com
Hi all,
It seems like we're getting closer to consensus, but aren't quite there
yet. Admittedly, my desire to avoid discussing semantics has failed because
sometimes you *must* consider them, but please let's not bring up semantics
unless it's absolutely necessary. We're very close to being able to put
together a proposal here. I promise I'll follow-up with semantics later,
but probably on a github repo rather than on P5P (though I'll drop a link
here).
One glaring issue with the design of the data checks is this:
my @grades :of(HASH[HASH[INT]]);
There have been some previous, private discussions about this which revolve
around the SHOUTY nature of the check names. They're contentious, but there
are reasons for them. First, `perldoc -f ref` has this:
If the unblessed referent is not a scalar, then the return value
will be one of the strings "ARRAY", "HASH", "CODE",
"FORMAT", or "IO", ... and so on
So we're trying to mostly match the names to what `ref` returns,
though obviously INT, STR, NUM, and friends don't quite fit.
Second, we have this Fahrenheit to Celsius sub:
sub f_to_c ($f :of(NUM)) :returns(NUM) {...}
f_to_c(32) returns 0. f_to_c(-1000) returns -573.333333333333.
However, that doesn't really make sense, since that's below absolute zero.
So we have this:
check Celsius :isa(NUM[-273.14..inf]);
check Fahrenheit :isa(NUM[−459.67..inf]);
Which gives us a much safer, and self-documenting signature:
sub f_to_c ($f :of(Fahrenheit) :returns(Celsius) {...}
If you have an error in your user check definition, you can fix it one
place and it works everywhere. But honestly, there are plenty of times
where adding a custom check to a one-off definition is overkill. So we
allow my $count :of(INT) = 0;,
In other words, the SHOUTY version of the check names is a subtle
disaffordance against using the built-in checks since, semantically, they
don't tell us much, but you can still use them.
Another reason is that a user-defined check would be required to have at
least one lower-case letter in the name, making it possible to immediately
distinguish them from built checks.
We could be a touch more live Java and have built-ins lower-case and
require leading upper-case for user-defined. That increases the likelihood
that we'll have parsing issues if we encounter a check that matches a
keyword or a subroutine name. This problem is pretty much non-existent if
we use attributes. However, while my int $count = 0; isn't a big deal,
other uses are more complex. What's the syntax for returning checked values
from subs? Branislav would like to apply checks to expressions, not just
variables. If we want that, how would that work? These are certainly cases
where semantics and syntax overlap.
Best,
Ovid
Thread Next
-
More on adding data checks in Perl
by Ovid