On Mon, Sep 16, 2019, at 7:10 PM, Mike Schinkel wrote:
> > On Sep 16, 2019, at 6:20 PM, Larry Garfield <la...@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. :-)

I have a presentation on the subject that I keep submitting to conferences.  
I'm waiting for one to pick it up. :-)

> > 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;

Can they?  In the super-narrow case of the object being defined in the same 
scope as it's used, potentially.  But once I pass it elsewhere, the static 
analyzer will have a really hard time figuring out what it's supposed to be.

Example:

$val = stdClass{
    foo => 'bar',
    baz => 5,
};

echo $val->bazoom; // IDE can tell this is wrong.

function thingie(object $params) { 
  echo $object->bazoom;
}

thingie($val); // we know this will break, but the IDE can't really tell

thingie(stdClass{bazoom: 5}); // This won't break.

Granted, I have not written a static analyzer myself so it's possible I'm 
speaking out of my butt here, but I don't see how an analyzer could reasonably 
tell if the echo statement in the function was correct or not because it has no 
local information on which to base that decision absent a defined class or 
interface.


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

To clarify: I virtually never use (object)[] syntax myself.  I think it's been 
a decade or more since I did so.  I would not endorse such a thing.  My point 
is that what's being proposed here, in relation to anon classes, has no 
meaningful benefit over that.

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

Citation needed?  And why not just define your data types in the first place?

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

You're definitely not unique because I do that too, and it's one of the 
examples I call out in presentations on why defined classes are superior to 
arrays.  

I'd noticed the Go inspiration as well.  I think it works well in Go, but less 
so in PHP.  Also bear in mind that in Go, you're instantiating an explicitly 
defined structure; even if you're defining that structure inline at 
instantiation, you're first defining the structure types.  (And the syntax for 
doing so inline is really funky.)  So that's no help at all for the anon class 
case.

> 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?

It is a hack; again, I am in no way endorsing its usage.  Just saying that an 
anon struct with arrows offers no meaningful advantages over the current hack.

> 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

I don't really follow this one, especially as you're essentially describing an 
inline JSON for PHP. :-)

> 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?

I think this is where we fundamentally disagree.  "It's just like the anonymous 
blob of array data you're used to but with arrows" is not a useful or helpful 
stepping stone toward defined classes.  If anything, I see it as one less 
reason for people to start using real defined classes because "it's already 
objects, so it's OO, so what do you want from my life?"

When I was a kid, there was a brief period where schools tried to teach an 
"intermediate" writing style between print and cursive called D'Nealian.  The 
theory was that it would make it easier to transition them from print to 
cursive.  In practice, it did the exact opposite because it meant two, not one, 
transitions in writing style and a lot of students got stuck at the 
intermediate and never moved on.  Myself included; to this day I write in a 
sort of perverted D'Nealian/curisve and never learned proper cursive.

cf: https://en.wikipedia.org/wiki/D%27Nealian

The intermediate step you describe I see not actually helping matters, and if 
anything hurting them.  That's because good OOP is not "passing arrays but with 
defined properties".  If someone replaced this:

function doSomething(int $a, array $options = []) { ... }

with this:

function doSomething(int $a, SomethingOptions $options = null) { ... }

I would still reject their code, because it's just using an object as an 
over-engineered way around... the lack of named parameters.  Rather, the 
defined class should mean something, not just be a bunch of names collected 
together.  That's a different way of thinking, and trying to have a smooth 
"lots of easy little steps" transition will just leave a lot of people, and 
their code, stuck at all of those intermediate steps.

> > 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?

As I said before, I think named params and constructor-promotion would do just 
that, or nearly so, depending on the particulars of their syntax.  (The devil 
is always in the details.)

My engine-C-fu is basically nil (or null, since this is PHP), so I'm no help in 
implementing such things, but I'm happy to collaborate on the research and 
design part of those, with an eye toward making the construction process as 
easy as possible.

--Larry Garfield

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

Reply via email to