Extending D's support for object-oriented design with private(this)
Jonathan M Davis
newsgroup.d at jmdavisprog.com
Tue May 21 17:27:18 UTC 2024
On Tuesday, May 21, 2024 3:50:38 AM MDT Quirin Schroll via dip.ideas wrote:
> On Saturday, 27 April 2024 at 07:39:19 UTC, Jonathan M Davis
>
> wrote:
> > (particularly since the change from private, public, etc. being
> > protection attributes to visibility attributes seems to have
> > been tricky enough that a number of subtle bugs were introduced
> > in the process).
>
> I know this is slightly off-topic, but I have two questions about
> that:
> 1. When did this happen? I don’t need an exact date, but before
> 2015 and after 2015 would be helpful to me because I started
> learning D end of 2015 and so I could know if I ever used D with
> the old “protection attributes” way.
It was DIP 22:
https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP22.md
It looks like the original changes were merged in 2016.
> 2. What is the difference? I don’t need details, maybe a single
> example does the job.
Before DIP 22, functions which the code did not have access to (e.g. a
private function in another module) were considered to be part of the
overload set but then resulted in an error when a function which the calling
code didn't have access to was the best match. This meant that simply adding
a private function to your module could break someone else's code if it
happened to be a better match for the arguments than the overload that
they'd been using. E.G. maybe they had a function foo(long), and you added a
private foo(int) to a module that they imported, then any calls to foo with
integer literals - like foo(42) - would suddenly try to call your function
instead of theirs, resulting in an error, since it was private.
After DIP 22, functions which the code does not have access to are not
considered part of the overload set. So, if you have multiple functions with
the same name which could match, a function which that code does not have
access to will no longer result in an error. Instead, you'll get the best
match out of the functions that you actually have access to. So, adding a
private foo(int) to your module won't suddenly result in foo(42) trying to
call your foo instead of the foo(long) that the code was already using.
So before, private, public, etc. were protection modifiers / attributes, and
now they're visibility modifiers / attributes, since before, they controlled
whether you had access to a symbol, whereas now, they control whether that
symbol is visible. You can still get at the private stuff via traits, but
otherwise (barring compiler bugs), the private symbols don't exist for
modules that import that module, and you won't get breakage just because the
list of private symbols in a module that you're importing changes.
- Jonathan M Davis
More information about the dip.ideas
mailing list