digitalmars.D - public aliases to private/package symbols
- Martin Nowak (3/3) Jan 24 2012 Should aliases be allowed to raise the accessibility of a symbol?
- Trass3r (2/3) Jan 24 2012 Yeah I do use that by having a private template function and public
- Nick Sabalausky (3/6) Jan 24 2012 Yes.
- Nick Sabalausky (14/21) Jan 24 2012 How else are you going to separate the interface for the internal
- Peter Alexander (13/17) Jan 24 2012 Things can be obvious in different ways.
- Timon Gehr (7/23) Jan 24 2012 Non-obvious? Perfectly obvious: Access checking rules do not apply to
- Peter Alexander (18/20) Jan 24 2012 You are probably right about not introducing holes, but I can
- Nick Sabalausky (32/51) Jan 24 2012 In all the above, the type *should* be Bar, not Foo (although it might n...
- Martin Nowak (4/27) Jan 26 2012 The solution seems to be to check protection only during symbol lookup.
- Timon Gehr (15/34) Jan 24 2012 That is a valid counter-argument. While I am sure these issues could be
- Nick Sabalausky (4/46) Jan 24 2012 There's no need for special cases. Just don't go de-aliasing symbols. Th...
- Timon Gehr (7/59) Jan 24 2012 It does not.
- Nick Sabalausky (15/27) Jan 24 2012 That's not a problem that's specific to alias. It's symptomatic of a mor...
- Nick Sabalausky (16/48) Jan 24 2012 Of course, my position isn't purely defensive. Here's why access-expandi...
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (7/7) Jan 25 2012 Another example would be synchronized classes:
- Nick Sabalausky (3/10) Jan 25 2012 Or just cause f to be protected by the class's mutex.
- Nick Sabalausky (4/16) Jan 25 2012 After all, if you're making a public alias of f, then you obviously *do*...
- =?ISO-8859-15?Q?S=F6nke_Ludwig?= (7/24) Jan 25 2012 ...although it would be a bit awkward to have the original function
- Nick Sabalausky (9/13) Jan 24 2012 FWIW, If someone were to argue that, my response would be something like...
- equinox atw.hu (9/9) Jan 25 2012 Hi,
- Nick Sabalausky (3/10) Jan 25 2012 I think LDC can do that...At least in theory anyway, since LLVM has a C
- Bernard Helyer (4/17) Jan 25 2012 It does, but they tell you not to use it. Make of that what you
- Steven Schveighoffer (3/10) Jan 25 2012 IIRC, Walter is (slowly) working on that.
- Andrew Wiley (14/21) Jan 25 2012 As far as platform support goes, GDC *should* be able to target pretty
Should aliases be allowed to raise the accessibility of a symbol? http://d.puremagic.com/issues/show_bug.cgi?id=4533 http://d.puremagic.com/issues/show_bug.cgi?id=6013
Jan 24 2012
Should aliases be allowed to raise the accessibility of a symbol?Yeah I do use that by having a private template function and public aliases to certain instances.
Jan 24 2012
"Martin Nowak" <dawg dawgfoto.de> wrote in message news:mailman.782.1327427928.16222.digitalmars-d puremagic.com...Should aliases be allowed to raise the accessibility of a symbol? http://d.puremagic.com/issues/show_bug.cgi?id=4533 http://d.puremagic.com/issues/show_bug.cgi?id=6013Yes.
Jan 24 2012
"Nick Sabalausky" <a a.a> wrote in message news:jfnag6$317n$1 digitalmars.com..."Martin Nowak" <dawg dawgfoto.de> wrote in message news:mailman.782.1327427928.16222.digitalmars-d puremagic.com...How else are you going to separate the interface for the internal implementation of a template from its for-public-consumption interface? This whole issue is literally *NO* different from "Should a public pointer/reference be allowed to point to private data?" or "Should a public function be allowed to expose a private one?" The answer is: "Obviously yes". I don't understand why anyone thinks this is any different just because they're aliases instead of pointers/references/functions/etc. All the arguments against public alias to private symbols apply equally to these questions too, and in those cases nobody would even question it. What is it about aliases that suddenly trips people up and makes them think the whole concept of accessibility should be flipped around on its head?Should aliases be allowed to raise the accessibility of a symbol? http://d.puremagic.com/issues/show_bug.cgi?id=4533 http://d.puremagic.com/issues/show_bug.cgi?id=6013Yes.
Jan 24 2012
On Tuesday, 24 January 2012 at 22:26:37 UTC, Nick Sabalausky wrote:This whole issue is literally *NO* different from "Should a public pointer/reference be allowed to point to private data?" or "Should a public function be allowed to expose a private one?" The answer is: "Obviously yes".Things can be obvious in different ways. For example, one could argue that it's also obvious that an alias should behave exactly the same as the thing it aliases. Allowing aliases to change protection would break that. For the record, I agree that the answer should be "yes", but it's not a decision that should be made rashly. If we aren't careful, we could introduce a hole in the protection system in a non-obvious way. C++'s protection system has a non-obvious hole: http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html Again, I agree, but what's obvious isn't always true, so it needs to be considered in depth.
Jan 24 2012
On 01/25/2012 12:09 AM, Peter Alexander wrote:On Tuesday, 24 January 2012 at 22:26:37 UTC, Nick Sabalausky wrote:The accessibility of something is not part of its behavior.This whole issue is literally *NO* different from "Should a public pointer/reference be allowed to point to private data?" or "Should a public function be allowed to expose a private one?" The answer is: "Obviously yes".Things can be obvious in different ways. For example, one could argue that it's also obvious that an alias should behave exactly the same as the thing it aliases. Allowing aliases to change protection would break that.For the record, I agree that the answer should be "yes", but it's not a decision that should be made rashly. If we aren't careful, we could introduce a hole in the protection system in a non-obvious way. C++'s protection system has a non-obvious hole: http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.htmlNon-obvious? Perfectly obvious: Access checking rules do not apply to names in explicit template instantiations. It is an explicit rule that states access checking is subverted.Again, I agree, but what's obvious isn't always true, so it needs to be considered in depth.Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.
Jan 24 2012
On Wednesday, 25 January 2012 at 00:08:25 UTC, Timon Gehr wrote:Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.You are probably right about not introducing holes, but I can imagine this getting tricky, and perhaps confusing in some cases. Here are some off the top of my head. module A; private class Foo {} public alias Foo Bar; In other modules that import A: Bar b = new typeof(b)(); // typeof(b) is Foo. Is this allowed? T foo(T)(T x) { return new T(); } Bar b; b = foo(b); // T is deduced to Foo, should this work? Bar b = new Bar(); mixin("b = new " ~ typeof(b).stringof ~ "();"); // This fails, the string is "Foo" Just thinking about this has made me change my position. Accessibility raising aliases should not be allowed. It's a minefield.
Jan 24 2012
"Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:jzvidktaqmkptrooimvt dfeed.kimsufi.thecybershadow.net...On Wednesday, 25 January 2012 at 00:08:25 UTC, Timon Gehr wrote:In all the above, the type *should* be Bar, not Foo (although it might not currently be - I'd consider that something that needs to be changed). Bar should refer to Foo *behind the scenes*, and as such, the fact that it refers to something else behind the scenes is totally irrelevent. This would also seem to be related to issue of error messages currently referring to the underlying type insted of the aliased type (which I'm convinced is the wrong way round).Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.You are probably right about not introducing holes, but I can imagine this getting tricky, and perhaps confusing in some cases. Here are some off the top of my head. module A; private class Foo {} public alias Foo Bar; In other modules that import A: Bar b = new typeof(b)(); // typeof(b) is Foo. Is this allowed? T foo(T)(T x) { return new T(); } Bar b; b = foo(b); // T is deduced to Foo, should this work? Bar b = new Bar(); mixin("b = new " ~ typeof(b).stringof ~ "();"); // This fails, the string is "Foo"Just thinking about this has made me change my position. Accessibility raising aliases should not be allowed. It's a minefield.The issue is not with aliases, accessability already has a natural grey area: ==================== module lib; private struct Foo {} // Should any of these be allowed? public Foo getFoo() { return Foo(); } public void takeFoo(Foo f) {} struct Bar { Foo f; } ------ module main; import lib; getFoo(); // Allowed? takeFoo(getFoo()); // Allowed? Bar b; // Allowed? takeFoo(b.f); // Allowed? b.f = getFoo(); // Allowed? // Allowed? If so, can you *do* anything with x? auto x = getFoo(); ====================
Jan 24 2012
The issue is not with aliases, accessability already has a natural grey area: ==================== module lib; private struct Foo {} // Should any of these be allowed? public Foo getFoo() { return Foo(); } public void takeFoo(Foo f) {} struct Bar { Foo f; } ------ module main; import lib; getFoo(); // Allowed? takeFoo(getFoo()); // Allowed? Bar b; // Allowed? takeFoo(b.f); // Allowed? b.f = getFoo(); // Allowed? // Allowed? If so, can you *do* anything with x? auto x = getFoo(); ====================The solution seems to be to check protection only during symbol lookup. Thus all of the above are allowed and you can do with x what Foo allows you to (aggregates default to public protection).
Jan 26 2012
On 01/25/2012 01:59 AM, Peter Alexander wrote:On Wednesday, 25 January 2012 at 00:08:25 UTC, Timon Gehr wrote:That is a valid counter-argument. While I am sure these issues could be sorted out, it would probably amount to over-engineering. This is basically the only useful use case worth considering: private template Tmpl(T){...} public alias Tmpl!int foo; Tmpl and Tmpl!int are two _distinct symbols_, and there is no dedicated syntax to make just one of them accessible. Therefore, this use case could be allowed as a special case: Explicit use of Tmpl from another module would be forbidden, but the instance Tmpl!int would be public under the name foo. (While explicitly instantiating Tmpl!int would fail, because Tmpl is not accessible (or ideally not visible).) There would be no public/private aliasing, and therefore all the issues you mentioned would not exist in this case.Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.You are probably right about not introducing holes, but I can imagine this getting tricky, and perhaps confusing in some cases. Here are some off the top of my head. module A; private class Foo {} public alias Foo Bar; In other modules that import A: Bar b = new typeof(b)(); // typeof(b) is Foo. Is this allowed? T foo(T)(T x) { return new T(); } Bar b; b = foo(b); // T is deduced to Foo, should this work? Bar b = new Bar(); mixin("b = new " ~ typeof(b).stringof ~ "();"); // This fails, the string is "Foo" Just thinking about this has made me change my position. Accessibility raising aliases should not be allowed. It's a minefield.
Jan 24 2012
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jfnlpu$k0p$1 digitalmars.com...On 01/25/2012 01:59 AM, Peter Alexander wrote:There's no need for special cases. Just don't go de-aliasing symbols. That takes care of everything.On Wednesday, 25 January 2012 at 00:08:25 UTC, Timon Gehr wrote:That is a valid counter-argument. While I am sure these issues could be sorted out, it would probably amount to over-engineering. This is basically the only useful use case worth considering: private template Tmpl(T){...} public alias Tmpl!int foo; Tmpl and Tmpl!int are two _distinct symbols_, and there is no dedicated syntax to make just one of them accessible. Therefore, this use case could be allowed as a special case: Explicit use of Tmpl from another module would be forbidden, but the instance Tmpl!int would be public under the name foo. (While explicitly instantiating Tmpl!int would fail, because Tmpl is not accessible (or ideally not visible).) There would be no public/private aliasing, and therefore all the issues you mentioned would not exist in this case.Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.You are probably right about not introducing holes, but I can imagine this getting tricky, and perhaps confusing in some cases. Here are some off the top of my head. module A; private class Foo {} public alias Foo Bar; In other modules that import A: Bar b = new typeof(b)(); // typeof(b) is Foo. Is this allowed? T foo(T)(T x) { return new T(); } Bar b; b = foo(b); // T is deduced to Foo, should this work? Bar b = new Bar(); mixin("b = new " ~ typeof(b).stringof ~ "();"); // This fails, the string is "Foo" Just thinking about this has made me change my position. Accessibility raising aliases should not be allowed. It's a minefield.
Jan 24 2012
On 01/25/2012 03:56 AM, Nick Sabalausky wrote:"Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jfnlpu$k0p$1 digitalmars.com...It does not. private class A{ static A factory(); } public alias A B; What is typeof(B.factory()) ?On 01/25/2012 01:59 AM, Peter Alexander wrote:There's no need for special cases. Just don't go de-aliasing symbols. That takes care of everything.On Wednesday, 25 January 2012 at 00:08:25 UTC, Timon Gehr wrote:That is a valid counter-argument. While I am sure these issues could be sorted out, it would probably amount to over-engineering. This is basically the only useful use case worth considering: private template Tmpl(T){...} public alias Tmpl!int foo; Tmpl and Tmpl!int are two _distinct symbols_, and there is no dedicated syntax to make just one of them accessible. Therefore, this use case could be allowed as a special case: Explicit use of Tmpl from another module would be forbidden, but the instance Tmpl!int would be public under the name foo. (While explicitly instantiating Tmpl!int would fail, because Tmpl is not accessible (or ideally not visible).) There would be no public/private aliasing, and therefore all the issues you mentioned would not exist in this case.Accessibility-raising aliases are trivially safe, because the alias declaration must have access to the aliased symbol.You are probably right about not introducing holes, but I can imagine this getting tricky, and perhaps confusing in some cases. Here are some off the top of my head. module A; private class Foo {} public alias Foo Bar; In other modules that import A: Bar b = new typeof(b)(); // typeof(b) is Foo. Is this allowed? T foo(T)(T x) { return new T(); } Bar b; b = foo(b); // T is deduced to Foo, should this work? Bar b = new Bar(); mixin("b = new " ~ typeof(b).stringof ~ "();"); // This fails, the string is "Foo" Just thinking about this has made me change my position. Accessibility raising aliases should not be allowed. It's a minefield.
Jan 24 2012
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jfnsne$10re$1 digitalmars.com...On 01/25/2012 03:56 AM, Nick Sabalausky wrote:That's not a problem that's specific to alias. It's symptomatic of a more general access issue (instances of private types exposed in a public interface) that is *not* solved by prohibiting access-expanding aliases: private class A{ static A factory(); } public class B{ A foo() { return A.factory(); } } In another module: typeof((new B()).foo()) // What should happen? If "public alias A B" must be banned due to tough accessibility questions, then so must "class B". Point is, it's not an issue specific to alias.There's no need for special cases. Just don't go de-aliasing symbols. That takes care of everything.It does not. private class A{ static A factory(); } public alias A B; What is typeof(B.factory()) ?
Jan 24 2012
"Nick Sabalausky" <a a.a> wrote in message news:jfo1i0$18rq$1 digitalmars.com..."Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jfnsne$10re$1 digitalmars.com...Of course, my position isn't purely defensive. Here's why access-expanding aliases cannot be prohibited: private struct DirtyFooImpl(int i){} template Foo { alias DirtyFooImpl!5 Foo; } That's a simplistic example of very common, very useful idiom. Note that there's no way to do that without access-expanding aliases. If access-expanding aliases are banned, then this idiom must go away too. Then, a big chunk of my Goldie project and no doubt many other projects suddenly break, and the only way around it is to publically expose things that are *not supposed to be exposed*, and congrats, now we've just stepped back in time to pre-encapsulation-enforcement days.On 01/25/2012 03:56 AM, Nick Sabalausky wrote:That's not a problem that's specific to alias. It's symptomatic of a more general access issue (instances of private types exposed in a public interface) that is *not* solved by prohibiting access-expanding aliases: private class A{ static A factory(); } public class B{ A foo() { return A.factory(); } } In another module: typeof((new B()).foo()) // What should happen? If "public alias A B" must be banned due to tough accessibility questions, then so must "class B". Point is, it's not an issue specific to alias.There's no need for special cases. Just don't go de-aliasing symbols. That takes care of everything.It does not. private class A{ static A factory(); } public alias A B; What is typeof(B.factory()) ?
Jan 24 2012
Another example would be synchronized classes: synchronized class X { public alias f g; private void f(){} } Now g() would be a public method that is not protected by the class' mutex. This case would have to be explicitly forbidden.
Jan 25 2012
"Sönke Ludwig" <ludwig informatik.uni-luebeck.de> wrote in message news:jfoh1s$25ce$1 digitalmars.com...Another example would be synchronized classes: synchronized class X { public alias f g; private void f(){} } Now g() would be a public method that is not protected by the class' mutex. This case would have to be explicitly forbidden.Or just cause f to be protected by the class's mutex.
Jan 25 2012
"Nick Sabalausky" <a a.a> wrote in message news:jfojur$2a7l$1 digitalmars.com..."Sönke Ludwig" <ludwig informatik.uni-luebeck.de> wrote in message news:jfoh1s$25ce$1 digitalmars.com...After all, if you're making a public alias of f, then you obviously *do* want that function to be public-accessible, just not through the *name* "f".Another example would be synchronized classes: synchronized class X { public alias f g; private void f(){} } Now g() would be a public method that is not protected by the class' mutex. This case would have to be explicitly forbidden.Or just cause f to be protected by the class's mutex.
Jan 25 2012
Am 25.01.2012 11:02, schrieb Nick Sabalausky:"Nick Sabalausky"<a a.a> wrote in message news:jfojur$2a7l$1 digitalmars.com......although it would be a bit awkward to have the original function change just because it is aliased somewhere (a bit like Schrödinger's cat). But actually I realize that there are far worse things concerning shared/synchronized + classes, so my example maybe is not really specific to 'alias' (e.g. I'm not sure what happens now if you make a delegate of f()...)"Sönke Ludwig"<ludwig informatik.uni-luebeck.de> wrote in message news:jfoh1s$25ce$1 digitalmars.com...After all, if you're making a public alias of f, then you obviously *do* want that function to be public-accessible, just not through the *name* "f".Another example would be synchronized classes: synchronized class X { public alias f g; private void f(){} } Now g() would be a public method that is not protected by the class' mutex. This case would have to be explicitly forbidden.Or just cause f to be protected by the class's mutex.
Jan 25 2012
"Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:bfhygfbdlubuwelaqfws dfeed.kimsufi.thecybershadow.net...For example, one could argue that it's also obvious that an alias should behave exactly the same as the thing it aliases. Allowing aliases to change protection would break that.FWIW, If someone were to argue that, my response would be something like: 1. If you wanted it *exactly* the same, you wouldn't have aliased it at all. So naturally, that "exactly" is subject to reasonable exceptions. 2. Protection levels apply to symbols, not the construct or data the symbol refers to. 3. (Just reiterating I guess:) Protection levels are not, should not, and cannot realistically be transitive.For the record, I agree that the answer should be "yes", but it's
Jan 24 2012
Hi, I have been thinking . Would not C and C++ backend would make DMD more = versatile? D language could be used in many platforms easily. D language could be used in .net and elsewhere. It could be compiled with other language that are also translated into = C/C++. Regards M=E1rton Papp
Jan 25 2012
<equinox atw.hu> wrote in message news:op.v8mxx6s9xa30qa marton-pc...Hi, I have been thinking . Would not C and C++ backend would make DMD more versatile? D language could be used in many platforms easily. D language could be used in .net and elsewhere. It could be compiled with other language that are also translated into C/C++.I think LDC can do that...At least in theory anyway, since LLVM has a C backend.
Jan 25 2012
On Wednesday, 25 January 2012 at 12:03:15 UTC, Nick Sabalausky wrote:<equinox atw.hu> wrote in message news:op.v8mxx6s9xa30qa marton-pc...It does, but they tell you not to use it. Make of that what you will.Hi, I have been thinking . Would not C and C++ backend would make DMD more versatile? D language could be used in many platforms easily. D language could be used in .net and elsewhere. It could be compiled with other language that are also translated into C/C++.I think LDC can do that...At least in theory anyway, since LLVM has a C backend.
Jan 25 2012
On Wed, 25 Jan 2012 05:26:20 -0500, <equinox atw.hu> wrote:Hi, I have been thinking . Would not C and C++ backend would make DMD more versatile? D language could be used in many platforms easily. D language could be used in .net and elsewhere. It could be compiled with other language that are also translated into C/C++.IIRC, Walter is (slowly) working on that. -Steve
Jan 25 2012
On Wed, Jan 25, 2012 at 4:26 AM, <equinox atw.hu> wrote:Hi, I have been thinking . Would not C and C++ backend would make DMD more versatile? D language could be used in many platforms easily. D language could be used in .net and elsewhere. It could be compiled with other language that are also translated into C/C++.As far as platform support goes, GDC *should* be able to target pretty much any platform GCC can currently target. There are probably some platform-specific issues at this point; one example would be that you have to disable the section-anchors optimization to get D running on ARM. There are also some fun things like Fibers not working because the getcontext/setcontext/makecontext functions in glibc are just stubs on ARM, but Iain has done an excellent job of adding GCC-specific version blocks to Druntime that replace most of the platform-specific code with pre-written GCC intrinsics. I know Daniel Green had some difficulty getting a toolchain that supports TLS on Windows, hopefully he can chime in on whether that's just Windows or will be an issue on other platforms as well.
Jan 25 2012