> On Nov 18, 2019, at 5:53 AM, Rowan Tommins <rowan.coll...@gmail.com> wrote:
> 
> On Mon, 18 Nov 2019 at 00:18, Mike Schinkel <m...@newclarity.net> wrote:
>> Even if short, a code base littered with method names like toV5Json() or
>> getV5Array() or formatForJsonV5() is still inconsistent.
> 
> Inconsistent with what?

Inconsistent with each other. If one developer names it toV5Json() and another 
developer names it getV5Array() then those two developers choices are 
inconsistent. 

Yes, a team lead could require an interface be used for consistency across a 
team, which is fine, but it is not consistent across unrelated projects. Having 
worked with GoLang for a while where interfaces are not required to be 
explicitly named by classes that implement them I have learned that having 
consistency across unrelated projects can result in some surprisingly 
serendipitous reuse scenarios.

> Unless you suggest we introduce enough magic methods that every method
> name in your application begins with two underscores, you are always going
> to have to name things.

Forgive me for saying, but that argument is bordering on reductio ad absurdum. 
We are talking about a magic method for converting to a built-in data type. 

In PHP — ignoring null — there are only seven built-in data types, we already 
have a magic method for one of them (string), having one for resource makes no 
sense to me since it is such a special case, and so the only ones for which 
most instances of a declared class can be fully captured are array and object.  
IOW, two (2) potential magic methods:  __toArray() and either __toObject() or 
__toStdClass().

That said, I could see a value in having __toInt(), __toFloat(), and __toBool() 
as having them would allow us to represent scalar data types in classes. That 
could be extremely useful in selected contexts.

So given the argument there would at maximum be five (5) new magic methods that 
could be added vs. the infinite methods you assert this approach would invite.

P.S. That said, I could see adding more for well-known data that goes beyond 
existing data types, e.g. JSON, XML, HTML, CSV, etc. but really if we did that 
I would argue that PHP should create a first-class built-in data type for them 
first.


> If there is a common requirement for objects to be converted to a
> particular type of array, then you should pick a standard name for that

You assert that a developer "should" do it the way you believe is correct, but 
what is the arbiter of "should" vs. "should not" here?  Is there some 
fundamental best practice that the industry has universally embraced that I am 
unfamiliar with, or just your opinion?  

(I am not trying to be sarcastic, but I am challenging you to justify your use 
of "should.")

> I'm not asking for any kind of perfection, I'm just saying names should be
> meaningful. Bear in mind that namespaces are really just part of the class
> name, so all you're really saying is that you like long specific class
> names and short generic method names.

Absolutely agree that names need to be meaningful, which is why I want more 
control, not less.  

What you are implicitly saying is that rather than allow others the option to 
use __toArray() which by its nature could result in consistent use across 
unrelated projects you want to deny others who value it from being able to take 
advantage of it because you personally do not see value in it and would not use 
it.  Or did I misrepresent?

>> Similarly it is not clear to me was toV5Json() or getV5Array() or
>> formatForJsonV5() mean.
> 
> I was imagining an API that had gone through different versions, so needed
> methods to serialize objects into the JSON published in version 5 of a
> specification.

Godforbid someone uses that kind of naming for their methods. Versioning 
screams out for encoding into namespace names, not method names. Why burden the 
developer with the requirement to use the version name in every single method 
call?  Better to isolate it to use a use statement.

BUT, this is a tangent and a different debate from the discussion about 
__toArray().

> If your code base is such a mess that you can't propose any method name
> without it conflicting, and can't trace usages of any method that needs
> renaming to not conflict, then yes, you get a one-off benefit from the fact
> that __ is reserved. That seems a pretty poor justification for a language
> feature.

I was not talking about *my codebase*, I was talking about the collective 
entirety of all existing PHP codebases.

So I now understand that you were proposing even less than I thought you were 
proposing.  I thought you were proposing that PHP would recognize and give 
speaking meaning to a method called toArray() or similar.  Now I realize you 
were proposing even less and instead placing the burden of said standardization 
on each project, guaranteeing no serendipitous reuse across projects.  :-(


> One huge benefit I haven't mentioned yet is the ability to add parameters.
> Imagine if your mustache formatters are used in both plain text and HTML
> contexts, and that affects some of the data to return.

When you have the need for parameters, by all means create a named method.  But 
why block the use cases that do not need parameters?  Why not simply let 
developers who find __toArray() useful be able to use them?


> If you have a
> Thinking about it, if you're only going to allow one method per class, with
> the class's namespaced name telling you what it does, you might as well use
> __invoke():

But it is reasonable to expect that a class could need both an __invoke() and a 
__toArray() method. 

Also there is no guarantee that an object that implements __invoke() will 
return an array whereas there should be a reasonable guarantee that if 
function_exists($object,'__toArray') is true that casting to (array) would be 
valid.


> You can only rely on __toArray if you standardise on every object
> implementing it; at which point, you can standardise on any name you like.

But method name standardization does not work across unrelated projects.  
Because programmers.

Casting to (array) would work across unrelated projects.

> People are quite happily using polymorphism with named methods in literally
> millions of OO code bases.

https://en.wikipedia.org/wiki/Status_quo_bias 
<https://en.wikipedia.org/wiki/Status_quo_bias>

> I'm not suggesting *PHP* standardises on some other name, just that *your
> code base* standardises on common names for common tasks.

And therein is where your argument breaks down compared to the argument for 
__toArray().  It assumes each team's and/or project's codebase is an island.

> Well, I started this sub-thread saying I was "sceptical" rather than
> "strongly opposed". If the feature was added, I would simply ignore it, and
> probably argue against its use in code review and style guides.

I think I have discovered another difference between you and I.  When someone 
proposes a feature I can easily ignore, I do not write long emails arguing 
against it. 

#justsaying :-)

> However, other people have pointed out that unlike (string)$object,
> (array)$object does have a default behaviour, and adding an overload for it
> has the potential to break code relying on that. So it's not an entirely
> zero-cost feature.

I do not see this as an issue because this BC break is entirely opt-in by the 
developer.

It is possible a library developer could add a __toArray() in a new version of 
a open-source library where one did not previously exist and thus break other's 
code that depended on the previous version of the library. That would be no 
different than if the library developer changed the behavior of one of their 
existing methods.  So that would be one the library developer, not on PHP. 


-Mike

Reply via email to