Re: Stricter implicit boolean coercions
| From: | Rowan Tommins | Date: | Tue, 26 Apr 2022 19:25:53 +0000 |
| Subject: | Re: Stricter implicit boolean coercions | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-117630@lists.php.net to get a copy of this message | ||
On 26/04/2022 14:53, Andreas Leathley wrote:
This is also something I am interested in - having functions which do the same as implicit type casts, so something like "coerce_to_int('hello')" would lead to a TypeError like it would when passing it to an int parameter, and maybe "is_coerceable_to_int('hello')" which would return false, so it would be possible to check values the same way as PHP does internally. The current explicit cast functions are quite heavy-handed and not great for every situation - when parsing a CSV or getting data from a database I would rather coerce values where an error could occur if it doesn't make sense than to explicitely cast and not even notice if the value made no sense at all.Yep, that's pretty much exactly where I was going. My current thinking is to have at least one of (deliberately long straw man names): type_coerce_or_return_default(string $type, mixed $value, mixed $default): mixed type_coerce_or_throw_error(string $type, mixed $value): mixed type_can_be_coerced(string $type, mixed $value): bool Accepting the type as a string is ugly, but means we don't need three functions for every type, and can easily support nullable types, union types, etc. Crucially, no special syntax means it's possible to write polyfills that compile in old PHP versions. For simple types, you can mostly get away with one function: $float_or_error = type_coerce_or_return_null('float', $var) ?? throw new TypeError; $is_valid = type_coerce_or_return_null('float', $var) !== null; But that's no use when null is a valid return type, so you need a hand-picked default and a bunch of extra boilerplate: if ( $nullable_float = type_coerce_or_return_default('?float', $var, false) === false ) { throw new TypeError; } $is_valid = type_coerce_or_return_default('null|float|bool', $var, 'invalid value') !== 'invalid value'; The main point I'm stuck on at the moment is exactly how strict these should be, since we already have more than one set of coercion rules for each type, as Mel Dafert pointed out elsewhere on this thread. On the one hand, they should probably match with at least some existing rules; on the other, it would be weird to introduce them then immediately deprecate some behaviour because we've decided to make the language stricter elsewhere. Regards, -- Rowan Tommins [IMSoP]