private & fileprivate


(Ted van Gaalen) #1

Please do NOT drop the current distinction between *private* and *fileprivate*
as it is now in Swift 3
It is needed for correct OOP.

As written before, but now a bit more compact, I hope:

I would like to have the inner members of a class as default private,
(not fileprivate) that is, that each entity inside the class body is not visible
in the outer scope. not even in the same file!

I would only reveal entities of a class to the outer scope that are needed.there.
(as is the case with class properties in Objective-C and most other OOP supporting languages)

This is what I have to do now,
Each and every entity that I wish to keep hidden
I have to prefix with *private*: like in this example class:
This is tedious and should be unnecessary.

class TG3DGauge: SCNNode
{
    
    private var needles = [SCNNode]()
    private var fmtStr = “" // private should be the default!
    
    var value: CGFloat = 0 // access default “internal”! Visible to the outside world.
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }
    
    private var nodeUnitText = SCNNode()
    private var nodeValueText = SCNNode()
    
    private var valRange: ClosedRange<CGFloat> = (0...100.0)
    private var valScaleFactor: CGFloat = 1

  // etc. much more stuff here and
        // most of it should be private, that is
        // only visible within the class body!
  .
        .
} // end class TG3DGauge

If I don’t specify an access modifier, then the default
for the items defined in classes is *internal*,
which means that these items are visible in the whole application source.

However, this is only desirable for items that I want to
reveal explicitly, of course.
That is exactly why I need the *private* access modifier as it is now
and not *fileprivate*
So I am very glad that this access modifier *private* finally became
available in Swift 3

In my classes, *private* is probably the most used keyword, but
*private* should be the default for entities within a class body
just like it is for entities within functions.

As far as I know, prefixing with *private* is the only solution in Swift to protect
functions, vars etc. in my class against unwanted access
from the outer scope. I think this is not the way it should be.

Making all entities in a class private prevents this.
and offers also reasonable protection against
the Fragile Base Class problem, (thanks Chris for url) :
https://en.wikipedia.org/wiki/Fragile_base_class

A solution for as it is now, albeit not a perfect one would be,
to have some sort of access modifier which defines
all items within the class to be private by default.
perhaps the keyword *closedscope* like in this example:

closedscope class TG3DGauge: SCNNode
{
    
    var needles = [SCNNode]() // is now private by default
    var fmtStr = “" // is now private by default

    public var value: CGFloat = 0 // Public!! visible outside class
                               // “fileprivate" or “internal” can also be used.
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }
    
    var nodeUnitText = SCNNode() // is now private by default
    var nodeValueText = SCNNode() // is now private by default

    //etc.

Again, for this reasons, don’t drop the distinction between
between *fileprivate* and *private*
if this is done, there is afaics no way to protect items within a class body.
Leave it as it is now, please. (also to prevent source breaking as well)

(btw, the above TG3DGauge class is a perfect example:
With real gauges it would not be a good idea if one can touch
the needles and gears inside the gauge’s casing,
which is exactly the case with OOP. e.g.
In my class example people would e.g. be able to set the angle
from needles (if not declared private) directly, without updating the value.)

TedvG
www.tedvg.com <http://www.tedvg.com/> (see my gauges from above class here)

···

Le 13 oct. 2016 à 07:52, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

On Oct 12, 2016, at 9:56 PM, Russ Bishop via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

I actually consider it very lucky that most of our changes so far have been fairly non-controversial. Everybody has a different idea of what would make Swift a better language, and all of us well-meaning. But when those ideas conflict, some group is going to end up unhappy. I'm actually very glad that (a) we haven't had too many of these cases, and (b) even when we have, people have been able to accept it and move on to contributing to the next issue.

Strong agreement here as well. This proposal has been litigated numerous times already, and the bar for source-breaking changes is much higher now. To effectively re-open the discussion would require a proposal that significant changes the model with a lot of evidence that such a new model is a drastic improvement over what we have now. “Back out SE-0025” is not a viable option now.

  - Doug

Not really. This proposal could be backed out without source-breaking changes by treating private as a synonym for fileprivate and we’d have Swift 2 behavior without breaking source. If the core team doesn’t want to consider that then we can just move on and live with it.

Not speaking for the core team, just MHO:

I agree with Russ here, and with others who have said upthread that the “thing that has changed” is that we are starting to get usage experience with fileprivate vs private. I think we all understand the value of having fewer access control levels, and so if “private” isn’t conceptually pulling its weight, then it is reasonable to consider phasing it out.

That said, there is no specific rush to have this discussion, and I think it is reasonable to put a pretty high burden of proof on someone who wants to drive such a proposal. For example, if we had the discussion in the spring timeframe, we should have a pretty large body of Swift 3 code readily at hand (e.g. SwiftPM packages and other various github repos).

Given that, it should be easy enough to see how widely private is actually being used in practice. If it is very rare, then the argument to ditch it (make it a synonym for fileprivate, and eventually phasing out fileprivate) is strong. If lots of people are using private and only some are using fileprivate, then the discussion is quite different.

-Chris

I don’t think monitoring the usage of private vs fileprivate is fair. By default, people will use private until they encounter visibility issues and discover they need to change to fileprivate. So private will probably being use far more than fileprivate.
Nonetheless it does not mean people chosen private because it effectively reduce the visibility to the class scope, but just because it is easier to discover and to type than fileprivate and fit in many cases.

I tend to write class will all ivars private by default (as it is a sensible default), and then, when I start to write extensions and other parts, I have to switch to fileprivate for a bunch of ivars. It create an inconsistent mess in my ivars declaration as it is difficult to know if an ivar is private because I has to be, or because I didn’t encounter a case that need it to be fileprivate instead.

Honestly, I don’t see any value in the introduction of fileprivate.


(Trans) #2

Sorry, but that is laughable. So far I haven't seen a sole on here
that seems to really know anything about OOP. You all are just copying
and extrapolating on ObjC/C++/Java. Which got it all sorts of wrong
from the get go.

Go learn you some SmallTalk for the greater good.

···

On Thu, Oct 13, 2016 at 5:27 PM, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:

Please do NOT drop the current distinction between *private* and
*fileprivate*
as it is now in Swift 3
It is needed for correct OOP.


(Trans) #3

Sorry, that was a little harsh. I just think there are a lot of
opinions here based on personal biases and not necessary the best
prior experiences. If you want good OOP it is best to let people with
*real* OOP experience, like SmallTalk, work it out.


(Jamie Lemon) #4

I agree with Ted that I would have expected the inner members of a class to be private by default. (Not a big deal if I have to explicitly prefix most of my concerned vars now - but it is just different to what I would have expected). Certainly, in the past, I would be more used to having to explicitly define chosen vars as “public” ( e.g. in the past world of Objective C I was used to defining selected vars with @synthesize to “open them up" )

···

On 13 Oct 2016, at 22:27, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

Please do NOT drop the current distinction between *private* and *fileprivate*
as it is now in Swift 3
It is needed for correct OOP.

As written before, but now a bit more compact, I hope:

I would like to have the inner members of a class as default private,
(not fileprivate) that is, that each entity inside the class body is not visible
in the outer scope. not even in the same file!

I would only reveal entities of a class to the outer scope that are needed.there.
(as is the case with class properties in Objective-C and most other OOP supporting languages)

This is what I have to do now,
Each and every entity that I wish to keep hidden
I have to prefix with *private*: like in this example class:
This is tedious and should be unnecessary.

class TG3DGauge: SCNNode
{

    private var needles = [SCNNode]()
    private var fmtStr = “" // private should be the default!

    var value: CGFloat = 0 // access default “internal”! Visible to the outside world.
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }

    private var nodeUnitText = SCNNode()
    private var nodeValueText = SCNNode()

    private var valRange: ClosedRange<CGFloat> = (0...100.0)
    private var valScaleFactor: CGFloat = 1

// etc. much more stuff here and
        // most of it should be private, that is
        // only visible within the class body!
.
        .
} // end class TG3DGauge

If I don’t specify an access modifier, then the default
for the items defined in classes is *internal*,
which means that these items are visible in the whole application source.

However, this is only desirable for items that I want to
reveal explicitly, of course.
That is exactly why I need the *private* access modifier as it is now
and not *fileprivate*
So I am very glad that this access modifier *private* finally became
available in Swift 3

In my classes, *private* is probably the most used keyword, but
*private* should be the default for entities within a class body
just like it is for entities within functions.

As far as I know, prefixing with *private* is the only solution in Swift to protect
functions, vars etc. in my class against unwanted access
from the outer scope. I think this is not the way it should be.

Making all entities in a class private prevents this.
and offers also reasonable protection against
the Fragile Base Class problem, (thanks Chris for url) :
https://en.wikipedia.org/wiki/Fragile_base_class

A solution for as it is now, albeit not a perfect one would be,
to have some sort of access modifier which defines
all items within the class to be private by default.
perhaps the keyword *closedscope* like in this example:

closedscope class TG3DGauge: SCNNode
{

    var needles = [SCNNode]() // is now private by default
    var fmtStr = “" // is now private by default

    public var value: CGFloat = 0 // Public!! visible outside class
                               // “fileprivate" or “internal” can also be used.
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }

    var nodeUnitText = SCNNode() // is now private by default
    var nodeValueText = SCNNode() // is now private by default

    //etc.

Again, for this reasons, don’t drop the distinction between
between *fileprivate* and *private*
if this is done, there is afaics no way to protect items within a class body.
Leave it as it is now, please. (also to prevent source breaking as well)

(btw, the above TG3DGauge class is a perfect example:
With real gauges it would not be a good idea if one can touch
the needles and gears inside the gauge’s casing,
which is exactly the case with OOP. e.g.
In my class example people would e.g. be able to set the angle
from needles (if not declared private) directly, without updating the value.)

TedvG
www.tedvg.com<http://www.tedvg.com/> (see my gauges from above class here)

Le 13 oct. 2016 à 07:52, Chris Lattner via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> a écrit :

On Oct 12, 2016, at 9:56 PM, Russ Bishop via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org>> wrote:
I actually consider it very lucky that most of our changes so far have been fairly non-controversial. Everybody has a different idea of what would make Swift a better language, and all of us well-meaning. But when those ideas conflict, some group is going to end up unhappy. I'm actually very glad that (a) we haven't had too many of these cases, and (b) even when we have, people have been able to accept it and move on to contributing to the next issue.

Strong agreement here as well. This proposal has been litigated numerous times already, and the bar for source-breaking changes is much higher now. To effectively re-open the discussion would require a proposal that significant changes the model with a lot of evidence that such a new model is a drastic improvement over what we have now. “Back out SE-0025” is not a viable option now.

- Doug

Not really. This proposal could be backed out without source-breaking changes by treating private as a synonym for fileprivate and we’d have Swift 2 behavior without breaking source. If the core team doesn’t want to consider that then we can just move on and live with it.

Not speaking for the core team, just MHO:

I agree with Russ here, and with others who have said upthread that the “thing that has changed” is that we are starting to get usage experience with fileprivate vs private. I think we all understand the value of having fewer access control levels, and so if “private” isn’t conceptually pulling its weight, then it is reasonable to consider phasing it out.

That said, there is no specific rush to have this discussion, and I think it is reasonable to put a pretty high burden of proof on someone who wants to drive such a proposal. For example, if we had the discussion in the spring timeframe, we should have a pretty large body of Swift 3 code readily at hand (e.g. SwiftPM packages and other various github repos).

Given that, it should be easy enough to see how widely private is actually being used in practice. If it is very rare, then the argument to ditch it (make it a synonym for fileprivate, and eventually phasing out fileprivate) is strong. If lots of people are using private and only some are using fileprivate, then the discussion is quite different.

-Chris

I don’t think monitoring the usage of private vs fileprivate is fair. By default, people will use private until they encounter visibility issues and discover they need to change to fileprivate. So private will probably being use far more than fileprivate.
Nonetheless it does not mean people chosen private because it effectively reduce the visibility to the class scope, but just because it is easier to discover and to type than fileprivate and fit in many cases.

I tend to write class will all ivars private by default (as it is a sensible default), and then, when I start to write extensions and other parts, I have to switch to fileprivate for a bunch of ivars. It create an inconsistent mess in my ivars declaration as it is difficult to know if an ivar is private because I has to be, or because I didn’t encounter a case that need it to be fileprivate instead.

Honestly, I don’t see any value in the introduction of fileprivate.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Goffredo Marocchi) #5

Well, this is some good attitude ;).

···

Sent from my iPhone

On 14 Oct 2016, at 00:50, Trans via swift-evolution <swift-evolution@swift.org> wrote:

On Thu, Oct 13, 2016 at 5:27 PM, Ted F.A. van Gaalen via > swift-evolution <swift-evolution@swift.org> wrote:

Please do NOT drop the current distinction between *private* and
*fileprivate*
as it is now in Swift 3
It is needed for correct OOP.

Sorry, but that is laughable. So far I haven't seen a sole on here
that seems to really know anything about OOP. You all are just copying
and extrapolating on ObjC/C++/Java. Which got it all sorts of wrong
from the get go.

Go learn you some SmallTalk for the greater good.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ted van Gaalen) #6

Most disturbing,
What are you trying to achieve?

Well, I can be a little harsh at times too, perhaps at times
when I do not fully understand or misinterpret situations or people.
in that case I will admit my shortcoming and apologise if necessary.

However, you are being very negative, rude and insulting,
Btw, I also work with Smalltalk and assure that you are
completely out of touch with the Smalltalk community
which is very friendly and social and so is the Swift community.

I see no need to further converse with you.

TedvG

···

On 14 Oct 2016, at 02:14, Trans <transfire@gmail.com> wrote:

Sorry, that was a little harsh. I just think there are a lot of
opinions here based on personal biases and not necessary the best
prior experiences. If you want good OOP it is best to let people with
*real* OOP experience, like SmallTalk, work it out.


(Jean-Daniel) #7

That argument don’t apply for a language where you can structure your code in extensions as in Swift.

···

Le 13 oct. 2016 à 23:27, Ted F.A. van Gaalen <tedvgiosdev@gmail.com> a écrit :

Please do NOT drop the current distinction between *private* and *fileprivate*
as it is now in Swift 3
It is needed for correct OOP.


(Jeremy Pereira) #8

I agree with Ted that I would have expected the inner members of a class to be private by default. (Not a big deal if I have to explicitly prefix most of my concerned vars now - but it is just different to what I would have expected). Certainly, in the past, I would be more used to having to explicitly define chosen vars as “public” ( e.g. in the past world of Objective C I was used to defining selected vars with @synthesize to “open them up" )

@synthesize has nothing to do with instance variable visibility, all it did was synthesise an instance variable to back a property (which was really a pair of methods). In Objective-C instance variables are protected (i.e. visible to subclasses) by default and all methods (which by extension means properties too) are public.

The waters are somewhat muddied by the fact that the Objective-C compiler can only see declarations in the current code unit and any imports, so you can hide non private instance variables by putting them in the @implementation and you can hide properties and methods by declaring them in a category that isn’t in an import. However, anybody can defeat the second of these by declaring their own category with the hidden method signatures in it.

private by default is comparatively rare, it’s not true of Java, C#, Javascript, or Python. Having said, that it does make sense to me but would be an enormous breaking change for Swift now.

I was against the private/fileprivate distinction when it was proposed, but now it’s done and I’ve applied it to my own code, I am fine with it. I did a global replace of fileprivate with private in one of my largest converted source files and experienced only one breakage. I think there is a use case for fileprivate, so I wouldn’t want to get rid of it but I think it’s rare enough that the ugliness of its name doesn’t bother me.

···

On 14 Oct 2016, at 09:35, Jamie Lemon via swift-evolution <swift-evolution@swift.org> wrote:

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Goffredo Marocchi) #9

We will see how this will fare one way or the other in say 10-15 years.

···

Sent from my iPhone

On 15 Oct 2016, at 14:43, Jean-Daniel via swift-evolution <swift-evolution@swift.org> wrote:

Le 13 oct. 2016 à 23:27, Ted F.A. van Gaalen <tedvgiosdev@gmail.com> a écrit :

Please do NOT drop the current distinction between *private* and *fileprivate*
as it is now in Swift 3
It is needed for correct OOP.

That argument don’t apply for a language where you can structure your code in extensions as in Swift.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ted van Gaalen) #10

in 10-15 years compilers/interpreters are merged and update themselves as AI.
so we can tell in human language what an app should do :o)

@Jean: can you explain that about extensions in this context (oop) ?

TedvG

ted van gaalen

···

On 15 Oct 2016, at 21:44, Goffredo Marocchi <panajev@gmail.com> wrote:

We will see how this will fare one way or the other in say 10-15 years.

Sent from my iPhone

On 15 Oct 2016, at 14:43, Jean-Daniel via swift-evolution <swift-evolution@swift.org> wrote:

Le 13 oct. 2016 à 23:27, Ted F.A. van Gaalen <tedvgiosdev@gmail.com> a écrit :

Please do NOT drop the current distinction between *private* and *fileprivate*
as it is now in Swift 3
It is needed for correct OOP.

That argument don’t apply for a language where you can structure your code in extensions as in Swift.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution