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