[CONCEPT][DISCUSSION] Instance as boolean

php.internals

Josh Bruce

6 years ago
Link to working draft: https://bit.ly/php-0001 <https://bit.ly/php-0001> Discussion on implementing a means by which a class instance can interacted with syntactically as a boolean. At this point in the discuss the only means discussed is creation of a method (magic or via an interface). Ability to cast is not ruled out. And, my limited knowledge of PHP at this depth, much less under the hood, means there could be a lot of unknown unknowns regarding the ways a boolean can be interpreted and interacted with; therefore, those may not be covered at this time. I’m also not liking the overly contrived nature of the samples and will improve those over time should interest maintain or increase. Cheers, Josh ps. If you have any feedback or information on social interactions here that might help, please do let me know, normally I would have watched for a while before putting my foot in - hopefully it doesn’t end up in my mouth. :)

Marcio Almada

6 years ago
Hello Josh,
> Link to working draft: https://bit.ly/php-0001 <https://bit.ly/php-0001>
From a type safety POV I'd prefer to have an interface available, the same way we did to the Stringable interface RFC. But I'd rather keep these engine affecting behaviors with the same magic method naming conventions and its `__` prefix. So `implements Bool` + `function __toBool() : bool` is the only path that seems entirely consistent with what we already have. The draft doesn't mention (bool) casting behavior at the time I'm reading it, but you do mention the possibility. It seems necessary to me. Why wouldn't `(bool) $my_bool_obj` behave differently from `(string) $my_stringable_obj`?
> > ps. If you have any feedback or information on social interactions here that might help, please do let me know, normally I would have watched for a while before putting my foot in - hopefully it doesn’t end up in my mouth. :)
Thanks, Márcio Almada

Josh Bruce

6 years ago
> On Jul 8, 2020, at 12:54 PM, Marcio Almada <marcio.web2@gmail.com> wrote: > > Hello Josh, > >> Link to working draft: https://bit.ly/php-0001 <https://bit.ly/php-0001> > > From a type safety POV I'd prefer to have an interface available, the > same way we did > to the Stringable interface RFC. But I'd rather keep these engine > affecting behaviors > with the same magic method naming conventions and its `__` prefix. > > So `implements Bool` + `function __toBool() : bool` is the only path that seems > entirely consistent with what we already have. > > The draft doesn't mention (bool) casting behavior at the time I'm > reading it, but you do > mention the possibility. It seems necessary to me. Why wouldn't > `(bool) $my_bool_obj` > behave differently from `(string) $my_stringable_obj`? > >> >> ps. If you have any feedback or information on social interactions here that might help, please do let me know, normally I would have watched for a while before putting my foot in - hopefully it doesn’t end up in my mouth. :) > > > Thanks, > Márcio Almada >
Hello Marcio, Thank you for the input. Re casting - In the previous thread the following concern was presented and I don’t know enough about that area to respond effectively: "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 <https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229>” I concur with the Stringable mention - thank you for that - I have updated based on this feedback: https://bit.ly/php-0001 <https://bit.ly/php-0001> I’ve also included a “questions outstanding” section as I could imagine people losing threads and wanted to give a way to “get up to speed” quickly. Given that the goal would be to have the class be used in place of a bool everywhere, I would think we would need to make it cast-able to a bool, yeah? Cheers, Josh ps. Thank you again. I feel like every bit of feedback causes a re-write and iteration on the presentation. Lol

Marcio Almada

6 years ago
Hi
> > Re casting - In the previous thread the following concern was presented and I don’t know enough about that area to respond effectively: "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” >
Frankly this is something subject to personal opinions and will change over time according to community shifts. I think the main obligation of languages and runtimes is to show consistency in their design and behavior. If somehow part of the community wants to enforce that "casting is a bad practice" (because IDE support or whatever valid reason in our current decade) it's ok. But making the language behave differently for each casting scenario actually makes it harder for userland to apply the good practices of the moment consistently.
> I concur with the Stringable mention - thank you for that - I have updated based on this feedback: https://bit.ly/php-0001 > Given that the goal would be to have the class be used in place of a bool everywhere, I would think we would need to make it cast-able to a bool, yeah? >
Yes, precisely. Thanks, Márcio

Marco Pivetta

6 years ago
Hey Marcio, On Thu, Jul 9, 2020 at 7:49 PM Marcio Almada <marcio.web2@gmail.com> wrote:
> Hi > > > > > Re casting - In the previous thread the following concern was presented > and I don’t know enough about that area to respond effectively: "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 > ” > > > > Frankly this is something subject to personal opinions and will change > over time according to community shifts. > >
Not sure what's "subject to personal opinions" in the objective bug exposed in the snippet above? Greets, Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

Marcio Almada

6 years ago
Hi,
> > Hey Marcio, > >> >> Hi >> >> > >> > Re casting - In the previous thread the following concern was presented and I don’t know enough about that area to respond effectively: "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” >> > >> >> Frankly this is something subject to personal opinions and will change >> over time according to community shifts. >> > > Not sure what's "subject to personal opinions" in the objective bug exposed in the snippet above? >
So there is a bug in a contrived code snippet therefore casting is a universal bad practice? It's at least a huge stretch. Some might say your bad practice was actually using `null` ;)

Josh Bruce

6 years ago
>>> >>> Frankly this is something subject to personal opinions and will change >>> over time according to community shifts. >>> >> >> Not sure what's "subject to personal opinions" in the objective bug exposed in the snippet above? >> > > So there is a bug in a contrived code snippet therefore casting is a > universal bad practice? > It's at least a huge stretch. Some might say your bad practice was > actually using `null` ;)
Good stuff - very helpful (and I’m grateful), thank you both. This might actually be an interesting (possibly the) use case for what we’re talking about. Updated: https://bit.ly/php-0001 <https://bit.ly/php-0001> Added pre-roll section on perceived roadblocks as I’m experiencing one. Added “Usage” section. Renamed code sample header to “Rationale" *** I didn’t have a chance to look at the code linked before and tend to agree: 1. Avoid null (I’m a bit extreme with this one) 2. I tend to avoid casting as well and, if the first is followed, a casting problem could become moot. PHP doesn’t like to halt - most primitives when cast to bool either effectively return the result of an empty check or a not-zero check - an object, if instantiated, is always true. __toBool would give us a way of saying it’s not true (it’s not empty, it's not zero, but it's not okay for some reason - maybe we need to do some follow-on configuration method calls…just making stuff up). :) Cheers, Josh

Larry Garfield

6 years ago
On Wed, Jul 8, 2020, at 11:39 AM, Josh Bruce wrote:
> Link to working draft: https://bit.ly/php-0001 <https://bit.ly/php-0001> > > Discussion on implementing a means by which a class instance can > interacted with syntactically as a boolean. > > At this point in the discuss the only means discussed is creation of a > method (magic or via an interface). > > Ability to cast is not ruled out. > > And, my limited knowledge of PHP at this depth, much less under the > hood, means there could be a lot of unknown unknowns regarding the ways > a boolean can be interpreted and interacted with; therefore, those may > not be covered at this time. > > I’m also not liking the overly contrived nature of the samples and will > improve those over time should interest maintain or increase. > > Cheers, > Josh > > ps. If you have any feedback or information on social interactions here > that might help, please do let me know, normally I would have watched > for a while before putting my foot in - hopefully it doesn’t end up in > my mouth. :)
Hi Josh. Your social interactions seem fine, no worries. :-) You may need to ask for wiki access; the configuration/rules around it are, honestly, kinda weird. To the RFC itself, as you've likely noticed you've stumbled into a long-running contentious question. __toString() is itself already controversial and some don't like it, while others want to see every possible primitive type added for completeness. Focusing on Bool is, I think, a good choice because it has an argument for it other than "well it works for strings." You hint at it in the writeup but really bury the lead: Null objects. Being able to not use null or false as a "not found" case and instead return an "empty" value object is very nice, but then you also want to know if the value returned is legitimate. An object that could self-cast to boolean makes something like this viable and type-safe: $user = $repo->getUserById(5); if ($user) { // Do stuff with user } else { // The user wasn't found. } No exception needed, no null, no false, just a safe "empty" user object; whether you want to branch the logic based on that is then up to the caller. It also allows an "empty" object to still have default values inside it (like a username of "Anonymous" or something), which are up to the implementer. I'd say focus on that benefit. The similarity to __toString() is just to show that the implementation is consistent with existing patterns, not an argument for adding _toBool() itself. Feel free to steal the user-repo example if you want. I have no strong feelings about interface vs. magic method, that's an old race I don't have a horse in. --Larry Garfield

Josh Bruce

6 years ago
> > Focusing on Bool is, I think, a good choice because it has an argument for it other than "well it works for strings." You hint at it in the writeup but really bury the lead: Null objects. > > Being able to not use null or false as a "not found" case and instead return an "empty" value object is very nice, but then you also want to know if the value returned is legitimate. An object that could self-cast to boolean makes something like this viable and type-safe: > >
Thanks! I think you’re right - maybe just taking a minute to figure out what the lead was. lol I updated the repo and link: https://bit.ly/php-0002 <https://bit.ly/php-0002> Going to be starting a new thread with subject that matches better where we are: Objects able to define emptiness (and possibly truthiness by extension to maintain consistency - but object may be an exception??). Cheers, Josh ps. Also did get registered to the wiki from a different thread conveniently happening at the same time. :)