class/struct inner member access scope classifier


(Ted van Gaalen) #1

Hello! Hope you are all OK!

Using and converting To Swift 3.0 with many advantages
and very little problems.OK, thanks to all !
also for the reasonably smart converter. Yes, yes, yes, I’m
still missing the classical for ;; loop (don’t wake me up
again plse :o) but overall it is quite good!

I also value the -finally correct- meaning of the scope qualifier “private” , thanks,
which is as it should be (imho) inner scope restricting.

As for “fileprivate”: as yet, I haven’t found a case
where I should use “fileprivate” also because to me, the contents of
a file should in principle not have anything to do with the entities
contained in it, as a file should be just an data carrier. Therefore,
it should have no effect to wether or not concatenate source.swift files
into one big file for example, although I would not recommend this.

As far as I can see without binoculars, the “fileprivate” acces modifier
could be dropped, were it not for source compatibility reasons...
  
Unless I am missing something:
Still. something is not quite right yet, I think.
Just like in a Swift function, I don’t want the inner elements
of a class (or struct ?) to be visible in outer scope!
This is the default case in most OOP languages.
I fail to understand why this is not so in Swift, please enlighten me.

As it is now, and as far as I know, I have to explicitly
declare *all* entities inside a class that should not be accessible
outside the class as private, like in this real-world example:

class TG3DGauge: SCNNode
{
    
    private var needles = [SCNNode]()
    private var fmtStr = “" // private should be the default imho.
    
    var value: CGFloat = 0
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }
    
    private var nodeUnitText = SCNNode()
    private var nodeValueText = SCNNode()
    
    private var valRange: ClosedRange<CGFloat> = (0...100.0)
    
    var rangeNeedlesActive: Bool = true
    {
        didSet
        {
            needles[2].isHidden = !rangeNeedlesActive
            needles[3].isHidden = !rangeNeedlesActive
        }
    }
    
    private var valScaleFactor: CGFloat = 1

  // etc. more stuff
  .
        .
} // end class TG3DGauge

It should (imho) be the other way around: that every member of
a class is private by default - that is invisible outside the scope
were it is declared in. This was (and still is) the case with Objective C,
where you need to explicitly declaring them in the sourcefile.h file
to make them visible and accessible in the outer scope
Everything else, as existing in the sourcefile.m remains hidden, not visible
in the outer scope.

As a solution/suggestion and also to prevent the gruesome
horror (did i already wrote something about that? :o) of source breaking.
I could think of the “closedscope” (or some other word)
access modifier, which states that all things declared inside a class,
are private within the class and thus invisible in the outer scope, unless
preceeded with an overriding acces scope modifier like “public", “internal" or "fileprivate”

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 also for “fileprivate" or “internal”
    {
        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.

This “closedscope" modifier should only be effective for the current class, not its superclass(es),
allowing one to hide/reveal entities in each class independently being part of the hierarchy.
Also entities declared private should not be visible in descendant classes

Also please note that I do miss the “protected” scope access modifier which allows entities to be exclusively
visible to descendant classes, as in Java. Why not implement it in Swift as well?

AFAICS: All mentioned here would not be a source breaking.

Opinions, remarks welcome.

met vriendelijke groeten
Ted


#2

Just to weigh in here, I too am enjoying Swift 3 greatly.

However, my experience with access modifiers is rather different. I am very
glad that `internal` is the default: this reduces extraneous noise for the
common case, and makes it really easy for new programmers to jump in.

Furthermore, I am beginning to think that changing the meaning of `private`
and introducing `fileprivate` may not have been worth the complexity. Even
with file-scope visibility, one must still use the full path to a member in
order to use it: eg. MyClass.InnerStruct.specialFunction(), so the risk of
collisions is minuscule.

Before the change, the only visibility scopes to consider were file,
module, and everywhere. Now there can be nested private scopes, which may
be “unutterable” in the sense that there is no way to declare a member in
one scope with the same visibility as a private member of an outer scope.

When using the pattern whereby a type is built with many extensions in a
single file, shared helper members must now be declared `fileprivate`
whereas before they were simply `private`. I readily acknowledge that this
is a *small* annoyance, but it is nevertheless that much extra typing and
and that much extra noise.

I don’t expect that reverting such a major change would be worth the
upheaval, especially since many people seem to like it, but I think there
is value in the simpler model that we used to have.

In any event, I *do* think it would be worth renaming “fileprivate” to
something shorter, if a suitable word can be found. I remember how much
bikeshedding went on the first time around, including several people trying
to find a better term than “fileprivate” without any luck, so it may well
turn out that there just isn’t a suitable replacement.

If there is one though, count me on the side in favor of shortening
“fileprivate”.

Nevin

···

On Mon, Sep 26, 2016 at 3:58 PM, Ted F.A. van Gaalen via swift-evolution < swift-evolution@swift.org> wrote:

Hello! Hope you are all OK!

Using and converting To Swift 3.0 with many advantages
and very little problems.OK, thanks to all !
also for the reasonably smart converter. Yes, yes, yes, I’m
still missing the classical for ;; loop (don’t wake me up
again plse :o) but overall it is quite good!

I also value the -finally correct- meaning of the scope
qualifier “private” , thanks,
which is as it should be (imho) inner scope restricting.

As for “fileprivate”: as yet, I haven’t found a case
where I should use “fileprivate” also because to me, the contents of
a file should in principle not have anything to do with the entities
contained in it, as a file should be just an data carrier. Therefore,
it should have no effect to wether or not concatenate source.swift files
into one big file for example, although I would not recommend this.

As far as I can see without binoculars, the “fileprivate” acces modifier
could be dropped, were it not for source compatibility reasons...

Unless I am missing something:
Still. something is not quite right yet, I think.
Just like in a Swift function, I don’t want the inner elements
of a class (or struct ?) to be visible in outer scope!
This is the default case in most OOP languages.
I fail to understand why this is not so in Swift, please enlighten me.

As it is now, and as far as I know, I have to explicitly
declare *all* entities inside a class that should not be accessible
outside the class as private, like in this real-world example:

class TG3DGauge: SCNNode
{

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

    var value: CGFloat = 0
    {
        didSet // trigger value change, rotate needles etc.
        {
            valueChange()
        }
    }

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

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

    var rangeNeedlesActive: Bool = true
    {
        didSet
        {
            needles[2].isHidden = !rangeNeedlesActive
            needles[3].isHidden = !rangeNeedlesActive
        }
    }

    private var valScaleFactor: CGFloat = 1

// etc. more stuff
.
        .
} // end class TG3DGauge

It should (imho) be the other way around: that every member of
a class is private by default - that is invisible outside the scope
were it is declared in. This was (and still is) the case with Objective C,
where you need to explicitly declaring them in the sourcefile.h file
to make them visible and accessible in the outer scope
Everything else, as existing in the sourcefile.m remains hidden, not
visible
in the outer scope.

As a solution/suggestion and also to prevent the gruesome
horror (did i already wrote something about that? :o) of source breaking.
I could think of the “closedscope” (or some other word)
access modifier, which states that all things declared inside a class,
are private within the class and thus invisible in the outer scope, unless
preceeded with an overriding acces scope modifier
like “public", “internal" or "fileprivate”

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 also
for “fileprivate" or “internal”
    {
        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.

This “closedscope" modifier should only be effective for the current
class, not its superclass(es),
allowing one to hide/reveal entities in each class independently being
part of the hierarchy.
Also entities declared private should not be visible in descendant classes

Also please note that I do miss the “protected” scope access modifier
which allows entities to be exclusively
visible to descendant classes, as in Java. Why not implement it in Swift
as well?

AFAICS: All mentioned here would not be a source breaking.

Opinions, remarks welcome.

met vriendelijke groeten
Ted

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


(Jeremy Pereira) #3

Hello! Hope you are all OK!

As far as I can see without binoculars, the “fileprivate” acces modifier
could be dropped, were it not for source compatibility reasons...
  
Unless I am missing something:

Yes you are missing something. I, for example have a few cases where it is useful. On the other hand, I was against the change in the meaning of private but, I have to concede that the new meaning is useful.

As for dropping file private, why? You don’t have to use it if you don’t want to, so it’s not hurting you. On the other hand, I can use it when I deem it to be the right thing to do.

I don’t want the inner elements
of a class (or struct ?) to be visible in outer scope!
This is the default case in most OOP languages.

The default in Java is package scope. I’m not sure what the default in C++ is, but it’s not private, ditto Javascript. So while that might not be most OOP languages, it probably covers most OOP programs.

While I think private by default has merit, we are where we are.

···

On 26 Sep 2016, at 20:58, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:


(Zachary Waldowski) #4

I'll politely disagree and point out you *must* use fileprivate in order
to get what it provides. It's unavoidable in that sense.

As the access control change has been implemented for what only can be
described in a number of weeks, it's disappointing that a feature I used
to great effect in prior versions of Swift has already been relegated to
"if you don't like the name, don't use it."

Sincerely,
Zachary Waldowski
zach@waldowski.me

···

On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution wrote:

As for dropping file private, why? You don’t have to use it if you don’t
want to, so it’s not hurting you. On the other hand, I can use it when I
deem it to be the right thing to do.


(Shawn Erickson) #5

If coming from that perspective if has only changed name to fileprivate
from private and you can then ignore private if you don't find it useful.
If anything it more clearly states in common language your intent then the
old naming (especial compared to other languages).

···

On Tue, Sep 27, 2016 at 6:20 AM Zach Waldowski via swift-evolution < swift-evolution@swift.org> wrote:

On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution > wrote:
> As for dropping file private, why? You don’t have to use it if you don’t
> want to, so it’s not hurting you. On the other hand, I can use it when I
> deem it to be the right thing to do.

I'll politely disagree and point out you *must* use fileprivate in order
to get what it provides. It's unavoidable in that sense.

As the access control change has been implemented for what only can be
described in a number of weeks, it's disappointing that a feature I used
to great effect in prior versions of Swift has already been relegated to
"if you don't like the name, don't use it."

Sincerely,
  Zachary Waldowski
  zach@waldowski.me
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jeremy Pereira) #6

That’s not the point I was making. It was mooted that fileprivate should be dropped altogether leading to not having any means of specifying file scope at all. I was simply pointing out that people who don’t like file scope already have the option of not using fileprivate.

···

On 27 Sep 2016, at 14:20, Zach Waldowski via swift-evolution <swift-evolution@swift.org> wrote:

On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution > wrote:

As for dropping file private, why? You don’t have to use it if you don’t
want to, so it’s not hurting you. On the other hand, I can use it when I
deem it to be the right thing to do.

I'll politely disagree and point out you *must* use fileprivate in order
to get what it provides. It's unavoidable in that sense.


(Ted van Gaalen) #7

Hi Jeremy and Nevin

Sorry for the delay. quite busy.

As described, the point of my message is that I would like to have the inner members of a class
as default private, that is, not visible in the outer scope and to reveal members (entities)
of the class to the outside world *explicitly* by specifying an access qualifier like
“public” or “internal”, so exactly the other way round as it is now.
In the current situation I have to precede all declarations which I don’t want to reveal
with “private”. Usually most entities of a class should not be visible outside of it.
To prevent source breaking one could precede the class definition with a keyword, telling
Swift that all members of a class are private by default like so

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 also for “fileprivate" or “internal”

(as written before)

If this “closedscope” qualifier is not used things are exactly as it is now.

The “fileprivate” qualifier doen’t need to go so no source breaking here.
I simply stated that I am not really a fan of it.

Kind Regards
Ted

···

On 27 Sep 2016, at 10:34, Jeremy Pereira <jeremy.j.pereira@googlemail.com> wrote:

On 26 Sep 2016, at 20:58, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:

Hello! Hope you are all OK!

As far as I can see without binoculars, the “fileprivate” acces modifier
could be dropped, were it not for source compatibility reasons...

Unless I am missing something:

Yes you are missing something. I, for example have a few cases where it is useful. On the other hand, I was against the change in the meaning of private but, I have to concede that the new meaning is useful.

As for dropping file private, why? You don’t have to use it if you don’t want to, so it’s not hurting you. On the other hand, I can use it when I deem it to be the right thing to do.

I don’t want the inner elements
of a class (or struct ?) to be visible in outer scope!
This is the default case in most OOP languages.

The default in Java is package scope. I’m not sure what the default in C++ is, but it’s not private, ditto Javascript. So while that might not be most OOP languages, it probably covers most OOP programs.

While I think private by default has merit, we are where we are.


(Sean Heber) #8

This was all already argued about *extensively*. As in.. for weeks and weeks.

For the record, I still think things are mis-named, but that ship has sailed. IMO the existing “fileprivate” should have been “internal” and existing “internal” should have been “external”. But oh well.

l8r
Sean

···

On Sep 27, 2016, at 1:40 PM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:

In another thread (no link because we’re not on a forum :wink: the idea was raised that in the future, if and when Swift starts using submodules, the “fileprivate” scope could be turned into “submodule” scope.

By default every file would constitute its own submodule, and developers could choose to put several files together into a submodule if they wish.

Perhaps there may be a shorter word that nicely implies “submodule scope”.

Nevin

On Tue, Sep 27, 2016 at 12:20 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org> wrote:

> On 27 Sep 2016, at 14:20, Zach Waldowski via swift-evolution <swift-evolution@swift.org> wrote:
>
>
>
>
> On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution > > wrote:
>> As for dropping file private, why? You don’t have to use it if you don’t
>> want to, so it’s not hurting you. On the other hand, I can use it when I
>> deem it to be the right thing to do.
>
> I'll politely disagree and point out you *must* use fileprivate in order
> to get what it provides. It's unavoidable in that sense.

That’s not the point I was making. It was mooted that fileprivate should be dropped altogether leading to not having any means of specifying file scope at all. I was simply pointing out that people who don’t like file scope already have the option of not using fileprivate.

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

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


#9

In another thread (no link because we’re not on a forum :wink: the idea was
raised that in the future, if and when Swift starts using submodules, the
“fileprivate” scope could be turned into “submodule” scope.

By default every file would constitute its own submodule, and developers
could choose to put several files together into a submodule if they wish.

Perhaps there may be a shorter word that nicely implies “submodule scope”.

Nevin

···

On Tue, Sep 27, 2016 at 12:20 PM, Jeremy Pereira via swift-evolution < swift-evolution@swift.org> wrote:

> On 27 Sep 2016, at 14:20, Zach Waldowski via swift-evolution < > swift-evolution@swift.org> wrote:
>
>
>
>
> On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution > > wrote:
>> As for dropping file private, why? You don’t have to use it if you don’t
>> want to, so it’s not hurting you. On the other hand, I can use it when I
>> deem it to be the right thing to do.
>
> I'll politely disagree and point out you *must* use fileprivate in order
> to get what it provides. It's unavoidable in that sense.

That’s not the point I was making. It was mooted that fileprivate should
be dropped altogether leading to not having any means of specifying file
scope at all. I was simply pointing out that people who don’t like file
scope already have the option of not using fileprivate.

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


(Jay) #10

If a submodule doesn't provide self contained functionality then it
shouldn't be a submodule, and if it does then it might as well be a
separate module. I think submodules would discourage small granular module
development and composition at a larger scale, it would discourage making a
clean public interface for the module which might make them more reusable
and testable. Also of course it would mean more keywords/syntax/classifiers
to manage it which makes things more complicated (unnecessarily in my view).

But I haven't really thought much about potential advantages... what are
they?

···

On Tue, 27 Sep 2016 at 19:55 Sean Heber via swift-evolution < swift-evolution@swift.org> wrote:

This was all already argued about *extensively*. As in.. for weeks and
weeks.

For the record, I still think things are mis-named, but that ship has
sailed. IMO the existing “fileprivate” should have been “internal” and
existing “internal” should have been “external”. But oh well.

l8r
Sean

> On Sep 27, 2016, at 1:40 PM, Nevin Brackett-Rozinsky via swift-evolution > <swift-evolution@swift.org> wrote:
>
> In another thread (no link because we’re not on a forum :wink: the idea was
raised that in the future, if and when Swift starts using submodules, the
“fileprivate” scope could be turned into “submodule” scope.
>
> By default every file would constitute its own submodule, and developers
could choose to put several files together into a submodule if they wish.
>
> Perhaps there may be a shorter word that nicely implies “submodule
scope”.
>
> Nevin
>
>
>
> On Tue, Sep 27, 2016 at 12:20 PM, Jeremy Pereira via swift-evolution < > swift-evolution@swift.org> wrote:
>
> > On 27 Sep 2016, at 14:20, Zach Waldowski via swift-evolution < > swift-evolution@swift.org> wrote:
> >
> >
> >
> >
> > On Tue, Sep 27, 2016, at 01:34 AM, Jeremy Pereira via swift-evolution > > > wrote:
> >> As for dropping file private, why? You don’t have to use it if you
don’t
> >> want to, so it’s not hurting you. On the other hand, I can use it
when I
> >> deem it to be the right thing to do.
> >
> > I'll politely disagree and point out you *must* use fileprivate in
order
> > to get what it provides. It's unavoidable in that sense.
>
> That’s not the point I was making. It was mooted that fileprivate should
be dropped altogether leading to not having any means of specifying file
scope at all. I was simply pointing out that people who don’t like file
scope already have the option of not using fileprivate.
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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