> On Nov 19, 2019, at 10:54 AM, Rowan Tommins <rowan.coll...@gmail.com> wrote:
> Neither. We should discuss the advantages of the feature, the potential
> costs, and whether other features would be even better.

In concept, I agree.  

But AFAIK no other "better" features were proposed.  Do you have an alternate 
to propose for __toArray()?  I am all ears.

> I think that's where this conversation has broken down a bit, which may be
> my fault: I wasn't intending to argue against all the possibilities of the
> feature, only the specific arguments you were raising. We disagree over
> whether (array)$foo would be used more consistently than meaningful method
> names, so maybe we should leave that there, and look at some other pros and
> cons of the feature.

I appreciate you elaborating. 

We can certainly disagree; in both cases it is just our opinion for what might 
happen if a new feature is introduced, and neither of us can know for certain 
what the potential future holds.

That said, which I think you acknowledged, it is a bit of bikeshedding on both 
our parts to belabor this one point any longer.


> What makes __toString() worthy of a special case in my mind is that there
> are fairly common scenarios where variables are _implicitly_ cast to
> string: in double-quoted strings, echo, etc. Having the language be able to
> automatically call a particular method in those situations is therefore
> more valuable.

The same can be said for __toBool(), and could be said for any other data type 
assuming that the appropriate __toType() were available.

Said another way, if __toString() was not in PHP then no implicit casting would 
be possible and thus nobody would do it. 

So there really is no difference; if we had __toArray() and __toBool(), people 
could start using them where they would be implicitly cast to those values.

> I think I'd actually be more receptive to a proposal to
> allow _all_ casts to be overloaded, rather than adding array as a second
> special case, because *implicitly* casting to array doesn't seem like it
> would be any more common than other types.

The feels like "perfect being the enemy of the good" again.

If there is anything I have picked up by studying the nature of enhancements to 
PHP it is that they are added incrementally at best. Consider type hinting; we 
have basic type hinting today but we are just now getting union types.  It 
would have been ideal to get all typing needs addressed at once, but if that 
had been the bar we probably would still be doing without.

Also consider that implementation of _all_ casts would be a heavier lift than 
implementing just one today, and then hopefully implementing others later.

And consider that the nature of PHP with its voting means that larger changes 
are exponentially harder to get accepted.

So for me, rather than argue against a feature because we don't take all 10 
steps at once, I would celebrate moving 1 step at a time in the positive 
direction, because we would at least be 1 step ahead of where we are today.

> Yes, I would see that as a better example. I think operator overloading in
> general makes sense when the object itself can be thought of as a
> special-case of the primitive it's emulating operators for. So in this
> case, the IsSuccessful class would be "a special kind of boolean"; and the
> hypothetical List or Collection classes I mentioned a couple of days ago
> would be "a special kind of array". We even have that in PHP for built-in
> types: GMP objects can now be used with mathematical operators like $foo *
> $bar, and those operations do what you'd expect them to do on an integer or
> float.

Exactly!  I agree that for general purpose classes the general array cast is 
less ideal.

But there would really be value in having "cast" magic methods to wrap built-in 
data types and then add related methods to them.

> Operator overloading can also be used just as a cute way of spelling
> something - probably most famously, C++ uses the << and >> operators for
> writing to and reading from streams, even though they're actually overloads
> of the bit-shift operator.

Interestingly, I am against general operator overloading, because Ruby and 
Rails.

Seriously, when operators can be overloaded you can end up with code that is 
almost impossible to decipher.  But I do not think the same is true for casting 
as I tried to illustrate by example.

> Overloading of cast operators is no different - the clearest use cases for
> __toString() are where the whole class basically represents a piece of
> text, and the more controversial are where (string)$foo is actually a cute
> spelling of one method on a complex class.

I fully agree with that.  

> That's not necessarily a reason to not add a feature - any feature can be
> abused - but it potentially makes it harder for users to understand each
> other's code, and that's a cost we should at least consider.

I would like to err on the side of power combined with documentation and 
education rather than prohibition. 

> This is an interesting example. On the one hand, there is only one array
> ever going to be produced by that class; but on the other hand, the
> ultimate use of it is explicitly passing to a function that expects a
> different type. Assuming the same behaviour as __toString, the code shown
> would give an error under strict_types=1, and need changing to
> wp_kses((array)$allowed_html)

You assume that my proposed __asArray() was not also implemented. 

However  — per the proposal — when __asArray() returns true PHP would treat the 
object as an array in any context where an array is expected but still allow 
methods to be called.

> A different interpretation would be that this is the Builder Pattern, and
> the target type happens to be an array rather than an object. So you might
> decide that the consistency you really needed is that all builders should
> have a build() method, and the last line of the example would become:
> 
> $clean_html = wp_kses($_POST[ 'content' ] ?? null,
> $allowed_html_builder->build());

Totally. 

But the primary use-case for __toArray() I have identified is to support 
patterns that exist in other peoples code — such as WordPress core — where you 
cannot easily rearchitect the code to be what a developer thinks they really 
need; you have to go with what is not what you want to be.

> That doesn't mean the version you wrote is *wrong*, but should make us
> consider why one version deserves special treatment by the language and the
> other one doesn't.

What other version, and what special treatment is needed?

I think I am sensing a pattern in your objections:  For you, providing benefits 
in one area is to be avoided unless all areas can receive similar benefits?  
And when providing all areas with similar benefits would mean infinite 
features, you would prefer that no use cases get improved at all, even if the 
areas proposed to be improved represent the ~80 percentile of use-cases?

Tell me if I am grasping your objections correctly?

-Mike

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

Reply via email to