2021-06-29 0:06 GMT+02:00, Rowan Tommins <rowan.coll...@gmail.com>: > On 28/06/2021 21:28, Olle Härstedt wrote: >> Sorry for hijacking the thread, but are there no other alternatives, >> really? Just brainstorming: >> >> 1) Setting to silence the warning. > > > Just to reiterate: in PHP 8.0, an undefined constant is not a warning, > it's an error. My apologies to code golfers: you can no longer save two > bytes by leaving the quote marks off your strings. > > However, that's not really the problem. The problem is when there *is* a > constant with that name: > > const foo='strtoupper'; > function foo($x) { return 'test'; } > $input = ['hello', 'world']; > var_dump( array_map(foo, $input) ); // this runs strtoupper(), not foo() > > This doesn't work even in old versions of PHP where undefined constants > fell back to strings. > > Even in cases where this trick did work in older versions of PHP, it was > just a variant of option one, "use our current ugly callable syntax" - > it saved you those two bytes, but it didn't actually provide you a > function reference. > > Unifying the constant and function name tables would not be to just a > different way of writing strings, it would let array_map(foo, $input) > actually check that function foo existed, and represent callables as a > proper type. Meanwhile, to let array_map($object->foo, $input) do the > same thing (instead of the current [$object, 'foo'] syntax) you also > need to unify the method and property tables, which is probably even > harder. > > > >> 2) Setting to silence the warning IF and only if argument expects a >> callable, like in array_map (won't work with a pipe() function, >> though, since pipe() would take any number of arguments and that can't >> be typed) > > > In the general case, this is a non-starter: the parameters need to be > parsed from the source code before function definitions are even known. > You could special-case a handful of built-in functions, but that would > be extremely clunky. > > > >> 3) Silence the warning if you type-case explicitly, like in >> `pipe($start, (callable) htmlentities);`. Another alternative is >> `(fn)` as a type-cast. Not much better than `pipe($start, >> htmlentities(?))`, I guess. Just different style. > > > This falls into my third option: "add a dedicated callable syntax". That > could be something that looks a bit like PFA but isn't, like Nikita's > RFC; or something that looks a bit like a type cast; or any number of > other ideas which have been brainstormed for about as long as I've been > programming PHP. > > >> 4) Silence the warning ONLY when it's the right-hand argument to pipe >> operator, like `$start |> str_len`. > > > Re-wording this as "interpret the unquoted word as a function reference > rather than a constant when...", this one is at least plausible. In > practice, though, a lot of functions don't take only one parameter, so > the previous pipe proposal included a placeholder for which argument you > wanted to "pipe into". At which point you don't need to special case > keywords, because you can just write this: > > $start |> str_len($$)
True. I wish we had numbers for how common the case is when you DON'T want to pipe into the first argument. If it's rare enough, it might be worth it to let the rare cases be dealt with by writing manual lambdas. So allow some boilerplate. Another alternative would be to add both '?' and parsing unquoted string as function reference together with pipe operator, but start with the simple one (whichever that is, I wouldn't know). Or start with the one that has chance of being accepted by the voters. :) > Regards, > > -- > Rowan Tommins > [IMSoP] Thanks for your explanations! Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php