Re: [PHP-DEV] Re: Alias for `int|float`
After reading through all of the suggestions above, I have come to this conclusion that all suggestion can be incorporated in the following ways: Types can exist in name spaces, Either in the global namespace or in the user defined name spaces. If one wants to import a type from a name space, it can easily use "use" statement per file. Alternatively, it can include a namespace and it does all that handy job for the dev. I agree with the idea of creating an RFC and document all use cases, possible ways to implement and also the features that can be added currently or will be left for the future scope. Regards Ahmad On 9/30/22, Olle Härstedt wrote: > 2022-09-30 17:16 GMT+02:00, Larry Garfield : >> On Fri, Sep 30, 2022, at 4:04 AM, Olle Härstedt wrote: >>> 2022-09-29 5:08 GMT+02:00, Hamza Ahmad : 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. >> >> Background: >> >> Type aliases have been discussed several times. > > Ya ok, not what I could find in externals.io ^^ > >> There's definitely >> interest, but like many things it runs into the problems of time and >> figuring out the details. >> >> In particular, I don't get the sense that there's much appetite for >> file-local aliases. While that would have some benefit, it could lead to >> all kinds of confusion when then using code from another file. Consider: >> >> A.php: >> >> use int|float as number; >> >> interface A >> { >> public function a(number $a) {} >> } >> >> B.php: >> >> // Yeah, aliasing this is very helpful. >> use (Request)|(ServerRequest)|array|null as input; >> >> interface B >> { >> public function b(input $b) {} >> } >> >> C.php: >> >> class C implements A, B >> { >> // Which of these to use? >> public function a(int|float $a) {} >> public function a(number $a) {} >> // Or do I need to repeat the definition of "number" in every file? > > Yes, you would. That's the limit of my current suggestion. Same > semantics as use-statements. > >> // WTF do I do here? Do I have to repeat the entire definition either >> // inline or in this file's "use" block? Both suck. >> public function b(...) > > Neither suck. :) Just "normal" inheritance boilerplate in the absence > of project-global type aliasing. > > Do you have similar counter-examples for non-OOP code? > >> } >> >> >> This becomes even more of an issue when you start talking about function >> types, which is often mentioned as the primary use case. >> >> type fn(int $a, string $b): Request as mycallback >> >> function do(mycallback $callback) {} >> >> So I have to duplicate the type def in every file now? This is not an >> improvement. > > It's an improvement for readability, especially when repeated in one > file. But my suggestion does not include function-types, because > there's no such thing already in the system. Just to let use-statement > include more of already existing types. If function-types were added > later, they should be supported too, yes. > >> >> So we have to go with app-global aliases, but then... how do you handle >> resolution? Autoloading? Namespacing? Conflict resolution? I dunno, >> that's all hard, and that's where the conversation usually peters out. > > Yeah, always better to have a clear limitation, is it not? :D > >> The degenerate case you mention of simple type renaming has its own >> interesting implications, which are also a factor for the broader case. >> Specifically, does that create a new type unto itself > > No. Keep the same semantics of the current use-statement. But it could > be a future extension, sure. But then you need some kind of "factory" > way to produce those types. In FP they do it with "abstract types", > where the implementation of a type is hidden from outside the module. > In PHP, maybe with Foo::make() functions or such. Different > discussion. > >> or does the >> difference get elided at compile time? For instance: >> >> use int as userId; >> use int as productId; >> >> function a(userId $user) { >> b($userId); >> } >> >> function b(productId $product) { >> // ... >> } >> >> a(123); >> >> >> Does this work? Is it a compile error for mismatched types (as in Go, >> which >> has this exact feature) or no? If it
Re: [PHP-DEV] Re: Alias for `int|float`
2022-09-30 17:16 GMT+02:00, Larry Garfield : > On Fri, Sep 30, 2022, at 4:04 AM, Olle Härstedt wrote: >> 2022-09-29 5:08 GMT+02:00, Hamza Ahmad : >>> 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. > > Background: > > Type aliases have been discussed several times. Ya ok, not what I could find in externals.io ^^ > There's definitely > interest, but like many things it runs into the problems of time and > figuring out the details. > > In particular, I don't get the sense that there's much appetite for > file-local aliases. While that would have some benefit, it could lead to > all kinds of confusion when then using code from another file. Consider: > > A.php: > > use int|float as number; > > interface A > { > public function a(number $a) {} > } > > B.php: > > // Yeah, aliasing this is very helpful. > use (Request)|(ServerRequest)|array|null as input; > > interface B > { > public function b(input $b) {} > } > > C.php: > > class C implements A, B > { > // Which of these to use? > public function a(int|float $a) {} > public function a(number $a) {} > // Or do I need to repeat the definition of "number" in every file? Yes, you would. That's the limit of my current suggestion. Same semantics as use-statements. > // WTF do I do here? Do I have to repeat the entire definition either > // inline or in this file's "use" block? Both suck. > public function b(...) Neither suck. :) Just "normal" inheritance boilerplate in the absence of project-global type aliasing. Do you have similar counter-examples for non-OOP code? > } > > > This becomes even more of an issue when you start talking about function > types, which is often mentioned as the primary use case. > > type fn(int $a, string $b): Request as mycallback > > function do(mycallback $callback) {} > > So I have to duplicate the type def in every file now? This is not an > improvement. It's an improvement for readability, especially when repeated in one file. But my suggestion does not include function-types, because there's no such thing already in the system. Just to let use-statement include more of already existing types. If function-types were added later, they should be supported too, yes. > > So we have to go with app-global aliases, but then... how do you handle > resolution? Autoloading? Namespacing? Conflict resolution? I dunno, > that's all hard, and that's where the conversation usually peters out. Yeah, always better to have a clear limitation, is it not? :D > The degenerate case you mention of simple type renaming has its own > interesting implications, which are also a factor for the broader case. > Specifically, does that create a new type unto itself No. Keep the same semantics of the current use-statement. But it could be a future extension, sure. But then you need some kind of "factory" way to produce those types. In FP they do it with "abstract types", where the implementation of a type is hidden from outside the module. In PHP, maybe with Foo::make() functions or such. Different discussion. > or does the > difference get elided at compile time? For instance: > > use int as userId; > use int as productId; > > function a(userId $user) { > b($userId); > } > > function b(productId $product) { > // ... > } > > a(123); > > > Does this work? Is it a compile error for mismatched types (as in Go, which > has this exact feature) or no? If it is, how do you make it work? Do you > need explicit casts? If it does work, have you gained much since it's no > more useful than docblocks? If it does work, how long before SA tools turn > it into an error anyway and make everything more complicated? (Because you > know they will.) Not sure I agree with you there. Obviously, static analyzers would have to abide to the semantics of the core language, no...? > Does the same answer apply for longer type aliases like the nutty ones in > the earlier examples? > > These are the kinds of questions that need to be answered before any serious > RFC could be attempted. Isn't an RFC a good place to document all these cases? I was thinking that an RFC could be a good place even for things we do NOT want to implement. to help pave the way for features we
Re: [PHP-DEV] Re: Alias for `int|float`
On Fri, Sep 30, 2022, at 4:04 AM, Olle Härstedt wrote: > 2022-09-29 5:08 GMT+02:00, Hamza Ahmad : >> 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. Background: Type aliases have been discussed several times. There's definitely interest, but like many things it runs into the problems of time and figuring out the details. In particular, I don't get the sense that there's much appetite for file-local aliases. While that would have some benefit, it could lead to all kinds of confusion when then using code from another file. Consider: A.php: use int|float as number; interface A { public function a(number $a) {} } B.php: // Yeah, aliasing this is very helpful. use (Request)|(ServerRequest)|array|null as input; interface B { public function b(input $b) {} } C.php: class C implements A, B { // Which of these to use? public function a(int|float $a) {} public function a(number $a) {} // Or do I need to repeat the definition of "number" in every file? // WTF do I do here? Do I have to repeat the entire definition either // inline or in this file's "use" block? Both suck. public function b(...) } This becomes even more of an issue when you start talking about function types, which is often mentioned as the primary use case. type fn(int $a, string $b): Request as mycallback function do(mycallback $callback) {} So I have to duplicate the type def in every file now? This is not an improvement. So we have to go with app-global aliases, but then... how do you handle resolution? Autoloading? Namespacing? Conflict resolution? I dunno, that's all hard, and that's where the conversation usually peters out. The degenerate case you mention of simple type renaming has its own interesting implications, which are also a factor for the broader case. Specifically, does that create a new type unto itself, or does the difference get elided at compile time? For instance: use int as userId; use int as productId; function a(userId $user) { b($userId); } function b(productId $product) { // ... } a(123); Does this work? Is it a compile error for mismatched types (as in Go, which has this exact feature) or no? If it is, how do you make it work? Do you need explicit casts? If it does work, have you gained much since it's no more useful than docblocks? If it does work, how long before SA tools turn it into an error anyway and make everything more complicated? (Because you know they will.) Does the same answer apply for longer type aliases like the nutty ones in the earlier examples? These are the kinds of questions that need to be answered before any serious RFC could be attempted. Answers for them can certainly be found, but so far no one has really done the work, in particular around how to make aliases cleanly global. If you're interested in tackling that, fantastic; I think most people would be on board with it (especially for function types). But be aware it's a not-small puddle you're wading into. (I think Danack had a writeup similar to this but it went a bit further; not sure where it is off hand, but he probably knows.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Re: Alias for `int|float`
2022-09-30 12:15 GMT+02:00, Lynn : > On Fri, Sep 30, 2022 at 11:04 AM Olle Härstedt > wrote: > >> 2022-09-29 5:08 GMT+02:00, Hamza Ahmad : >> > 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 = TypeDef::extend('number', static fn (number > $value, number $min) => $value >= $min); > typedef number = TypeDef::extend('number', > static fn (number $value, ?number $min, number $max) => ($min === null || > $value >= $min) && $value <= $max); > typedef even = TypeDef::extend('number', static > fn (number $value) => $value % 2 === 0); > typedef positive = number<0>; > typedef negative = number; > typedef fraction = float<0, 1>; > typedef string = TypDef::extend('string', static fn (string > $value, int $min) => strlen($value) >= $min); > typedef string = TypeDef::extend('string', static fn > (string $value, ?int $min, int $max) => length_is_between($value, $min, > $max)); > typedef regex = 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; // no minimum length, max length > of 32 > // or typedef LimitedString = string; 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 `number` > 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC: StreamWrapper Support for glob()
Hi, On Sun, Sep 18, 2022 at 11:02 PM Timmy Almroth wrote: > Hi @Dan, hi @Sara. Thanks for giving us your feedback on this. > > > I think that although the RFC discussion can go ahead without a patch, > > it would be better to have a patch before it went to vote, as there > > seem to be quite a few hidden details that might not be able to be > > made to work. > > I wanted that too. But it's hard to find someone willing to invest the time > and effort. And it's even harder when that time invested is not guaranteed > to lead to something. Therefore a PoC patch was produced that should give a > good understanding of what is intended. It was not my choice but I > understood the reasons. > > I had a quick look to that PoC and it's basically just a quick wrapper that depends on GLOB_ALTDIRFUNC. Unfortunately that's a non standard extension that might be missing on some platform (e.g. alpine won't probably work because from a quick look the musl libc doesn't seeem to implement it - https://git.musl-libc.org/cgit/musl/tree/include/glob.h ). The code obviously needs more work and we will need bunch of tests for this. Well obviously it's just a PoC but what I want to say is that implementation is really main thing here and should also help to provide more details in RFC. For example it's not currently clear that you would change underlaying glob implementation on some platforms - quite important thing to mention though. To be honest if there is a good implementation, I think it's quite unlikely that the RFC will fail. Regards Jakub
Re: [PHP-DEV] Re: Alias for `int|float`
On Fri, Sep 30, 2022 at 11:04 AM Olle Härstedt wrote: > 2022-09-29 5:08 GMT+02:00, Hamza Ahmad : > > 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 = TypeDef::extend('number', static fn (number $value, number $min) => $value >= $min); typedef number = TypeDef::extend('number', static fn (number $value, ?number $min, number $max) => ($min === null || $value >= $min) && $value <= $max); typedef even = TypeDef::extend('number', static fn (number $value) => $value % 2 === 0); typedef positive = number<0>; typedef negative = number; typedef fraction = float<0, 1>; typedef string = TypDef::extend('string', static fn (string $value, int $min) => strlen($value) >= $min); typedef string = TypeDef::extend('string', static fn (string $value, ?int $min, int $max) => length_is_between($value, $min, $max)); typedef regex = 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; // no minimum length, max length of 32 // or typedef LimitedString = string; 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 `number` 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.
Re: [PHP-DEV] Re: Alias for `int|float`
2022-09-29 5:08 GMT+02:00, Hamza Ahmad : > 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
Re: [PHP-DEV] Re: Alias for `int|float`
Sadly, I am disappointed with the way this suggestion has been looked down on. On 9/29/22, Olle Härstedt wrote: > 2022-09-29 12:33 GMT+02:00, Ryan Jentzsch : >> `number` type But frankly this seems a bit silly and reminds me too much >> of >> JavaScript. > > That's just an example. You can also consider `use array|ArrayAccess > as arraylike`, or such. > > Olle > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php