On Tue, 19 Nov 2019 at 17:58, Mike Schinkel <m...@newclarity.net> wrote:

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


It's hard to know without understanding the use cases, which is why I got
so hung up on your "consistency" argument - I wanted to understand what you
were trying to achieve, and if this was the best way to achieve it.

One thing you mentioned earlier was implicit interfaces, i.e. being able to
match "any object that has a foo() method" rather than "any object that
opted into the Fooable interface". You seemed to be saying that __toArray()
would bring similar advantages, but maybe if we had implicit interfaces,
those advantages would already be there? I may have completely
misunderstood, but that's just an example of the wider thinking I'm talking
about.




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


Not quite. What I meant was that there are lots of places which implicitly
cast *something* to string, and would still do so if we didn't have
__toString(). For instance, it's common to use an integer in a
double-quoted string or echo statement, which will implicitly cast it to
string, so being able to use an object in the same place feels natural and
useful.




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

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



Possibly, but it's also about how we *prioritise* features. If the general
plan is "eventually we hope to have overloads for all casts, but let's do
them one at a time", we should have some reason why array comes next. My
gut feel is that implicit casts to boolean (e.g. in if statements) are the
next most common after strings, so if asked to prioritise, I would pick
that over arrays.

There's also a kind of "tipping point" where splitting up the feature no
longer makes sense - it would be weird to have __toString, __toArray, and
__toBool; then add __toInt; then wait a release to add __toFloat. So I
guess my suggestion is that maybe we've already reached that tipping point,
and rather than bikeshedding the order to add things in, we should go ahead
and add them all.

But maybe there is a reason that __toArray() is easier / less dangerous /
more useful than the rest.




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


I guess this is where I'm less optimistic; I think overloaded casts could
be just as unreadable as any other overloaded operator if abused - and just
as powerful if used appropriately.

I'd actually really love to be able to write $price = new Money('GBP', 100,
0) + new Money('GBP', 50, 50);




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


Just to play devil's advocate, the same reasoning could be used to dismiss
your dislike of full operator overloading.




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


OK, I'd completely missed that proposal. It's an interesting idea, but it
feels like there are some rough edges: why would you implement the function
but return false, and how would that behave? And what if it returned true
but there was no __toArray? Also, would the function actually receive the
object, or the result of calling __toArray() on it? Would it be different
in strict_types mode?

In keeping with the idea of one feature at a time, it would probably make
sense to work out the details of that mechanism for strings first, since we
already have __toString(), then extend both parts to arrays at the same
time.




> > $allowed_html_builder->build());
>
> 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.
>



My example requires exactly the same interaction with the third-party code
as your example - create a custom object, and call some methods on it. If
the __toArray() call is completely automatic, then your example saves the 9
characters of "->build()", but it doesn't change the *architecture* of the
solution.




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



The version using "$foo->build()" rather than "(array)$foo", and the
special treatment of "(array)$foo" actually calling "$foo->__toArray()".





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




Almost. It's more that I'm against adding a large number of small features
that each make one use case slightly easier, but don't generalise very well.




>   ... even if the areas proposed to be improved represent the ~80
> percentile of use-cases?
>



Quite the opposite! I'm sceptical of this feature precisely because I think
the use cases for it are rather narrow.


Regards,
-- 
Rowan Tommins
[IMSoP]

Reply via email to