[RFC] [DISCUSSION] Scalar Pseudo-type

php.internals

Fleshgrinder

8 years ago
Hi Internals! I prepared a PR to add the `scalar` pseudo-type to PHP after the discussions around adding a `mixed` pseudo-type. I strongly believe that it makes sense to provide the most common primitive union types with handy aliases even if we are going to add union types in the future to PHP. https://github.com/php/php-src/pull/2987 I added support for parameter type covariance and return type contravariance to make it as useful in daily development as possible. I will provide the RFC write-up asap at: https://wiki.php.net/rfc/scalar-pseudo-type
-- Richard "Fleshgrinder" Fussenegger

Nikita Popov

8 years ago
On Sun, Dec 24, 2017 at 3:34 PM, Fleshgrinder <php@fleshgrinder.com> wrote:
> Hi Internals! > > I prepared a PR to add the `scalar` pseudo-type to PHP after the > discussions around adding a `mixed` pseudo-type. I strongly believe that > it makes sense to provide the most common primitive union types with > handy aliases even if we are going to add union types in the future to PHP. > > https://github.com/php/php-src/pull/2987 > > I added support for parameter type covariance and return type > contravariance to make it as useful in daily development as possible. > > I will provide the RFC write-up asap at: > > https://wiki.php.net/rfc/scalar-pseudo-type >
I think this RFC could benefit from displaying some use-cases for this type annotation. I can't recall any recent instance where I would have found this specific type combination useful, though I'm sure there are good examples. I also wonder whether in weak typing mode, scalar should also accept __toString objects (and cast them to string), similarly to how a bool|int|float|string union would behave. Nikita

Fleshgrinder

8 years ago
On 12/24/2017 5:30 PM, Nikita Popov wrote:
> I think this RFC could benefit from displaying some use-cases for this type > annotation. I can't recall any recent instance where I would have found > this specific type combination useful, though I'm sure there are good > examples. > > I also wonder whether in weak typing mode, scalar should also accept > __toString objects (and cast them to string), similarly to how a > bool|int|float|string union would behave. > > Nikita >
I will extend it with some examples. I guess that that would be useful in weak mode. Will try to hack it in. I am currently also working on another RFC that adds a `Convertible` interface with a single `into` method that has its return type set to `scalar` where objects can opt-in to become `scalar` compatible. Even in strict mode. The idea is that the object's `into` method is automatically called by the engine and the receiver gets the canonical `scalar` value that represents the object. This is specifically useful for value objects that often represent single `scalar` values in a type safe manner.
-- Richard "Fleshgrinder" Fussenegger

Fleshgrinder

8 years ago
On 12/24/2017 5:42 PM, Fleshgrinder wrote:
> I will extend it with some examples. > > I guess that that would be useful in weak mode. Will try to hack it in. > > I am currently also working on another RFC that adds a `Convertible` > interface with a single `into` method that has its return type set to > `scalar` where objects can opt-in to become `scalar` compatible. Even in > strict mode. The idea is that the object's `into` method is > automatically called by the engine and the receiver gets the canonical > `scalar` value that represents the object. This is specifically useful > for value objects that often represent single `scalar` values in a type > safe manner. >
Added some examples but I will stop now working on anything because people already start complaining again. Contributing to PHP is like kicking a combat dog ... let's wait for some support for this feature in general first.
-- Richard "Fleshgrinder" Fussenegger

Sebastian Bergmann

8 years ago
Am 24.12.2017 um 15:34 schrieb Fleshgrinder:
> I prepared a PR to add the `scalar` pseudo-type to PHP after the > discussions around adding a `mixed` pseudo-type. I strongly believe that > it makes sense to provide the most common primitive union types with > handy aliases even if we are going to add union types in the future to PHP.
Thank you, Richard, for working on this. I spent a lot of time this year introducing scalar type declarations into existing code bases. In quite a few cases I was not able to do so because the existing code works with parameters that can be of two or more scalar types. With PHP 7.2, I can only document this outside of the code using @param annotations (until the code has been refactored to work with only one parameter type). With a "scalar" type declaration I would not have to fall back to @param annotations and could express the type in actual syntax.

Niklas Keller

8 years ago
> > Am 24.12.2017 um 15:34 schrieb Fleshgrinder: > > I prepared a PR to add the `scalar` pseudo-type to PHP after the > > discussions around adding a `mixed` pseudo-type. I strongly believe that > > it makes sense to provide the most common primitive union types with > > handy aliases even if we are going to add union types in the future to > PHP. > > Thank you, Richard, for working on this. > > I spent a lot of time this year introducing scalar type declarations into > existing code bases. In quite a few cases I was not able to do so because > the existing code works with parameters that can be of two or more scalar > types. With PHP 7.2, I can only document this outside of the code using > @param annotations (until the code has been refactored to work with only > one parameter type). > > With a "scalar" type declaration I would not have to fall back to @param > annotations and could express the type in actual syntax. >
If you want just two of those and not all, you'd still have to use PHPdoc for those? IIRC you voted against union types, which would be a better fit in that case? Regards, Niklas

lists@rhsoft.net

8 years ago
Am 26.12.2017 um 14:38 schrieb Sebastian Bergmann:
> Thank you, Richard, for working on this. > > I spent a lot of time this year introducing scalar type declarations into > existing code bases. In quite a few cases I was not able to do so because > the existing code works with parameters that can be of two or more scalar > types. With PHP 7.2, I can only document this outside of the code using > @param annotations (until the code has been refactored to work with only > one parameter type). > > With a "scalar" type declaration I would not have to fall back to @param > annotations and could express the type in actual syntax
https://wiki.php.net/rfc/union_types sebastian (sebastian) - voted NO would you mind to explain this?

Sebastian Bergmann

8 years ago
Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net:
> would you mind to explain this?
"Foo|Bar", "array|string", etc. (still) make no sense to me. "scalar" makes sense to me although it is but an alias for "bool|float|int|string".

lists@rhsoft.net

8 years ago
Am 26.12.2017 um 16:56 schrieb Sebastian Bergmann:
> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >> would you mind to explain this? > > "Foo|Bar", "array|string", etc. (still) make no sense to me. > > "scalar" makes sense to me although it is but an alias for > "bool|float|int|string".
honestly *that* makes no sense for me with "float|int" you would have no need for dozens of aliases, in that case "numeric" when i expect some number but not a string and not a boolean return by a strpos() or similar functions also i have function which allows "int|array" where the internal logic loops the array internally but i don't want a random boolean or string there it's all about express accepted types as strict as possible in code to find errors early and in strict_types mode even the caller which needs to be fixed in the stack-trace

Larry Garfield

8 years ago
On Tuesday, December 26, 2017 9:56:21 AM CST Sebastian Bergmann wrote:
> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: > > would you mind to explain this? > > "Foo|Bar", "array|string", etc. (still) make no sense to me. > > "scalar" makes sense to me although it is but an alias for > "bool|float|int|string".
If I may, I think the argument has always been that 1) Foo & Bar makes total sense 2) int|float makes total sense 3) int & string is illogical so wouldn't matter anyway 4) Foo|Bar rarely makes sense but may sometimes, and its legality is an acceptable trade-off to get the first two. In previous discussions it always seemed that people fixated on case 4 and ignored the usefulness of cases 1 and 2. --Larry Garfield

lists@rhsoft.net

8 years ago
Am 26.12.2017 um 19:18 schrieb Larry Garfield:
> On Tuesday, December 26, 2017 9:56:21 AM CST Sebastian Bergmann wrote: >> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >>> would you mind to explain this? >> >> "Foo|Bar", "array|string", etc. (still) make no sense to me. >> >> "scalar" makes sense to me although it is but an alias for >> "bool|float|int|string". > > If I may, I think the argument has always been that > > 1) Foo & Bar makes total sense > 2) int|float makes total sense > 3) int & string is illogical so wouldn't matter anyway
not true function x(int|string $x) { $x = (int)$x; } $x can be simply from a database simply because without MYSQLI_OPT_INT_AND_FLOAT_NATIVE which is sadly not default you get everything back as string and so you can place the casting in the function instead of every single caller in strict_types mode while you don#t accept object, array or boolean here why not cast a boolean here? in case of the result of strpos() in the caller is false it likely should not call the function anyways but handle that error itself
> 4) Foo|Bar rarely makes sense but may sometimes, and its legality is an > acceptable trade-off to get the first two. > > In previous discussions it always seemed that people fixated on case 4 and > ignored the usefulness of cases 1 and 2
as this is a programming language it's up to the user who writes the code in the language what is useful for his case - so if one is fixated on 3 or 4 because they would become possible the argumentation is strange anyways and "etc. (still) make no sense to me" is a personal opinion which hardly justifies a downvote at all unless there are real technical reasons in my total valid usecase of 3) above in strict_types mode i must ommit the typehint at all or modify every single caller and that alone would justify unions

Rowan Collins

8 years ago
On 26 December 2017 18:35:29 GMT+00:00, "lists@rhsoft.net" <lists@rhsoft.net> wrote:
> > >Am 26.12.2017 um 19:18 schrieb Larry Garfield: >> If I may, I think the argument has always been that >> >> 1) Foo & Bar makes total sense >> 2) int|float makes total sense >> 3) int & string is illogical so wouldn't matter anyway > >not true > >function x(int|string $x) >{ > $x = (int)$x; >}
I think there's a misunderstanding here. Some previous proposals for "union types" also included "intersection types", so that you could assert "parameter must implement both of these interfaces". So 'Foo|Bar $x' would mean '$x instanceof Foo || $x instanceof Bar' and 'Foo&Bar $x' would mean '$x instanceof Foo && $x instanceof Bar'. I presume that's what Larry means by "int & string is illogical", because it would translate to "is_int($x) && is_string($x)", which is false for all values of $x. This is different from "int | string", which, as you say, might have valid uses. Regards,
-- Rowan Collins [IMSoP]

Larry Garfield

8 years ago
On Wednesday, December 27, 2017 3:50:54 AM CST Rowan Collins wrote:
> On 26 December 2017 18:35:29 GMT+00:00, "lists@rhsoft.net"
<lists@rhsoft.net> wrote:
> >Am 26.12.2017 um 19:18 schrieb Larry Garfield: > >> If I may, I think the argument has always been that > >> > >> 1) Foo & Bar makes total sense > >> 2) int|float makes total sense > >> 3) int & string is illogical so wouldn't matter anyway > > > >not true > > > >function x(int|string $x) > >{ > > > > $x = (int)$x; > > > >} > > I think there's a misunderstanding here. Some previous proposals for "union > types" also included "intersection types", so that you could assert > "parameter must implement both of these interfaces". So 'Foo|Bar $x' would > mean '$x instanceof Foo || $x instanceof Bar' and 'Foo&Bar $x' would mean > '$x instanceof Foo && $x instanceof Bar'. > > I presume that's what Larry means by "int & string is illogical", because it > would translate to "is_int($x) && is_string($x)", which is false for all > values of $x. This is different from "int | string", which, as you say, > might have valid uses. > > Regards,
Correct. Union types I've always seen presented as offering both union and intersection. There are cases where union is great, and where it's kinda silly. There are cases where intersect is great, and where it's kinda silly. Most of the anti- arguments I've seen for "union types" have fixated on "int && string is meaningless, and Foo || Bar is bad design, so union types are bad!" Entirely ignoring the flip side, which is int || string (valid use cases) and Foo && Bar (many many valid use cases). --Larry Garfield

lists@rhsoft.net

8 years ago
Am 29.12.2017 um 00:21 schrieb Larry Garfield:
> Correct. Union types I've always seen presented as offering both union and > intersection. There are cases where union is great, and where it's kinda > silly. There are cases where intersect is great, and where it's kinda silly. > > Most of the anti- arguments I've seen for "union types" have fixated on "int && > string is meaningless, and Foo || Bar is bad design, so union types are bad!" > Entirely ignoring the flip side, which is int || string (valid use cases) and > Foo && Bar (many many valid use cases)
well, that explains why the same person which hase a usecase for a "scalar" pseudo-type donw-votes https://wiki.php.net/rfc/union_types but it makes his vote not logical at all frankly the only valid reasons to down-vote something should be technical ones which matters for the PHP core itself and not "i don't understand a feature hence nobody should have it"

Tony Marston

8 years ago
wrote in message news:4b55eed1-8656-ff70-e4e9-ad5e40213405@rhsoft.net...
> > > >Am 29.12.2017 um 00:21 schrieb Larry Garfield: >> Correct. Union types I've always seen presented as offering both union >> and >> intersection. There are cases where union is great, and where it's kinda >> silly. There are cases where intersect is great, and where it's kinda >> silly. >> >> Most of the anti- arguments I've seen for "union types" have fixated on >> "int && >> string is meaningless, and Foo || Bar is bad design, so union types are >> bad!" >> Entirely ignoring the flip side, which is int || string (valid use cases) >> and >> Foo && Bar (many many valid use cases) > >well, that explains why the same person which hase a usecase for a "scalar" >pseudo-type donw-votes https://wiki.php.net/rfc/union_types but it makes >his vote not logical at all > >frankly the only valid reasons to down-vote something should be technical >ones which matters for the PHP core itself and not "i don't understand a >feature hence nobody should have it"
You are missing the point. If an RFC is so badly written that someone does not understand it, or understand what benefits it is supposed to provide, then there is no point in up-voting it. You may contrive a use case where it provides a small benefit, but if that use case is so limited or so obscure that it does not apply to a significant number of developers then that RFC should be voted down simply because it does not provide any significant benefits.
-- Tony Marston

Fleshgrinder

8 years ago
On 12/29/2017 12:21 AM, Larry Garfield wrote:
> On Wednesday, December 27, 2017 3:50:54 AM CST Rowan Collins wrote: >> On 26 December 2017 18:35:29 GMT+00:00, "lists@rhsoft.net" > <lists@rhsoft.net> wrote: >>> Am 26.12.2017 um 19:18 schrieb Larry Garfield: >>>> If I may, I think the argument has always been that >>>> >>>> 1) Foo & Bar makes total sense >>>> 2) int|float makes total sense >>>> 3) int & string is illogical so wouldn't matter anyway >>> >>> not true >>> >>> function x(int|string $x) >>> { >>> >>> $x = (int)$x; >>> >>> } >> >> I think there's a misunderstanding here. Some previous proposals for "union >> types" also included "intersection types", so that you could assert >> "parameter must implement both of these interfaces". So 'Foo|Bar $x' would >> mean '$x instanceof Foo || $x instanceof Bar' and 'Foo&Bar $x' would mean >> '$x instanceof Foo && $x instanceof Bar'. >> >> I presume that's what Larry means by "int & string is illogical", because it >> would translate to "is_int($x) && is_string($x)", which is false for all >> values of $x. This is different from "int | string", which, as you say, >> might have valid uses. >> >> Regards, > > Correct. Union types I've always seen presented as offering both union and > intersection. There are cases where union is great, and where it's kinda > silly. There are cases where intersect is great, and where it's kinda silly. > > Most of the anti- arguments I've seen for "union types" have fixated on "int && > string is meaningless, and Foo || Bar is bad design, so union types are bad!" > Entirely ignoring the flip side, which is int || string (valid use cases) and > Foo && Bar (many many valid use cases). > > --Larry Garfield >
What is the use case for `int|float`? I mean, if f is able to process a `float` than f is able to process an `int` and since `int` is already automatically changed to a `float`, well, you're done. The only situation (I can think of) where this might make a difference is while formatting them. However, in those cases one usually wants to accept many more types (or better yet, let the type format itself). I think that the union RFC was missing proper rules for disjunction (and conjunction if intersection were to be included) as well as information on disjointness. The latter would be important for exhaustive switches that are enforced by the runtime (we'd probably need new keywords here, e.g. `match` + `is`).
-- Richard "Fleshgrinder" Fussenegger

Rowan Collins

8 years ago
On 29 December 2017 12:08:16 GMT+00:00, Fleshgrinder <php@fleshgrinder.com> wrote:
>What is the use case for `int|float`? I mean, if f is able to process a >`float` than f is able to process an `int` and since `int` is already >automatically changed to a `float`, well, you're done.
I think it is somewhat tedious if we discuss every possible pair of types, just as it would be somewhat messy if we added a new keyword for every combination we found a use case for. The beauty of a general-purpose syntax is precisely that a user can use whatever combination they need, and not use combinations they don't need. I'm sure there are plenty of nonsensical or redundant checks that can be expressed in other parts of the language, but that doesn't mean those language constructs are useless or damaging. Regards,
-- Rowan Collins [IMSoP]

lists@rhsoft.net

8 years ago
Am 29.12.2017 um 13:08 schrieb Fleshgrinder:
> What is the use case for `int|float`? I mean, if f is able to process a > `float` than f is able to process an `int` and since `int` is already > automatically changed to a `float`, well, you're done
just read the mass of bugreports caused by float answered with the default paragraph below and you know why you don't want your int-values silently converted to a float 7 may become to 7.000000000000000001 or something similar and "$x === 7" may also fail wile the argument was int 7 ________________________ Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://www.floating-point-gui.de/

Nikita Popov

8 years ago
On Fri, Dec 29, 2017 at 1:08 PM, Fleshgrinder <php@fleshgrinder.com> wrote:
> On 12/29/2017 12:21 AM, Larry Garfield wrote: > > On Wednesday, December 27, 2017 3:50:54 AM CST Rowan Collins wrote: > >> On 26 December 2017 18:35:29 GMT+00:00, "lists@rhsoft.net" > > <lists@rhsoft.net> wrote: > >>> Am 26.12.2017 um 19:18 schrieb Larry Garfield: > >>>> If I may, I think the argument has always been that > >>>> > >>>> 1) Foo & Bar makes total sense > >>>> 2) int|float makes total sense > >>>> 3) int & string is illogical so wouldn't matter anyway > >>> > >>> not true > >>> > >>> function x(int|string $x) > >>> { > >>> > >>> $x = (int)$x; > >>> > >>> } > >> > >> I think there's a misunderstanding here. Some previous proposals for > "union > >> types" also included "intersection types", so that you could assert > >> "parameter must implement both of these interfaces". So 'Foo|Bar $x' > would > >> mean '$x instanceof Foo || $x instanceof Bar' and 'Foo&Bar $x' would > mean > >> '$x instanceof Foo && $x instanceof Bar'. > >> > >> I presume that's what Larry means by "int & string is illogical", > because it > >> would translate to "is_int($x) && is_string($x)", which is false for all > >> values of $x. This is different from "int | string", which, as you say, > >> might have valid uses. > >> > >> Regards, > > > > Correct. Union types I've always seen presented as offering both union > and > > intersection. There are cases where union is great, and where it's kinda > > silly. There are cases where intersect is great, and where it's kinda > silly. > > > > Most of the anti- arguments I've seen for "union types" have fixated on > "int && > > string is meaningless, and Foo || Bar is bad design, so union types are > bad!" > > Entirely ignoring the flip side, which is int || string (valid use > cases) and > > Foo && Bar (many many valid use cases). > > > > --Larry Garfield > > > > What is the use case for `int|float`? I mean, if f is able to process a > `float` than f is able to process an `int` and since `int` is already > automatically changed to a `float`, well, you're done. > > The only situation (I can think of) where this might make a difference > is while formatting them. However, in those cases one usually wants to > accept many more types (or better yet, let the type format itself). > > I think that the union RFC was missing proper rules for disjunction (and > conjunction if intersection were to be included) as well as information > on disjointness. The latter would be important for exhaustive switches > that are enforced by the runtime (we'd probably need new keywords here, > e.g. `match` + `is`). >
int|float is the natural type of numeric operations in PHP. Integers automatically overflow into floating point numbers, so signatures using int in conjunction with numeric operations are somewhat problematic. Having an explicit number type also goes well with an explicit number cast. PHP internally has a notion of a number cast (which is the basis for arithmetic operations), but currently does not expose it. As such, number casts currently have to be simulated using workarounds like +$x. Regarding the union type RFCs, from what I remember, one of my personal issues with it were the complex rules involving scalar type unions in weak typing mode. It's non-trivial to decide what a value should be casted to if it does not have the correct type. It's sort of clear what "1.5" passed to an int|float union becomes, but it's not intuitively obvious what should happen if you pass "foo" to a bool|int union, etc. Regards, Nikita

Sara Golemon

8 years ago
On Tue, Dec 26, 2017 at 10:56 AM, Sebastian Bergmann <sebastian@php.net> wrote:
> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >> would you mind to explain this? > > "Foo|Bar", "array|string", etc. (still) make no sense to me. > > "scalar" makes sense to me although it is but an alias for > "bool|float|int|string". >
Would you feel differently if we combined union types with type aliasing? use Numeric = int | float; function foo(Numeric $bar) { ... } -Sara

lists@rhsoft.net

8 years ago
Am 26.12.2017 um 20:15 schrieb Sara Golemon:
> On Tue, Dec 26, 2017 at 10:56 AM, Sebastian Bergmann <sebastian@php.net> wrote: >> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >>> would you mind to explain this? >> >> "Foo|Bar", "array|string", etc. (still) make no sense to me. >> >> "scalar" makes sense to me although it is but an alias for >> "bool|float|int|string". >> > Would you feel differently if we combined union types with type aliasing? > > use Numeric = int | float; > > function foo(Numeric $bar) { ... }
looks also good for me (while directed to someone else) but i would still prefer function foo(int|float $bar) because it's more native and hence works finally the same way for every code which targets the minimum PHP version where it's available at the first look "use Numeric = int | float" looks gut, but you need namespaces to avoid collisions and the same thing could have a different meaning in different namespaces while "int|float" is very clear and could also be "myClassA|myClassB" without explicit declaration what could also be a problem with "use Numeric = int | float" is what happens with existing code if someone changes that line by add another type while functions don#t expect that one as input at the time they where written - that can't happen with "int|float" in the function declaration because it's a case-by-case decision anyways, it would be a good progress if PHP programmers would be able to declare type-hints for everything in hwatever way it is implemented phpdoc even warns when documentation block and type hints differ and it's something to enhance code quality compared to "i can't declare a typehint at all or need 3 different functions"

Markus Fischer

8 years ago
Hi all, On 26.12.17 16:56, Sebastian Bergmann wrote:
> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >> would you mind to explain this? > > "Foo|Bar", "array|string", etc. (still) make no sense to me. > > "scalar" makes sense to me although it is but an alias for > "bool|float|int|string".
I followed the discussion and found it interesting how strong the focus shifted about the discussion of the practical use cases. I would be for union types or scalars in ab instant, but I never had reason to scan our code-base and figure what would make really sense. Mind you this is a private codebase (Laravel based, as can be seen by some of the class names) but one where we tend to be very explicit about documenting everything, thus I knew I could just go ahead and extract the type hints using the '|' character and get back a pretty complete picture: $ grep -r '@param' *|grep \| | awk '{ print $4 }'|sort -u Attachment[]|Collection Attachment[]|null Builder|null Channel|Post|int|null Channel|int|null ClientInterface|null Client|int|null Collection|Attachment[] Collection|Channel[] Collection|Comment[] Collection|JsonapiModel[] Collection|Model[] Collection|Post[] DateTime|Carbon|string|null Dispatcher|null EloquentCollection|JsonapiModel[] Exception|null Group|Group[]|Client|Client[]|Channel|Channel[]|null Group|int|null JsonapiModel|null Model|int|null Post[]|null Post|int|null Profile|int|null ResponseInterface|null Throwable|null User|int|null \ArrayAccess|array|JsonapiModel[]|null array|false array|null int[]|int int|int[] int|null mixed|null null|LoggerInterface null|Model null|Model[]|Collection null|string string[]|Expression[] string|int string|null This is extracted from a codebase with ~400 files and ~43k LOC (incl. comments). I'm not saying anything like this is relevant codebase, but it's a project whose code quality I know well and I know the reason for every piece there. Since the discussion focuses on scalars here and ignoring all the nullables (they're auto-documented that way via PhpStorm) as well as ignoring the pseudo array-type hints, this leaves us really with only: - array|false Only 1 occurrence, used for crafting a remote HTTP call which has an interface which accepts either an array or false 🤷‍♀️ - string|int Only 1 occurrence, used for error codes which may come in either flavor, send back via HTTP somewhere I was surprised how less of a use we would really have for a) `scalar` itself and b) scalar unions. OTOH, typed array hints seem to be very useful as are class based union types. Although if one looks closely, it's clear this isn't a "union" problem, but rather an emulation due to the absence of Generics, e.g. Attachment[]|Collection Is clearly a replacement for something like Collection<Attachment> I hope I didn't distract to much from the discussion but though I throw in some data from an actual application. I'm sure there are much better OSS projects out there which could be used for such analysis. thanks, - Markus

lists@rhsoft.net

8 years ago
Am 29.12.2017 um 18:29 schrieb Markus Fischer:
> On 26.12.17 16:56, Sebastian Bergmann wrote: >> Am 26.12.2017 um 16:46 schrieb lists@rhsoft.net: >>> would you mind to explain this? >> >> "Foo|Bar", "array|string", etc. (still) make no sense to me. >> >> "scalar" makes sense to me although it is but an alias for >> "bool|float|int|string". > > I followed the discussion and found it interesting how strong the focus > shifted about the discussion of the practical use cases
because a lot of people demand that instead realize that with union-types all that discussions would have ended because it's totally on the application side written in PHP after that

Andreas Heigl

8 years ago
Hey All.
> Am 26.12.2017 um 14:38 schrieb Sebastian Bergmann <sebastian@php.net>: > >> Am 24.12.2017 um 15:34 schrieb Fleshgrinder: >> I prepared a PR to add the `scalar` pseudo-type to PHP after the >> discussions around adding a `mixed` pseudo-type. I strongly believe that >> it makes sense to provide the most common primitive union types with >> handy aliases even if we are going to add union types in the future to PHP. > > Thank you, Richard, for working on this. > > I spent a lot of time this year introducing scalar type declarations into > existing code bases. In quite a few cases I was not able to do so because > the existing code works with parameters that can be of two or more scalar > types. With PHP 7.2, I can only document this outside of the code using > @param annotations (until the code has been refactored to work with only > one parameter type). > > With a "scalar" type declaration I would not have to fall back to @param > annotations and could express the type in actual syntax.
Just a stupid question from someone that isn't following all the discussions here. So forgive me if the question was already asked and answered. What would be wrong with a "composed type hint"? Something like int|float|double $numeric. Or array|Traversable $iterator? It would allow people to add "mixed" typehints without having to introduce multiple typehints that combine different scalar typehints. And it could even allow typehinting different Objects in one function. Yes, it allows people to shoot themselfes into their own feet. And I'd only allow that for parameter types and never ever for return types. But it might be an idea. Cheers Andreas

Alexander Lissachenko

8 years ago
In some distant future it could be implemented in more natural way with classes for primitive types and automatic boxing/unboxing for primitive built-in types: Php\Type\Object Php\Type\Scalar ⌊ Php\Type\String ⌊ Php\Type\Integer ⌊ Php\Type\Float ⌊ Php\Type\Boolean Php\Type\Array And it will be easy to typehint all scalars via common parent class: public function acceptsScalar(Scalar $scalarValue). But all scalar objects in this case should be implemented as immutable or should be passed as copy (like arrays). So, I would vote no for adding special scalar typehint without mapping it to the common class or interface, like iterable => Traversable, callable => Closure, etc Best regards, Alexander 2017-12-26 18:59 GMT+03:00 Andreas Heigl <andreas@heigl.org>:

Fleshgrinder

8 years ago
On 12/26/2017 5:20 PM, Alexander Lisachenko wrote:
> In some distant future it could be implemented in more natural way with > classes for primitive types and automatic boxing/unboxing for primitive > built-in types: > > Php\Type\Object > Php\Type\Scalar > ⌊ Php\Type\String > ⌊ Php\Type\Integer > ⌊ Php\Type\Float > ⌊ Php\Type\Boolean > Php\Type\Array > > And it will be easy to typehint all scalars via common parent class: > > public function acceptsScalar(Scalar $scalarValue). > > But all scalar objects in this case should be implemented as immutable or > should be passed as copy (like arrays). So, I would vote no for adding > special scalar typehint without mapping it to the common class or > interface, like iterable => Traversable, callable => Closure, etc > > Best regards, Alexander >
This is what I would like to see but making the primitives objects without too much BC is a complicated thing to achieve. Auto-boxing could be a solution. However, we would need many new things and new things are in general not well received in the PHP world if they replace other things.
-- Richard "Fleshgrinder" Fussenegger