Re: Re: Alias for `int|float`
| From: | Olle Härstedt | Date: | Fri, 30 Sep 2022 14:53:05 +0000 |
| Subject: | Re: Re: Alias for `int|float` | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-118717@lists.php.net to get a copy of this message | ||
2022-09-30 12:15 GMT+02:00, Lynn <kjarli@gmail.com>:
> On Fri, Sep 30, 2022 at 11:04 AM Olle Härstedt <olleharstedt@gmail.com>
> wrote:
>
>> 2022-09-29 5:08 GMT+02:00, Hamza Ahmad <office.hamzaahmad@gmail.com>:
>> > Hi Olle,
>> >
>> > I appreciate your idea of introducing a similar concept of typedef.
>> > What if you write an RFC explaining that concept. I can join you
>> > however in co-authoring this request.
>> >
>> > Seriously, I have had issues with writing such type again and again.
>> > If you look at mixed type, it is indeed an alias of some union types.
>> > Adding such an option to userland would lead to introduction of
>> > various type hints. Plus, it will help devs write short hand aliases
>> > for their intersection types.
>>
>> Note that my suggestion here is NOT about a project-global type alias,
>> but an extension of the existing file-only alias, the use-statement.
>> This can also explain the lack of reaction. :) Internal devs might
>> already have consensus on the right way to proceed here, even if
>> there's no RFC yet.
>>
>> Olle
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: https://www.php.net/unsub.php
>>
>>
> I don't know if file based type aliases make sense, but just spitballing
> some ideas here.
> ```
> // core php or perhaps some libraries
> typedef number = int|float;
> typedef number<number $min> = TypeDef::extend('number', static fn (number
> $value, number $min) => $value >= $min);
> typedef number<?number $min, number $max> = TypeDef::extend('number',
> static fn (number $value, ?number $min, number $max) => ($min === null ||
> $value >= $min) && $value <= $max);
> typedef even = TypeDef::extend('number<?number $min, number $max>', static
> fn (number $value) => $value % 2 === 0);
> typedef positive = number<0>;
> typedef negative = number<max: 0>;
> typedef fraction = float<0, 1>;
> typedef string<int $min> = TypDef::extend('string', static fn (string
> $value, int $min) => strlen($value) >= $min);
> typedef string<?int $min, int $max> = TypeDef::extend('string', static fn
> (string $value, ?int $min, int $max) => length_is_between($value, $min,
> $max));
> typedef regex<string $expression> = TypeDef::extend('string', static fn
> (string $value, string $regex) => preg_match($regex, $value));
>
> namespace App\Domain;
>
> typedef NonEmptyString = string<1>; // minimum length of 1
> typedef LimitedString = string<null, 32>; // no minimum length, max length
> of 32
> // or typedef LimitedString = string<max: 32>; as alternative notation with
> named parameters
> typedef SomeToken = regex<'/a-z0-9{12}/i'>;
>
> // only allows even numbers ranging from -100 to 100
> function someFunction(even<-100, 100> $number) {}
>
> namespace Elsewhere;
>
> use App\Domain\NonEmptyString;
> use App\Domain\LimitedString;
> use App\Domain\SomeToken;
>
> someFunction(102); // fails
$max check from ðZ̉ûÚ‹ýß
> Mõi±ñnumber<min, max>
> someFunction(-99); // fails % 2 check from
> even
>
> ```
>
> I tried to use some consistency for the examples, by no means this is what
> I think it must look like, just making sure the intent of the examples is
> clear. This would be nothing more than syntactic sugar to what I'd
> otherwise write in custom objects to validate types and values and ensure
> type safety. This also doesn't take into account how operators should
> behave or how autoloading could/should behave.
Impressive repertoire of ideas, but probably out of scope from what I
was thinking of. :) Some call this "refinement types":
https://en.wikipedia.org/wiki/Refinement_type
Olle