Re: Features related to Object Initializers
| From: | Mike Schinkel | Date: | Tue, 17 Sep 2019 00:10:40 +0000 |
| Subject: | Re: Features related to Object Initializers | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-107184@lists.php.net to get a copy of this message | ||
> On Sep 16, 2019, at 6:20 PM, Larry Garfield <larry@garfieldtech.com> wrote:
>
> I think everyone's in agreement about:
>
> 1) Making objects easier to work with.
> 2) Devs should use objects more.
I am glad we are reaching some common ground. :-)
> (Side note: I have an article submitted to php[architect] entitled "Never* use
> arrays" that goes into this topic in much more detail. I am 100% on board with getting
> developers using objects more and arrays less.)
Yes, I saw the article on your blog that you linked. Very nice. :-)
> However, why do we want devs to use objects more? If we just want the arrow-like syntax, then
> this works today:
>
> $val = (object)[
> 'foo' => 'bar',
> 'baz' => 5,
> ];
>
> And now developers are using an anonymous "object". However, that offers basically
> no meaningful improvement except funnier passing semantics.
> ...
> 2) They're more self-documenting and statically analyzable (by your IDE or any other
> tool)... but that's true only if you have an explicitly defined class!
> ...
> So for me, the entire "easier to use anonymous one-off classes" argument falls apart,
> because there's no material benefit there other than saying "but now it's using
> objects". For that, as noted, we already have an ample syntax that accomplishes just as much.
I can envision several benefits you do not mention, maybe because you've forgotten them, were
not aware of them, or they did not occur to you?
In descending order of significance:
1. IDEs could validate local uses for stdClasses — Given the following syntax, PhpStorm could and
likely would implement an inspection that displayed a warning on the line with $val->bazoom
because everything it needs to validate is there. And I see no reason other IDEs could not do the
same:
$val = stdClass{
foo => 'bar',
baz => 5,
};
echo $val->bazoom;
2. Empowering beginners — If you are a beginner, or a work-to-live[1] programmer then I think
there is a good chance you will find the syntax (object)[..] foreign and confusing. I think they
would find the following syntax easier to tackle and thus more likely to use, especially if they
came from Javascript (note I omitted stdClass in hopes we could land on using such syntax for
stdClass or anonymous classes):
$val = {
foo => 'bar',
baz => 5,
};
By empowering beginners they would be more likely to objects they can later refactor instead of
arrays (see #5 below.)
3. Simplifying refactoring — It will be easier to refactor an object initializer for stdClass to a
declared class than to refactor from the hybrid array/object syntax.
4. Simplified syntax — I tend to make a lot more typos when initializing array keys in PHP than I
do when initializing objects in GoLang (the proposed PHP syntax is very similar to the equivalent in
Go.) Maybe I am unique in that, but I doubt it.
I also find array keys with quotes harder to read (but maybe that's because I have 56 year old
eyes instead of younger eyes that guys like you have? :-)
5. The (object)[...] syntax feels like a hack — I use that syntax, but every time I do I feel like
I am doing something I should not be. And I also rarely see that syntax being used in the wild, so
maybe others feel the same?
5. PSON! — I we had an object initializer syntax, we could finally have a competitor to JSON; i.e.
PSON! Imagine if we had only had it 15 years ago... :-o
Remember, the above were in descending order of significance.
> It's only an advantage if I do this:
>
> function doSomething(int $a, SomethingOptions $options = null) { ... }
>
> Doing that has many advantages, I think we all agree. But going halfway doesn't give us
> any benefits other than swapping [' '] for ->.
Other than the assertion that it only has advantages with declared classes, I do generally agree
this is usually the most beneficial approach.
But as I said before, naming is hard — except for abstract examples where you can just name it
"Something" :-) — and developers often don't know what object schema they will need
until they have written much of the code. So the ability to have a syntax that supports stepwise
refinement rather than starting with one and having to switch to the other makes a lot more sense to
me.
Allowing developers to start with doSomething(int $a, object $options = null) and then later refine
the code to doSomething(int $a, SomethingOptions $options = null) creates less discontinuity for
development rather than giving them only one option for anonymous class initializer, e.g. the array
initializer syntax?
> So rather than making it easier for people to make "anonymous structs that use object
> syntax", we should be making it easier for people to define for-realsies named classes and
> using them, because *that* is where the benefit comes from.
If you can actually make it easy, I would be the first to support that. I just cannot envision how
you can without more upfront complexity than simple object initializers need.
So please, prove me wrong! :-)
> And for that part of the problem (making named struct-like classes easier to work with), as
> noted in the other thread I find the named parameters/auto-promotion combination to solve the
> problem just as well, and then some.
There has recently been a call from several people on the list for everyone to try and find
solutions that are not "You loose so I can win."
Rather than protest object initializers to enable named parameters/auto-promotion instead, can we
not work together to find a way to achieve all three with one simple syntax and as few new sigils
used as possible?
-Mike
[1] That phrase came from one of my ex-girlfriends. It was derisive, and aim at me because I liked
working. And note the qualifier "ex-."