On Thu, Mar 13, 2025, at 23:26, Bob Weinand wrote: > Hey Rob, > > On 13.3.2025 21:46:49, Rob Landers wrote: >> On Thu, Mar 13, 2025, at 12:01, Tim Düsterhus wrote: >>> Hi >>> >>> Am 2025-03-12 11:10, schrieb Rob Landers: >>> > - Accessing inner classes is done via a new token: ":>" instead of >>> > "::". >>> >>> I don't particularly like that. It is “invented syntax” and I don't >>> think that inner classes are sufficiently valuable to dedicate an entire >>> operator to them that could serve a more useful purpose in the future. >>> It also got 4 negative points in the rating back when the namespace >>> separator was decided: https://wiki.php.net/rfc/namespaceseparator >>> >>> Would `\\` (i.e. two backslashes) work? The outer class for inner >>> classes effectively act as a namespace, so it makes sense to me to use >>> syntax that is similar to namespaces. >>> >>> I'll look into the rest when there is a new implementation, since I >>> assume some details will still be clarified and fixed as part of >>> implementing the proposal. >>> >>> Best regards >>> Tim Düsterhus >>> >> >> I am not particularly attached to the separator. I specifically chose it due >> to being a mixture of :: and -> and -: seemed like a bad idea. In other >> words, an inner class felt natural to use :> -- however, I have some issues >> with it myself. Particularly, it is too much like |> and as shown in the >> namespace RFC, way too easy to typo. Personally, after using it for a few >> days, I'd almost rather go back to :: ... >> >> I will give \\ a try, but it has to be typed quite a bit when referencing >> inner classes, so keeping it easy to type is a must. I feel like \\ requires >> a large movement to type, at least on a qwerty non-english keyboard. Maybe >> people using other keyboards can chime in. > Please go back to ::. The double colon was perfectly fine, the only thing > which was weird was the implicit constant. It's fine for constants and inner > classes to share the same name scoping (i.e. a constant must not share a name > with an inner class). But an inner class should not be an actual constant. > > But otherwise, this was perfectly fine. >
My biggest issue with `::` is that it gets weird: class Foo { public class Bar {} public const Bar = ""; public static function Bar() {} } echo Foo::Bar; // this is the constant new Foo::Bar(); // this is the class Foo::Bar(); // this is the method new (Foo::Bar()); // this is the method new (Foo::Bar); // this is constant I can now differentiate between these all in the AST, but it seems weird to me. If we go this route, I'd personally have the preference to allow them all and let people's code-style dictate what is acceptable or not -- assuming I can ensure there is no ambiguity in the grammar. At least with `:>` (or something else) we don't have to even have that discussion. :) >>> I don't think that inner classes are sufficiently valuable >> >> I'm curious why some people feel this way and why some other people are >> saying the opposite (emphatically). I'll nudge the private emails I've >> received to speak up publicly on the list as well. But, why do you feel this >> way? > > I don't know why some people feel this way, but at least with the autoloading > mechanisms we have in PHP there are definite limitations to multiple classes > in one file: > - If you deserialize your data structure and it contains another class, whose > name does not match the file name, you better hope to god that it has been > autoloaded already. Surprising failures in production follow. (e.g.: the > amphp\parallel process runner will try to serialize your exception. That's > fine. But as soon as it's accidentally bubbling up and as it's not > autoloadable, the hell breaks loose.) > - Enums or Data Transfer objects specific to one or multiple functions of > only this specific class would naturally fit into the same file. But you > can't do it ... because the autoloading might try to load the enum first, > before the class whose constructor or function you want to call is actually > loaded. > - Now, if you actually stuff multiple classes / enums into a single file, > it's non-trivial to figure out (as the human reader, but obviously for the > autoloader too) which file to access to read up the definition of a specific > enum (short of using dedicated tooling for it). > > > Certainly, one may say - yeah, just religiously use different files for ... > every ... single ... class. > But what's the point of that dogma? > It definitely doesn't help the organization of dedicated helper structures > tied to a single class. > It's a tool for organization. It's not complex to understand. > > Outside of very puristic arguments I don't see any reason why one would not > want inner classes. > > > Further, with short classes, should they hopefully be introduced as well, it > will become trivial to write shapes for any internal datastructures - simply > using a "class Point(int $x, int $y); private Point $pos;" rather than "/** > @var list{int, int} */ private array $pos;". > This will be a very ergonomic way to reduce ad-hoc arrays which are only > typehinted by phpdoc, giving proper typing and also safe access to structures > via named accessors rather than [0] and [1] etc. > > Further Questions on the (original) RFC: > > - Why is there a conflict in static properties and the inner class name? The > former always has a leading $ sigil. > Funny enough, this was due to me messing up the AST such that it was trying to access a property instead of a constant. Once I fixed that, the conflict went away. > - Any particular reason to disallow abstract inner classes? Feels arbitrary. > This went away as well, once I started cleaning up the grammar. Basically, I couldn't work out how to allow `::` in `extends`. I eventually figured it out once I implemented `:>`. Replacing `:>` with virtually anything else is quite possible -- including going back to `::` (I think). > And a note: I consider the inheritance example misguided as "static > constructors" (static methods which invoke new()) would be a better pattern > here. Could you maybe come up with another example here? > > > > Bob > That was a pretty bad example! It illustrated the point but would probably be a bad practice. — Rob