On Sun, Jan 6, 2013 at 2:05 AM, Stas Malyshev <smalys...@sugarcrm.com>wrote:
> You convinced me that this feature is actually harmful to PHP - dealing
> with unset() throwing fatal errors is much worse than occasional empty()
> check. This is a huge landmine - now any code that unsets object
> property can return fatal error, and there's, unlike is_null, not even
> any way to check it.

Wait, what are you talking about here? About this particular proposal or
the accessors RFC in general? The fact that unset() can throw a (catchable)
fatal error is just the same without this particular syntax. If you define
a property with an object-typehinted set accessor, then unset() will not be
possible (throwing a catchable fatal). And I really don't see what's wrong
with this. Unset() does not and should not work silently on anything you
pass it. Some things just can't be unset() and we shouldn't pretend like
they can just by silently ignoring. On this topic, a tangentially related
note: The current accessors RFC will make an unset() call on a property
without setter just do nothing *without an error*. I don't know why you
would think this is a good idea. I honestly can't see how just silently
ignoring instructions is any good. If something can't be unset PHP should
tell you so, rather than leaving you with an (incorrect!) sense of the
operation being performed successfully.

>> The timeframe in which it is NULL is usually contained to the
constructor.

> So what? Objects are constructed all the time, and constructors can call
> any other code. Also, nothing really guarantees the constructor actually
> has initialized the variable - the constructor author could have
> forgotten it just as you could have forgotten to initialize it without
> "no NULL" requirement - so when you are using the API of the object, you
> can not know if the constructor initialized it or not. And if you're
> sure your code is right - you don't need null checks anyway, as you know
> your code never assigns null there.

There are some things one should address here:

1. First of all, there never is a guarantee for everything. All kinds of
typing mechanism can only go so far. They are supposed to help you find
mistakes and prevent issues, but they can't do *everything*. If you know
some magic method to prevent all possible bugs in software, please let me
know. Typehinting is just another defense mechanism preventing many common
faults, but it can't prevent everything.

2. Secondly, the main purpose of typehints is to prevent people setting
incorrect values. If you know that only a "DateTime" instance is valid and
that NULL is not valid, then you should allow only that, only the DateTime.
Allowing NULL absolutely doesn't make sense (as it's not a valid value for
your application), so I'm not sure why you insist on allowing it.
unset()ing it doesn't make sense, so we shouldn't allow it. Your
argumentation goes along the lines of "It's possible that this property
could maybe end up being NULL, so it does not make sense to prevent people
from assigning NULL". The second part of that sentence does not follow from
the first part. The fact that it can be NULL before initialization does not
mean that we shouldn't prevent API users from doing a NULL assignment.

3. The constructor is typically (or at least that's how it *should be*)
small and doesn't do work, so there isn't much to do wrong. But sure, it
can still happen that you forget to initialize something, no arguing that.
The typehint on the property will not prevent this, absolutely. Still it
will prevent all other incorrect assignments to the property, which is
exactly its goal.

I'd summarize this as follows: The typehint prevents all incorrectly-typed
assignments, but it does not prevent missing initialization. Your
argumentation is that because it can't prevent missing initialization, we
shouldn't bother with preventing incorrect assignments either. I hope you
realize that this makes no sense.

Nikita

Reply via email to