Proposal: A way for classes to define a response to any primitive type cast

php.internals

Josh Bruce

6 years ago
Apologies, first time, still learning and have no historical context - timing is what it is. Proposal type: Concept Implementer: Unknown, fallback to me after slow learning Presumed simple implementation as the pattern should already be in place: Cast of (string) -> __toString() - already implemented Cast of (bool) -> __toBool() Cast of (int) -> __toInt() Cast of (object) -> __toObject() …and so on. Alternative implementation using an interface: \CastableTo{type} Extreme implementation: Make both of the previous available. Known unknowns: - Level of interest in something like this in the PHP community outside of one upvote on a Stackoverflow question I submitted: https://stackoverflow.com/questions/62747837/php-7-tostring-or-other-interface-for-boolean-values <https://stackoverflow.com/questions/62747837/php-7-tostring-or-other-interface-for-boolean-values> - Whether this conversation or proposal has already occurred. - The historical conversation leading to the creation of the __toString() method (and stopping there). - The current conversation around using magic methods in general and specifically when defining a cast response. - Enough details on PHP internal development to implement myself (this is the first time in 20 years I felt I couldn’t comfortably accomplish what I wanted to, thanks for that). - What potential collisions could occur if someone (me) wanted to implement all possibilities in a single class. - Right now __toBool() would be of the most personal benefit - if proposal is converted to an RFC, would it be better (faster/smoother) to do one RFC for all the cast possibilities - or to have an RFC for each cast separately? Thank you for the consideration, information, and feedback. Cheers, Josh ps. Also, apologies again for walking into a new space on a mission, not my normal approach. pps. The primary project inspiring the proposal: https://github.com/8fold/php-shoop <https://github.com/8fold/php-shoop>

Marco Pivetta

6 years ago
Hey Josh, Similar proposals were raised recently for `__toArray()`: see https://externals.io/message/108369#108369 I'd endorse avoiding object-to-<scalar> casts via cast operations: they are a good source of bugs. My rationale for the discouragement of magic cast methods is explained with some code examples at https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229 Greets, Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On Mon, Jul 6, 2020 at 4:17 PM Josh Bruce <josh@joshbruce.dev> wrote:

Josh Bruce

6 years ago
> On Jul 6, 2020, at 11:54 AM, Marco Pivetta <ocramius@gmail.com> wrote: > > Hey Josh, > > Similar proposals were raised recently for `__toArray()`: see > https://externals.io/message/108369#108369 > > I'd endorse avoiding object-to-<scalar> casts via cast operations: they are > a good source of bugs. > My rationale for the discouragement of magic cast methods is explained with > some code examples at > https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229 > > Greets, > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ > > > On Mon, Jul 6, 2020 at 4:17 PM Josh Bruce <josh@joshbruce.dev> wrote: > >> Apologies, first time, still learning and have no historical context - >> timing is what it is. >> >> Proposal type: Concept >> >> Implementer: Unknown, fallback to me after slow learning >> >> Presumed simple implementation as the pattern should already be in place: >> >> Cast of (string) -> __toString() - already implemented >> >> Cast of (bool) -> __toBool() >> >> Cast of (int) -> __toInt() >> >> Cast of (object) -> __toObject() >> >> …and so on. >> >> Alternative implementation using an interface: >> >> \CastableTo{type} >> >> Extreme implementation: >> >> Make both of the previous available. >> >> Known unknowns: >> >> - Level of interest in something like this in the PHP community outside of >> one upvote on a Stackoverflow question I submitted: >> https://stackoverflow.com/questions/62747837/php-7-tostring-or-other-interface-for-boolean-values >> < >> https://stackoverflow.com/questions/62747837/php-7-tostring-or-other-interface-for-boolean-values >>> >> - Whether this conversation or proposal has already occurred. >> - The historical conversation leading to the creation of the __toString() >> method (and stopping there). >> - The current conversation around using magic methods in general and >> specifically when defining a cast response. >> - Enough details on PHP internal development to implement myself (this is >> the first time in 20 years I felt I couldn’t comfortably accomplish what I >> wanted to, thanks for that). >> - What potential collisions could occur if someone (me) wanted to >> implement all possibilities in a single class. >> - Right now __toBool() would be of the most personal benefit - if proposal >> is converted to an RFC, would it be better (faster/smoother) to do one RFC >> for all the cast possibilities - or to have an RFC for each cast separately? >> >> Thank you for the consideration, information, and feedback. >> >> Cheers, >> Josh >> >> ps. Also, apologies again for walking into a new space on a mission, not >> my normal approach. >> >> pps. The primary project inspiring the proposal: >> https://github.com/8fold/php-shoop <https://github.com/8fold/php-shoop> >> >> >>
Thank you for the reply Marco. Decided to put something together: https://github.com/joshbruce/external-project-proposals/blob/master/php-concepts/interact-with-instance-as-php.md <https://github.com/joshbruce/external-project-proposals/blob/master/php-concepts/interact-with-instance-as-php.md> I really appreciated the links to and conversations on __toArray. I hope I adequately incorporated and differentiated the desired outcome (interact as if PHP primitive) instead of focusing on the implementation (cast). Also, just to make sure I caught what you were saying: You recommend avoiding making thing “cast-able” - but ardently necessarily opposed to other means. Cheers, Josh

Rowan Collins

6 years ago
On 07/07/2020 18:13, Josh Bruce wrote:
> Decided to put something together:https://github.com/joshbruce/external-project-proposals/blob/master/php-concepts/interact-with-instance-as-php.md
Hi Josh, Reading through this, it seems to cover a few different concepts, which are certainly related, but not quite the same. Firstly, we have interfaces such as Countable and Serializable, which don't make the object act like any particular primitive type, they just customise its interaction with particular functions. Iterators could potentially be included in that category, too, because it's fairly easy to imagine the language having multiple primitive types that can be iterated (e.g. separate "list" and "dictionary" types). ArrayAccess feels more explicitly about making an object "act like" an array, but more precisely it overloads the [] operator - it doesn't allow the object to be used in other contexts where arrays are allowed. More general operator overloading was discussed recently, and the particular proposal put forward did not pass its RFC vote. [1]  __toString, on the other hand, only allows the object to be *converted to* a string, not act like one. You can't, for instance, influence the behaviour of the concatenation operator, and make "Hello" . $object . "!" return an object instead of a string, or a string that doesn't begin "Hello". An __toArray method was proposed recently, to mixed reaction. [2] The other closely related topic is what is often discussed as "scalar methods" or "scalar objects" - the ability to call methods on non-object values, and possibly to define your own methods that can be called in this way. This would seem to fit your use case with Shoop quite well: rather than Shoop::array($array)->first()->unfold(), you would just call $array->first(). It's fairly high on a lot of people's wish lists, but there's a lot of details to get right in both design and implementation, so I strongly recommend searching for previous discussions and proofs of concept before diving in. [1] https://wiki.php.net/rfc/userspace_operator_overloading [2] https://externals.io/message/105589
-- Rowan Tommins (né Collins) [IMSoP]

Илья Сомов

6 years ago
> This would seem to fit your use case with Shoop quite well: > rather than Shoop::array($array)->first()->unfold(), you would just call > $array->first(). It's fairly high on a lot of people's wish lists, but > there's a lot of details to get right in both design and implementation, > so I strongly recommend searching for previous discussions and proofs of > concept before diving in.
We don't need methods on non-scalar objects, if we have [pipe operator](https://wiki.php.net/rfc/pipe-operator-v2): sth like `$array |> array_first(?)`. This would allow much greater flexibility.