On Thu, Jan 16, 2020 at 10:12 AM Claude Pache <claude.pa...@gmail.com> wrote:
> > > > Le 7 janv. 2020 à 11:23, Nikita Popov <nikita....@gmail.com> a écrit : > > > > Hi internals, > > > > I'd like to propose a small RFC, which addresses a few minor issues that > > have not been handled by the original "uniform variable syntax" RFC: > > > > https://wiki.php.net/rfc/variable_syntax_tweaks > > > > This is all about edge cases of edge cases, of course. I think the only > > part here that is not entirely straightforward and may need some > discussion > > is how arbitrary expression support for instanceof should be handled. > > > > Regards, > > Nikita > > Hi, > > The RFC looks good for me, except for one point. Concerning the arbitrary > expression support for `new` and `instanceof`, I strongly think that the > most consistant choice for delimiters among “(...)” (parentheses) and > “{...}” (braces) is not braces “{...}”, but parentheses “(...)”. Your > argument is based on the position of the expression (RHS vs LHS). My > argument is based on the type (in a broad sense) of the thing that the > expression is supposed to represent. > > The braces are used when the expression is expected to represent: > > * a variable name: `${...}` > * a property name: `$x->{...}` — `X::${...}` > * a method name: `$x->{...}()` — `X::{...}()` > > In all those cases, the expression inside `{...}` must evaluate to a > string, and will be interpreted as a name. > > On the other hand, the parentheses are used when the expression is > expected to represent: > > * an array: `(...)["key"]` > * an object: `(...)->prop` — `(....)->meth()` — `clone (...)` > * a function: `(...)($arg)` > * a class: `(...)::KONST` — `(...)::${statProp}` — `(...)::${statMeth}()` > > In the first two cases, the expected entity, “array” or “object”, is a > first-class value, and the expression inside `(...)` will be interpreted as > such. > > The last two cases are more interesting. For the ”function” cases, it can > be: > * a string representing a function (interpreted as the fully qualified > name of a function); > * an array `[ $obj, "meth" ]`, `[ "klass", "meth" ]` or a string > "klass::meth" representing a method; > * a closure or another object implementing the magic __invoke() method. > > For the “class” case, it can be: > * a string representing a class (interpreted as the fully qualified name > of a class); > * an instance of a class. > > In those cases, the expected entity may be a first-class citizen (a > closure, an instance of a class), or an entity that, although not a > first-class citizen, is unambiguously(*) represented by some other > first-class value (a function by their fully qualified name, etc.) and > could have been reasonably designed as first-class citizen (and indeed, a > function may be replaced with a Closure object with the same functionality). > > (*) (For the sake of not complicating the argument, I’m ignoring callables > whose meaning depends on context such as `["self", "foo"]`.) > > You rightly noted that the braces `{...}` are used exclusively on the RHS; > that follows from their meaning: a bare name has no significance out of > context, where the context is whether it is a function name, or whether it > is a property/method name and of which object/class the property/method is, > or etc. That context is more naturally provided before (at the left of) the > name. > > On the other hand the parentheses `(...)` are often used on the LHS: this > place is the natural place for an entity (an object, a class, etc.) that > don’t need more context to be well-defined, and that serves as target for > some action (call the function, look up the property of an object, etc.) > However, although the entity is often placed at LHS, this is not > systematic; consider f.e. `clone $obj`, which is quite similar to `new > klass`. > Thanks for the feedback Claude. I think you make a compelling case, and have updated the RFC to use "new (expr)" and "$x instanceof (expr)" syntax instead. Regards, Nikita