On Fri, Mar 22, 2024 at 12:01 PM Rowan Tommins [IMSoP]
<imsop....@rwec.co.uk> wrote:
>
> On Fri, 22 Mar 2024, at 08:17, Jordi Boggiano wrote:
>
> We perhaps could make sure that as does not throw if used with `??`, or that 
> `??` catches the type error and returns the right-hand expression instead:
>
> So to do a nullable typecast you would do:
>
>     $a as int|float ?? null
>
>
> While this limits the impact to only expressions combining as with ?? it 
> still has the same fundamental problem: you can't meaningfully use it with a 
> nullable type.
>
>
> As a concrete example, imagine you have an optional $description parameter, 
> and want to ensure any non-null values are converted to string, but keep null 
> unchanged.
>
> At first sight, it looks like you could write this:
>
> $descString = $description as string|null ?? (string)$description;
>
> But this won't work - the ?? swallows the null and turns it into an empty 
> string, which isn't what you wanted. You need some syntax that catches the 
> TypeError, but preserves the null:
>
> $descString = $description as string|null else (string)$description;
> // or
> $descString = $description as string|null catch (string)$description;
> // or
> $descString = $description as string|null default (string)$description;
>
>
> I actually think there are quite a lot of scenarios where that idiom would be 
> useful:
>
> $optionalExpiryDateTime = $expiry as ?DateTimeInterface else new 
> DateTimeImmutable($expiry);
> $optionalUnixTimestamp = $time as ?int else strotime((string)$time);
> $optionalUnicodeName = $name as ?UnicodeString else new UnicodeString( $name 
> );
> etc
>
> And once you have that, you don't need anything special for the null case, 
> it's just:
>
> $nameString = $name as ?string else null;
>
> Regards,
> --
> Rowan Tommins
> [IMSoP]

I'm not sure I can grok what this does...

$optionalExpiryDateTime = ($expiry === null || $expiry instanceof
DateTimeInterface) ? $expiry : new DateTimeImmutable($expiry)

Maybe? What would be the usefulness of this in real life code? I've
never written anything like it in my life.

Personally, this is much more readable (assuming I got the logic right):

using always null if not match, and handle the case for when $expiry
isn't a string:

$optionalExpiryDateTime = $expiry == null ? $expiry : $expiry as
DateTimeInterface ?? new DateTimeImmutable($expiry as string ?? "now")

But I can't think of why you'd want null ... null would apply to all
types and have a dedicated branch, no matter what any other type is.

Robert Landers
Software Engineer
Utrecht NL

Reply via email to