Make class and struct members private by default / Type-Based access


(Ted van Gaalen) #1

Hello,

(this is related to: Type-based ‘private’ access within a file)

Currently class and struct items (variables, functions..) are public by default
that is, always accessible outside the class’s scope
for example: (Swift 3.1)

class AsItIsNow
{
    private var a = 10
    private var b = 12
    
    func aPlusB() -> Int
    {
       return a + b
    }

    private func helperFunction()
    {
       . . .
    }
}

Having all items public by default has the following disadvantages:

   • All members are exposed by default, wether intended or not. This
      could lead to class misusage unintended by the class’s creator.

   • To prevent undesired access of functions vars etc. inside a class
      one has to prefix often too many items with the ‘private’ access modifier keyword.
      Most of the functionality and items inside a class or struct are meant to
      be used internally and should not be revealed to the outside world.

   • It does not comply (contradicts) with lexical scope as in Swift functions etc.
  
   • It is frontally different to most other programming languages and
     therefore confusing for those coming from C#, C++, Java, Pascal etc.

I experience this as fundamentally wrong.

Imho it should be as in the next example, everything in a class
is private by default. To access/deploy items from outside they
need to be defined with the ‘public’ access modifier,
not the other way around, please.

class AsItShouldBeImho
{
   var a = 10 // private by default
    var b = 12 // also
    
    public func aPlusB() -> Int
    {
       return a + b
    }
    
    func privateFunction()
    {
       . . .
    }
}

‘public’ could be an inferred attribute
for items defined with getters and setters..
or the compiler would demand public
for getters and setters..

The ‘protected’ keyword is needed.
‘protected’ would mean that the items are
accessible in subclasses (class only)

private items would also be inaccessible in
class extensions.

It is as yet unclear to me why it has not been done
like so from the beginning of Swift…

I’ve been lost in the eternal discussions over private access modifiers,
the volume of it makes me think that (either way in this discussions) the whole
scope definition is wrong in Swift .
especially using a file as scope limiter.
Imho there should be lexical scope only.
as in most other programming languages.
If done so correctly , one wouldn’t even need the ‘private’ keyword...

Kind Regards
TedvG

www.tedvg.com <http://www.tedvg.com/>
www.ravelnotes.com


(Xiaodi Wu) #2

The default access level is internal by default, not public. While there
are good reasons to not make members public by default, it is important
that members are internal by default.

One important reason: progressive disclosure. Access modifiers make sense
after you understand what encapsulation is all about. Encapsulation only
really makes sense after you can actually write a type. If members are
private by default, you cannot write a useful type without also learning
access modifiers!

Put another way:

struct Point {
let x: Int
let y: Int
}

...is by itself a useful type. If x and y were private, then this type
would do nothing. Users would have to learn about access modifiers before
they can write a useful type.

···

On Mon, Apr 3, 2017 at 18:13 Ted F.A. van Gaalen via swift-evolution < swift-evolution@swift.org> wrote:

Hello,

(this is related to: Type-based ‘private’ access within a file)

Currently class and struct items (variables, functions..) are public by
default
that is, always accessible outside the class’s scope
for example: (Swift 3.1)

class AsItIsNow
{

    private var a = 10
    private var b = 12

    func aPlusB() -> Int
    {
       return a + b
    }

    private func helperFunction()
    {

       . . .
    }

}

Having all items public by default has the following disadvantages:

   • All members are exposed by default, wether intended or not. This
      could lead to class misusage unintended by the class’s creator.

   • To prevent undesired access of functions vars etc. inside a class
      one has to prefix often too many items with the ‘private’ access
modifier keyword.
      Most of the functionality and items inside a class or struct are
meant to
      be used internally and should not be revealed to the outside
world.

   • It does not comply (contradicts) with lexical scope as in Swift
functions etc.

   • It is frontally different to most other programming languages and
     therefore confusing for those coming from C#, C++, Java, Pascal etc.

I experience this as fundamentally wrong.

Imho it should be as in the next example, everything in a class
is private by default. To access/deploy items from outside they
need to be defined with the ‘public’ access modifier,
not the other way around, please.

class AsItShouldBeImho
{
   var a = 10 // private by default
    var b = 12 // also

    public func aPlusB() -> Int
    {
       return a + b
    }

    func privateFunction()
    {
       . . .
    }
}

‘public’ could be an inferred attribute
for items defined with getters and setters..
or the compiler would demand public
for getters and setters..

The ‘protected’ keyword is needed.
‘protected’ would mean that the items are
accessible in subclasses (class only)

private items would also be inaccessible in
class extensions.

It is as yet unclear to me why it has not been done
like so from the beginning of Swift…

I’ve been lost in the eternal discussions over private access modifiers,
the volume of it makes me think that (either way in this discussions) the
whole
scope definition is wrong in Swift .
especially using a file as scope limiter.
Imho there should be lexical scope only.
as in most other programming languages.
If done so correctly , one wouldn’t even need the ‘private’ keyword...

Kind Regards
TedvG

www.tedvg.com
www.ravelnotes.com

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


(Ted van Gaalen) #3

Hi Xiaodi,

that currently all members of a class or struct are exposed by default by having
a default scope of ‘internal’ and are therefore accessible in the entire module
is imho very bad unstructured programming practice.

In no other OOP language it is implemented
that way..

from this Swift blog:
https://developer.apple.com/swift/blog/?id=5 <https://developer.apple.com/swift/blog/?id=5>

i quote from this blog:

"By default, all entities have internal access.
This allows application developers to largely ignore access control,
and most Swift code already written will continue to work without change."

Whoever wrote this, imho it is bad: especially this part:
"This allows application developers to largely ignore access control”

To say the least, this not really a very well thought over sentence,
which appears to me something like:
“Hey yeah, it’s ok, just start coding like a blind horse,
don’t worry about the details now. Care about it later. ”

This is certainly not my idea of what is described as “Progressive Disclosure”
and encourages bad and unstructured programming. Students learn
undesirable habits which, as with any habit, are hard to get rid off and
can carry on throughout a large part of their career.

So, in this perspective, what is related to “Progressive Disclosure” should
be viewed with a grain of salt and due to the complexity of Swift its relevancy
is limited and should be approached with caution.

True, in Swift , one can write in a very simple way, but this apparent triviality is
deceiving... To make professional applications with Swift (or for that
matter in any other serious programming language ) one should only
start making real apps equipped with a thorough understanding of the overall
language structure, its philosophy and environment, rather sooner than later.

That ’s exactly where tutorials, courses, books, playgrounds etc. are meant for!
There is a lot of very good material available, so there is really no obstacle
to learn these fundamentals of the Swift language quite well before embarking
on creating professional Swift apps.

Of course, one cannot (should not) define anything at all without knowing
about scope, access modifiers! Luckily, compared to other aspects of PLs,
understanding scope of variables is almost trivial. Provided of course that
the scope mechanism is natural and orthogonal, unfortunately this is
not the case in Swift,.

Also in Swift there should be lexical scope only, I think, as in almost any other
procedural / OOP programming language. Swift is one of them.
This also eliminates the necessity of the keywords “private” and “fileprivate”
and makes the scope context easy to conceive , especially for
beginning programmers.

But it seems to be too late now to correct this deficiency (imho) in Swift I guess..

Concerning your *struct* example:
with correct lexical scope, it should then be written like this:

struct PointOfView
{
  public let x: Int // or any other applicable access modifier
         public let y: Int

        public func distanceToPoint( p: PointOfView) -> Double {. . .}
        
        let pr: Int // private by default, not available outside this struct.
        func Foo() { . . .} // private function
}

As written before, for a class, one can add
‘protected’ items like so:

     protected var foo:Double // available to descendants (subclasses)

Kind Regards from a sunny www.speyer.de
TedvG
www.tedvg.com

···

On 4. Apr 2017, at 01:44, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

The default access level is internal by default, not public. While there are good reasons to not make members public by default, it is important that members are internal by default.

One important reason: progressive disclosure. Access modifiers make sense after you understand what encapsulation is all about. Encapsulation only really makes sense after you can actually write a type. If members are private by default, you cannot write a useful type without also learning access modifiers!

Put another way:

struct Point {
let x: Int
let y: Int
}

...is by itself a useful type. If x and y were private, then this type would do nothing. Users would have to learn about access modifiers before they can write a useful type.
On Mon, Apr 3, 2017 at 18:13 Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

(this is related to: Type-based ‘private’ access within a file)

Currently class and struct items (variables, functions..) are public by default
that is, always accessible outside the class’s scope
for example: (Swift 3.1)

class AsItIsNow
{
    private var a = 10
    private var b = 12
    
    func aPlusB() -> Int
    {
       return a + b
    }

    private func helperFunction()
    {
       . . .
    }
}

Having all items public by default has the following disadvantages:

   • All members are exposed by default, wether intended or not. This
      could lead to class misusage unintended by the class’s creator.

   • To prevent undesired access of functions vars etc. inside a class
      one has to prefix often too many items with the ‘private’ access modifier keyword.
      Most of the functionality and items inside a class or struct are meant to
      be used internally and should not be revealed to the outside world.

   • It does not comply (contradicts) with lexical scope as in Swift functions etc.
  
   • It is frontally different to most other programming languages and
     therefore confusing for those coming from C#, C++, Java, Pascal etc.

I experience this as fundamentally wrong.

Imho it should be as in the next example, everything in a class
is private by default. To access/deploy items from outside they
need to be defined with the ‘public’ access modifier,
not the other way around, please.

class AsItShouldBeImho
{
   var a = 10 // private by default
    var b = 12 // also
    
    public func aPlusB() -> Int
    {
       return a + b
    }
    
    func privateFunction()
    {
       . . .
    }
}

‘public’ could be an inferred attribute
for items defined with getters and setters..
or the compiler would demand public
for getters and setters..

The ‘protected’ keyword is needed.
‘protected’ would mean that the items are
accessible in subclasses (class only)

private items would also be inaccessible in
class extensions.

It is as yet unclear to me why it has not been done
like so from the beginning of Swift…

I’ve been lost in the eternal discussions over private access modifiers,
the volume of it makes me think that (either way in this discussions) the whole
scope definition is wrong in Swift .
especially using a file as scope limiter.
Imho there should be lexical scope only.
as in most other programming languages.
If done so correctly , one wouldn’t even need the ‘private’ keyword...

Kind Regards
TedvG

www.tedvg.com <http://www.tedvg.com/>
www.ravelnotes.com <http://www.ravelnotes.com/>

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


(David Waite) #4

I think you may be forgetting Java (and Ruby, and Python, and Go, and Objective-C, and…)

In my experience , the hard-private-by-default comes from C++ and heavily influenced languages like C# and Rust.

-DW

···

On Apr 4, 2017, at 7:07 AM, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:

Hi Xiaodi,

that currently all members of a class or struct are exposed by default by having
a default scope of ‘internal’ and are therefore accessible in the entire module
is imho very bad unstructured programming practice.

In no other OOP language it is implemented
that way..


(Ted van Gaalen) #5

Hi David

jikes! You’re right, total blunder. I should do my homework better :o)
I have been using Java before, be it with the assumption that it had private scope
for class members, because of the line of PLs I was using before I started using Java
I went on programming assuming that it had, which never led to scope conflicts because
of programming consequently within this assumption, so, I never noticed this. :o)

This is because in most PLs in my history Fortran -> Cobol-> PL/1 -> Pascal -> Modula ->
C -> C++ consistent lexical scope is present (since ca. 1960 with Algol)
After that C# (nice language too, which has it) and ObjC (which hasn’t) and Smalltalk for many years
which has (needs) no scope modifiers at all (in a class all methods are not private
but variables are.)

Sorry for the incorrect assumptions.
Nevertheless I hold on to my point of view that there should be lexical scope only in Swift,
(as Swift being a procedural/OOP language)
however rigidly enforcing this in Swift 4 would be probably too much of a change now.

I do not understand what is so hard on private-by-default? (that is, if used
this way right from the beginning of writing an application,
(provided a program language is set up that way)

TedvG
www.tedvg.com

···

On 4. Apr 2017, at 22:17, David Waite <david@alkaline-solutions.com> wrote:

On Apr 4, 2017, at 7:07 AM, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi Xiaodi,

that currently all members of a class or struct are exposed by default by having
a default scope of ‘internal’ and are therefore accessible in the entire module
is imho very bad unstructured programming practice.

In no other OOP language it is implemented
that way..

I think you may be forgetting Java (and Ruby, and Python, and Go, and Objective-C, and…)

In my experience , the hard-private-by-default comes from C++ and heavily influenced languages like C# and Rust.

-DW