Re: [PHP-DEV] Re: PHP RFC: Nullsafe Calls

June 4, 2019 19:05 (AllenJB)
On 03/06/2019 23:52, Mark Randall wrote:
> On 03/06/2019 09:28, Jean-Baptiste DELHOMMEAU wrote: >> I would like to  awaken the discussion around the RFC Nullsage Calls : >> > > Personally, I have my suspicions that PHP is starting to expose itself > to operator fatigue. There have been quite a few suggestions made over > the last couple of years that want to add new operators that would > just serve as syntax sugar for a niche problem (for example, chaining) > but serve to make things more convoluted than they need to be.
This is hardly a niche problem - The case this particular RFC deals with is something I (and I would expect, most developers) encounter on a regular basis. Off the top of my head (and the RFC list for 7.4), operators added since 7.0: spaceship, null coalesce, array spread, null coalesce assign. Assuming I totally missed a couple, that's half a dozen in 4 years. (I would be inclined to argue for removing array spread from the list as a consistency fix for the (argument) unpack operator). And they're all making common code easier to read. The spaceship operator is probably the only one I'd argue is "niche" from my personal experience.
> > That said, let me now proceed to be a massive hypocrite and propose a > new operator, because IMO we should be looking to gain the most > general benefit out of the operators that are added. > > Let's try and find a wider solution, for example, right now if you try > to chain things that hit a null, an Error object is thrown... so maybe > we could use that. > > There's also been lots of calls for more built-in functions to throw > exceptions rather than writing notices and errors, and so the use of > try / catch would become more prominent with that as well. > > But... a 5 line try/catch block can be a pain, so maybe we could > create a shorthand that would return a particular value whenever an > exception was thrown? > > Instead of ... > > try { >   $result = $x->y()->z(); > } > catch (Error $ex) { >   $result = null; > }
This case isn't what the null safe calls operator deals with (as I read the RFC and expect null safe calls to work). In the above example / the "attempt" syntax propsal, the code catches any error (of the specified type - eg. NullObjectError) that occurs either on the line in the try block, or generated by any of the code in the methods in the try block ($x->y() or $x->y()->z()). The null safe calls operator (as I would expect it to work) only deals with either $x being null or y() returning null. If $x->y() or $x->y()->z() internally generates an error (of any type, including the proposed NullObjectError), I would expect that to not be caught. As such the proposed "attempt" syntax is not something I would use or recommend using in place of null safe calls - it would (inadvertently) hide bugs in the code and make unexpected results harder to debug. Only a simple assignment example is given for the "attempt" proposed syntax. Because it uses commas and => (and the visual complexity, but that's opinion rather than technical), the "attempt" syntax isn't usable in many situations where null safe calls can be used. Common use cases I can think of would be parameters in a method call, which with null safe calls would be:   $m->n($x?->y()?->z()); Or building an array (DB record / SQL query parameter list, API response), which with null safe calls would be:   $arr = [     'item1' => $x?->y()?->z(),   ]; While other use cases outside of null safe calls certainly exist for the proposed "attempt" syntax, I would say they're much fewer and further between than the use cases for null safe calls and that it doesn't do much to visually simplify those cases. And if you wanted to add anything to either the try or catch sections, the "attempt" syntax would get very messy (and risk introducing hard to see bugs) or require rewriting back to a try/catch - in this regard I would say it's similar to ifs / loops without curly braces and should be avoided. AllenJB
June 4, 2019 21:17 (Mark Randall)
On 04/06/2019 20:05, AllenJB wrote:
> Common use cases I can think of would be parameters in a method call, > which with null safe calls would be: >   $m->n($x?->y()?->z()); > AllenJB
You bring up many good points about the (extremely hastily) composed syntax suggestion for short catch blocks, and their resolution is probably best left for a different discussion. It is an attempt to work around the somewhat built-in flaw in using nulls for such operations, mainly that null itself can often be a perfectly legitimate return value from the last link of the chain, and I believe being able to tell the difference would have at least some useful applications. Clearly there's ways around that using the current, more verbose method, but it would be nice if a way could be found so that this potential ambiguity wasn't there in the first place if this new mechanism is added. Mark Randall