Can you publicly alias a private type?

Nick Sabalausky a at a.a
Wed Jun 22 06:19:23 PDT 2011


"Peter Alexander" <peter.alexander.au at gmail.com> wrote in message 
news:itsp16$1jl5$1 at digitalmars.com...
> On 22/06/11 1:41 PM, Nick Sabalausky wrote:
>> "Peter Alexander"<peter.alexander.au at gmail.com>  wrote in message
>> news:itsl71$1cnq$1 at digitalmars.com...
>>> On 21/06/11 7:59 PM, Nick Sabalausky wrote:
>>>> "Peter Alexander"<peter.alexander.au at gmail.com>   wrote in message
>>>> news:itq945$2ag0$1 at digitalmars.com...
>>>>> Is the following legal D?
>>>>>
>>>>> // module A
>>>>> private class Foo;
>>>>> public alias Foo Bar;
>>>>>
>>>>> // module B
>>>>> import A;
>>>>> Bar b; // I can't use Foo, but can I use Bar?
>>>>>
>>>>>
>>>>> I'm adding module level protection for types into DMD and wondering if
>>>>> this should be legal.
>>>>>
>>>>
>>>> I'm no authority on this, but I'm pretty sure that's supposed to be
>>>> legal.
>>>> Access modifiers work non-transitively on just the given symbol. And 
>>>> it's
>>>> a
>>>> useful idiom in cases that are more complex than that (ex: Using a
>>>> templated
>>>> alias to provide a cleaner public interface to a private implementation
>>>> that
>>>> has a more complex interface).
>>>>
>>>> Your code above is analogous to this, which *definitely* is supposed to
>>>> be
>>>> legal:
>>>>
>>>> // module A
>>>> private foo() {}
>>>> public bar()
>>>> {
>>>>       foo();
>>>> }
>>>>
>>>> // module B
>>>> import A;
>>>> bar(); // I can't use foo(), but can I use bar(). Nothin' wrong with
>>>> that.
>>>>
>>>
>>> That is similar, but not analogous.
>>>
>>> The problem arises when we come to more complex types:
>>>
>>> // module A
>>> private class Foo;
>>> public alias Foo[] Foos;
>>>
>>> // module B
>>> void main()
>>> {
>>>      Foos fs; // Legal? Seems so.
>>>      Foo f = fs[0]; // Clearly can't use Foo here, it's private.
>>>      auto f2 = fs[0]; // Legal?
>>>      fs[0].memFun(); // Legal?
>>> }
>>>
>>> Of course, the same problems arise if you alias something like 
>>> Array!Foo.
>>>
>>> So the difference between class aliasing and functional composition is
>>> that class aliasing does not completely encapsulate the class, while the
>>> function does. Function composition is more analogous to structural
>>> composition.
>>>
>>> In my opinion, it should be illegal to publicly alias a private type (or
>>> any derivative type) because it introduces too many issues, as I have
>>> demonstrated above.
>>>
>>
>> That issue is not unique to alias:
>>
>> private class Foo {}
>> public bar(Foo f) {}
>
> Yeah, there's quite a few places where this crops up. Basically, I think 
> that private types (and related types, e.g. arrays of private types and 
> templates of private types) should be disallowed from appearing anywhere 
> in the public interface of a module. So that would include:
>
> - aliases
> - function arguments
> - function return types
>
> There's probably more places where we'd need to add checks.
>

Ultimately, the problem boils down to when a private type is required to use 
a public interface. I agree that's a potential issue. However, I don't 
believe that's relevent to the original scenario being discussed:

private class Foo {}
public alias Foo Bar;

In your example, the user needs to be able to use the Foo symbol in order to 
get full use out of Foos. However, in my example, the user does *not* need 
to use the Foo symbol in order to get full use out of Bar. They can just use 
Bar in place of Foo. The "Foo" symbol is a necessary part of Foos's 
interface, but it is *not* a necessary part Bar's interface.




More information about the Digitalmars-d mailing list