-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Typed Properties #1797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typed Properties #1797
Conversation
@BurakDev anything is possible, but who's going to maintain it? :-) |
Imagine how huge that project would be: Setting up a project, collect all the patches, applying them. Dealing with conflicts between patches. Maintaining patches which get dropped as the author abandons them after he got a reject. Pulling newest php repo changes and merging them. In The end you come to a point where you are the one responsible to maintain all the RFCs, and they get more and more... Scripts and frameworks would require you to re-compile php with the specific extensions enabled. There are two possible scenarios how this ends: Either no-one will use the new features, to avoid being incompatible with 95% of the environments, or they get used, and php ends up in recompiling the interpreter for every new script. Another point is that you will get incompatibilities. Some RFCs would be incompatible to each other, as they are using the same syntax to do something different. So in the end you need a php interpreter compiled and running per script to avoid running into this problem. And to go a little further: This makes composer or working with libraries at all a huge problem, as they might require a feature which is incompatible with your current feature set. I could go on deeper and deeper like per-folder-interpreter etc. But it should be clear by now why going any of these ways is no good idea at all. Also I think the amount of work required to maintain that project would not match the benefits you get from declined RFCs. So there is only one solution: take the feedback from declined RFCs, analyse them, make them better, and push for another vote run. Just keep on working on the good RFCs like typed properties or generics and generic arrays. |
@IceReaper nicely detailed :-) tldr: a complete clusterfuck ;-) |
I'm dumbfounded as to why this RFC has any nay votes at all. I build from source anyway and I am sorely tempted to annex this PR into my personal PHP fork. Keep up the good work. |
:( |
Do you keep working on this for another vote run, or is this complete approach trashed now? |
We need this :( |
@IceReaper it's not worth going again, I don't think. |
@krakjoe Don't be that pessimistic … |
Many userland devs want this feature. It's so sad we have to wait at least another year. ;-( |
@sirsnyder agree that they want. but better have it nicely implemented without all the proposed breaks than screw a bunch of code bases... specially doctrine users, where proxies relies on |
@krakjoe: keep on it, the feature was not rejected, the implementation details were. I am sure many people will support you in this endeavor to come to a solution that gets accepted. Just look at annotations. 😁 |
@krakjoe I'd like to ask you if you wanna try this [1] approach instead for 7.2. Might be more receptive. [1] #1797 (comment) |
@guilhermeblanco it doesn't address |
@guilhermeblanco just saw, if they only check the write and not reading it does address |
@kinncj I briefly mentioned about it, but let me expand. |
@guilhermeblanco you can remove a property defined by a class?? That seems beyond wrong. Bizzarre. |
The same way you can DEFINE a property you can UN-DEFINE it. And he is marking an Instance Property as undefined, the same as you can dynamically create Instance Properties in PHP. |
@mindplay-dk It's perfectly possible to |
Why not:
Dynamic or un-typed properties are not allowed in strict classes, or any other dynamic voodoo __get, __set or adding/removing properties on the fly, or other nonsense that flies in the face of good practice for strong/strict typed classes. Perhaps allow __get and __set to access and set typed properties as a separate RFC. PHP is written in C which has strong typing. Why in the name of sanity did typed properties get voted down in PHP? |
I think it is a good ideea to have more strict types in php because it is easier to debug and maintain any application. Furthermore I think php should have method overloading because it is a hastle now...my opinion |
@negreanucalin Lol. Core developers doesn't think like you, so you can't see this features |
@sharifzadesina "you can't see this features soon"- yes...I know unfortunately but at least I can dream of it...I hope I'll be alive to see it :P |
@negreanucalin Hahaha 👍 |
Would it be possible to reboot discussion on this RFC? With all the great features in PHP 7.1, I feel this is the only one that seems to be missing. I have some suggestions in relation to the above comments and my experience of working with static typed languages. The first is that I don't believe that enforcing type checking when reading a variable is necessary; setting is a given, and should be perfectly adequate to ensure that the property is the expected type, combined with smarter and efficient checks. When we are initialising an instance of a class, it should be safe to assume that all typed properties that cannot have a nullable state should be initialised via the constructor. For example: class ExampleClass
{
protected int $x;
protected int $y;
public function __construct(int $x, int $y)
{
$this->x = $x; // Type check $this->x on assignment.
} // We should throw an exception here, as $this->y has not been initialised, and cannot be null.
} By instead using There is then the above mentioned situation by @guilhermeblanco where it is necessary for a property that is lazy initialised, without requiring a nullable state, something along the lines of what Swift has may be beneficial: class ClassMetadata
{
private string $name;
private lazy Table $table = new Table($this->name);
// Alternatively, with a closure (Swift supports both for readability, however we
// could enforce a closure for consistency and simplicity of implementation)
private lazy Table $table {
return new Table($this->name);
}
public function __construct($name)
{
$this->name = $name;
}
} Using a With static properties, unless they are nullable, they should also be initialised. class ExampleClass
{
protected static int $x = 1;
protected static ?int $y; // Allowed.
protected static int $z; // Throws exception, must be initialised or nullable.
protected static Object $object; // We would probably only want to allow primitive data types as it works currently?
protected static ?Object $object; // However, it seems like this could be allowed?
} Finally, regarding magic methods, there's probably no harm in enforcing the type in Just trying to get the ball rolling again on this. |
@GroovyCarrot @bwoebi is currently working on a typed properties implementation. You can follow the progress of this here: master...bwoebi:typed_ref_properties. I'm not sure whether this implementation performs a type check each time a property is accessed. A patch to improve internal type representation was just committed to the PHP master branch today. Apparently this will make it easier to continue working on typed properties. There will no doubt be a new RFC once the typed properties implementation is completed. |
I would love to see this RFC revived.
I would suggest to keep the lazy feature out of it though. For one, this
RFC is big enough as is, and this could be a separate RFC, so it probably
should be.
For another, it's one of those features that let you make something akin to
a compiler optimization - if it's possible to defer the initialization of a
property without any side effects, why not simply have PHP always do that?
Why even make you opt in? Constants are always lazy evaluated, so why does
the user need to opt into a micro optimization in this manner?
Either way, discussions about this feature shouldn't hold up typed
properties, since it's a new feature that can be added at a later time.
…On Jan 14, 2017 02:59, "Jake Wise" ***@***.***> wrote:
Would it be possible to reboot discussion on this RFC? With all the great
features in PHP 7.1, I feel this is the only one that seems to be missing.
I have some suggestions in relation to the above comments and my experience
of working with static typed languages.
The first is that I don't believe that enforcing type checking when
reading a variable is necessary; setting is a given, and should be
perfectly adequate to ensure that the property is the expected type,
combined with smarter and efficient checks. When we are initialising an
instance of a class, it should be safe to assume that all typed properties
that cannot have a nullable state should be initialised via the
constructor. For example:
class ExampleClass{ protected int $x; protected int $y; public function __construct(int $x, int $y) { $this->x = $x; // Type check $this->x on assignment. } // We should throw an exception here, as $this->y has not been initialised, and cannot be null.}
By instead using protected ?int $y then the property is valid to be
uninitialised after the class has been initialised, and code using it
should account for that. Also using unset() on non-nullable typed
properties, which should be the functional equivalent of using $this->y =
NULL; and therefore throw a type exception.
There is then the above mentioned situation by @guilhermeblanco
<https://github.com/guilhermeblanco> where it is necessary for a property
that is lazy initialised, without requiring a nullable state, something
along the lines of what Swift has may be beneficial:
class ClassMetadata{ private string $name; private lazy Table $table = new Table($this->name); // Alternatively, with a closure (Swift supports both for readability, however we // could enforce a closure for consistency and simplicity of implementation) private lazy Table $table { return new Table($this->name); } public function __construct($name) { $this->name = $name; }}
Using a lazy token when declaring a property could then require a
proceeding closure to initialise it when accessed for the first time. It's
difficult to really tell what the problem was in the example, however it
looks potentially more of a design problem than a language feature
limitation.
With static properties, unless they are nullable, they should also be
initialised.
class ExampleClass{ protected static int $x = 1; protected static ?int $y; // Allowed. protected static int $z; // Throws exception, must be initialised or nullable. protected static Object $object; // We would probably only want to allow primitive data types as it works currently? protected static ?Object $object; // However, it seems like this could be allowed?}
Finally, regarding magic methods, there's probably no harm in enforcing
the type in __get(), I personally only really see 'magic' methods being
appropriate for proxying invocations to and from other objects, in which
case the client and the object being proxied should deal with the necessary
type checking. A solid lazy property language feature in PHP would address
the need to use magic, which I think would replace the vast majority of
good cases for using it.
Just trying to get the ball rolling again on this.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1797 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAGTtF8nN1MMyer96WuFh45Pd9xCs756ks5rSCwEgaJpZM4HtdW5>
.
|
Thanks @theodorejb for the update, glad to see some work is being done for this. Is there a place that discussion of these features normally takes place? I am aware that the RFC proposed and implemented here seems to have swung from an initial positive response, to being rejected; and I'm curious as to the process for RFC's regarding planning and development. @mindplay-dk completely agree that lazy properties would need to be a separate RFC. I do however think that it is worth adding tokens like that for clarity, as code like the above could be misread as a function without carefully considering syntax. It's also probably wise to follow what modern languages are doing in order to easily support the inevitable RFC's down the line. I'm not sure if this is particularly the forum for talking about the RFC, but reviewing it here (https://wiki.php.net/rfc/typed-properties) I can see that a conscious decision was made to avoid validation of the objects:
The focus here should not be to enforce the type on the variable every time that it is written to and read from. While that will create type safety, I think that this is in reality impractical and inefficient to achieve. There isn't actually any benefit in implementing it like this anyway: this is prone to logic errors as every time you are using the property, you will still have to check whether or not it has been initialised, even though it promises to be of the specified type. So in objective c, every variable is statically typed (as in C), properties are actually just synthesised instance variables with getter and setter methods for them by the compiler, so when you are doing In objective c an object can be initialised without needing to initialise all of the statically typed properties on it, as we are suggesting it should work here. The difference is that primitive data types are actually initialised to class A {
public int $x;
}
$a = new A();
var_dump($a->x); // int(0) The other part to creating stability for this is to account for the situations where an object type property has not been initialised, yet code might still try to call methods on it. In objective c, you can call methods on class A {
public X $x;
}
class X {
public int y;
}
$a = new A();
var_dump($a->x); // NULL
$v = $a->x->y; // (no exception thrown)
var_dump($v); // NULL PHP obviously does not do this, and with various good reasons. Variables can be any type, and we don't know what type The key point here is that there's a known root issue with potentially uninitialised properties, but the language is built to accommodate for this, and does not complain about many of the symptoms. In the example above, the exception thrown by PHP would be that you cannot get the property of a non-object (NULL), however the actual root cause of this issue is that So hopefully I have shown why having typed-uninitialised properties in PHP would just be a large step backwards rather than forwards, as we would be implementing a feature that modern languages are actively trying to stamp out. Which comes back to my original point of the necessity for a property typing feature in PHP to require constructor validation for typed properties that cannot be null; without validating the object after initialisation, then this feature isn't reporting the most likely problem that you are going to want it to raise to you: that a required dependency for an object has not been injected into it's constructor. Not to mention the fact that it seems like it's a much simpler implementation to just check when you're assigning, and when the object is constructed? |
Is there a document somewhere that summarizes the reasons why this proposal was rejected? Have any of the items been addressed since then? |
RFC