@francois I understand your point, but I have a different view of the userland situation. Let me give some examples:
In the array case, Iterator / Traversable doesn't solve casting, it solves iteration. Given a Traversable object from a third party library, if a method from another (or the same) third party library requires an array as an argument, the developer would have to iterate the object and build an array herself in a Mediator or Adapter class. If she could cast it, then all she would need to do is orchestrate the messaging, without fiddling in the middle. As for the other cases, there are plenty of examples that could prove that a userland object may want to have a different representation as a string than as other scalar types. Money is the first that comes to mind: $money = new Money(12.5, Money::DOLLARS); var_dump((string) $money); // string(5) "$12.5" var_dump((float) $money); // float(12.5) While there is information loss in the conversion, it is just a userland example that could well benefit from different representations in the various scalar types. For example, if an interest were to be calculated from a Money object, the currency wouldn't matter, and the interest calculator may as well expect just a float as argument. Also, there's a huge cognitive gap. For example, if a developer wants an object to be evaluated as a boolean, she would have to force an empty string as the __toString() method return. That by itself does not represent her intention. Without proper documentation, it's just a matter of time for another developer to find this behavior and remove it or replace it with something more representative of a string representation of the object. Cheers! El mié., 13 de may. de 2015 a la(s) 6:37 p. m., François Laupretre < franc...@php.net> escribió: > Hi, > > > De : Guido Contreras Woda [mailto:guiw...@gmail.com] > > > > Multiple frameworks and libraries define interfaces or objects that wrap > > around some scalar value and add behavior, the most common case being > > arrays and Collection / Hash[Set|List] objects. Although this objects > > benefit from the possibility of having behavior themselves, sometimes the > > implementation is outside our project scope (an external dependency) and > > interaction between this object and other blocks of code that expect > scalar > > types usually needs to be controlled by the user, which adds the > necessity > > for adapters or some sort of mediator. > > > > Now that we have the ability to hint return types, a common interface > could > > be built that, given an object that implements it, lets userland code use > > this object as if it were the scalar type it is wrapping. Unboxing the > > object is pretty easy, and I wouldn't go as far as proposing interfaces > for > > rebuilding the object itself (not now, at least). > > > > So, what do you think of a set of interfaces that allow userland objects > to > > be used as scalar types? > > First, we probably don't need anything for arrays. The Iterator interface > family already provides everything we need to consider an object as an > array. > > For other scalar types, while I agree casting should be supported, I don't > like the solution of creating new methods. I would prefer always calling > __toString() and then, convert the string to the desired type. So, > (int)$object would just be a shortcut for (int)(string)$object. Quite easy > to implement, no new method, just need to enrich the convert_to_xxx() > functions to go through convert_to_string first. I already had this idea > for 7.0 but missed time. Maybe for 7.1. > > I also think it's more consistent as an object could not be transformed to > different unrelated values when cast to different scalar types. If $object, > when cast to int, becomes 10 and, when cast to string, becomes 'foo', is it > consistent in such a loose typing system ? So, I prefer that, by > construction, (int)$obj always gives the same value as (int)(string)$obj. > > Regards > > François > >