develooper Front page | perl.perl5.porters | Postings from January 2022

Re: No implicit coercion?

Thread Previous | Thread Next
From:
Darren Duncan
Date:
January 7, 2022 09:27
Subject:
Re: No implicit coercion?
Message ID:
71045948-5d2f-f29b-8615-c9b912887f19@darrenduncan.net
I just saw this proposal now, holidays.

Ovid, now THIS proposal in principle is something I can strongly get behind, 
with just the details to discuss.

THIS proposal I feel more properly addresses the real problem that the 
so-called-3-valued-logic proposal seemed to be aimed at a symptom of and that I 
was never really comfortable with.

I also disagree with H.Merijn Brand's proposal that such functionality is tied 
to declared typed variables, because that approach is too limited.

A proper general solution addresses arbitrarily complex expressions at every 
stage of the expression tree, whose inputs and outputs are typically anonymous 
and not named variables.

Ovid's proposal and explicitly typed variables are complementary features, one 
is not a substitute for the other.

Also, applied consistently, Ovid's no implicit conversions proposal would NOT 
block re-assignment to a variable of values of different types, because no 
coersion is happening here.  Again, complementary ideas.  So eg "+=" would be 
blocked but "=" would not.

I also strongly support David Nichol's proposal to call the pragma "no coersion" 
rather than "use explicit" because the former is very clear what is going on, 
disabling an active behavior, while the latter is way too ambiguous, "explicit 
what", that doesn't say its about type coercion.

I also believe that Ovid's proposal should also handle the "undef" situation, 
meaning that "no coercion" ALSO causes attempts to use undef as if it were a 
defined value also fail.  You can test if an undef value is undef and you can 
assign undef to things, but you can't add to it or catenate it etc.

Note that in a stricter interpretation of Ovid's proposal that I prefer, using 
anything in a boolean context ALSO fails unless it is explicitly a boolean using 
that new real boolean feature.

And so, I see these things as all being distinct and mutually exclusive and that 
implicit coersion between them should be an error under the pragma:

- undef
- boolean
- integer
- float
- character string
- octet string

And that's before we get to any kind of reference type.

Note that I consider regexes to be specific to character strings and feeding 
them anything else should fail.

To go along with the pragma, there should be a simple consistent built-in 
function/operator for asking, using the strict definition consistent with 
otherwise using a debugging-type module, what kind of thing some $foo is.

And I mean for example builtin::is_int() only returns true for a PVIV or 
whatever its called, and NOT for a string that matches "\d+".

As for the set of explicit coercion functions, it should not simply be one 
overloaded one per target type named after the target type unless there is a 
clearly defined and reasonable single best way to convert.

So for example, "undef" can reasonably cast to a single value of every other 
type, boolean can reasonably cast to integer and float in one way, and integer 
to float in one way.

But beyond that there shouldn't really be single generic explicit casts, instead 
there should be one or more cast function/operator that is explicit in how it is 
casting.

For example, all float to integer casts should be named after what rounding 
method they are using when the float isn't an exact integer.  So no "to_int" but 
yes to the likes of "int_round_down/floor", "int_round_up/ceiling", 
"int_round_to_zero/truncate" etc.

Also number to string casts should be specifying the numeric base such as 
"to_text_base_10" or "to_text_base_16" or alternately just have people use a 
sprintf type function instead for that.

So while forbidding implicit conversions is the main goal, we want any explicit 
conversion routines to also be explicit on HOW they are converting, such as the 
examples I gave, or a lot of the benefits of the pragma are lost.

I have thought about all this a lot further while doing some of my own language 
design projects, so can go down the rabbit hole further if I'm asked.

-- Darren Duncan

On 2021-12-27 10:35 a.m., Ovid via perl5-porters wrote:
> Hi all,
> 
> This is not a pre-RFC, but I think most of us have been bitten at times by bugs like this:
> 
>      my @values = (in => "data.csv");
>      $values[2]++;
> 
> Except that $values[2] was the string "n/a" and now it's "1".
> 
> 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
> 
> Instead, we have to do this:
> 
>      use explicit;
>      my $num = 4;
>      $num = float($num);
>      # or `$num = 4.0;`
>      $num += .42; # works just fine
> 
> This would also be fatal:
> 
>      use explicit;
>      my $value = {};
>      say ++$value;

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