> 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`.

—Claude

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to