On Monday, 27 December 2021, 20:28:22 CET, David Nicol <davidnicol@gmail.com> wrote:
On Mon, Dec 27, 2021 at 12:35 PM Ovid via perl5-porters <perl5-porters@perl.org> wrote:
> >
> > my @values = (in => "data.csv");
> > $values[2]++;
> >
> > Except that $values[2] was the string "n/a" and now it's "1".
>
> Huh? $values[2] was undefined.
I was imagining, from the example, that csv() returned an array ref (should have been an AoA for the example) and that a third field in which you're expecting a number was actually the string "n/a".
Some protest that we need to make sure our data is pristine to avoid that, but I'm sure most of us can tell stories of dirty data that can't be cleaned at the source.
> > The core of the idea is simple. it would be lovely to have something to prevent implicit coercion in a given lexical scope:
> >
> > use explicit;
> > my $num = 3; # integer
> > $num += .42; # fatal because it creates a float
> >
>
> What am I missing?
>
> sub increment_integers_or_die {
> defined(wantarray()) and croak("increment_integers_or_die called in non-void context");
> for my $numb (@_){
> /\D/ and die "NOT AN INTEGER: >>>$numb<<<\n";
> $numb++;
> }
> }
I'm sorry, David, but that's a perfect example of what we don't want to do (or maybe I'm just missing what you're trying to say).
We can think of code as business code (I'd say functional, but the terms overloaded) and structural. Business code is the code that does what it says on the ticket we've gotten. Structural code is the stuff that ties all of the business code together (the beautiful house versus the foundation, girders, wiring, etc.). If we have "pre-fab" structural code that solves common business code problems, that's less of that code that we have to write. For example, when was the last time most of us have had to write iterator classes in Perl. I haven't had to do it for years, except for lazy iterators (hmm ...) because I can iterate directly over arrays and hashes.
Sometimes it's nice to have a bit more strictness in the language and since Perl happily, and often silently, coerces our IVs, NVs, and PVs into each other (but I'm pretty sure it doesn't coerce your HVs, AVs, or GVs), even if we don't want that. So we have to write extra structural code to get our functional behavior. This means:
* More work for the developer to implement
* More things for the maintainer to learn
* More bugs as the newly implemented functional code is written incorrectly (as it is in your example)
More and more static languages are benefiting from being able to use dynamic features (the JVM has had invokedynamic for years). More and more dynamic languages are benefitting from being able to use static features. Sometimes that's a huge win.
I've had times where the following has bitten me had in JSON generation (pretty sure most of us have had things like this):
$ perl -MDevel::Peek -E 'my $x = 3; say Dump($x)'
SV = IV(0x1308244c0) at 0x1308244d0
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 3
$ perl -MDevel::Peek -E 'my $x = 3; warn $x; say Dump($x)'
3
SV = PVIV(0x149824c20) at 0x1498244d0
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 3
PV = 0x600002510270 "3"\0
CUR = 1
LEN = 10
In the second example, we now have a PV value for the scalar and we had a string in the JSON instead of an integer. The cause of that was because the client was *logging* their data and I had to dig around to figure out exactly where to put the "0+$var" as late as possible to fix this. Just for once, I would like to not have to worry about those issues any more.
Having at least IV, NV, PV, (and the new boolean type) not auto-coerce into one another for a given lexical scope (or data structure) would be heaven-sent.
Best,
Ovid
--
IT consulting, training, specializing in Perl, databases, and agile development
http://www.allaroundtheworld.fr/. Buy my book! -
http://bit.ly/beginning_perl --
"Lay off that whiskey, and let that cocaine be!" -- Johnny Cash