Private symbol (in)visibility within a module
NotYouAgain
NotYouAgain at gmail.com
Sun May 5 07:22:32 UTC 2024
Specifying more than one function with the same name in the same
scope is known as overloaded functions.
Overloaded functions enable you to supply different semantics for
a function, depending on the types and number of its arguments.
In C++, C#, Java, Swift...and others, senseless name clashes do
not occur between private and public symbols.
Only with D does the nature of a private symbol take on an
**inconsistent** meaning.
Examples below (for comparison), include: C#, Java, Swift, C++
and D.
================ C# ====================
static int Main()
{
Foo f = new Foo();
Console.WriteLine(f.test(4)); // Error
Console.WriteLine(f.test("hi there!"));
return 0;
}
public class Foo
{
private int test(int n) { return n; }
public string test(string str) { return str; }
}
===== Java =============
public class Program
{
public static void main(String[] args)
{
Foo f = new Foo();
System.out.println(f.test(4)); // Error
System.out.println(f.test("hi there!"));
}
}
class Foo
{
private int test(int n) { return n; }
public String test(String str) { return str; }
}
========= Swift ===========
class Foo
{
private func test(val: Int) -> Int
{
return val;
}
fileprivate func test(val: String) -> String
{
return val;
}
}
var f = Foo();
print(f.test(val: 5)); // Error
print(f.test(val: "Hi there!"));
============ C ++ ======================
class Foo
{
private: int test(int n) { return n; }
public: std::string test(std::string str) { return str; }
};
int main()
{
Foo f;
std::cout << f.test(4) << '\n'; // Error
std::cout << f.test("hi there!") << '\n';
return 0;
}
============ D is different to ***ALL*** of the above
==============
module m;
@safe:
private:
import std;
void main()
{
Foo f = new Foo();
writeln(f.test(3)); // fine, calls the private method of a
class
writeln(f.test("hi there!")); // fine, calls the public
method of a class
}
public class Foo
{
private int test(int n) { return n; }
public string test(string str) { return str; }
}
=================================
So why is D different here? Because the lowest level of
modularity in D is 'the module', and classes/structs within a
module have no mechanism in D to explicately encapsulate
themselves. Their encapsulation is wholly dependent on the
encapsulation at the module level.
I propose D introduce some CONSISTENCY with the concept of
'private', by allowing classes/struct to once again have their
OWN private members through the use of a new attribute
'private(this)', and requiring that D exclude private(this)
members from the overload lookup set as well.
Thus, with such a change:
=============================
module m;
@safe:
private:
import std;
void main()
{
Foo f = new Foo();
writeln(f.test(3)); // Error
writeln(f.test("hi there!"));
}
public class Foo
{
private(this) int test(int n) { return n; }
public string test(string str) { return str; }
}
=====================================
Some background:
https://wiki.dlang.org/DIP22
https://forum.dlang.org/post/kb33b3$2346$1@digitalmars.com
More information about the dip.ideas
mailing list