Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
Hi! I agree with you. The one case where this syntax may be very useful is if we want to implement class casting. So introduce a pair of magic methods I do not think we want to implement class casting. I'm not sure how class casting even makes sense - if the object is of one class, how can you just make it into another class by casting? If you mean casting actually returns another object of different class, then just make a method for that that returns that object, I do not see how obscuring the purpose of this operation with unobvious syntax would help. The discussion is starting to drift very far from my original proposal. Instead of trying to guess what I mean, can't people just refer to my very simple definitive proposed behavior? My proposal is simple: behave as an inline type hint. The same type hints you have in arguments lists, but inline. The use case is I want to make sure this value is of this type and a side benefit is the IDE can know the variable is of this type too (for autocompletion purposes). Whether they'd be exposed with the cast syntax or otherwise isn't that important. Languages like ActionScript expose inline type validation both by static typing hints and by casting. In both cases the operation simply validates the class can be seens as an instance of this class/interface. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
I'd like to also ask people to read what the intended effect of the proposal is instead of going into abstract discussions about how casting one class to another doesn't make sense (this is not what's being proposed). Just like PHP typehints look like static typing but *aren't*, the same way the fact this looks like a static cast *doesn't* make it so. A dynamic language can't have static casts, and I'd think this is obvious to everybody. Instead, I'm adapting the principle so it fits with existing PHP behaviors and patterns. Syntax which looks like static typing is fine by me as well. Examples: ClassName $foo = expression(); foreach ($list as InterfaceName $item) { ... } etc. The only operation done here is validating the variable is a valid instance of this type. No transformation is happening. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
What's wrong with instanceof? You can then throw fatal error if you want, it's just two lines: if(!($foo instanceof Bar)) { trigger_error(E_USER_ERROR, Wrong foo!); } That's 3 lines on top of the line where you assign the value, and you forgot the 4th line for the IDE: - /* @var $foo Bar */ $foo = expression(); if(!($foo instanceof Bar)) { trigger_error(E_USER_ERROR, Wrong foo!); } - Versus this: Bar $foo = expression(); And assignment is a kinda common operation. So I hope you can see what's wrong with it now. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
And assignment is a kinda common operation. So I hope you can see what's wrong with it now. No I do not. Not every imaginable use case should have dedicated language construct for it - sometimes it is OK to type 2 lines of code. Sometimes even 3. This case is well served by existing language syntax, which also allows much more flexibility and control over what happens if the variable does not match. I see no reason to invent language construct the only purpose of which is to save you typing one if clause. Let me ask you - do you think the existing PHP typehints are pointless too? Do you feel they don't give you enough flexibility? Do you feel they reinvented a language construct for the purpose of saving the typing of one if clause (per argument) (per method) (per class)? And why do you keep ignoring the fact that IDE's need additional clutches to understand the type of the variable? Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
On Wed, Aug 15, 2012 at 10:06 AM, Stan Vass sv_for...@fmethod.com wrote: I'd like to also ask people to read what the intended effect of the proposal is instead of going into abstract discussions about how casting one class to another doesn't make sense (this is not what's being proposed). I think you confused everyone by a) having typecasting in the title and b) starting with the (Foo) casting syntax (so everyone assumed that you indeed want some kind of class casts, whatever that may be). I had typecasting / typehinting in the title, and I'd like to remind everyone again that in dynamically typed languages class casts are often implemented as a basic validation operation, consistent with what I proposed. Regarding the actual proposal, could you maybe clarify the use-cases for this? I can see that it could be useful in principle, but your actually named use cases confuse me somewhat. In particular, I don't see how this would help dependency injection containers. I can see that it helps service locators and registries, but both of those are considered antipatterns, so there is no reason to add additional language features for them. DICs are only used to inject top-level dependencies, so in that case types should be fairly well covered by parameter type hints. Two use cases apart from registries: PHP has no typed iteration and arrays, so you the only way to guarantee (and the IDE to know) the type of a variable in these cases is a hint: Foo $bar = $array[1]; foreach ($array as Foo $item) { ... } Automatically this applies to everything that uses ArrayAccess as a shorthand too, and properties of anonymous objects (stdClass). The current alternative is peppering code with pseudo-PHPDoc inline hints, and instanceof assertions which truly is a facility the language core should provide, instead of us emulating it. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
Hi! Let me ask you - do you think the existing PHP typehints are pointless too? Do you feel they don't give you enough flexibility? Do you feel they reinvented a language construct for the purpose of saving the typing of one if clause (per argument) (per method) (per class)? They are not pointless, but I think they are often misunderstood and not used correctly. And they definitely lack flexibility in many cases. But they are helpful for one important thing - defining interface between the method and the method client. Having strictly typed variables does not serve it, and trying to make PHP into half-baked half-statically-typed language does not sound like a good idea to me. All right, your method accepts an array of objects, instances of Foo. How do you enforce this contract? Here's how my proposal enforces it: function foobar(array $collectionOfFoo) { foreach ($collectionOfFoo as Foo $item) { ... } } What's your proposal? From the discussion so far, I'd guess it's peppering out code with if-s with the same error written everywhere everytime we check the item in an array. Because I don't think inventing language constructs for the purpose of helping IDEs simulate static typing in dynamically typed language makes much sense. The same applies to typehints, so make up your mind. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
Hi! All right, your method accepts an array of objects, instances of Foo. How do you enforce this contract? You are trying to re-invent generics/parametrized types and bolt it onto PHP. I still don't think it is a good idea - PHP is not a statically typed language. Just check you array elements if you need. You're 10 years too late to argue the merits of typehints in PHP. I am not proposing the introduction of typehints. I'm just saying we have the option to use them in arguments, let's have the options inline too. This way we can validate expressions and structures we can't today, in a minimal, readable, consistent, easy to maintain way. By peppering here you mean one if. Yes, this is my proposal - if you need to do a check - do a check. Yes, exactly: one if. For your entire codebase that has one single assignment in it. Or one foreach. Pick one or the other, but not both, otherwise they become two ifs, and that invalidated your argument. The same applies to typehints, so make up your mind. No it does not. But this is exactly why I think one of the problems with strict typing in arguments is - because people take it and starting to use it as a legitimation of turning PHP into weird hybrid of dynamically typed language with random islands of static typing popping in random places. I still do not think it is a good idea. Saying weird hybrid random islands popping random doesn't make simple type validation hints any more awkward than they were yesterday before I posted this thread, Stas. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
Stas already pointed out that parameter typehints allow you to define the interface for your method. Return typehints would server a similar purpose and as such I'd consider them useful. But variable typehints don't serve any such purpose. I gave an example validating an array of Foo instances, which the current system doesn't solve. Of course PHP could extend argument typehints to describe this, but Stas *just* said he doesn't want generics and so on in PHP. All right, I don't either. I just want a clean way to describe my expectation that a variable is what it is, and assuming that all function arguments are one single instance simply doesn't match the real world out there. People iterate arrays, they pass arrays around. And they have expectations for what's inside those arrays. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
But variable typehints don't serve any such purpose. Actually, one could even say that they don't serve *any* purpose, short of providing the IDE with type information, because your code would work just as well even without the type check. If the type were wrong, it would just throw a fatal error when trying to do something with it (like invoking a method that does not exist). Just like with argument typehints. Point me to an argument typehint that is required for your code to run. You and Stas keep giving arguments against argument typehints, which is really awkward. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Inline typecasting / typehinting for classes and interfaces
I've felt the need for this for some time. Proposed syntax: - $x = (InterfaceName) $container-service; Proposed behavior: --- Checks if the instance if an instance of the given class/interfaces. If yes, does nothing, if not, issues a fatal error. Pseudo code: $temp = $container-service; if ($temp instanceof InterfaceName) { $x = $temp; } else { trigger_error('The object can not be cast to InterfaceName'); } Use cases: As my example hints, the intent is to provide type safety and hinting for the increasingly used dependency injection container pattern. It's useful to provide type safety also for all similar patterns which may not return a result of the expected type: Registry, ServiceLocator, Factory etc. Additionally to runtime type safety, this will also serve to editors/IDEs as an inline hint to provide proper autocompletion, i.e. instead of this: /** @var $foo InterfaceName */ $foo = $container-service; People can now just write: $foo = (InterfaceName) $container-service; Alternative syntax: -- I realize casting isn't a perfect match as the behavior is equivalent to inline type hinting. On the other hand, casting and inline type hinting in dynamic languages often behave identically (see the casting behavior in ActionScript which combines type hints with a JS-like dynamic type system). And this syntax doesn't introduce new keywords. Still, alternative ways to implement this could be: 1. $foo = $container-service as InterfaceName; 2. $foo = $container-service is InterfaceName; 3. $foo = (InterfaceName $container-service); 4. InterfaceName $foo = $container-service; All of those would be fine, especially 4, which has precedent in other languages, and in PHP as well with typehinting and in catch blocks: catch (ClassName $e) { ... } I'm ok with suggestions for any syntax that is as short, if it fits the behavior better. Feedback? Stan
Re: [PHP-DEV] Decorators Revisited
Would this work with methods which take arguments by reference or return by reference? Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Inline typecasting / typehinting for classes and interfaces
Proposed syntax: - $x = (InterfaceName) $container-service; I'm against this. Let's be honest, how different is this that an optionally static type? InterfaceName $x = $container-service; To be clear, I WANT optionally static typing. For the most part, type-hinting in class methods solves the static typing needs, but if we were able to declare a class member to be a certain type that would be another significant improvement. I have a proposal in the works, but I don't want to hijack your thread. To sum up: I think we need something LIKE what you are proposing, but I'm against this particular proposal. What you want is option 4 under my alternative syntaxes section :) I'm ok with syntax 4, in fact, the more I think about it, the more I prefer that one (the one you want). I don't mind the syntax as much, I want the feature. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Error handling brainstorming
The overall mood seems to be that since PHP has an error handler, everyone is free to handle errors any way they want. Everyone is surprisingly ignoring the two giant holes in that theory: 1) PHP Errors come with a severity code and a string message. You want to handle specific errors in a specific way? You better start writing giant regexes parsing the string messages. 2) When everyone starts handling errors in their own way with error handlers, you can't reliably use third party code. You are in your own universe. Stan
Re: [PHP-DEV] Error handling brainstorming
You are either purposefully exaggerating or not doing it right. if(fileop1() fileop2() fileop3()) { // do valid stuff } else { // do error stuff } It's not that hard. I guess it was my mistake that I simplified my actual code for simplicity's sake. Please show me how would my actual code look stuffed in an if statement: try { $cacheBaseFile = Core\CACHE_PATH . '/Compiled/' . \str_replace('\\', '-', $symbolName); // The validator checks whether the cache is fresh. $cacheIsFresh = include $cacheFileBase . '.val.php'; // Attempt to load the cache (it should be there if the validator is there, unless someone messed with the files). if ($cacheIsFresh) { $result = include $cacheFileBase . '.main.php'; } else { $this-generateCache($symbolName); ... } return $result; } catch (IncludeIOError $e) { // One or more of the files were damaged or missing. ... } When you have: 1) comments 2) multiple statements 3) assign variables 4) call functions/methods with long arguments etc. ...you can't just stuff it in an if (op() op() op()) and pretend this is in any way a maintainable code style. With exceptions: try { fileop1(); fileop2(); fileop3(); normal_actions(); } catch (IOException $e) { exceptional_actions(); } Now imagine fileop1 throws some other exception - note that you have no idea which exceptions are there and nothing guarantees you fileop1 throws only IOException, and by the proposal here, any problem in any code whatsoever results in exception now, even if the problem was in converting log message to utf-8 while writing some log inside some function called by fileop2(). Now your whole app has failed, even though you don't really care about that log message at all. Exceptions aren't about log messages, they're about exceptions - error conditions that have to be handled. If my code above generates another type of exception there are only two options: 1) Either I catch that exception because I know how to handle it -or- 2) I don't catch it, and the app should correctly stop right there before data damage is done. I know PHP's model is all messed up, but no one here, I believe, is asking about putting non-error log messages in Exceptions. IO failure is an exception. If your IO operation fails, you can't just log it and plow forward blissfully without handling the problem. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Error handling brainstorming
Hi! Because checking that the returned variable is `!== FALSE` is *way* better than throwing an exception, right? Yes, it is. You can control it, unlike the exception which you can not, unless, again, you wrap everything into try/catch on every kind of exception possible. Have you stopped for a moment to think this opinion through? Look at two typical patterns of error handling. The examples below are generalized from my file cache code. Having no cache is exceptional, because 99.999% of the time I run this, there is cache, except the first time when there's not. Tell me again how you using try..catch is very verbose and how you need to supply multiple catch blocks for every kind of exception possible? With exceptions: try { fileop1(); fileop2(); fileop3(); normal_actions(); } catch (IOException $e) { exceptional_actions(); } Without exceptions: $valid = true; if (fileop1() !== FALSE) { $valid = false; } if ($valid fileop2() !== FALSE) { $valid = false; } if ($valid fileop3() !== FALSE) { $valid = false; } if ($valid) { normal_actions(); } else { exceptional_actions(); } -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Why do disabled functions / classes generate a WARNING.
Hi all, Can anyone explain to me the reason that when a function or class is disabled via the ini setting, an attempt to access the disabled item generates a non-fatal error? I'm looking at a segfault in the SPL caused by the blind creation of a class, which seems to only fail when the class is disabled. I'm wondering in how many other places this could occur. The obvious solution is to be more careful and check return values, but a FATAL would also have prevented execution continuing. Thanks, Leigh. PHP has a long history of issuing errors of the wrong type at the wrong time. My experience shows it's best to have an error handler convert all errors to catchable exceptions, with some error types (like E_STRICT, E_ERROR etc.) to become instant fatal errors (can't be caught). This would also solve your use case since the warning will become an exception with a stack trace clearly pointing to the origin of your problem. Additionally you can handle an exception on a higher level in the stack once instead of doing it for every function/class call. I'm afraid fixing the default behavior is a big hopeless since it'll break BC and require a major rethinking of the way PHP issues errors. See: set_error_handler(). Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Why do disabled functions / classes generate a WARNING.
a php function/operation can raise more than one warning, how would you handle that? with exceptions you would only get the first one. another issue is that with the current error handling model a call can trigger a non-fatal error and still return some data. with exeptions you can't do that. so changing our internal error handling isn't as easy to start throwing ErrorException-s, it would require much more workthan that. Yes it is a bit more work than that. For example include issues two errors on include failure, I mute one of them and turn the other into an exception, which is one of the behaviors you've mentioned. There are ways to fix everything, but you have to be specific, if you want me to be specific as well. Either way I'm trying to give a practical solution you can implement today. Aside from practicality, I do also support the idea that accessing disabled symbols should be a fatal error, not a warning. Stan
Re: [PHP-DEV] Why do disabled functions / classes generate a WARNING.
Which brings up the issues that I mentioned before. Getting the return of an erroring function isn't such a big issue, but turning everything into exceptions would prevent getting any return value from any function/operation which triggers anything, Maybe you want to keep your cake and eat it too, but in practice, functions which return useful content and also error are simply poorly designed. You can work around such function, for example if I absolutely need both channels, exception AND return value, I have this: 1) switch the error handler in a temporary mode which logs errors in an array without throwing them. 2) call the offending function 3) preserve the return value and read the log 4) create an exception class instance which contains all needed data 5) throw it. Alternatively I can choose to just return the value and not throw anything, depends what makes most sense. I wrap this once and then I can call it just as usual, getting both channels. BUT, this is very rare, and is a sign of a poor design of the function IMHO. Stan
Re: [PHP-DEV] Error handling brainstorming
When I said I'd like to see E_STRICT be fatal/exceptions it wasn't a typo. My choice isn't based as much on what the current error severity is, or what the error severity is supposed to represent in general, because I've found in PHP often the error severity has no connection with the error that's being reported. So I decided this by observing the real-world errors that use a certain severity. Many warnings and all E_STRICT errors clearly point to bugs in the code, wrong method signatures, non-existing variables and constants being used, which can easily do actual data damage if the script keeps running in undefined state (even if the engine is just fine with it). PHP should not split the language semantic into loose, less loose and strict, there should be just one set of semantics: the PHP semantics, and when code does something that doesn't fit, it shouldn't be an ignorable warning. I've found this speeds up the development process, keeps bug count down and protects the site/app's data in case of bugs. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Error handling brainstorming
On Sat, Aug 4, 2012 at 1:16 AM, Stan Vass sv_for...@fmethod.com wrote: When I said I'd like to see E_STRICT be fatal/exceptions it wasn't a typo. My choice isn't based as much on what the current error severity is, or what the error severity is supposed to represent in general, because I've found in PHP often the error severity has no connection with the error that's being reported. So I decided this by observing the real-world errors that use a certain severity. Many warnings and all E_STRICT errors clearly point to bugs in the code, wrong method signatures, non-existing variables and constants being used, which can easily do actual data damage if the script keeps running in undefined state (even if the engine is just fine with it). are you sure about that? E_STRICT is more about code that works but relying on some quirk or side-effect or simply does a stupid thing. Well think about it. Why is it a goal to let quirky/stide-effect/stupid code run? This almost always ends badly. It also reduces compatibility between code libraries. I.e.: it is the opposite, we allowed sloppy code in the past, and introduced E_STRICT to allow the pedantic people to find and fix the quirks and E_DEPRECATED for finding and migrating the code which will go away. If you use a well tested, popular library by sloppy coders who don't mind E_STRICT and E_NOTICE, but you're pedantic, what happens? You have to live with your error log filled with noise from the library or fork the library. And when the sloppy coders miss bugs because they've decided the real PHP is about sloppy code that still works somehow, they miss bugs and then blame themselves or PHP for being a language that allows buggy code. This is the end result if trying to turn PHP into everything for everybody. Instead, PHP should make up it's mind and stop littering the php.ini with semantics/behavior configuration for the language. Have one behavior. Stick with it. Make it obvious.
Re: [PHP-DEV] Error handling brainstorming
if we turn E_STRICT to behave exactly as E_ERROR there is no point keeping the E_STRICT level. personally I disagree with turning something which was a pedantic notice in one version into an unsupported feature which fatals out if you try to use it in the next. maybe E_STRICT-E_DEPRECATED-E_ERROR I do think there's no point keeping the E_STRICT level. In fact, there's no point keeping any level except - E_WARNING (strictly for developer tips like deprecated functionality, and not for say division by zero errors or Stream I/O errors like it is today); - E_ERROR (everything that's not a developer tip but an error, should be this type, not a notice/warning/strict); - E_FATAL_ERROR (direct script halt). That's just how I see it. Today we have these instead: - E_ERROR - E_WARNING - E_PARSE - E_NOTICE - E_CORE_ERROR - E_CORE_WARNING - E_COMPILE_ERROR - E_COMPILE_WARNING - E_USER_ERROR - E_USER_WARNING - E_USE_NOTICE - E_STRICT - E_RECOVERABLE_ERROR - E_DEPRECATED - E_USER_DEPRECATED Most of those have no reason to exist and especially they have no reason to be exposed as different severities at the user level. It seems like the severity levels have become a poor man's error *type* codes, which are needed, and at much more granular level, but as this is a severity, that's not the place to differentiate them. I never spoke about E_STRICT going fatal in the next version of PHP. I'm saying this in the context of my advice about using an error handler. I do this in my error handler (not just development, but also production), but still I think it could be a nice long-term goal to cleaning up PHP. Stan
Re: [PHP-DEV] Traits behavior still up in the air in 5.4
The methods in the class have *always* higher precedence. This is the same 'overriding' behavior used for inheritance. From my personal perspective, changing this would lead to a major inconsistency with how subclassing works. Hi, I've subsequently read your RFC carefully and saw some of those items are by design. However while they're by design, the end result seems rather confusing I should say. While I'm glad the RFC was shooting for consistency in general, traits are not subclassing. Therefore aligning the behavior of features for vertical reuse with features for horizontal reuse seems somewhat arbtirary to me. The use cases for overriding methods like this seem sketchy at best. What is the use case, and how are those use cases more important than the confusion caused by allowig this? 2. Using as syntax when importing a trait does NOT rename a method, but creates an alias CLONE, the original method still callable. Proposed behavior: the original name should be only accessible within the trait and its methods, not from the class methods or by calling the class instance's methods from outside. Again, this happens to be 'by design'. PHP is a rather dynamic language, and we happen to have things like $c-$foo(); where $foo is a string. Renaming is technically not reasonable, and would also lead to major confusion when metaprogramming is used. Can you please explain how are function names by variable at all related to this? $object-foo() and $object-$foo() aren't even related in any way semantically. If a conflict exists while grafting a trait, the original method will be overshadowed silently and the method will be only accessible by the alias. The entire idea of aliasing is to avoid a conflict with an existing method of the same name. While if there's no collision, it's accessible by both. So in practice it works by chance. How is working by chance in any way aiding meta programming? 3. Properties silently collide in traits and classes. Please read https://wiki.php.net/rfc/horizontalreuse#handling_of_propertiesstate carefully. Again, this is intended behavior. If you want to be notified of such collisions, please use E_STRICT. I've read them carefully now, but there's no solid reason given for this behavior, or why the proper behavior only exists in E_STRICT. I can't really see state is a complex topic as a reason why trait property collisions are handles inconsistently with method collisions. 4. The documentation says static propeties can't be defined by traits. Yet they can. I don't know what's the bug here: a doc bug, or a code bug. For consistency, static properties should work, if instance properties work. Nothing is gained supporting it half-way. Could you please point me *exactly* to the paragraph where we have something written about static properties? I do not see that I wrote anything special about static properties in the RFC. And I do not find it in the docs either. static properties should work like normal properties. Sure. From the manual page for traits: Static variables can be referred to in trait methods, but cannot be defined by the trait. This paragraph is then following by a code example using function-static variables as what seems like an example for a replacement for static trait properties, strongly suggesting the former aren't supported. Yet they are. The RFC seems to also give examples of method-level static variables, and I honestly can't see how this is related to traits or trait/class-level members at all. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Traits behavior still up in the air in 5.4
Could you please point me *exactly* to the paragraph where we have something written about static properties? I do not see that I wrote anything special about static properties in the RFC. And I do not find it in the docs either. static properties should work like normal properties. I'd like to add something to my answer to this question: while I've added a doc bug for this quote I gave, people handling the documentation *don't want to fix it*, because they think static members *should notwork* in traits, this is how they read the RFC for some reson. Thus a clear sign people are confused about this behavior. It has to be clarified. Stan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Traits behavior still up in the air in 5.4
From that follows that traits override the super class's methods. And, conflict resolution is only done between traits, not between a class and its traits. The class body is a definite thing. Why would you purposefully add something to a class body that conflicts with a trait? The class needs to know exactly what the traits are doing. There is no black-box reuse. But that's precisely my point. No class would *purposefully* add something to conflict with a trait. Then by your own description the only case is *accidentally* adding something to conflict with it. In such a case why on Earth is it allowed without a fatal error? The use case for overriding is typically that you got a conflict that you need to resolve by making a call to both conflicting methods. Consider two traits that happen to provide a log() function, and in the resulting class you need to call both in all places log() has been called before. Since the user of these traits is the only place where such semantic is sensibly defined, the method in the class body is overriding the traits methods, and can access aliases you introduced for the traits' methods. The way it works right now, on conflict, a class may access the trait method via the alias, or its own overriden copy by the conflicting name. What is a trait to do? It can't access its own method at all as it doesn't know the alias. The way this is implemented makes no sense, I'm afraid. Let's use your example and make something more complex out of it: trait T { function bar(){ $this-print(); $str = 'print'; $this-$str(); } function print() { echo 'trait'; } } class C { use T { print as foo; } } What is supposed to happen in this example if we assume renaming? Would you expect the first function call to print() in bar() to work after the renaming? Would you expect the second call, using metaprogramming, to work as well? It's very simple: 1) *only* the original name should work for methods defined in a trait (including metacalls). 2) *only* the new name should work from methods defined in the using class (including metacalls). Yes, I know: this is a lot more complicated to implement. *But* if we'll take shortcuts in user-facing behavior just because it's simpler to implement, then aliasing should've have never been added at all for 5.4, until it can be implemented reasonably. If we use aliasing instead of renaming, we have predictable behavior for all options. It's not predictable at all. If the class defines function print in your example above, the trait suddenly can't call it's own method anymore! Metacall or not. Please do me the favor and consult the mailing list archives. It is all in the various discussions. If behavior specification and reasoning worked by consulting the archives for internals, we wouldn't have RFCs. I see no good reasoning in the RFC for this behavior, and going though thousands of emails in the archive is not a reasonable way to find out the reasoning. There is no proper way to handle state, state requires splitting, merging, and what not. None of the research prototypes provides a simple solution. State does not require splitting, merging. What does state splitting even mean? Here's a very simple design principle here: if you can't guarantee correctness for a behavior, provide a limited behavior, which guarantees correctness. This is how language design works. If there's a conflict, die with a fatal error, make people rename their properties so there's no conflict. Assuming *silently* that the user is intentionally colliding state variables between traits because he/she wants to merge/split state is insanity IMO. The solution we have is a 'best effort' solution. If you can do better, please make a proposal. I did in my original email. No property collisions. Fatal errors. It's very simple. I assume we are talking about: http://php.net/manual/en/language.oop5.traits.php Static variables and members/properties are not related at all. The writer of the documentation didn't get the wording correct. Please feel free to submit a patch. I've submitted a doc bug. No one want to fix it since they think it's PHP that's wrong, not the manual. I can't do anything more about it. Here's the link: https://bugs.php.net/bug.php?id=62156 Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Traits behavior still up in the air in 5.4
Because it is not a matter of horizontal reuse. Why don't you get a warning when you override an inherited method? Because that is precisely the way things are supposed to work. The body of a class is not a trait. These methods are not 'equals'. I still think that design decision is a sensible one with respect to the rest of PHP. If traits act like superclasses, why can the class call a private trait method, by that logic? It shouldn't be able to. You've mixed two paradigms here and the result is messy. Traits are for horizontal reuse. If you're justifying this by giving examples about superclasses, this is the wrong mental model for traits. Ask anybody what are traits. The most common answer is a glorified copy-and-paste. Do it, you'll see. Glorified copy-and-paste. Now ask yourself, if you have class Foo { public $bar; public $bar; } would that be fine? No. So it's not a copy-and-paste. But if you copy pasted a private method would you be able to call it? Yes. So it's copy-and-paste. So what is it? It's neither and both. I expect a mighty confusion and abuse of traits because they can't decide what they are in 5.4. Traits should pick one model and stick to it. It's very simple: 1) *only* the original name should work for methods defined in a trait (including metacalls). 2) *only* the new name should work from methods defined in the using class (including metacalls). Yes, I know: this is a lot more complicated to implement. *But* if we'll take shortcuts in user-facing behavior just because it's simpler to implement, then aliasing should've have never been added at all for 5.4, until it can be implemented reasonably. So, what is your proposal? My proposal is what I said above. Either aliases should be *dropped* as a feature from traits and the feature has to be rethought, or they have to work sensibly as outlined in 1) and 2) above. IMO they do more harm than help in their current form. Sometimes not implementing a compromise is a feature itself. If we use aliasing instead of renaming, we have predictable behavior for all options. It's not predictable at all. If the class defines function print in your example above, the trait suddenly can't call it's own method anymore! Metacall or not. It is calling another method instead, indeed. That's composition, and that's what traits are designed for. http://scg.unibe.ch/archive/papers/Berg07aStatefulTraits.pdf Let me quote that PDF you've linked me to: By default, variables are private to the trait that defines them. Because variables are private, CONFLICTS BETWEEN VARIABLES CANNOT OCCUR when traits are composed. If, for example, traits T1 and T2 each define a variable x, then the composition of T1 + T2 does not yield a variable conflict. Variables are only visible to the trait that defines them By default, instance variables are private to their trait. If the scope of variables is not broadened at composition time using the variable access operator, CONFLICTS DO NOT OCCUR AND THE TRAITS DO NOT SHARE STATE. Emphasis mine. This is absolutely not what is implemented in 5.4, and this is in part why we're having this thread now. Here's the proof: trait T { private $foo = 0; public function set($x) { $this-foo = $x; } public function get() { echo $this-foo . br; } } trait T2 { private $foo = 0; public function set2($x) { $this-foo = $x; } public function get2() { echo $this-foo . br; } } class C { use T, T2; public function classGet () { echo $this-foo . br; } } $x = new C; $x-set(321); $x-get(); // Correctly produces 321 $x-set2(123); $x-get2(); // Correctly produces 123 $x-get(); // Incorrect, the paper says it should still be 321, instead the var is shared, so it's 123 $x-classGet(); // Incorrect, the paper says this shouldn't work at all, instead it's 123 Assuming *silently* that the user is intentionally colliding state variables between traits because he/she wants to merge/split state is insanity IMO. Instead of calling my insane, I would prefer if you make constructive proposals. I'm not calling you insane, I'm calling PHP's behavior on trait conflicts insane, and I definitely stand by this, and the paper you're linking me to also seems to confirm this. I keep giving you more reasonable behaviors, but I don't think you're acknowledging them. I guess, since you are an expert in language design (and an active user of PHP), you are aware of this behavior: class T1 { public function foo() { $this-prop = 1; } } class T2 extends T1 { public function bar() { $this-prop = 2; } } $o = new T2; $o-foo(); $o-bar(); var_dump($o); What is your point again? My point which I've described multiple times at this point is that traits are not classes, we already have classes in PHP, you know? Imitiating classes with traits is the wrong mental model for their behavior, and the paper you're linking me to confirms tht. There is nothing
Re: [PHP-DEV] Traits behavior still up in the air in 5.4
I'd like to apologize for my language. My goal isn't to insult anybody, especially PHP contributors of major features like traits. I hope we can talk strictly implementation issues, I think I have a good idea how we can move this forward, I'll email you a list of behavior changes that I think make sense next 48 hours and we can discuss it offlist to keep the noise low here, if you'd like. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Traits behavior still up in the air in 5.4
I'd like to point out some puzzling behaviors in Traits as they exist in the production releases of PHP 5.4. 1. Name collisions between a trait method and a class method using the trait go unreported, the class silently shadowing the trait method: trait T { function foo() { $this-bar; } function bar() { echo 'trait'; } } class C { use T; function bar() { echo 'class'; } } $c = new C; $c-foo(); // class Proposed behavior: Fatal error on collision, unless the method is imported with a unique name using the { ... as ... } syntax. 2. Using as syntax when importing a trait does NOT rename a method, but creates an alias CLONE, the original method still callable. trait T { function bar() { echo 'trait'; } } class C { use T { bar as foo; } } $c = new C; $c-bar(); // trait Proposed behavior: the original name should be only accessible within the trait and its methods, not from the class methods or by calling the class instance's methods from outside. 3. Properties silently collide in traits and classes. trait T1 { private $foo; trait T2 { private $foo; } class C { use T1, T2; } // No error. Proposed behavior: An error is produced only when the properties differ in visibility or a default value, which is clearly insufficient to determine they're used for the same purpose, and hold the same data. Instead they should use the same logic as method conflicts: fatal error on name collision. Alternatively, each trait property whould be accessible within the trait that defines it, not from other traits used in the same class, or the class itself. 4. The documentation says static propeties can't be defined by traits. Yet they can. I don't know what's the bug here: a doc bug, or a code bug. For consistency, static properties should work, if instance properties work. Nothing is gained supporting it half-way. Not many use 5.4 yet, so the sooner all this is clarified, the better, before it becomes completely unfixable due to BC. Feedback? Stan
Re: [PHP-DEV] 6.0 And Moving Forward
I do like the idea of pseudo-objects with methods as a way to create much cleaner APIs for strings and arrays, but the legacy APIs need to stick around. You don't need to break BC to remove legacy APIs in PHP6. #1. Introduce the new APIs in 5.x and gradually mark the old ones as deprecated, but keep them available. People will write forward-compatible code using the new APIs. #2. 2 years pass before 6.0 is out. #3. Remove the old, already deprecated APIs from 6.0. Simple. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] 6.0 And Moving Forward
Chaos will surely be, if we break PHP5 code. It should work without modification. ?php6 is fine, ?php isn't. On Jul 18, 2012 9:34 PM, Daniel Macedo admac...@gmail.com wrote: People are forgetting why we have version numbers. Yes, it's very spectacular to have all the new stuff in a major release, but that's not what major versions are for. Major versions are for BC breaks. And point releases are for BC-compatible new features. Therefore in 5.x releases old and new features should co-exist, and in 6.x the old ones should just go. Otherwise there's no point of using versions *at all*, and PHP can just publish build numbers or dates. Here's a refresher of the rules of versioning: http://semver.org/ Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Pseudo-objects (methods on arrays, strings, etc.)
But OOP-like syntax on non-object data is still weird. The question about data manipulation behavior (is it a pointer like other objects or is it a scalar like existing array?) is a tough one. For the user's point of view there is no difference between the passing semantics of numbers/string primitives and objects. Only arrays differ. However we already have ArrayAccess and so on for objects, which creates array-like objects with object passing semantics. So the idea that something that looks like array will have passing semantics like an array is already wrong in PHP. The clarity of passing semantics is not a valid argument against pseudo methods for string/int/float/array primitives. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Implicit isset in ternary operator
It changes the semantics. If the variable is set to a falsey value and ?: uses an implicit isset, the value of the expression will be the falsey value. $config['width'] = '' $width = $config['width'] ?: 300 # $width == '' If !empty were used instead of isset, you could preserve semantics ($a ?: dflt = !empty($a) ? $a : dflt). Since this has been discussed before, here's a previous solution with zero of those problems: // A new operator. $width = $config['width'] ?? 300; // Actual behavior of the operator in pseudo code: $width = isset($config['width']) ? $config['width'] : 300; Why wasn't it implemented? No reason, it just wasn't. But people keep asking about it, so it's only a matter of time. Stan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Adding a more logical string slicing function to PHP
This is actually something I have been toying with a bit. Adding the ability to call methods on both strings and arrays. I still don't like the idea of making them real objects as the overhead and the amount of code that would need to be changed in the core and in every extension is daunting. Anybody out there have a patch along these lines? -Rasmus Glad to see pseudo-object methods for scalars/arrays brought up again. It'll improve workflow a lot. I want to ask/suggest two clarifications on this: 1) You said 'strings and arrays', I hope that's 'scalars and arrays'. As the current PHP semantics work, and with very minor exceptions, int/float works as a numeric string when passed to a string function, and numeric strings work when passed to a number function. I.e. those should work: $a = 1234; /* int */ echo $a-substr(1); // '234' $a = '1.23456'; /* string */ $a-format(2); // '1.23' This means the extension methods for primitives should be split in two groups: arrays (lists and maps) - one API set scalars (bool, int, float, strings) - one API set 2) Because the language currently has no scalar hinting (I know it's coming), IDE autocompletion of the extension methods may not work very well (unless the IDE assumes everything is a scalar unless hinted otherwise). Both hinting, incl. for method/function return types, and extension methods should be introduced together as they make each other more useful, than independently. Let me know what you think. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Adding a more logical string slicing function to PHP
Looking at JavaScript which acts quite similarly to the proposed approach, the Number methods [1] are not many and not often useful, but still they exist. What happens if you do 3.3-ceil() ? If ceil() exists only in \numeric, you could say autoconvert, but if it exists in both \string and \numeric we have a problem, so the only sensible way is to drop type juggling for those autoboxed objects imo. Which is also what JS does btw. If you have an ambiguous value on your hands, you should cast it (x.toString() or parseInt(x)) first and then call what you want to call on it. Another interesting to note is that JS doesn't allow method calls directly on numbers - 3.toPrecision(2) for example is a syntax error, you have to put it in a var first. I guess it's not a problem since you should just inline the value you want anyway, the Number methods don't do super fancy things. Anyway, I hope this helps, my point is just that you shouldn't forget to check out how other languages solved the issue before hitting the wall ourselves. Not saying we have to do it all like JS, but they have something that works, so it's worth studying. Jordi Boggiano We could use the library organization of JS, in that purely math-related methods like 'ceil', 'sin' etc., constants like PI, E etc. will be in namespace \math and take any scalar numeric input. As a lot of them take more than one arguments, and the arguments are sometimes commutative, it makes less sense to present those ones in particular as methods. The few number methods that make sense as methods can then be in the scalar API. Almost like JS but not quite. Since's PHP's interpretation of types is slightly different than JS, we can surely take a page from JS, that's good (and I support it) but it needs to be nudged more towards PHP's PoV. Re. number literals, (3).toPrecision(2) works in JS, I guess they wanted to avoid some ambiguity in the parser, ex. 3.0.toPrecision(2). Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Change default serialize precision from 100 to 17
The default serialize precision is currently [1] set at 100. A little code inspection shows precision, in this case, takes the usual meaning of number of significant digits. Given that the implicit precision of a (normal) IEEE 754 double precision number is slightly less than 16 digits [2], this is a serious overkill. Put another way, while the mantissa is composed of 52 bits plus 1 implicit bit, 100 decimal digits can carry up to 100*log2(10) =~ 332 bits of information, around 6 times more. Given this, I propose changing the default precision to 17 (while the precision is slightly less than 16, a 17th digit is necessary because the first decimal digit carries little information when it is low). From my tests, this makes serialization and unserialization of doubles around 3 times faster (counting the function calls to serialize/unserialize, plus a loop variable increment and stop condition check). It also makes the serialization data. Crucially, from my tests, the condition that the variable stays the same before and after serialization+unserialization still holds. The test include, for little endian machines, verifies this. If no one objects, I'll change the default precision to 17. I've always done this, and the default of 100 has been puzzling. We have another problem. The counterpart of serialize precision, the display precision INI setting is currently lower than 17 on most PHP installs, and it this leads to actual data loss in places where people expect least. All database drivers/APIs I've tested have escape/quote routines which are affected by this supposedly display only precision. The below test is performed on a 32-bit system (integers over 2^31 become floats): $x = new PDO('mysql:localhost', '...', '...'); ini_set('precision', 12); // typical for many PHP installs echo $x-quote(pow(2,50)); // (string) '1.12589990684E+15' ini_set('precision', 17); echo $x-quote(pow(2,50)); // (string) '1125899906842624' In the first example, the E notation, the API sends this to the database: 112589990684000, and was supposed to be 1125899906842624. It's off by -2624. The immediate fix for this is to keep *both* precisions to 17, and in the long term, they should switch to serialize.precision and not use the display precision. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Change default serialize precision from 100 to 17
ini_set('precision', 17); After some testings, here is what I get : ?php ini_set('precision', 14); echo 0.1; // 0.1 echo 0.2; // 0.2 echo 0.3; // 0.3 ini_set('precision', 17); echo 0.2; // 0.10001 echo 0.2; // 0.20001 echo 0.3; // 0.2 ? The default precision of 14 (or 12) must have been chosen to address this overlong string representation of many simple floats ? While I agree with you that any data loss must be forbidden, couldn't this also break existing code ? Would it be possible to displays a value based on the shortest decimal fraction that rounds correctly back to the true binary value, like python 2.7 and 3.1 do ? (http://docs.python.org/tutorial/floatingpoint.html) Just my 2cts :) Nicolas As I've shown in the previous post, looks better doesn't mean is more accurate. It's true that precision has been set to 12 or 14 in order to look better with some small decimal fractions, but that can't be the only concern when that same precision is used also for serialization during database escaping. It's hard to imagine when the display precision of an echoed float being longer or less aesthetically pleasing to a human eye may break code, but when real precision is lost, and this is sent to the database like that, this is a much more tangible problem. In terms of formatting of floats for humans, we still have printf() and number_format(), which allow control independent of the ini setting (which people use when they need that explicit control). Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] A quick consensus on magic method idea
This creates problems for opcode caches since the classes are all precompiled and usually optimized to the point where the opcodes that loads them are NOP'ed away and you just have the full class table cached in memory for each op_array. Walking through that class table on every request and looking for these magic methods to call would be quite annoying, especially since most of them wouldn't have such a method to begin with. -Rasmus As a class is added to the table (on first execute of the opcodes) it can check at that point if the magic method exists, and put it in a separate compact list to call for every request. Walking all classes repeatedly is thus avoided. However, a remaining problem is the user no longer controls when exactly are his classes initialized, and in what concrete order. We have the potential for race conditions, where classes B, and C rely on initialized class A, or on some other initialization routine called in userland, which has not been executed yet, producing sometimes broken code that's hard to debug. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] GPU Acceleration
PHP doesn't have anything significant that would benefit from a GPU right now. As a more realistic goal, (1) APC should become a standard part of the PHP distro, and later (2) part of the Zend Engine. Once this is done, (3) the next step is JIT, and few months ago there was some work done on LLVM for this, but I never heard about it since. And only then, esoteric things like running on the GPU can be realistically pondered. So, long way ahead... Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] rename T_PAAMAYIM_NEKUDOTAYIM to T_DOUBLE_COLON
It's amazing to me this has become such a long discussion. The facts are simple: 1) People don't ask for the other parse errors even half as often as they as for T_PAAMAYIM_NEKUDOTAYIM 2) They do so because it looks like gibberish to them, so it looks unlikely to be a common thing you can Google, nor it gives something recignizable to start with 3) Yes, to all who are not sure, more people know English than Hebrew. 4) Yes, we all acknowledge it's an easter egg joke that refers to the creators of PHP. But that particular joke has outworn its welcome in the community after repeatedly causing support issues. T_DOUBLE_COLON already exists as a constant in userland, so the jump to it won't be an epic change. Let's do it as a proof that we're not a nerd gridlock bound to argue forever about even the most minor and obviously positive changes PHP can implement. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Skipping of defaulted parameters.
Option 4 would probably be the worse one to go for. Looking any number of languages that support defaults and you will see code like ... someFunction(param1,param7param11) It does get ugly fast for large numbers of arguments... But any function with more than a handful of arguments is already asking for trouble... At that point you should be passing in a data structure / instance / array or something other than so many parameters. The above example would have at least 10 arguments, so I'd also say it'd look bad never mind the syntax. Also a subtle thing: if your email reader doesn't use fixed width font, it's hard to appreciate the look of each approach in an actual code editor. And I'd say commas next to each other appear quite readable, self-sufficient in fixed-width font, not to mention self-explanatory. Using 'default' would raise more confusion, such as, is that valid: $foo = default; bar($foo); If it's made valid, i.e. if it acts as a constant, I suspect before long people will be assigning 'default' as yet another alternative to a false/null value, and we'll need yet another concept to resolve that. If it's not made valid, it'll be counter-intuitive as it looks exactly like a constant passed as an argument. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Named parameters
This is just not happening people. Please re-read all the past conversations about it. If you come to some sort of epiphany that solves all of the issues brought up in the past, please submit a patch. Otherwise, a never ending thread about this *again* is pointless. Thanks, -- Brian. Brian, can we please not do that. Many things that have been rejected multiple times have made it into PHP, including closures and namespaces. Things are not static, and the rationale for a feature may change in time. The absolute minimum is, if you have objections, to be specific, or at least provide concrete links to specific objections, instead of sending people to hunt for the decisions manually. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Process failed? BC and use cases for property_exists() broken in PHP 5.3
Hi! 3) The use case for this function required the existing behavior (i.e. can you safely call property $x from the current scope with no warning?), and that *ignored* when the behavior was changed. We already have Reflection classes for inquiring protected/private properties of a class from any scope. Maybe we can fix this by having an argument to the function that if false, checks only for existence, and if true, checks also for access? On the other hand, we already have isset() for vars and is_callable() for methods, so this use case might to be covered. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 A flag seems like a viable solution, but I'm worried that something that was flagged as a bug, was not, and caused change in docs, tests and behavior, while all agreed with each other before. This is at beast a feature request which should have been discussed as such, considering BC break implications and so forth. As for isset(), it doesn't cover the use case for property_exists(), as isset() returns false when a property exists, and is one of these values: null, false, int 0, float 0, string '', empty array() property_exists() more closely relates to array_key_exists() for objects in that regard. Stan Vass -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Process failed? BC and use cases for property_exists() broken in PHP 5.3
I think this is a great case study that could lead to some improvements in the process of fixing bugs in PHP: http://bugs.php.net/bug.php?id=45743 A potential bug was reported on property_exists() that it won't report inaccessible properties in the scope. The problem is this was, in fact, the intended behavior, and despite everything saying the function works correctly, everything around it was changed in order to agree with the new behavior for no good reason that I can see: 1) A test existed that specifically tested propert_exists() respects visibility of the property from the call scope. So for this 'bugfix' to pass tests, the *test was simply changed*. 2) The documentation specifically said the function respects visibility of the property, so for this 'bugfix' to agree with documentation, the *documentation was changed*. 3) The use case for this function required the existing behavior (i.e. can you safely call property $x from the current scope with no warning?), and that *ignored* when the behavior was changed. We already have Reflection classes for inquiring protected/private properties of a class from any scope. So, what happened here? Stan Vass