Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Le 21/01/2013 10:10, Nikita Popov a écrit : On Mon, Jan 21, 2013 at 9:17 AM, SPONEM, Benoît b.spo...@baclesse.fr mailto:b.spo...@baclesse.fr wrote: Hi This typehinting will support the basic types (int, string) ? Benoit It will support them only when scalar typehints are added for methods ;) Nikita Thank for your reponse ! There are any plans for this? Benoit
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Thu, Jan 10, 2013 at 11:11 PM, Stas Malyshev smalys...@sugarcrm.comwrote: Hi! The proposal is pretty clear, but could you explain this part: The current accessors proposal will need special handling of the typehint in any case (it can't be handled as a normal method typehint). What special handling is required? I now added a patch for this proposal: https://gist.github.com/4579298 (For more detailed individual commits see here: https://github.com/nikic/php-src/commits/alternativeSyntax) If there are no more issues I'll start the vote on this. Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On 1/20/2013 9:26 AM, Nikita Popov wrote: I now added a patch for this proposal: https://gist.github.com/4579298 (For more detailed individual commits see here: https://github.com/nikic/php-src/commits/alternativeSyntax) One thing I hadn't noticed is that the proposal was to move the typehint, what happens in this case then: public DateTime $date { get; set(stdClass $value); } Would the above produce a compilation error on the stdClass part? -- -Clint -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sun, Jan 20, 2013 at 4:47 PM, Clint Priest cpri...@zerocue.com wrote: On 1/20/2013 9:26 AM, Nikita Popov wrote: I now added a patch for this proposal: https://gist.github.com/**4579298https://gist.github.com/4579298(For more detailed individual commits see here: https://github.com/nikic/php-**src/commits/alternativeSyntaxhttps://github.com/nikic/php-src/commits/alternativeSyntax ) One thing I hadn't noticed is that the proposal was to move the typehint, what happens in this case then: public DateTime $date { get; set(stdClass $value); } Would the above produce a compilation error on the stdClass part? Yes, that's an error. And I'm not sure what that is supposed to mean in the first place (it has two different typehints at two different places...) This proposal will allow a typehint before the property name and only there. Allowing one in both places doesn't make much sense to me. Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Tue, Jan 8, 2013 at 7:03 PM, Steve Clay st...@mrclay.org wrote: On 1/8/13 2:56 AM, Christian Stoller wrote: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' Much agreed. After instantiation, these shouldn't behave differently: public $foo = null; public Foo $foo = null; Sure, method signatures have special behavior based on a default value, but IMO: 1. those semantics aren't entirely intuitive to begin with 2. property initializers aren't method sigs 3. the semantics would apply only to some properties public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. I like that it's an established practice of doing exactly what we're trying to do. Could we not just make it obvious?: public Foo|null $foo; I updated the RFC to include the current state regarding default value and nullability: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax One question that still needs to be discussed is what syntax regarding parentheses we want to use if this makes it. Currently both set { } and set($foo) { } style accessors are supported. Do we want to keep those two with the new syntax? Nikita PS: I hope I'm not interrupting all those heated annotations discussion too much ^^
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! The proposal is pretty clear, but could you explain this part: The current accessors proposal will need special handling of the typehint in any case (it can't be handled as a normal method typehint). What special handling is required? One question that still needs to be discussed is what syntax regarding parentheses we want to use if this makes it. Currently both set { } and set($foo) { } style accessors are supported. Do we want to keep those two with the new syntax? Within this context, I'd prefer getting rid of set {} and only have set($param) {}. You don't save that much typing and you do it at the cost of additional obscurity and complexity - now every developer and every tool that deals with it needs to remember there's hidden $value parameter. IMHO not worth it. I can see what get; gives you - you can say just do the natural thing. But if you start writing code anyway - i.e. if you do {} - then I think it should look like a real function. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Thu, Jan 10, 2013 at 11:11 PM, Stas Malyshev smalys...@sugarcrm.comwrote: Hi! The proposal is pretty clear, but could you explain this part: The current accessors proposal will need special handling of the typehint in any case (it can't be handled as a normal method typehint). What special handling is required? I have written that in anticipation of a rewrite of the current automatic accessor implementation. Currently it creates a string of PHP code and compiles it as the method body. We were planning to replace this with handling directly in the object handlers (because automatic accessors just need to use the normal property code rather than the accessor one). In this case we'd have to handle the typehint explicitly. But I'm not sure whether we will still do this, so I'm not sure whether that statement in the RFC is still true. On this subject, are you (personally) okay with the current approach for creating automatic accessors (i.e. create PHP code string and compile)? One question that still needs to be discussed is what syntax regarding parentheses we want to use if this makes it. Currently both set { } and set($foo) { } style accessors are supported. Do we want to keep those two with the new syntax? Within this context, I'd prefer getting rid of set {} and only have set($param) {}. You don't save that much typing and you do it at the cost of additional obscurity and complexity - now every developer and every tool that deals with it needs to remember there's hidden $value parameter. IMHO not worth it. I can see what get; gives you - you can say just do the natural thing. But if you start writing code anyway - i.e. if you do {} - then I think it should look like a real function. Just to make sure I got it all right, you are suggesting: * Parentheses must be used on all accessors, so it's set($value) {} and get() {} and isset() {} and unset() {} and something like get {} is not possible? * Automatic accessors don't have parentheses so they are just set; get; isset; unset; Is that right? If so, then I think it's a reasonable approach. Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! that statement in the RFC is still true. On this subject, are you (personally) okay with the current approach for creating automatic accessors (i.e. create PHP code string and compile)? It might be more efficient to generate the opcodes directly, since they are always the same and you'd really need to only plug the string into one place (or in case of typehints, two places), but I don't have preference one way or another, depending on which is easier. If we won't have reentrancy, line numbers, etc. issues then generating a string may be easier and also more robust if opcodes ever change. Just to make sure I got it all right, you are suggesting: * Parentheses must be used on all accessors, so it's set($value) {} and get() {} and isset() {} and unset() {} and something like get {} is not possible? * Automatic accessors don't have parentheses so they are just set; get; isset; unset; Is that right? If so, then I think it's a reasonable approach. Yes, I think this makes it look consistent - albeit at the price of some added verbosity. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Nikita, 2013/1/10 Nikita Popov nikita@gmail.com On Tue, Jan 8, 2013 at 7:03 PM, Steve Clay st...@mrclay.org wrote: On 1/8/13 2:56 AM, Christian Stoller wrote: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' Much agreed. After instantiation, these shouldn't behave differently: public $foo = null; public Foo $foo = null; Sure, method signatures have special behavior based on a default value, but IMO: 1. those semantics aren't entirely intuitive to begin with 2. property initializers aren't method sigs 3. the semantics would apply only to some properties public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. I like that it's an established practice of doing exactly what we're trying to do. Could we not just make it obvious?: public Foo|null $foo; I updated the RFC to include the current state regarding default value and nullability: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax One question that still needs to be discussed is what syntax regarding parentheses we want to use if this makes it. Currently both set { } and set($foo) { } style accessors are supported. Do we want to keep those two with the new syntax? Nikita PS: I hope I'm not interrupting all those heated annotations discussion too much ^^ In the RFC, one thing is not clear: How to provide typehints for nullable properties that actually have accessors. Will it be like this? public DateTime $date = null { get { ... } set { ... } } Lazare INEPOLOGLOU Ingénieur Logiciel
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
We all agree that nullable properties need to be addressed. Now why just don't discuss a possible syntax and move on? Initializers, parenthesis around unsetters, etc can all be detailed and discussed later. Here are the proposed syntaxes: public DateTime? $date { get { ... } set { ... } } public DateTime $date = null { get { ... } set { ... } } public DateTime $date { get { ... } set($value = null) { ... } } public $date { get { ... } set(DateTime $value = null) { ... } } Now choose your options from 1-4 and move on... Sometimes you truly love to discuss instead of act. Tsc, tsc, tsc... Cheers, On Thu, Jan 10, 2013 at 7:24 PM, Lazare Inepologlou linep...@gmail.comwrote: Nikita, 2013/1/10 Nikita Popov nikita@gmail.com On Tue, Jan 8, 2013 at 7:03 PM, Steve Clay st...@mrclay.org wrote: On 1/8/13 2:56 AM, Christian Stoller wrote: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' Much agreed. After instantiation, these shouldn't behave differently: public $foo = null; public Foo $foo = null; Sure, method signatures have special behavior based on a default value, but IMO: 1. those semantics aren't entirely intuitive to begin with 2. property initializers aren't method sigs 3. the semantics would apply only to some properties public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. I like that it's an established practice of doing exactly what we're trying to do. Could we not just make it obvious?: public Foo|null $foo; I updated the RFC to include the current state regarding default value and nullability: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax One question that still needs to be discussed is what syntax regarding parentheses we want to use if this makes it. Currently both set { } and set($foo) { } style accessors are supported. Do we want to keep those two with the new syntax? Nikita PS: I hope I'm not interrupting all those heated annotations discussion too much ^^ In the RFC, one thing is not clear: How to provide typehints for nullable properties that actually have accessors. Will it be like this? public DateTime $date = null { get { ... } set { ... } } Lazare INEPOLOGLOU Ingénieur Logiciel -- Guilherme Blanco MSN: guilhermebla...@hotmail.com GTalk: guilhermeblanco Toronto - ON/Canada
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Am 08.01.2013 08:56, schrieb Christian Stoller: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' To me this makes perfect sense. It takes up the syntax php has been using for method-definitions. A syntax we would be using to create a classic setter method if there wasn't a fancy new one. public function setDate(DateTime $date = NULL) { $this-date = $date; } Anything other than this would result in an inconsistency. Having accepted that syntax previously and now introducing yet another one, would be confusing and unnecessary. Although, as Stas has pointed out, *not* allowing NULL for a property will not prevent it from being NULL...depending on wether it has been initalized. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
It takes up the syntax php has been using for method-definitions. The fact is that the existing syntax for nullable type hinting has its own problems. For example, this is not possible: function foo( Bar $bar = null , $mandatory ) { ... } I would love to have the question mark syntax for both properties and argument type hinting. Although, as Stas has pointed out, *not* allowing NULL for a property will not prevent it from being NULL...depending on wether it has been initalized. This does not apply in all cases. Here is an example of a property that is guaranteed not to be null: class Foo { private $_date; public DateTime $date { get { return is_null($date) ? new DateTime() : $this-date; } set { $this-date = $value; } } } Lazare INEPOLOGLOU Ingénieur Logiciel 2013/1/8 Lars Schultz lars.schu...@toolpark.com Am 08.01.2013 08:56, schrieb Christian Stoller: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' To me this makes perfect sense. It takes up the syntax php has been using for method-definitions. A syntax we would be using to create a classic setter method if there wasn't a fancy new one. public function setDate(DateTime $date = NULL) { $this-date = $date; } Anything other than this would result in an inconsistency. Having accepted that syntax previously and now introducing yet another one, would be confusing and unnecessary. Although, as Stas has pointed out, *not* allowing NULL for a property will not prevent it from being NULL...depending on wether it has been initalized. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Am 08.01.2013 10:03, schrieb Lazare Inepologlou: The fact is that the existing syntax for nullable type hinting has its own problems. For example, this is not possible: function foo( Bar $bar = null , $mandatory ) { ... } Sure it's possible;) I did not get a syntax error for that...I even use that case many times in my code exactly for that purpose, to allow $bar to be null but require $mandatory to be defined explicitly. I would love to have the question mark syntax for both properties and argument type hinting. Introducing a BC-Break and/or yet another syntax? Is that worth it? This does not apply in all cases. Here is an example of a property that is guaranteed not to be null: class Foo { private $_date; public DateTime $date { get { return is_null($date) ? new DateTime() : $this-date; } set { $this-date = $value; } } } The property is still null;) Only the return value of the getter will not be null. But that's not the issue, is it? I am not arguing the case of NOT allowing null, Stas wanted to always allow null because of this reason and not have a special syntax to declare this. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
2013/1/8 Lars Schultz lars.schu...@toolpark.com Am 08.01.2013 10:03, schrieb Lazare Inepologlou: The fact is that the existing syntax for nullable type hinting has its own problems. For example, this is not possible: function foo( Bar $bar = null , $mandatory ) { ... } Sure it's possible;) I did not get a syntax error for that...I even use that case many times in my code exactly for that purpose, to allow $bar to be null but require $mandatory to be defined explicitly. Seems you are right. Sorry. I would love to have the question mark syntax for both properties and argument type hinting. Introducing a BC-Break and/or yet another syntax? Is that worth it? This does not apply in all cases. Here is an example of a property that is guaranteed not to be null: class Foo { private $_date; public DateTime $date { get { return is_null($date) ? new DateTime() : $this-date; } set { $this-date = $value; } } } The property is still null;) Only the return value of the getter will not be null. But that's not the issue, is it? I am not arguing the case of NOT allowing null, Stas wanted to always allow null because of this reason and not have a special syntax to declare this. No, the field $_date can be null. The property $date is not null, cannot be set to null and cannot return null. Furthermore, it cannot be unset (should fail with an error) and isset always returns true. Lazare INEPOLOGLOU Ingénieur Logiciel
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On 1/8/13 2:56 AM, Christian Stoller wrote: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' Much agreed. After instantiation, these shouldn't behave differently: public $foo = null; public Foo $foo = null; Sure, method signatures have special behavior based on a default value, but IMO: 1. those semantics aren't entirely intuitive to begin with 2. property initializers aren't method sigs 3. the semantics would apply only to some properties public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. I like that it's an established practice of doing exactly what we're trying to do. Could we not just make it obvious?: public Foo|null $foo; Steve Clay -- http://www.mrclay.org/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Tue, Jan 8, 2013 at 7:03 PM, Steve Clay st...@mrclay.org wrote: On 1/8/13 2:56 AM, Christian Stoller wrote: But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' Much agreed. After instantiation, these shouldn't behave differently: public $foo = null; public Foo $foo = null; Sure, method signatures have special behavior based on a default value, but IMO: 1. those semantics aren't entirely intuitive to begin with 2. property initializers aren't method sigs 3. the semantics would apply only to some properties public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. I like that it's an established practice of doing exactly what we're trying to do. Could we not just make it obvious?: public Foo|null $foo; I'm not going to argue whether or not determining nullability via = null is a good or bad idea, but it's the way things currently work in PHP. Adding other mechanisms for nullability (or multiple typehints, like it is your suggestion) is something that may be considered, but it is outside the scope of this RFC. Those things apply to typehints in general, not just to property typehints. If you want pursue this further, then I would ask you to create a separate RFC (or just a separate internals discussion maybe). Thanks, Nikita
RE: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi. I like the proposal of this RFC very much ;-) But the way 'nullable' properties are defined is not very intuitive and unclean, in my opinion. Stas has already mentioned that. `public DateTime $date = NULL;` // this looks like the property is initialized with null, but it does not show that the property is 'nullable' If type hinted properties are not allowed to be set to null, I would propose this way to make a property nullable: public DateTime? $date; In C# the question mark after a type is a short hand for a generic Nullable type. -Original Message- From: Nikita Popov [mailto:nikita@gmail.com] Sent: Saturday, January 05, 2013 1:48 AM To: Steve Clay Cc: PHP internals Subject: Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors On Sat, Jan 5, 2013 at 12:31 AM, Steve Clay st...@mrclay.org wrote: Would the following two be exactly functionally equivalent? public Foo $foo; public $foo { get; set(Foo $value) { $this-foo = $value; } } We should also consider how an author would allow type-hinted properties to accept NULL as a new value, in both proposals. I think that's a very interesting question, thanks for bringing it up. I think a good approach here would be the same one used for function argument typehints, i.e. allow NULL when NULL is specified as the default value. So `public DateTime $date;` would not allow an explicit NULL assignment, whereas `public DateTime $date = NULL;` would. Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Was it considered to augment type hinting syntax - both in parameter lists and for the hinted property RFC - to permit giving multiple types at once? public DateTime|DateTimeImmutable $refdate; public Foo|NULL $object; // the issue discussed in the previous msgs function bar(array|string $arg) ... best regards Patrick
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sun, Jan 6, 2013 at 10:05 AM, Patrick Schaaf p...@bof.de wrote: Was it considered to augment type hinting syntax - both in parameter lists and for the hinted property RFC - to permit giving multiple types at once? public DateTime|DateTimeImmutable $refdate; public Foo|NULL $object; // the issue discussed in the previous msgs function bar(array|string $arg) ... best regards Patrick That's an interesting idea (at least something worth discussion), but please in a different thread. Same goes to the initializers that were mentioned previously in this thread. Both things are related to this proposal, but only slightly, and should be discussed separately to keep things clean. Thanks :) Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sun, Jan 6, 2013 at 2:59 AM, Stas Malyshev smalys...@sugarcrm.comwrote: This is pretty bad by itself. But the fact that everybody would be using this feature in this way - since they would think I don't need null default, null is always the default and I'd initialize it in the ctor anyway, not realizing that declaring public DateTime $foo blocks unset - is even worse. At least with setter you need to explicitly define typehinted setter - and there you have a place to think about it. With public DateTime $foo 99% of people would never even remember to think about it - until they'd start getting mysterious fatal errors on unsets. That's why I think it makes it worse. In this mail I'm only going to address the unset() concern. First of all it should be made clear that contrary to the impression that you conveyed unset() is a fallible operation. It absolutely is fallible, even when overloaded properties and offset (__unset/offsetUnset) are not involved. If I write `unset($foo[0])` then this is an operation that can throw a fatal error, for example when $foo is a string. Why does this throw a fatal error? Because a string offset can not be unset. It's an operation that does not make sense and so PHP throws an error. PHP could also just do nothing, leave the string intact and pretend the unset() was successful. But it doesn't do so and it's good that it doesn't do so. What we are talking about here is a similar situation. We are talking about a property where it does not make sense to unset it. The unset operation is not meaningful and as such shouldn't be allowed. It's as easy as that. That's the first point. The second point is that even *if* an issue existed here (which it does not) then you are presenting it in a *totally* disproportional matter. You make it seem like unset()ing properties is this super important operation that we do all the time and the world would collapse if it failed. That's not true. Unset() on object properties is only used *very* rarely. Symfony Standard (including Symfony, Doctrine, Twig, ...) has a total of !! 4 !! property unsets (compare this to their ~3800 accessor methods). The ZF2 has 8 property unsets of which only !! 3 !! are targeted at specific properties (the remaining 5 are on stdClass-like objects). Again, compare this to their ~4k accessor methods. In summary: a) Unset() is a fallible operation, it's okay if it throws an error if the unset is not reasonably possible. b) Even if you *don't* agree with this assessment it's quasi a non-issue as property unsets are incredibly rare. Dismissing a feature based on something like this is absolutely implausible. c) You can always allow unset() and NULL assignment by specifying it as the default value. Not hard to do *should* you once run into issues of this kind. Thanks, Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
2013/1/5 Nikita Popov nikita@gmail.com I think that's a very interesting question, thanks for bringing it up. I think a good approach here would be the same one used for function argument typehints, i.e. allow NULL when NULL is specified as the default value. So `public DateTime $date;` would not allow an explicit NULL assignment, whereas `public DateTime $date = NULL;` would. I was wondering about this question too. I really like that solution. Bernhard
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
This looks really nice. I would love to see this in PHP +1 - Jon On Fri, Jan 4, 2013 at 8:41 AM, Nikita Popov nikita@gmail.com wrote: Hi internals! I already brought this up before, but I think the discussion at that time was not very constructive and largely off-topic, so I'm bringing it up again. To make sure everything is clear I wrote an RFC document: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax This RFC proposes an alternative syntax for typehinting accessors, which will in particular also allow to typehint properties directly, even if no accessors are used (public DateTime $date). What are your opinions on this? Thanks, Nikita -- Connect with me on *http://twitter.com/jwage* http://twitter.com/jwage and http://about.me/jwage to keep in touch. Join OpenSky today: http://osky.co/l6a75g
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
+1 from me as well. On 1/4/2013 8:41 AM, Nikita Popov wrote: Hi internals! I already brought this up before, but I think the discussion at that time was not very constructive and largely off-topic, so I'm bringing it up again. To make sure everything is clear I wrote an RFC document: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax This RFC proposes an alternative syntax for typehinting accessors, which will in particular also allow to typehint properties directly, even if no accessors are used (public DateTime $date). What are your opinions on this? Thanks, Nikita -- -Clint
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On 1/4/13 9:41 AM, Nikita Popov wrote: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax I like the proposal so far. I'm still a little hesitant about syntax for allowing the setting of NULL values. Since properties are NULL by default (I wish this were explicit in the docs), these are _completely equivalent_: public $f; public $f = null; So it bothers me that these would result in different behavior: public Foo $f; public Foo $f = null; Now, all properties with an object type must be NULL initially, so really we're deciding whether a property can be set *back* to NULL (outside the setter). We could just make the most common case the default behavior. Otherwise the author must provide the signature of the setter with/without = null. Steve Clay -- http://www.mrclay.org/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! typehints, i.e. allow NULL when NULL is specified as the default value. So `public DateTime $date;` would not allow an explicit NULL assignment, whereas `public DateTime $date = NULL;` would. I think this is way too much magic. This means default is no longer a default, but instead some obscure flag that somehow is carried over to the setter. I do not think redefining initialization as permitting nulls is a good idea, initialization and value set are two different things. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Stas, I think this is way too much magic. This means default is no longer a default, but instead some obscure flag that somehow is carried over to the setter. I do not think redefining initialization as permitting nulls is a good idea, initialization and value set are two different things. Too much magic? It's completely consistent with how method parameters work now. In fact, I'd argue that introducing a new syntax for this would be inconsistent with the current paradigm. This becomes especially true if initializers are added, where the property would be initialized to a non-null value. Hence adding the ability for it to *never* actually *be* null in the first place... Anthony
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! Too much magic? It's completely consistent with how method parameters work now. In fact, I'd argue that introducing a new syntax for this would be inconsistent with the current paradigm. But this in for methods, and you are putting it into entirely different place - property initializer. That's what I call magic - somehow property initializer magically becomes method parameter's default value. This becomes especially true if initializers are added, where the property would be initialized to a non-null value. Hence adding the ability for it to *never* actually *be* null in the first place... I think property initializers won't work well, especially combined with this syntax. What should public DateTime $foo = 42; produce? Essentially it looks like the only initializer useful here would be NULL. In this case, why not just make it simple and always allow NULL there and get rid of the confusing syntax? You'd have to allow NULL anyway since otherwise you'd be unable to implement unset() and won't have any useful isset(). In fact, initial value of any object property will always be NULL, so not allowing NULL is pointless as there's always NULL there when you start. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Stas, But this in for methods, and you are putting it into entirely different place - property initializer. That's what I call magic - somehow property initializer magically becomes method parameter's default value. The same could be used to justify the param order difference between strings and arrays But these are arrays, they are entirely different... This becomes especially true if initializers are added, where the property would be initialized to a non-null value. Hence adding the ability for it to *never* actually *be* null in the first place... I think property initializers won't work well, especially combined with this syntax. What should public DateTime $foo = 42; produce? A compile time fatal error. If it's typed, the only values allowed are the type and null (in the initializer) Essentially it looks like the only initializer useful here would be NULL. In this case, why not just make it simple and always allow NULL there and get rid of the confusing syntax? You'd have to allow NULL anyway since otherwise you'd be unable to implement unset() and won't have any useful isset(). In fact, initial value of any object property will always be NULL, so not allowing NULL is pointless as there's always NULL there when you start. No, the other initializer that would be useful is `new Foo`. Assigning a default value is not an initializer. An initializer is something that's run on object construction (and has been discussed in other threads): class Foo { public DateTime $bar { init: { $bar = new DateTime(); } } } As far as why not just make it always allow null is that it half defeats the point of typed accessors in the first place. Java has huge issues with null pointers. And if you set the property in the constructor (and it's typed), you should never have the chance for it to be non-null, unless you explicitly define it that way. Otherwise, you'd have to litter your code with is_null checks... Which defeats the point of the syntax in the first place. Sure, there are going to be use-cases for supporting null. But there are also plenty of use-cases for explicitly Not allowing null. In fact, I'd argue that the not allow null use-cases are the most frequent and most critical ones... Anthony
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sun, Jan 6, 2013 at 1:18 AM, Stas Malyshev smalys...@sugarcrm.comwrote: Hi! Too much magic? It's completely consistent with how method parameters work now. In fact, I'd argue that introducing a new syntax for this would be inconsistent with the current paradigm. But this in for methods, and you are putting it into entirely different place - property initializer. That's what I call magic - somehow property initializer magically becomes method parameter's default value. This becomes especially true if initializers are added, where the property would be initialized to a non-null value. Hence adding the ability for it to *never* actually *be* null in the first place... I think property initializers won't work well, especially combined with this syntax. What should public DateTime $foo = 42; produce? Consider the normal function typehints: `function foo(DateTime $foo = 42)`. Same problem, same solution. You can only assign compatible types. For object typehints NULL is the only compatible compile-time value. For array typehints arrays can be used as initializers. Essentially it looks like the only initializer useful here would be NULL. In this case, why not just make it simple and always allow NULL there and get rid of the confusing syntax? Again, same for function typehints. NULL is the only possible initializer there, too. But still we don't take that as a reason to always allow NULL for them. You'd have to allow NULL anyway since otherwise you'd be unable to implement unset() and won't have any useful isset(). Not every property needs the ability to be unset(). Not being able to unset it is a feature actually. It guarantees that it will always be available (after the initial set) and does not have to be checked. In fact, initial value of any object property will always be NULL, so not allowing NULL is pointless as there's always NULL there when you start. The timeframe in which it is NULL is usually contained to the constructor.
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! No, the other initializer that would be useful is `new Foo`. Assigning a You really put it in the same answer as telling me it's the same as parameter defaults? Here you introduce completely new concept, not existing in PHP at all - non-constant initializers. And this is a whole new can of worms - when it should be run, what should happen when it's run, what is the order, etc. And we already have a perfectly good place to do this - constructors. We don't really need this whole new level of complications with dynamic initializers, just do it in the constructor. As far as why not just make it always allow null is that it half defeats the point of typed accessors in the first place. Java has huge Of course it does not. It would be really useless addition if the whole point of it was not allowing nulls in variables, and pointless too, since there's no way do to it. Even with initializers, how you guarantee that no code is run before your initializer? Like another initializer? You can not. So you always have a possibility of having null. It is true in any language, not just Java - pretty much any language that has object types also has empty value. issues with null pointers. And if you set the property in the constructor (and it's typed), you should never have the chance for it to be non-null, unless you explicitly define it that way. Otherwise, you'd And you will have to ensure constructor never accesses this property, constructor can never be extended with a code that uses this property, constructor never calls any outside method that may use this property, etc., etc. The complexity of this solution quickly gets out of hand and does not guarantee anything in fact. And now you also have to deal with unset() failing with a fatal error, too. explicitly Not allowing null. In fact, I'd argue that the not allow null use-cases are the most frequent and most critical ones... If the whole point of this feature is to save is_null check, I do not think we need it in PHP, since it can not guarantee it, and it does much more and changes much more in the language than simple is_null check. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! Again, same for function typehints. NULL is the only possible initializer there, too. But still we don't take that as a reason to always allow NULL for them. For function, non-optional parameters are always mandatory provided. For properties, it is not true - there are no mandatory properties. I'm surprised how you do not see the different between function parameters explicitly provided and object properties which are never provided when object is constructed and always have to be set manually or use default. They work pretty much in opposite ways here - you can not call function without parameters, and you can not directly assign parameters when creating an object. Not every property needs the ability to be unset(). Not being able to unset it is a feature actually. It guarantees that it will always be available (after the initial set) and does not have to be checked. 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. 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. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sun, Jan 6, 2013 at 2:05 AM, Stas Malyshev smalys...@sugarcrm.comwrote: 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
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On 1/5/13 7:25 PM, Anthony Ferrara wrote: No, the other initializer that would be useful is `new Foo`. Assigning a default value is not an initializer. An initializer is something that's run on object construction (and has been discussed in other threads): class Foo { public DateTime $bar { init: { $bar = new DateTime(); } } } I think property init() would enable two bad practices: 1. putting too much logic in a property (SRP) 2. building dependencies within the object instead of injecting them (the better way is what we already do: receive dependencies in the constructor and assign them to the properties) null pointers. And if you set the property in the constructor (and it's typed), you should never have the chance for it to be non-null, unless you explicitly define it that way. Otherwise, you'd have to litter your code with is_null checks... Which defeats the point of the syntax in the first Which is why I think the default setting signature should not have = null. If someone wants to allow setting the property *back* to null, they could easily: public Foo $foo { get; set($value = null); } I agree with you that, in an ideal world, a property with a declared type would *never not have* that type, but I think a property init() would be a bad tradeoff to make that a reality. The class constructor is the best place to do this, and maybe this is why C# forces property storage to be in fields; you can set fields directly from the constructor without going through property setters. Steve Clay -- http://www.mrclay.org/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! 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. This is pretty bad by itself. But the fact that everybody would be using this feature in this way - since they would think I don't need null default, null is always the default and I'd initialize it in the ctor anyway, not realizing that declaring public DateTime $foo blocks unset - is even worse. At least with setter you need to explicitly define typehinted setter - and there you have a place to think about it. With public DateTime $foo 99% of people would never even remember to think about it - until they'd start getting mysterious fatal errors on unsets. That's why I think it makes it worse. 1. First of all, there never is a guarantee for everything. All kinds of This is a useless platitude. I've outlines specific scenarios where it fails to do what it seemingly promises to do. 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 Allowing NULL is *inevitable*, that's the whole point, since that's what the value is when the object is created, and you can not guarantee this value was initialized. The only thing you can do is to *pretend* it can not be null, even though you know it can be, and ignore the cases where it is null, because you're sure your code is correct. 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 You can easily prevent people from assigning NULL, what you can not do is guarantee the property never returns NULL (at least not with the short syntax, the explicit accessor is a different thing, there you can do it just fine). That's what is wrong with this thing. This shortcut doesn't actually do what people would think it does. It is misleading. 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 Small and work have wildly different definitions. In real life, constructors frequently call out to other methods when initializing. E.g. somehing like: public function __construct() { $this-log = Logger::getInstance(); $this-db = DBFactory::getInstance(); } or something like that, happens all the time. Now imagine Logger somehow tries to use something that uses $this-db and assumes it's not null - since it can never be null, we declared it not null! 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. It's not my argument. My argument is this syntax makes promise of the value never be null and it is specifically proposed with this sole purpose (and argument is unless it is the promise this syntax has no value at all). And it does not do that. In addition, it breaks unset() which would be completely unexpected by 99% of users. I think in this way it will do more harm than good as it would lead people to write code which behaves worse than if this syntax did not exist. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Stas, You really put it in the same answer as telling me it's the same as parameter defaults? Here you introduce completely new concept, not existing in PHP at all - non-constant initializers. And this is a whole new can of worms - when it should be run, what should happen when it's run, what is the order, etc. And we already have a perfectly good place to do this - constructors. We don't really need this whole new level of complications with dynamic initializers, just do it in the constructor. I didn't introduce it. It was introduced in another thread about this very same RFC. As far as introduce completely new concept, not existing in PHP at all, that's the entire purpose of an RFC. That's what we're doing right here. We're talking about introducing new functionality and features that may make people's lives easier. So to discuss the feature, yet limit it to not including new functionality, is rather odd... As far as why not just make it always allow null is that it half defeats the point of typed accessors in the first place. Java has huge Of course it does not. It would be really useless addition if the whole point of it was not allowing nulls in variables, and pointless too, since there's no way do to it. Even with initializers, how you guarantee that no code is run before your initializer? Like another initializer? You can not. So you always have a possibility of having null. It is true in any language, not just Java - pretty much any language that has object types also has empty value. You always have the possibility of having null before the object is constructed. That's given. But after the constructor finishes, you can actually guarantee that the property is never null. For example: class Foo { private $other; final public function __construct() { $this-other = new Other; } } What case, other than reflection abuse, is $this-other *ever* null after construction? The only case is when the class itself sets it to null. Which is quite easy to check for when looking at the class. Having an empty type, and having it be able to be set on anything are two very different concepts. Take for example method type hinting: function foo(Bar $bar) {} In PHP, inside foo(), $bar will *never* be anything except an instance of Bar. It's not possible. Trying to pass Null would generate a catchable fatal: http://codepad.viper-7.com/Le3jC1 This concept is just an exception of that. After construction, if the property is not declared with = NULL, it's never allowed to be set to it. Simple as that. It's the same thing as setting the setter to a function which type hints against Bar $bar instead of Bar $bar = NULL; issues with null pointers. And if you set the property in the constructor (and it's typed), you should never have the chance for it to be non-null, unless you explicitly define it that way. Otherwise, you'd And you will have to ensure constructor never accesses this property, constructor can never be extended with a code that uses this property, constructor never calls any outside method that may use this property, etc., etc. The complexity of this solution quickly gets out of hand and does not guarantee anything in fact. And now you also have to deal with unset() failing with a fatal error, too. No language can protect you from yourself. If you do something inside the class that screws everything up, then you're SOL. That's not what this concept is about. It's about me as the class writer *knowing* that nobody outside my class can screw it up. I know that if I write my code correctly, that nobody can set it to null and screw me up. As far as unset failing, we already have the ability to do that right now with __unset(). All this is doing is applying it to the implicit declaration when providing a type-hinted property variable... explicitly Not allowing null. In fact, I'd argue that the not allow null use-cases are the most frequent and most critical ones... If the whole point of this feature is to save is_null check, I do not think we need it in PHP, since it can not guarantee it, and it does much more and changes much more in the language than simple is_null check. No. The whole point of this is to make defensive coding easier. We can do it today with a combination of __get, __set, __unset. But that's dirty as hell, and leads to LOTS of code doing the same thing over and over again. Instead, we're looking at techniques that make peoples lives easier by reducing the boilerplate that they need to write. Just like the generators RFC... Generators don't provide anything that isn't already possible with iterators. They just make the amount of boilerplate required a LOT lower. And this concept does the same. And that doesn't even make mention of the performance gains by having the getter/setter be written in C instead of PHP... Anthony
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Stas, This is pretty bad by itself. But the fact that everybody would be using this feature in this way - since they would think I don't need null default, null is always the default and I'd initialize it in the ctor anyway, not realizing that declaring public DateTime $foo blocks unset - is even worse. At least with setter you need to explicitly define typehinted setter - and there you have a place to think about it. With public DateTime $foo 99% of people would never even remember to think about it - until they'd start getting mysterious fatal errors on unsets. That's why I think it makes it worse. So your argument is that people who don't take the time to understand how something works will somehow be worse off then they would be today? They can currently write all sorts of bastardized code that raises fatal errors. Should we try to stop them doing that as well? Should we implement BASIC style syntax where each line that generates an error just goes to the next line like nothing even happend (oh, right, we already do that, we should be ashamed of ourselves). Show me a public (real life) code base that calls unset on a parameter that's type hinted by a setter. Where you have either __set or a setBar() setter, and then somewhere else in the class you call unset() on the property. While I do understand that it's a possibility, I can't help but feel that you're completely grasping at straws here... 1. First of all, there never is a guarantee for everything. All kinds of This is a useless platitude. I've outlines specific scenarios where it fails to do what it seemingly promises to do. Yes, and all those scenarios are complete far edge-cases. Not one that I've seen yet is something that I've sen in production code more than once in my career... 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 Allowing NULL is *inevitable*, that's the whole point, since that's what the value is when the object is created, and you can not guarantee this value was initialized. The only thing you can do is to *pretend* it can not be null, even though you know it can be, and ignore the cases where it is null, because you're sure your code is correct. Again, before initialization (__construct is completed) all bets are off. You can screw yourself up as much as you want. But if I provide a final constructor, after initialization, the property should never be null unless I explicitly make it so INSIDE MY CLASS. If you, outside my class, want to screw with that, I want you to get a fatal error. That's the entire point of defensive programming. I can do what I'd like, but I don't want you to screw something up in a way that I don't expect. And that's what this RFC is talking about adding... 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 You can easily prevent people from assigning NULL, what you can not do is guarantee the property never returns NULL (at least not with the short syntax, the explicit accessor is a different thing, there you can do it just fine). That's what is wrong with this thing. This shortcut doesn't actually do what people would think it does. It is misleading. Yet again, post construct, if I can guarantee that nobody outside my class can assign null, I can guarantee that the property will never return null. Simple as that. It reduces the exposure area to the class itself. 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 Small and work have wildly different definitions. In real life, constructors frequently call out to other methods when initializing. E.g. somehing like: public function __construct() { $this-log = Logger::getInstance(); $this-db = DBFactory::getInstance(); } or something like that, happens all the time. Now imagine Logger somehow tries to use something that uses $this-db and assumes it's not null - since it can never be null, we declared it not null! Funny you bring that up. Because it's literally not possible in the code that you wrote to throw the error case you describe. That's because in the constructor there's literally no other reference to the active class other than $this. So the only possible way for that to happen would be to explicitly pass $this to the logger call. Otherwise, as the code you wrote would always, 100% of the time, work... And that's the point here. Not that it's not *possible* to break the system, but that they are such extreme edge-cases that throwing an error isn't a big deal. And they are such extreme edge-cases that
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! As far as introduce completely new concept, not existing in PHP at all, that's the entire purpose of an RFC. That's what we're doing right here. We're talking about introducing new functionality and features that may make people's lives easier. So to discuss the feature, yet limit it to not including new functionality, is rather odd... You can not both say it works just like method parameters and in the same breath say it needs the concept of dynamic initializers which never existed in PHP and which BTW was not introduced in the RFC either (and which won't solve the problem you're trying to solve anyway). You always have the possibility of having null before the object is constructed. That's given. Not before. While initialization is running. Which can be quite a complex process. E.g. look at SoapClient class - it parses whole WSDL in the constructor. Imagine you implemented something like this - there would be a bunch of things happening while object is being constructed. But after the constructor finishes, you can actually guarantee that the property is never null. For example: You can only guarantee it if you know ctor actually assigned the variable, but there's no way to check it in the code. I.e. if you manually reviewed the code, you can know it, but declaration itself in no way guarantees it, even though you were thinking it does. So for it to be actually useful, you need to know that ctor has already finished working and that that ctor actually assigned value to this property. And if you are third-party library using this class as an API, it's not very useful for you unless you code-review all third-party libraries you use. Declaration itself does not guarantee it, even if it looks and is promoted as if it did. In PHP, inside foo(), $bar will *never* be anything except an instance of Bar. It's not possible. Trying to pass Null would generate a catchable fatal: http://codepad.viper-7.com/Le3jC1 Again, for parameters you MUST provide parameter to call a function, otherwise function would not be called. So there's no way the control can enter the function and $bar not be assigned to instance of Bar, whatever the code around it is doing, however crazy it is. On the contrary, it is very easy to find scenario where property is declared as public Bar $bar; and still contains null. Unlike parameters, again, the declaration itself DOES NOT guarantee the property is not null. This concept is just an exception of that. After construction, if the property is not declared with = NULL, it's never allowed to be set to it. Simple as that. It's the same thing as setting the setter to a function which type hints against Bar $bar instead of Bar $bar = NULL; But that's not very useful. Who cares if it can't be set to null if it can still be null? You'll have to check it anyway. Or, even worse, you'll rely on your own insistence that it can not be null and get fatal error in production code. As far as unset failing, we already have the ability to do that right now with __unset(). All this is doing is applying it to the implicit declaration when providing a type-hinted property variable... With __unset, you will have to specifically write code to do that. Here, it is a side effect of a declaration that has nothing to do with unset and it is completely unobvious to 99.999% of the users that this is what will happen. No. The whole point of this is to make defensive coding easier. We can But you don't make it easier if you're making promises you can not keep, such as this value will never be null. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Stas, You can not both say it works just like method parameters and in the same breath say it needs the concept of dynamic initializers which never existed in PHP and which BTW was not introduced in the RFC either (and which won't solve the problem you're trying to solve anyway). I never said it *needed* dynamic initializers. I said it would be cool if it had them, but the concept stands on its own without them. You always have the possibility of having null before the object is constructed. That's given. Not before. While initialization is running. Which can be quite a complex process. E.g. look at SoapClient class - it parses whole WSDL in the constructor. Imagine you implemented something like this - there would be a bunch of things happening while object is being constructed. You miss the key point here. It's not that it can't happen, it's that nothing *outside your code* can interfere. If you set it in your constructor, it's set. If you don't, it's not. But it's on your shoulders... But after the constructor finishes, you can actually guarantee that the property is never null. For example: You can only guarantee it if you know ctor actually assigned the variable, but there's no way to check it in the code. I.e. if you manually reviewed the code, you can know it, but declaration itself in no way guarantees it, even though you were thinking it does. So for it to be actually useful, you need to know that ctor has already finished working and that that ctor actually assigned value to this property. And if you are third-party library using this class as an API, it's not very useful for you unless you code-review all third-party libraries you use. Declaration itself does not guarantee it, even if it looks and is promoted as if it did. There's no way to check lots of things unless you look at the code. In fact, there's tons of more pressing issues then this. What if the code calls shell_exec(rm -rf /);... OMG!!! The point I'm trying to get at here, is this is not about trying to defend yourself from yourself. It's about trying to let you write code easily that defends yourself from others. Simple as that... And as far as revewing 3pd libraries, if they fatal, that's on them. I'm talking about preventing *my class* from fataling. That's all that I can ever hope to do anyway... In PHP, inside foo(), $bar will *never* be anything except an instance of Bar. It's not possible. Trying to pass Null would generate a catchable fatal: http://codepad.viper-7.com/Le3jC1 Again, for parameters you MUST provide parameter to call a function, otherwise function would not be called. So there's no way the control can enter the function and $bar not be assigned to instance of Bar, whatever the code around it is doing, however crazy it is. On the contrary, it is very easy to find scenario where property is declared as public Bar $bar; and still contains null. Unlike parameters, again, the declaration itself DOES NOT guarantee the property is not null. You're mincing words here. The point I was making in the email you replied to wasn't that the variable couldn't contain NULL, but that it could never be *assigned* null. A very different concept... This concept is just an exception of that. After construction, if the property is not declared with = NULL, it's never allowed to be set to it. Simple as that. It's the same thing as setting the setter to a function which type hints against Bar $bar instead of Bar $bar = NULL; But that's not very useful. Who cares if it can't be set to null if it can still be null? You'll have to check it anyway. Or, even worse, you'll rely on your own insistence that it can not be null and get fatal error in production code. I don't need to check it if I know that it was set before I get to that point (such as in the constructor). As far as unset failing, we already have the ability to do that right now with __unset(). All this is doing is applying it to the implicit declaration when providing a type-hinted property variable... With __unset, you will have to specifically write code to do that. Here, it is a side effect of a declaration that has nothing to do with unset and it is completely unobvious to 99.999% of the users that this is what will happen. It's completely unobvious because it's not documented. Simple as that... And if you have a better alternative to signify the ability to pass null or not, I'm all ears. Would public nullable Foo $foo; be better? Or public not-nullable Foo $foo be better? What we're trying to do here is make life easier for the 99% use case. Not the far edge-cases that you've presented so far... No. The whole point of this is to make defensive coding easier. We can But you don't make it easier if you're making promises you can not keep, such as this value will never be null. Again, nobody promised this value will never be null. What we're talking about is the promise that
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
This proposal looks really good to me. It cuts out a lot of syntax and boilerplate for a commonly used case. However, there is one issue that I know somebody is going to raise: Argument: If you change the value of the property without using the setter then `get` could return something that has a type mismatch with the type-hint. If I understand the current RFC for properties correctly, the only place that a property can be directly written to without the accessor is inside of the `__setProperty` method. This almost nullifies the argument completely. The only other place for possible error would be assigning a value in the constructor that does not match the type-hint. However, because we adding a new syntax we *could* disallow assigning a value if it really was that problematic. I do not personally feel that would be necessary. I feel that this argument is not weighty enough to stop the proposal for this improved syntax. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
This shouldn't be an issue because it is not possible to set the property without going through the setter, which would be a type hinted accessor function. Ergo, an attempt to set the value to an invalid value would cause a fatal error and thus the setter would not be able to then set it to the invalid value. On 1/4/2013 9:15 AM, Levi Morrison wrote: This proposal looks really good to me. It cuts out a lot of syntax and boilerplate for a commonly used case. However, there is one issue that I know somebody is going to raise: Argument: If you change the value of the property without using the setter then `get` could return something that has a type mismatch with the type-hint. If I understand the current RFC for properties correctly, the only place that a property can be directly written to without the accessor is inside of the `__setProperty` method. This almost nullifies the argument completely. The only other place for possible error would be assigning a value in the constructor that does not match the type-hint. However, because we adding a new syntax we *could* disallow assigning a value if it really was that problematic. I do not personally feel that would be necessary. I feel that this argument is not weighty enough to stop the proposal for this improved syntax. -- -Clint
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Hi! This shouldn't be an issue because it is not possible to set the property without going through the setter, which would be a type hinted accessor function. It is possible, if this property's guard is set. Since guard works for all code called from inside the setter, if setter is doing something not trivial (meaning, calls any functions, explicitly or implicitly) it is possible to set the property directly. Since the value you are getting is defined by the getter, there are no guarantees there too. So effectively, unless both getter and setter are implicit, this does not give you anything compared to the typed setter. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
Would the following two be exactly functionally equivalent? public Foo $foo; public $foo { get; set(Foo $value) { $this-foo = $value; } } We should also consider how an author would allow type-hinted properties to accept NULL as a new value, in both proposals. Steve -- http://www.mrclay.org/ On Jan 4, 2013, at 9:41 AM, Nikita Popov nikita@gmail.com wrote: Hi internals! I already brought this up before, but I think the discussion at that time was not very constructive and largely off-topic, so I'm bringing it up again. To make sure everything is clear I wrote an RFC document: https://wiki.php.net/rfc/propertygetsetsyntax-alternative-typehinting-syntax This RFC proposes an alternative syntax for typehinting accessors, which will in particular also allow to typehint properties directly, even if no accessors are used (public DateTime $date). What are your opinions on this? Thanks, Nikita -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
We should also consider how an author would allow type-hinted properties to accept NULL as a new value, in both proposals. public $foo { get; set(Foo $value = NULL) { $this-foo = $value; } } Would work for traditional type-hints. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Fri, Jan 4, 2013 at 4:34 PM, Levi Morrison le...@php.net wrote: We should also consider how an author would allow type-hinted properties to accept NULL as a new value, in both proposals. public $foo { get; set(Foo $value = NULL) { $this-foo = $value; } } Would work for traditional type-hints. I just realized that `unset` would actually have a use here. Rather than setting something to `null` you would `unset` it. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On Sat, Jan 5, 2013 at 12:31 AM, Steve Clay st...@mrclay.org wrote: Would the following two be exactly functionally equivalent? public Foo $foo; public $foo { get; set(Foo $value) { $this-foo = $value; } } We should also consider how an author would allow type-hinted properties to accept NULL as a new value, in both proposals. I think that's a very interesting question, thanks for bringing it up. I think a good approach here would be the same one used for function argument typehints, i.e. allow NULL when NULL is specified as the default value. So `public DateTime $date;` would not allow an explicit NULL assignment, whereas `public DateTime $date = NULL;` would. Nikita
Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors
On 1/4/2013 4:29 PM, Stas Malyshev wrote: Hi! This shouldn't be an issue because it is not possible to set the property without going through the setter, which would be a type hinted accessor function. It is possible, if this property's guard is set. Since guard works for all code called from inside the setter, if setter is doing something not trivial (meaning, calls any functions, explicitly or implicitly) it is possible to set the property directly. Since the value you are getting is defined by the getter, there are no guarantees there too. So effectively, unless both getter and setter are implicit, this does not give you anything compared to the typed setter. I think I was referring to the possibility I mentioned in another email about a second call to a getter which was already guarded would return NULL and likewise a second call to a setter which was already being guarded would do whatever __set() does...? Ignored? -- -Clint -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php