Hi,

On Wed, Mar 16, 2016 at 9:21 PM, Ryan Pallas <derokor...@gmail.com> wrote:

> On Wed, Mar 16, 2016 at 12:50 PM, Larry Garfield <la...@garfieldtech.com>
> wrote:
>
> > On 3/16/16 11:36 AM, Phil Sturgeon wrote:
> >
> >>
> >> 2. This whole temporary nullability situation, where unset properties
> >> will error on attempted usage if not set. Should they instead error
> >> after the constructor has been called if they are still not holding a
> >> value?
> >>
> >
> > I fall back to a statement I made in a blog post a while back:
> >
> > http://www.garfieldtech.com/blog/empty-return-values
> >
> > " But consider what you could do instead that would not force me to throw
> > is_null() around my code, because throwing is_null() around my code makes
> > me sad. NULL should be the return value of last resort, because it means
> > nothing. (Literally.)"
> >
> > Allowing default-null on properties means that as someone using that
> > property, I have two options:
> >
> > 1) Throw a lot of is_null() calls around my code.
> > 2) Assume that whoever initialized the code provided a value by the time
> > initialization is done and skip those extra checks.
> >
> > Insert that old adage about what happens when you assume.
> >
> > End-of-constructor checks seem like a good approach; they have to be
> > uninitialized at some point when new is called initially, but they should
> > be guaranteed set as soon as possible.  End of the constructor is "as
> soon
> > as possible", and I think reasonably static-analysis-catchable.  (Meaning
> > my IDE can yell at me appropriately.)
> >
> > That removes is_null() calls from the rest of my codebase, which is a
> good
> > thing.
> >
> >
> I'm not sure I like the "after contructor" because that's not necessarily
> when the object is finished being initialized. Consider this:
>
> abstract class Contract
> {
>     private function __construct() {}
>
>     public static function fromArray(array $aProps) : Contract
>     {
>         $s = new static();
>         foreach ($aProps as $k => $v) {
>             if (property_exists(static::class, $k)) {
>                 $s->$k = $v;
>             }
>         }
>
>         return $s;
>     }
> }
>
> class User extends Contract {
>    public int $id;
>    public string $name;
> }
>
> $user = User::fromArray(['id' => 123, 'name' => 'derokorian']);
>
> In this example, the constructor finishes but the properties still are not
> initialized at time of finishing. This is a pretty common pattern as well.
>

Also, a LOT of code would end up with e.g. a default value of 0 for an
integer property, still having to check if it was properly populated with a
positive value - not much of an improvement over NULLs.

Cheers,
Andrey.

Reply via email to