Re: bikeshed: Typed Aliases

From: Date: Sat, 07 Sep 2024 00:46:28 +0000
Subject: Re: bikeshed: Typed Aliases
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message

> On Sep 6, 2024, at 16:40, Rob Landers <[email protected]> wrote:
> 
> 
> 
> On Sat, Sep 7, 2024, at 01:34, Larry Garfield wrote:
>> On Fri, Sep 6, 2024, at 6:27 PM, Rob Landers wrote:
>> 
>> >> I suspect there's also other edge case bits to worry about, particularly if
>> >> trying to combine a complex alias with a complex type, which could lead to violating the DNF rule. 
>> >> For example:
>> >
>> > Oh, DNF is the bane of my existence with this RFC—I don't want to mess 
>> > this up. I'll see you at the end of the example, though.
>> >
>> >> 
>> >> typealias Foo: (Bar&Baz)|Beep;
>> >> 
>> >> use (Bar&Baz)|Beep as Foo;
>> >> 
>> >> function narf(Foo&Stringable $s) {}
>> >> 
>> >> With the compile time approach, that would expand to
>> >> (Bar&Baz)|Beep&Stringable, which is not a valid type def.
>> >
>> > I can see how you arrived at this, but I think you may have missed a 
>> > step, since the entirety of Foo will be &'d with Stringable.
>> >
>> > Foo = (Bar & Baz) | Beep
>> >
>> > want: (Foo) & Stringable
>> >
>> > expand Foo: ((Bar & Baz) | Beep) & Stringable
>> >
>> > Which can be reduced to the following in proper DNF (at least, it 
>> > compiles—https://3v4l.org/0bMlP):
>> >
>> > (Beep & Stringable) | (Bar & Baz & Stringable)
>> >
>> > It's probably a good idea to update the RFC explaining how expansion works.
>> 
>> Woof.  We're not "fixingup" anyone's DNF elsewhere.  I cannot speak for
>> everyone, but I'd be perfectly fine not doing any magic fixing for now, and then debating
>> separately if we should do it more generally.  Just doing it for aliases doesn't seem like the
>> best plan.
>> 
>> --Larry Garfield
>> 
> 
> Oh, we're definitely not "fixingup" the expression to DNF... more like spending
> some time in the RFC showing how the expansion is the same execution as with a DNF expression to
> prove that it is a valid type expression.
> 
> — Rob

My main struggle with this is readability. As much as I want custom types (and type aliases is a
good chunk of the way there), the main issue I have is understanding what the valid inputs are:

function foo(Status $string): void { }

How do I know that Status is a) not a class, b) that I can fulfill the requirement with a string,
and/or maybe any object with __toString(), or maybe it’s ints? Or objects or enums?

Even with file-local aliases (which I would definitely prefer to avoid) we will most likely rely on
developer tooling (e.g. IDEs and static analyzers) to inform the developer what the right input
types are.

I would very much prefer to either go all in with an Enum-like (which means that we can hang methods
on to the value) or we need to distinguish between type hints for class-likes and type hints for
not-class-likes (*Bar anyone?).

Expanding on type-class-likes: within the type methods, $this->value would refer to the original
value, any operators would follow the _same_ rules as either the original values type (e.g. $int =
4; $string  = “foo”; $int . $string == “4foo", or call __toString() in all the normal
places for strings if defined).


type Stringable: string|int {
     public function __toString(): string
     {
          return (string) $this->value; // original value
     }

     // Add Stringable methods here
}.

So, with that in mind… I’d also like to open up the ability for Enums to be fulfilled by the
backed value, that is:

function foo(Bar $bar): void { }

Where Bar is:

enum Bar: string {
    case BAZ = 'baz';
    case BAT = ‘bat';
}

And you can call foo() like: foo(‘baz’) and  Bar::BAZ will be passed in. 

I realize I’m opening a barn down here, but I just don’t see file-local type aliases as that
useful, and while I like the functionality of type-class-likes, I think they would add more
non-class behavior (in addition to enums) for things that look like classes if we don’t add some
sort of identifier. I’d much rather that we add backed-value to enum casting, and at least make
that more consistent with this functionality if we’re going to conflate the syntax.

- Davey


Thread (25 messages)

« previous php.internals (#125463) next »