Robert Williams wrote on 14/09/2015 21:17:
I really don’t understand the resistance to this type of change, other than knowing that a fix will necessarily be messy.

The resistance is that not everyone agrees that there is a problem to be fixed.


The fact is, PHP distinguishes between a variable that has been declared but defined to null and one that hasn’t been declared. The value of the first may safely be assigned, compared, referenced, and so on, while attempting any of those things on the second one results in an error message.

No, it results in a warning you that you may have made a mistake somewhere in your code, or be leaving your code open to future bugs by not being explicit when initialising your variables.


The question of whether relying on those differences is philosophically acceptable is a moot point: they *are* different, period, and the rest of the language should acknowledge and support that — just as do most other languages with a similar design (e.g., JavaScript).

JavaScript has very different scoping rules to PHP, so direct comparisons are a bit tricky. All local variables must be declared with "var", at which point they "exist" throughout the scope of that function, and will not give ReferenceErrors, but will be of type "undefined". That "undefined" does seem to act like a value of the variable, though - you can pass it in to another function, and the parameter will also be "undefined". Omitted parameters also default to "undefined" in the same way. This makes it seem remarkably like PHP's null to me.

Perl also has similar semantics with its "undef" value and "defined" operator - if you set a variable $a to the special value "undef", then "defined $a" will return false. Crucially for the current discussion, you can set a hash member to undef without deleting that key, and "defined $a{foo}" will also evaluate to false. There is also an "exists" construct, which *only works on hash elements* - trying to evaluate "exists $a" is an error.

I don't know enough Ruby or Python to make any comparisons, and would welcome any examples to back up your assertion that other languages support this operation.


Based on code I’ve seen from fairly experienced developers, the confusion around this has probably led to millions of production bugs, many of them in the areas of validation and security. When a particular aspect of a language's design promotes bugs to such an extent, it needs to be revisited.

There are certainly plenty of bugs out there where somebody used isset() when they should have used array_key_exists(). This is not an argument for changing or replacing isset(), but it is definitely an argument for improving documentation, and maybe for creating a more user-friendly version of array_key_exists().

I have never seen a single example of a bug caused by a programmer assuming that unset($a) and $a=null would lead to different states distinguishable by isset(), either in the wild, or constructed in any of the discussions I've had on this topic.


For now, isset() and empty() can continue to work as-is but perhaps with a notice and deprecation when used with undeclared variables.

You realise that isset() with a notice on an undeclared var would literally be an alias for is_null(), right?

Regards,
--
Rowan Collins
[IMSoP]

Reply via email to