[RFC] Type hints

php.internals

Marcus Börger

22 years ago
Hello internals, while working with php 5 the last days i find it more and more annoying that we allow NULL with type hints. From my perspective allowing NULL with typehints would happen only very rare. So i looked into the issue once again and prepared a patch. first i looked back the mails for this issue and found three possible solutions: 1) (Zeev) allow NULL only when it is the first default argument. Here the disadvantage is that you cannot have non default parameters after one that allows NULL. Also this would introduce a BC break if we'd go this way after 5.0 is out because it changes the standard behavior. 2) (Andi) introduce 'not null' after php 5.0. This won't introduce a BC break. But it would require two new keywords 'NOT' and 'NULL'. The latter is not a problem because it is a define at the moment and the patch (a) shows that it easy to change it into a keyword. The problem is the new keyword 'not' which would introduce a BC break for everyone using the word 'not' already. 3) (Myself) introduce 'or null'. Obviously this would introduce a BC break when implemented after PHP 5.0 is out. The advantage is that it only requires NULL as an additional keyword (see above) and that it reflects the code it replaces. The replacement code is to check whether the parameter is an instance of the typehint "or" if specified check if it is null: func(Classname or NULL $param) {} replaces func($param) { if ($param instanceof Classname or is_null($param)) { // ok } else { // error } } Having listed the three ideas i think we must address this issue now and cannot delay it until after php 5.0 is out. Because of 2's additional keyword and 1's disadvantage i like 3 most. The patch (b) implements it and adds a testfile. Patch (c) also implements typehints for 'array' and 'class'. Array checks the parameter for being an array and class checks the parameter to be an instance of any class. These two we agreed to do already and so i added an updated patch for it which also includes the 'or null'. (a) http://somabo.de/php/ext/ze2/ze2-null-patch-20040501.diff.txt (b) http://somabo.de/php/ext/ze2/ze2-type-hints-null-20040501.diff.txt (c) http://somabo.de/php/ext/ze2/ze2-type-hints-20040501.diff.txt p.s.: As a sideeffect these patches speedup NULL handling. Best regards, Marcus

Michael Walter

22 years ago
Marcus Boerger wrote:
> Hello internals, > [...]
How about function foo(Class? bar) instead? Too much magic? Cheers, Michael

Derick Rethans

22 years ago
On Sat, 1 May 2004, Michael Walter wrote:
> Marcus Boerger wrote: > > Hello internals, > > [...] > How about > function foo(Class? bar) > instead? Too much magic?
Too much magic indeed. Derick

John Coggeshall

22 years ago
I agree with the idea that it would be nice to force an instance of a particular class, etc. to be passed. However, if we are going to introduce another keyword anyway why not keep BC intact by by introducing the 'force' keyword: function myfunction(force ClassName $param, NextClass $another) { } Where 'force' would prevent $param from being passed as anything but an acceptable ClassName. Alternatively, for the sake of parsing you could do: function myfunction(Classname forced $foo) { } I remember discussing 'array' as a typehint (big +1 there), but I don't see anything gained from such a type-hint. When exactly would you use it (that you couldn't use the existing type hinting).. I guess the obvious answer is when you don't know the type of class being passed, but if you don't know that how do you plan on actually using the parameter at all? John
-- -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=- John Coggeshall http://www.coggeshall.org/ The PHP Developer's Handbook http://www.php-handbook.com/ -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=-

Marcus Börger

22 years ago
Hello John, Saturday, May 1, 2004, 11:27:32 PM, you wrote:
> I agree with the idea that it would be nice to force an instance of a > particular class, etc. to be passed. However, if we are going to > introduce another keyword anyway why not keep BC intact by by > introducing the 'force' keyword:
the point of solution 3 was not to introduce a new keyword other than null. And adding null as a keyword dosn't have implications other that ppl may have a fucntion called 'null'. But i don't think that happens often. Using force or forced on the other hand seems to happen often at least i used it myself.
> I remember discussing 'array' as a typehint (big +1 there),
good so far
> but I don't > see anything gained from such a type-hint. When exactly would you use it > (that you couldn't use the existing type hinting).. I guess the obvious > answer is when you don't know the type of class being passed, but if you > don't know that how do you plan on actually using the parameter at all?
What are you speaking of here? array means the parameter must be an array. class means the parameter must be any class instance which can be used for reflection as an example. Best regards, Marcus

Andi Gutmans

22 years ago
Hi Marcus, It probably makes sense to go with (3) because as Zeev says, the majority of the times you don't want to allow NULL. If we decide to go this direction we definitely need to implement it before PHP 5 because otherwise it'll be a big BC break. I wouldn't use the syntax you proposed but you: function func(MyClass $obj or null); Concerning type hints, I don't think that a type hint of "class" is useful. If you don't use a base class as a type hint (which you will almost always use) then how useful will this really be? Also, it's not really Class but it's an Object, so we'd have to add another reserved word. In my opinion, I'd only go with the "array" part of the typehints patch. On another note, I think PHP 5 is already stable and quite mature. It's an order of magnitude more stable than PHP 4 was when it was released. I think we should start thinking of a deep feature freeze and a release date. As we're in the beginning of May I think sometime towards July makes sense. This does mean that we really need to stop adding stuff. I agree to open the typehints issue because it could potentially lead to a BC break depending what solution we take. Andi At 10:09 PM 5/1/2004 +0200, Marcus Boerger wrote:

Marcus Börger

22 years ago
Hello Andi, Sunday, May 2, 2004, 6:09:22 PM, you wrote:
> Hi Marcus,
> I wouldn't use the syntax you proposed but you: > function func(MyClass $obj or null);
an updated patch can be found here: http://somabo.de/php/ext/ze2/ze2-type-hints-20040502.diff.txt
> Concerning type hints, I don't think that a type hint of "class" is useful. > If you don't use a base class as a type hint (which you will almost always > use) then how useful will this really be? Also, it's not really Class but > it's an Object, so we'd have to add another reserved word. In my opinion, > I'd only go with the "array" part of the typehints patch.
the updated patch neither contain 'class' not 'object'. Adding Object as a reserved work is a bad ide imo because i thing many ppl use it for basic classes. The reasons i chose class in the first place were that i didn't want to add a new keyword and that i had the term 'instance of any class' in mind.
> On another note, I think PHP 5 is already stable and quite mature. It's an > order of magnitude more stable than PHP 4 was when it was released. I think > we should start thinking of a deep feature freeze and a release date. As > we're in the beginning of May I think sometime towards July makes sense. > This does mean that we really need to stop adding stuff. I agree to open > the typehints issue because it could potentially lead to a BC break > depending what solution we take.
more or less agreed. what i fear is missing the chance to act on bad test experience. but we can't wait forever, so how about a branch now, that could attract even more testers and hence give more feedback? best regards marcus

Andi Gutmans

22 years ago
I really would like to finalize this issue ASAP because it's the last *feature* I see for PHP 5.0. The main reason why I think we need to finalize it is because depending on the solution we choose, it would break BC if we fix it after 5.0. Consider the following options for a parameter with default value which allows null: MyClass $a or NULL = 5 MyClass $a = 5 or NULL MyClass or NULL $a = 5 I think all of these are pretty ugly and I don't feel comfortable with adding them to the language. The following (Zeev's idea) is much simpler and nicer, but I'm not 100% sure if this is the perfect solution: nullable MyClass $a = 5 Ideas/comments? Andi At 07:17 PM 5/2/2004 +0200, Marcus Boerger wrote:

Stanislav Malyshev

22 years ago
AG>>sure if this is the perfect solution: AG>>nullable MyClass $a = 5 I must be missing something, but why typehinted variable should have any default except for null anyway? If someone says "I want only MyClass here!", why he should be able to put 5 there?
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Wez Furlong

22 years ago
In the class case it doesn't make sense, but for other types it does. --Wez.

Stanislav Malyshev

22 years ago
WF>>In the class case it doesn't make sense, but for other types it does. We have typehints for other types? From current code I gathered an impression that zend_verify_arg_type() expects class name to be there. Anyway, why would you need typehints for scalar types?
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Wez Furlong

22 years ago
I was thinking "in general" and not about the specifics of what we have now. --Wez.

Andi Gutmans

22 years ago
At 01:52 PM 5/9/2004 +0300, Stanislav Malyshev wrote:
>WF>>In the class case it doesn't make sense, but for other types it does. > >We have typehints for other types? From current code I gathered an >impression that zend_verify_arg_type() expects class name to be there. >Anyway, why would you need typehints for scalar types?
There will be type hints for arrays too. Obviously, with PHP's dynamic typing we can't have type hints for scalar values. Andi

Stanislav Malyshev

22 years ago
AG>>There will be type hints for arrays too. Obviously, with PHP's dynamic AG>>typing we can't have type hints for scalar values. Well, with arrays it's the same thing - any non-array (while null being array for the matter) default should not be accepted. Here it's more complicated since we can have constant arrays, which we may or may not to allow (I think it's a simple compile-time check anyway, so it may be good to allow array initializers).
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Andi Gutmans

22 years ago
At 02:12 PM 5/9/2004 +0300, Stanislav Malyshev wrote:
>AG>>There will be type hints for arrays too. Obviously, with PHP's dynamic >AG>>typing we can't have type hints for scalar values. > >Well, with arrays it's the same thing - any non-array (while null being >array for the matter) default should not be accepted. Here it's more >complicated since we can have constant arrays, which we may or may not to >allow (I think it's a simple compile-time check anyway, so it may be good >to allow array initializers).
Yeah I agree. Already today, we have a special rule for constant arrays initialization. Andi

Wez Furlong

22 years ago
> The following (Zeev's idea) is much simpler and nicer, but > I'm not 100% > sure if this is the perfect solution:
> nullable MyClass $a = 5
I agree; this is the nicest so far, and like you, and I'm not 100% sure if it is the perfect solution. +1 on this, unless someone comes up with something better :) --Wez.

Andi Gutmans

22 years ago
At 01:42 PM 5/9/2004 +0300, Stanislav Malyshev wrote:
>AG>>sure if this is the perfect solution: >AG>>nullable MyClass $a = 5 > >I must be missing something, but why typehinted variable should have any >default except for null anyway? If someone says "I want only MyClass >here!", why he should be able to put 5 there?
Well maybe it's a bad example but he can put NULL instead of 5. Andi

John Coggeshall

22 years ago
On Sun, 2004-05-09 at 06:46, Andi Gutmans wrote:
> At 01:42 PM 5/9/2004 +0300, Stanislav Malyshev wrote: > >AG>>sure if this is the perfect solution: > >AG>>nullable MyClass $a = 5 > > > >I must be missing something, but why typehinted variable should have any > >default except for null anyway? If someone says "I want only MyClass > >here!", why he should be able to put 5 there?
I think I mentioned something pretty close to this (maybe I used forceable instead of nullable). However, it's not really obvious to me why you should be allowed to do the default assignment in this case. Can someone either give a quick example as to why I would want to assign a default value like this? Other than that, +1 on nullable in concept. John
-- -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=- John Coggeshall http://www.coggeshall.org/ The PHP Developer's Handbook http://www.php-handbook.com/ -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=-

Stanislav Malyshev

22 years ago
AG>>>AG>>nullable MyClass $a = 5 AG>>> AG>>>I must be missing something, but why typehinted variable should have any AG>>>default except for null anyway? If someone says "I want only MyClass AG>>>here!", why he should be able to put 5 there? AG>> AG>>Well maybe it's a bad example but he can put NULL instead of 5. Well, that was exactly my point, though not expressed explicitly: if you can put null there, you don't need 'nullable'. If you say 'MyClass $a', it doesn't allow null, if you say 'MyClass $a = null', it allows null. Or, other way around, if you say 'nullable MyClass $a', it defaults to null, otherwise it has no default. I think we should prohibit to put any default to typehinted variables except null in any case - since it doesn't make any sense except promoting code based on is_object checks etc. - the exact thing we wanted to avoid with typehints.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Andi Gutmans

22 years ago
At 01:57 PM 5/9/2004 +0300, Stanislav Malyshev wrote:
>AG>>>AG>>nullable MyClass $a = 5 >AG>>> >AG>>>I must be missing something, but why typehinted variable should have any >AG>>>default except for null anyway? If someone says "I want only MyClass >AG>>>here!", why he should be able to put 5 there? >AG>> >AG>>Well maybe it's a bad example but he can put NULL instead of 5. > >Well, that was exactly my point, though not expressed explicitly: >if you can put null there, you don't need 'nullable'. If you say 'MyClass >$a', it doesn't allow null, if you say 'MyClass $a = null', it allows >null. Or, other way around, if you say 'nullable MyClass $a', it defaults >to null, otherwise it has no default. I think we should prohibit to put >any default to typehinted variables except null in any case - since it >doesn't make any sense except promoting code based on is_object checks >etc. - the exact thing we wanted to avoid with typehints.
I think it makes sense not to allow default initialization of non-NULL values when there's a class type hint. Andi

Stanislav Malyshev

22 years ago
AG>>I think it makes sense not to allow default initialization of non-NULL AG>>values when there's a class type hint. Having this, do we actually need both "= null" and "nullable" keyword? They seem to be almost the same meaning, though not exactly - you can say 'nullable' on first parameter of two-parameter function, while you couldn't - at least, until now - say '= null' for it.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Andi Gutmans

22 years ago
At 02:14 PM 5/9/2004 +0300, Stanislav Malyshev wrote:
>AG>>I think it makes sense not to allow default initialization of non-NULL >AG>>values when there's a class type hint. > >Having this, do we actually need both "= null" and "nullable" keyword? >They seem to be almost the same meaning, though not exactly - you can say >'nullable' on first parameter of two-parameter function, while you >couldn't - at least, until now - say '= null' for it.
I don't quite understand. = NULL is if you want to suggest that this parameter is optional (default value). nullable is if you want the typehint to not error out if null is passed for the object. I think these two are two different things and should have different syntax. Maybe I misunderstood what you're saying. Andi

Derick Rethans

22 years ago
On Sun, 9 May 2004, Andi Gutmans wrote:
> I really would like to finalize this issue ASAP because it's the last > *feature* I see for PHP 5.0. The main reason why I think we need to > finalize it is because depending on the solution we choose, it would break > BC if we fix it after 5.0. > Consider the following options for a parameter with default value which > allows null: > MyClass $a or NULL = 5 > MyClass $a = 5 or NULL > MyClass or NULL $a = 5 > > I think all of these are pretty ugly and I don't feel comfortable with > adding them to the language. > The following (Zeev's idea) is much simpler and nicer, but I'm not 100% > sure if this is the perfect solution: > nullable MyClass $a = 5
null or MyClass $a = 5 ? I've no idea what nullable is supposed to mean... (well, I do :) I was also wondering if the following would also work: class b extends a { } function foo (a $obj) { } $b = new b; foo($b); (ie, an inherited class also passes the hint check) Derick

Stanislav Malyshev

22 years ago
DR>>I was also wondering if the following would also work: DR>> DR>>class b extends a { } DR>> DR>>function foo (a $obj) { } DR>> DR>>$b = new b; DR>>foo($b); DR>> DR>>(ie, an inherited class also passes the hint check) This should definitely work. As I see from current code, it also does :)
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Marcus Börger

22 years ago
Hello Stanislav, Sunday, May 9, 2004, 12:58:48 PM, you wrote: DR>>>I was also wondering if the following would also work: DR>>> DR>>>class b extends a { } DR>>> DR>>>function foo (a $obj) { } DR>>> DR>>>$b = new b; DR>>>foo($b); DR>>> DR>>>(ie, an inherited class also passes the hint check)
> This should definitely work. As I see from current code, it also does :)
It works. What we cannot do is inheriting a function and specifying a base class typehint: class Root { } class Base { function f(Base $p) {} } class Leaf { function f(Root $p) {} } It is doable as the following patch shows: http://somabo.de/php/ext/ze2/ze2-type-hint-classes-20040327.diff.txt (the patch me be a little bit outdated though). I guess this can pretty good wait for 5.1. marcus

Andi Gutmans

22 years ago
At 12:57 PM 5/9/2004 +0200, Derick Rethans wrote:
>On Sun, 9 May 2004, Andi Gutmans wrote: > > > I really would like to finalize this issue ASAP because it's the last > > *feature* I see for PHP 5.0. The main reason why I think we need to > > finalize it is because depending on the solution we choose, it would break > > BC if we fix it after 5.0. > > Consider the following options for a parameter with default value which > > allows null: > > MyClass $a or NULL = 5 > > MyClass $a = 5 or NULL > > MyClass or NULL $a = 5 > > > > I think all of these are pretty ugly and I don't feel comfortable with > > adding them to the language. > > The following (Zeev's idea) is much simpler and nicer, but I'm not 100% > > sure if this is the perfect solution: > > nullable MyClass $a = 5 > >null or MyClass $a = 5 ?
I don't like this. I think it's too long and ugly.
>I've no idea what nullable is supposed to mean... (well, I do :) > > >I was also wondering if the following would also work: > >class b extends a { } > >function foo (a $obj) { } > >$b = new b; >foo($b); > >(ie, an inherited class also passes the hint check)
Yep. It's an instanceof check. Andi

Derick Rethans

22 years ago
On Sun, 9 May 2004, Andi Gutmans wrote:
> >null or MyClass $a = 5 ? > > I don't like this. I think it's too long and ugly. > > >I've no idea what nullable is supposed to mean... (well, I do :)
I thought about this a bit more, but couldn't actually see why something like "nullable" is needed at all. Simple solution: If you expect an object of a specific class; if it also might be NULL, don't use a class hint at all. So *why* do we even need "bloat" like "nullable" or something similar. regards, Derick

Christian Schneider

22 years ago
Derick Rethans wrote:
> I thought about this a bit more, but couldn't actually see why something > like "nullable" is needed at all. Simple solution: If you expect an
I second that. I think it's the creeping feature creature at work here. I think we should _not_ complicate the PHP syntax here. Just a thought: Allow default values to violate the type hint (maybe only a default value of null). - Chris

Stanislav Malyshev

22 years ago
CS>>Just a thought: Allow default values to violate the type hint (maybe CS>>only a default value of null). Non-null defaults for class-typehinted variable is definitely bad. This means you code has to check somewhere if it's default or not - then why typehint it? If your method accepts non-objects - it should not be marked as "accepts only objects of this type".
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Ferdinand Beyer

22 years ago
On 10 May 2004 at 11:31, Jason Garber wrote:
> The only way I see that as being useful is to be able to assume
that you
> can safely say $bar->DoSomething() from within your function
WITHOUT
> FIRST HAVING TO write an if() statement that verifies that it is not
null. On the other hand in many situations it is useful to be able to pass an empty value, e.g. setHandler(HandlerClass $a) could be called with setHandler(null) to remove the handler. For string values you can pass an empty string, for numbers 0 or a negative number and for objects null. In other languages it is always possible to pass null instead of the object (e.g. Java), in C/C++, every pointer may be set to null. I agree that it is a bad idea to introduce another weird syntax. We should either always allow null or never. I would prefer the first solution but could easily live with the second.
-- Ferdinand Beyer <fb@fbeyer.com>

Marcus Börger

22 years ago
Hello Ferdinand, Monday, May 10, 2004, 6:01:12 PM, you wrote:
> On 10 May 2004 at 11:31, Jason Garber wrote:
>> The only way I see that as being useful is to be able to assume > that you >> can safely say $bar->DoSomething() from within your function > WITHOUT >> FIRST HAVING TO write an if() statement that verifies that it is not > null.
> On the other hand in many situations it is useful to be able to pass > an empty value, e.g. setHandler(HandlerClass $a) could be called > with setHandler(null) to remove the handler.
This is simply a design mistake. If you set something to NULL then that is very different from removing or with PHP syntax unsetting an entry. What you need is another method to do that say unsetHandler().
> For string values you can pass an empty string, for numbers 0 or a > negative number and for objects null.
And for all but the objects you can be pass NULL, too. Which then has a complete different effect/sense/result/semantik since: NULL !== 0 NULL !== "" NULL === NULL
> In other languages it is always possible to pass null instead of the > object (e.g. Java), in C/C++, every pointer may be set to null.
We don't have ponters. We pass references with PHP 5. And for references C++ doesn't allow NULL either. It is in some situations accomplishable but then results in SEGVs.

Jason Garber

22 years ago
Hello, I've been following this discussion from the beginning. To be pointed, I think that the whole matter is rather a serious case of "overfunctionality". Consider allowing a type hint such as function foo(MyClass $bar) The only way I see that as being useful is to be able to assume that you can safely say $bar->DoSomething() from within your function WITHOUT FIRST HAVING TO write an if() statement that verifies that it is not null. Even allowing null as a default parameter is somewhat disturbing. The programmer should ditch the typehint if he needs any behavior other than the one described above, and use a simple if() statement to find out if it is the correct class. If it is deemed necessary to allow a NULL default parameter, then let's keep it simple - function foo(MyClass $bar = NULL) IMHO, PHP has always been a language that can be used very simply, but still has the low-level power to accommodate all the other things that one wishes to accomplish. Let's keep it that way. __________________________________________________________ Jason Garber President & Chief Technology Officer IonZoft, Inc. 814.742.8030 :: jason@ionzoft.com :: http://IonZoft.com __________________________________________________________

Marcus Börger

22 years ago
Hello Jason, Monday, May 10, 2004, 5:31:38 PM, you wrote:
> Hello,
> I've been following this discussion from the beginning. To be pointed, I > think that the whole matter is rather a serious case of "overfunctionality".
> Consider allowing a type hint such as > function foo(MyClass $bar)
> The only way I see that as being useful is to be able to assume that you > can safely say $bar->DoSomething() from within your function WITHOUT > FIRST HAVING TO write an if() statement that verifies that it is not null.
> Even allowing null as a default parameter is somewhat disturbing. The > programmer should ditch the typehint if he needs any behavior other than > the one described above, and use a simple if() statement to find out if it > is the correct class.
Until here i very much agree. To clearify: The reason i provided all the patches is that i simply want the descibed behavior as default and if at all a syntax addition to allow NULL explicitly.
> If it is deemed necessary to allow a NULL default parameter, then let's > keep it simple - function foo(MyClass $bar = NULL)
As i pointed out before this solution comes with a slight disadvantage and it also contains some magic. It is simply semantically very different from secifying the allowed types and setting a default value. Combining them is therefore magic that is hard to understand.
> IMHO, PHP has always been a language that can be used very simply, but > still has the low-level power to accommodate all the other things that one > wishes to accomplish. Let's keep it that way.
Yes we have very good solution which one must not use. In C++ or Java you are forced to use all the syntax or you will fail. best regards marcus

Jason Garber

22 years ago
Hi Marcus, You are totally correct. I should have clarified my statement on the default parameter vs allowing nulls as they are very different. To sum it up, as Andi said: "I think the best solution for now is not to allow null in the regular type hint syntax, and have people who want to allow NULL's not use type hints at all..." +1 __________________________________________________________ Jason Garber President & Chief Technology Officer IonZoft, Inc. 814.742.8030 :: jason@ionzoft.com :: http://IonZoft.com __________________________________________________________ At 5/10/2004 06:24 PM +0200, Marcus Boerger wrote:

Andi Gutmans

22 years ago
I think it's hard to put closure on this type hints issue. The main problem as I see it, is that most PHP users, unlike Java users, usually do pass instantiated objects to functions which except objects, and as mentioned here, people would like to do $obj->method() without having to test for NULL. This pretty much means that we need to allow a type hint mechanism to not allow null. As no good syntax has been found for the less common case of allowing NULL's, I think the best solution for now is not to allow null in the regular type hint syntax, and have people who want to allow NULL's not use type hints at all (in any case, they need to manually check their parameter so they'll do one more manual check). We can then wait and see how much feedback we receive on this issue after 5.0 and if necessary, revisit this. In any case, if the default is not to allow null pretty much any solution we will come up with will keep BC. That's my 2c. Andi

Hans Lellelid

22 years ago
Andi Gutmans wrote:
> As no good syntax has been found for the less common case of allowing > NULL's, I think the best solution for now is not to allow null in the > regular type hint syntax, and have people who want to allow NULL's not > use type hints at all (in any case, they need to manually check their > parameter so they'll do one more manual check). > We can then wait and see how much feedback we receive on this issue > after 5.0 and if necessary, revisit this. In any case, if the default is > not to allow null pretty much any solution we will come up with will > keep BC.
Why not allow NULL if null is specified as the default value? i.e. if the parameter is optional? This change sounds like you can no longer use typehints for optional parameters. I have tons of code that looks like this: public function save(Connection $con = null) { if ($con === null) { $con = .....; } ... } I like that typehints will force $con to be of type Connection if not NULL. I like this & feel it would be very unfortunate (and obviously very breaking) for this to go away. Hans

Andi Gutmans

22 years ago
At 02:21 PM 5/10/2004 -0400, Hans Lellelid wrote:
>Andi Gutmans wrote: >>As no good syntax has been found for the less common case of allowing >>NULL's, I think the best solution for now is not to allow null in the >>regular type hint syntax, and have people who want to allow NULL's not >>use type hints at all (in any case, they need to manually check their >>parameter so they'll do one more manual check). >>We can then wait and see how much feedback we receive on this issue after >>5.0 and if necessary, revisit this. In any case, if the default is not to >>allow null pretty much any solution we will come up with will keep BC. > >Why not allow NULL if null is specified as the default value? i.e. if the >parameter is optional? This change sounds like you can no longer use >typehints for optional parameters. I have tons of code that looks like this: > >public function save(Connection $con = null) { > if ($con === null) { $con = .....; } > ... >} > >I like that typehints will force $con to be of type Connection if not >NULL. I like this & feel it would be very unfortunate (and obviously very >breaking) for this to go away.
Moving to the semantics that type hints don't allow NULL is not consistent with allowing NULL default values. In this case, you will have to not use type hints. As I mentioned, it's best to go this way for 5.0 and see responses and see how applications are being written during 5.0 adoption. Andi

Timm Friebe

22 years ago
On Mon, 2004-05-10 at 18:16, Andi Gutmans wrote:
> I think it's hard to put closure on this type hints issue.
[...]
> As no good syntax has been found for the less common case of allowing > NULL's, I think the best solution for now is not to allow null in the > regular type hint syntax, and have people who want to allow NULL's not use > type hints at all (in any case, they need to manually check their parameter > so they'll do one more manual check).
Will this affect optional arguments? I.e., will the following still work? class UserClass { public static function forName($name, ClassLoader $c= NULL) { // ... } } $works= UserClass::forName('MySQLConnection'); (not passing any value for the optional parameter) vs. $fails= UserClass::forName('MySQLConnection', NULL); (passing NULL as "value" for the optional parameter) - Timm

Jevon Wright

22 years ago
If so, maybe allow the type hint to always succeed, if it's got NULL as the default parameter? (that way foo() wouldn't act differently to foo(NULL), even though they both mean the same thing, ignoring the type hint) Jevon ----- Original Message ----- From: "Timm Friebe" <thekid@thekid.de> To: <internals@lists.php.net> Sent: Tuesday, May 11, 2004 9:44 PM Subject: Re: [PHP-DEV] [RFC] Type hints
> On Mon, 2004-05-10 at 18:16, Andi Gutmans wrote: > > I think it's hard to put closure on this type hints issue. > [...] > > As no good syntax has been found for the less common case of allowing > > NULL's, I think the best solution for now is not to allow null in the > > regular type hint syntax, and have people who want to allow NULL's not
use
> > type hints at all (in any case, they need to manually check their
parameter

Andi Gutmans

22 years ago
At 11:44 AM 5/11/2004 +0200, Timm Friebe wrote:
>On Mon, 2004-05-10 at 18:16, Andi Gutmans wrote: > > I think it's hard to put closure on this type hints issue. >[...] > > As no good syntax has been found for the less common case of allowing > > NULL's, I think the best solution for now is not to allow null in the > > regular type hint syntax, and have people who want to allow NULL's not use > > type hints at all (in any case, they need to manually check their > parameter > > so they'll do one more manual check). > >Will this affect optional arguments? I.e., will the following still >work? > > class UserClass { > public static function forName($name, ClassLoader $c= NULL) { > // ... > } > } > > $works= UserClass::forName('MySQLConnection'); > >(not passing any value for the optional parameter) vs. > > $fails= UserClass::forName('MySQLConnection', NULL); > >(passing NULL as "value" for the optional parameter)
Nope, why would it work? If we make the type hint strict (which I think we should) then you can't define it to NULL. Doing so would be kind of inconsistent. Andi

Timm Friebe

22 years ago
On Tue, 2004-05-11 at 14:23, Andi Gutmans wrote:
> At 11:44 AM 5/11/2004 +0200, Timm Friebe wrote:
[...]
> >Will this affect optional arguments? I.e., will the following still > >work?
[...]
> Nope, why would it work? If we make the type hint strict (which I think we > should) then you can't define it to NULL. > Doing so would be kind of inconsistent.
Aren't optional parameters and allowing NULL for typehints two different pairs of shoes? At least passing NO parameters and NULL as parameter is easily distinguishable in userland: $ php -r 'function test() { var_dump(func_num_args()); } test();' int(0) $ php -r 'function test() { var_dump(func_num_args()); } test(NULL);' int(1) - Timm

Sebastian Bergmann

22 years ago
Timm Friebe wrote:
> Aren't optional parameters and allowing NULL for typehints two > different pairs of shoes?
IMHO, they are. And should stay that way. Unfortunately the only way we currently have to denote a class-hinted parameter as optional is Class $object = null :-(
-- Sebastian Bergmann http://sebastian-bergmann.de/ http://phpOpenTracker.de/ Das Buch zu PHP 5: http://professionelle-softwareentwicklung-mit-php5.de/

Jason Garber

22 years ago
Consider this below: At 5/11/2004 03:23 PM +0300, Andi Gutmans wrote:
>At 11:44 AM 5/11/2004 +0200, Timm Friebe wrote: >>On Mon, 2004-05-10 at 18:16, Andi Gutmans wrote: >> > I think it's hard to put closure on this type hints issue. >>[...] >> > As no good syntax has been found for the less common case of allowing >> > NULL's, I think the best solution for now is not to allow null in the >> > regular type hint syntax, and have people who want to allow NULL's not use >> > type hints at all (in any case, they need to manually check their >> parameter >> > so they'll do one more manual check). >> >>Will this affect optional arguments? I.e., will the following still >>work? >> >> class UserClass { >> public static function forName($name, ClassLoader $c= NULL) { >> // ... >> } >> }
class UserClass{ public static function forName($name, $c = NULL) { if(is_null($c)) //... elseif($c instanceof ClassLoader) //... else //Throw an error } } Using this method, you can easily solve the issue pointed out above, while allowing the type hint to be strict. ~Jason

Timm Friebe

22 years ago
On Tue, 2004-05-11 at 14:36, Jason Garber wrote:
> Consider this below:
[...]
> class UserClass{ > public static function forName($name, $c = NULL) { > if(is_null($c)) > //... > elseif($c instanceof ClassLoader) > //... > else > //Throw an error > } > } > > Using this method, you can easily solve the issue pointed out above, while > allowing the type hint to be strict.
Jason, I know how to build a workaround; but this is just kludgy. Marcus complained in his original mail that he was "annoyed" by the fact of having to check on a type-hinted parameter being NULL. How about I suggest I'm annoyed about having to check non-type-hinted parameters in the way you suggested above? - Timm

Hans Lellelid

22 years ago
Hi, Timm Friebe wrote:
> Jason, I know how to build a workaround; but this is just kludgy. > > Marcus complained in his original mail that he was "annoyed" by the fact > of having to check on a type-hinted parameter being NULL. How about I > suggest I'm annoyed about having to check non-type-hinted parameters in > the way you suggested above?
+++1! Probably 50% of the classhints I use are for optional parameters. To lose this will mean losing 50% of my typehints. I don't think it's a pain to check non-null for optional params. For non-optional params I probably wouldn't check for non-NULL in most cases, anyway. If a value expects an object and is passed NULL then I'm fine with it breaking in an ugly E_FATAL way. I would add what I feel is an important point: PHP5's use of interfaces and abstract classes has brought an increased strictness to PHP OO. I think everyone is happy with these language features, but I think it's fair to say that these features are going to result in a much greater use of optional params -- in order to satisfy interface requirements but allow classes to have more flexible signatures. Thus, removing the ability to use class typehints on optional parameters will only become a larger problem than it is now. (and I think it's already a pretty big problem) Hans

Christian Schneider

22 years ago
Jason Garber wrote:
> public static function forName($name, $c = NULL) { > if(is_null($c)) > //... > elseif($c instanceof ClassLoader) > //... > else > //Throw an error
Error handling can be boring/tricky/cluttering and that's why most people will simply omit it or die() here. It's basically dead code which is A Bad Thing IMHO. I think function forName($name, ClassLoader $classloader = NULL) { if (!$classloader) $classloader = new ClassLoader; ... } would be much nicer, doesn't have error handling bloat and is as safe. All we'd need is to ignore the type hint for the default value. Simple, easy to understand and also safe as the two are close to each other (the same line) so no danger of discrepancy here. IMHO :-) But I got to the conclusion that as long as we don't introduce a new keyword/syntax for allowing/disallowing null I'm happy :-) Over and out, - Chris

Magnus Maatta

22 years ago
On Sunday 09 May 2004 19.24, Derick Rethans wrote:
> On Sun, 9 May 2004, Andi Gutmans wrote: > > >null or MyClass $a = 5 ? > > > > I don't like this. I think it's too long and ugly. > > > > >I've no idea what nullable is supposed to mean... (well, I do :) > > I thought about this a bit more, but couldn't actually see why something > like "nullable" is needed at all. Simple solution: If you expect an > object of a specific class; if it also might be NULL, don't use a class > hint at all. So *why* do we even need "bloat" like "nullable" or > something similar.
I agree. I can't see any use for this. /Magnus
-- Where's the man could ease a heart like a satin gown? -- Dorothy Parker, "The Satin Dress"

Hans Lellelid

22 years ago
Derick Rethans wrote:
> I thought about this a bit more, but couldn't actually see why something > like "nullable" is needed at all. Simple solution: If you expect an > object of a specific class; if it also might be NULL, don't use a class > hint at all. So *why* do we even need "bloat" like "nullable" or > something similar.
As someone who has invested many, many thousands of lines of code in PHP5, it is in my interest to have things work they way they currently work. Requiring a new keyword is a pretty big BC break to existing PHP5 releases, and while I understand that PHP5 is not stable & hence I shouldn't be complaining if you all do decide to break things (still dealing with aftermath of __toString() change) I also don't think the current implementation is all that bad. Allowing NULL even if there is a typehint doesn't bother me personally at all :) Perhaps if it must be changed, then NULL could be allowed only for parameters that had a default type of NULL? That would be equally acceptible, and simpler than having new PHP keyword. My $0.02, Hans

Marcus Börger

22 years ago
Hello Andi, Sunday, May 9, 2004, 12:39:15 PM, you wrote:
> The following (Zeev's idea) is much simpler and nicer, but I'm not 100% > sure if this is the perfect solution: > nullable MyClass $a = 5
> Ideas/comments?
I think this is probably the best idea so far. BUT it is very hard to implement :-( A working patch can be found here: http://somabo.de/php/ext/ze2/ze2-type-hints-20040509.diff.txt (Patch also contains two new tests) Look at it in deatil, you'll dislike it! But i tried several other ways and couldn't get anything else to work. I trued to do it with two subrules one for nullable and one for the typehint and it didn't work because somehow the parser gets confused on that (to me this looks like a bison error). And even a full blowup of the parameter parsing rule didn't work. I tried valgrind on it and it seemed to be happy. But i am nearly sure there is a memory leak somewhere. If not then there should be an error in the way it was implemented before. If you are interested in this patch i'll have a deeper look. But i'd prefer if someone could find a better way to do it. best regards marcus

Justin Hannus

22 years ago
IMHO if php is going to have the option to use type hinted parameters (which I really like) then it should have the option to use type hinted variables as well. Half stepping with the type hints are just going to complicate things. Afterall, NULL is a value and not a type. And if you use a type hinted parameter in your function - the argument passed to it, when declared, should be type hinted as well or throw an E_STRICT. Like many things this is probably easier said than done but..... <?php class UserClass { public static function forName($name, ClassLoader $c) { // ... } } ClassLoader $cl = NULL; UserClass::forName("somename", $cl); // passes the type hint $cl2 = NULL; UserClass::forName("somename", $cl); // throws an E_STRICT ?> No funny synatx no magic just clean code.

Timm Friebe

22 years ago
On Sat, 2004-05-01 at 22:09, Marcus Boerger wrote:
> Hello internals, > > while working with php 5 the last days i find it more and more > annoying that we allow NULL with type hints. > From my perspective allowing NULL with typehints would happen > only very rare.
I don't think this is true. I think there are a number of cases where passing NULL is used to "unset" or "delete" something. For example, say a class supports debugging using a listener model: class Foo { function setEventListener(Listener $l) { ... } } $foo= new Foo(); $foo->setEventListener(new ConsoleListener()); // ... $foo->setEventListener(NULL); This makes perfect sense to me and also gets rid of the constraint of having to define an "unsetEventListener" method. To wrap it up: Would you agree that being able to pass NULL to any pointer argument in C is annoying? [...]
> 2) (Andi) introduce 'not null' after php 5.0. This won't introduce > a BC break. But it would require two new keywords 'NOT' and 'NULL'. > The latter is not a problem because it is a define at the moment > and the patch (a) shows that it easy to change it into a keyword. > The problem is the new keyword 'not' which would introduce a BC > break for everyone using the word 'not' already.
I like this idea best: No magic such as "only when it is the first default argument" (the question "why" will inevitably come up sooner or later); plus no BC break. Concerning the new keyword argument, how about using the exclamation mark (already meaning "not"), as in: * function foo(Classname !NULL $val) { } The same as Andi's suggestion, but using ! instead of "not" * function foo(Classname $val !NULL) { } Ditto, but using postfix notation. Comes close to default value syntax which people are already used to. * function foo(Classname $val != NULL) { } This would be even more similar to the default value syntax. - Timm

Andi Gutmans

22 years ago
At 06:39 PM 5/2/2004 +0200, Timm Friebe wrote:
>On Sat, 2004-05-01 at 22:09, Marcus Boerger wrote: > > Hello internals, > > > > while working with php 5 the last days i find it more and more > > annoying that we allow NULL with type hints. > > From my perspective allowing NULL with typehints would happen > > only very rare. > >I don't think this is true. I think there are a number of cases where >passing NULL is used to "unset" or "delete" something. For example, say >a class supports debugging using a listener model: > > class Foo { > function setEventListener(Listener $l) { ... } > } > > $foo= new Foo(); > $foo->setEventListener(new ConsoleListener()); > // ... > $foo->setEventListener(NULL); > >This makes perfect sense to me and also gets rid of the constraint of >having to define an "unsetEventListener" method. > >To wrap it up: Would you agree that being able to pass NULL to any >pointer argument in C is annoying?
Personally, I would leave things the way they are today. But both Zeev and Marcus feel this is the wrong way to go and I understand their point.
>[...] > > 2) (Andi) introduce 'not null' after php 5.0. This won't introduce > > a BC break. But it would require two new keywords 'NOT' and 'NULL'. > > The latter is not a problem because it is a define at the moment > > and the patch (a) shows that it easy to change it into a keyword. > > The problem is the new keyword 'not' which would introduce a BC > > break for everyone using the word 'not' already. > >I like this idea best: No magic such as "only when it is the first >default argument" (the question "why" will inevitably come up sooner or >later); plus no BC break. > >Concerning the new keyword argument, how about using the exclamation >mark (already meaning "not"), as in: > >* function foo(Classname !NULL $val) { } > The same as Andi's suggestion, but using ! instead of "not" > >* function foo(Classname $val !NULL) { } > Ditto, but using postfix notation. Comes close to default value > syntax which people are already used to. > >* function foo(Classname $val != NULL) { } > This would be even more similar to the default value syntax.
I prefer "not null" :) Andi

Timm Friebe

22 years ago
On Sat, 2004-05-01 at 22:09, Marcus Boerger wrote:
> Hello internals,
[...] While thinking about this for a while and playing around with different notations, I stumbled across the following: function foo(Foo $f = 1) { } This will actually "compile" (but never work). It doesn't make any sense anyway. In my opinion, this should give an E_COMPILE_ERROR. - Timm