Re: bikeshed: Typed Aliases

From: Date: Tue, 10 Sep 2024 08:00:56 +0000
Subject: Re: bikeshed: Typed Aliases
References: 1 2 3 4 5 6 7 8 9 10 11 12  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
> On Sep 9, 2024, at 5:35 PM, Rowan Tommins [IMSoP] <[email protected]> wrote:
> 
> On 09/09/2024 19:41, Mike Schinkel wrote:
>> In Go you cannot add or subtract on a typedef without casting to the 
>> underlying type.  I would definitely prefer that to be relaxed, but only
>>  if it is relaxed via an explicit opt-in, e.g. something maybe like 
>> this:
>> 
>> typedef UserId: int operations: +, -, *, /;
>> typedef UserName: string operations: .;
> I think this would stray into some of the same complexity as operator overloads on objects, in
> terms of the types and values allowed. For instance:
> 
I tend to agree that allowing operations may be too much for an initial scope given that it is
unlike anything else in the current language and with no other languages offering an equivalent
AFAIK.

I would however make the distinction that it is unlike operator overloading because the big concern
was what constituted an operation for any given type could be too subjective.  In your example of
Metres it is pretty obvious, but not at all obvious for a User, for
example.  (BTW, thank you for not calling out my nonsensical example of operations on a
UserId; when I wrote that I clear was not thinking about if they were relevant, doh!)

However give the suggestion regarding operations with a typedef, the only operations that I
suggested would be valid would be the ones already defined on the underlying type, (when I mentioned
other operations I was thinking of methods — see my the following example with round — not
operators so that is not the same as operator overload.) For example:

/**
 * Currency is an int so for example in USD 1 
 * unit of currency not a dollar but a cent.
 */
typedef Currency: int operations: +,-,*,/,round;
function CalcTotal(Currency $subTotal, Currency $shipping, float $tax):Currency {
   return round($subTotal*(1+$tax/100),0) + $shipping;
}
> typedef Metres: int;
> 
> assert( Metres(2) +  Metres(1) === Metres(3) ); // most obvious
> assert( Metres(2) + 1 === Metres(3) ); // seems pretty clear

Both of those are in line with what I was suggesting.
> $_GET['input'] = '1';
> assert( Metres(2) + $_GET['input'] === Metres(3) ); // might be more controversial
> 
I would not consider this appropriate as it has two levels of conversion and could thus end up with
unintended edge cases. To do the above I think you would have to either convert or typecast:

assert( Metres(2) + intval($_GET['input']) === Metres(3) ); 
assert( Metres(2) + (int)$_GET['input'] === Metres(3) ); 
> typedef Feet: int;
> assert( Metres(2) + Feet(1) === Metres(3) ); // almost certainly a bad idea
> 
This would be operator overloading where knowledge of the conversion between meters and feet would
be required, and that is not in any way in scope with what I was suggesting.  

As an aside, I am against userland operator overloading as I have seen in other languages that
operator overloading gets abused and results in code that is a nightmare to maintain. OTOH, I would
support operator overloading in specific cases, e.g. a Measurement class in PHP core
could allow adding meters to feet, assuming such a proposal were made and all other aspects of the
RFC were of the nature to be voted in.

To reiterate on typedefs, what I was suggesting was that if an operation was explicitly allowed —
e.g. + — then anything that would work with the underlying type — such as adding an int 1 would
work without typecasting and yet still result in the typedef type, e.g. Meters(2) + 1 results in a
value of type Meters. (note that I corrected your spelling of 'Meters' here. ;-) 

But I agree, this is probably a bridge too far for a first RFC for typedefs. 

>> type MyNewType: Foo
>> type MyAlias = Foo
> I know this was only an example, but as a general point, I think we should avoid concise but
> cryptic differences like this. PHP is generally keyword-heavy, rather than punctuation-heavy, and I
> think that's a valid style which we should keep to.
Here, I also tend to agree WRT PHP.  Was just pointing out for sake of laying out other options that
were implied not to exist.

-Mike



Thread (25 messages)

« previous php.internals (#125487) next »