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

Reply via email to