Hi Robert, Answers inline.
On Tue, Dec 23, 2014 at 7:59 AM, Robert Stoll <p...@tutteli.ch> wrote: > > > > -----Ursprüngliche Nachricht----- > > Von: Leigh [mailto:lei...@gmail.com] > > Gesendet: Dienstag, 23. Dezember 2014 04:34 > > An: guilhermebla...@gmail.com > > Cc: PHP internals > > Betreff: Re: [PHP-DEV] [RFC] Package private class > > > > On 23 December 2014 at 00:32, guilhermebla...@gmail.com < > guilhermebla...@gmail.com> wrote: > > > Hi internals, > > > > > > I finalized a new proposal for PHP. It consists into adding support > > > for package-private classes in the language. > > > > > > A package private class is basically a class that can only be > > > instantiated in its declared namespace. This means that you cannot > > > extend, implement or use a class, interface or trait outside of > > > declared namespace. It can be referenced outside of the package, but > instantiation can only be done there. > > > > > > Other languages such as Java and C# consider package-private class as > > > a top-level class without any declared visibility. PHP cannot enforce > > > this as it would be an incredible BC break, but we can reuse an > > > already declared keyword "private" to fit this purpose. A class > > > declared without any visibility modifier is considered "public" and > > > works exactly as it currently does. The same applies to a class > > > written with "public" keyword (ie. public class Foo {}). > > > > > > Most of checks are done at compile time and only instantiation is done > > > at runtime (the only place I found out it could be done). Performance > > > impact seems negligible as only one top condition is added during > > > instantiation bytecode executor. > > > > > > > > > At this stage I want to collect implementation feedback. Explanation > > > is done above and the extensive amount of tests self explains what the > > > entire purpose of this feature is. RFC will be created together with > > > voting once I'm able to gather some considerations. > > > > > > Link to PR: https://github.com/php/php-src/pull/947 > > > > > > > > > Cheers, > > > > > > -- > > > Guilherme Blanco > > > MSN: guilhermebla...@hotmail.com > > > GTalk: guilhermeblanco > > > Toronto - ON/Canada > > > > Hey Guilherme, > > > > Good work, namespace visibility on classes and functions is something I > have been working on over the past few months. > > The reason I haven't created an RFC is because I couldn't decide on what > "private" and "protected" should mean for a class > > or function within a namespace. > > > > To me, a private class can only be instantiated within it's own > namespace (this seems the same as you have defined), but > > can be typehinted and used anywhere else. > > > > Maybe I was wrong to try and include "protected" in my own work, as it > caused me the most problems when trying to > > define what it should mean. > > My original feeling was that it should mean it can only be instantiated > in it's own namespace or sub-namespaces. > > > > I also considered a strict "visibility" view, private classes would not > be "visible" outside of their own namespace, and > > protected would not be "visible" outside of their own or child > namespaces ("visible" > > meaning no type hints or usage too). > > > > It is reassuring to see that your approach is the same as my initial > feelings, the accessibility keywords define instantiation > > usage, rather than a strict visibility. > > > > I haven't looked at your patch in detail. My PoC code revolved around > comparing the start of class names with the current > > namespace. Is yours the same? How do you feel about extending this to > functions? > > > > Thank's for the work on this. I wasn't sure I had the willpower to > finish my patch for PHP7, it's nice to see you have the > > same idea. > > > > Cheers, > > > > Leigh. > > > > -- > > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, > visit: http://www.php.net/unsub.php > > [Robert Stoll] > > Hey Guilherme, > > I like the idea but I am not sure whether it is wise to define private in > the way you did, namely that such classes can be seen outside of its > namespace. You referenced Java, which behaves differently for instance. > Classes not defined public are only visible in the same namespace. C# > classes with "internal" are visible in other namespaces but only within the > same assembly (correct me if I am wrong). > I understand how C# and Java define class visibility and even inside of PR I mentioned that ( https://github.com/php/php-src/pull/947#discussion_r21542750 ). I would think of private classes in PHP as Java has implemented them hence > they are not visible outside of its namespace. Why? I think one specifies > private classes if he/she wants to hide the concrete implementation to > others and hence it does not make sense IMO that it can be used as type > hint outside. One should use the corresponding interface instead. > Therefore, I believe it promotes better code style if we do not restrict > the visibility to instantiation only. I think a private class should not be > visible at all to others (cannot be used as type hint either). > Please remember that Java supports 4 levels of visibility on nested classes and only 2 on top level classes. What I added support is basically the 2 top level class visibility supported, since PHP does not allow nested classes. For top level classes, the allowed visibilities are public and package-private. Public classes can be instantiated anywhere in the code. I was forced to make this default in PHP to keep BC, which brought me the decision on how to classify package-private. I used private because there's no other semantical meaning when talking about top-level classes. > > Yet, I would prefer something like C#'s internal - defining that a certain > class is only visible within my own project (can still not be seen by > others), but that does not seem feasible right now since PHP has not an > assembly like structure. But, just as an idea which just popped into my > head, maybe we could introduce something as follows as well (clearly > another RFC - but might affect how we define private classes): > > namespace ch.tutteli.foo{ > public for ch.tutteli.bar, ch.tsphp* > private class Foo{} > } > > Syntax should not matter, can be changed respectively. The idea would be, > that we can define a class private (only visible within its own namespace) > but can give access to it by specifying "public for" clauses - in the above > example the class Foo would also be visible within the namespace ch.tutteli > and within the namespace ch.tsphp as well as its sub-namespaces (denoted by > the * at the end) > That would add a lot of overhead IMHO to library developers, since now you'd be required to specify who and where classes are allowed. That would demand tons of runtime checks, which is definitely a no-go since it may hurt performance a lot. Maybe it would make sense to introduce a protected modifier as well which > means, it is visible along the namespace tree - visible within the same > namespace as well as its sub-namespaces and parent namespaces (this would > fit with protected as access modifier of members). > However, this would be another RFC of course but we should consider such > ideas before deciding what private classes mean in PHP. > I thought a lot about protected class support too. But when drafting my original proposal, I started to ask myself how feasible it would be to support only declared and sub-namespaces. In reality, dependencies between sibling namespaces under same vendor name is not a breakage in modeling, so protected made zero sense to me. I decided to research around other language implementations but saw nothing that applied to top level classes. You can come up with a plan outside of my proposal (or as an enhancement of my proposal if accepted), but I would keep implementation as is for now until acceptance phase if none finds a problem on how I tackled this support. > > Cheers, > Robert > > -- Guilherme Blanco MSN: guilhermebla...@hotmail.com GTalk: guilhermeblanco Toronto - ON/Canada