digitalmars.D - Passing private functions to template algorithms
- FreeSlave (26/26) Jun 07 2016 I want to bring up this unpleasant topic for discussion, because
- Timon Gehr (4/30) Jun 07 2016 I think it is obvious that this should work. Visibility checks need to
- Stefan Koch (4/7) Jun 07 2016 I agree with you.
- deadalnix (3/11) Jun 07 2016 Unless you can provide such corner case, this post is
- Stefan Koch (2/8) Jun 07 2016 If I had a specific case in mind I would have provided it.
- deadalnix (2/3) Jun 08 2016 Then is is FUD.
- Max Samukha (4/12) Jun 07 2016 Something in the back of mine tells that no corner cases can be
- Max Samukha (19/22) Jun 08 2016 There is also this inconsistency:
- Dicebot (10/13) Jun 12 2016 My understanding is that right now template alias argument means
- Timon Gehr (8/22) Jun 12 2016 The lookup accesses the alias and is immediately rewritten to refer to
- Dicebot (8/37) Jun 12 2016 Yes, that is natural solution but it makes alias itself first-class
- Artur Skawina via Digitalmars-d (4/4) Jun 12 2016 The language does not prevent taking the address of a private
- Timon Gehr (20/60) Jun 12 2016 In my mind it already is a first-class symbol (it can even be part of an...
- Timon Gehr (2/3) Jun 12 2016 is useful
- Timon Gehr (4/8) Jun 12 2016 What do you think about the following?
- Basile B. (10/16) Jun 07 2016 Yes, I agree. This is also a concern for me. I've encountered a
I want to bring up this unpleasant topic for discussion, because I'm really tired of hacks I need to do in my code. Look at this snippet: private bool isFileNothrow(string path) { import std.file : isFile; import std.exception : collectException; bool ok; collectException(path.isFile, ok); return ok; } void main(string[] args) { import std.algorithm : filter; auto r = args.filter!(isFileNothrow); } Looks good, but it won't compile because isFileNothrow is invisible to std.algorithm. Technically it's right: function is private, so no access from other modules. But it makes me to do hacks like auto r = args.filter!(p => p.isFileNothrow); I don't see a way how can I reuse my functions while keeping it private without ugly hacks. How about allowing templates from other modules to have access to private functions? I think this would be pretty legal behavior, since template is instantiated in this module anyway.
Jun 07 2016
On 07.06.2016 20:45, FreeSlave wrote:I want to bring up this unpleasant topic for discussion, because I'm really tired of hacks I need to do in my code. Look at this snippet: private bool isFileNothrow(string path) { import std.file : isFile; import std.exception : collectException; bool ok; collectException(path.isFile, ok); return ok; } void main(string[] args) { import std.algorithm : filter; auto r = args.filter!(isFileNothrow); } Looks good, but it won't compile because isFileNothrow is invisible to std.algorithm. Technically it's right: function is private, so no access from other modules. But it makes me to do hacks like auto r = args.filter!(p => p.isFileNothrow); I don't see a way how can I reuse my functions while keeping it private without ugly hacks. How about allowing templates from other modules to have access to private functions? I think this would be pretty legal behavior, since template is instantiated in this module anyway.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.
Jun 07 2016
On Tuesday, 7 June 2016 at 18:59:03 UTC, Timon Gehr wrote:I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.I agree with you. However something in the back of my mind tells me that we'll be hitting nasty corner cases if we change the behavior.
Jun 07 2016
On Wednesday, 8 June 2016 at 00:48:00 UTC, Stefan Koch wrote:On Tuesday, 7 June 2016 at 18:59:03 UTC, Timon Gehr wrote:Unless you can provide such corner case, this post is contributing nothing.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.I agree with you. However something in the back of my mind tells me that we'll be hitting nasty corner cases if we change the behavior.
Jun 07 2016
On Wednesday, 8 June 2016 at 00:58:41 UTC, deadalnix wrote:On Wednesday, 8 June 2016 at 00:48:00 UTC, Stefan Koch wrote:If I had a specific case in mind I would have provided it.I agree with you. However something in the back of my mind tells me that we'll be hitting nasty corner cases if we change the behavior.Unless you can provide such corner case, this post is contributing nothing.
Jun 07 2016
On Wednesday, 8 June 2016 at 05:51:38 UTC, Stefan Koch wrote:If I had a specific case in mind I would have provided it.Then is is FUD.
Jun 08 2016
On Wednesday, 8 June 2016 at 00:48:00 UTC, Stefan Koch wrote:On Tuesday, 7 June 2016 at 18:59:03 UTC, Timon Gehr wrote:Something in the back of mine tells that no corner cases can be worse than the present situation. It is like disallowing private variables to be passed to imported functions.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.I agree with you. However something in the back of my mind tells me that we'll be hitting nasty corner cases if we change the behavior.
Jun 07 2016
On Tuesday, 7 June 2016 at 18:59:03 UTC, Timon Gehr wrote:I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.There is also this inconsistency: ---- module a; private int _x; alias x = _x; private void _foo() { } alias foo = _foo; ---- module main; import a; void main(string[] args) { x = 1; // ok foo(); // a._foo is not accessible } What's the reason for this? Should both aliases be private? Public?
Jun 08 2016
On 06/07/2016 09:59 PM, Timon Gehr wrote:I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.My understanding is that right now template alias argument means transparent symbol lookup. It acts as if doesn't access alias symbol in template but aliased one directly. I agree such semantics are sub-optimal but changing that can break quite some existing idioms. Consider this snippet for example: enum name ( alias sym ) = sym.stringof; Right now it evaluates to name of passed symbol. If we change lookup semantics to be non-transparent, it must always return `sym` for consistency.
Jun 12 2016
On 12.06.2016 10:28, Dicebot wrote:On 06/07/2016 09:59 PM, Timon Gehr wrote:The lookup accesses the alias and is immediately rewritten to refer to the aliased symbol. Visibility checks should be applied during the lookup, but not after the rewrite.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.My understanding is that right now template alias argument means transparent symbol lookup. It acts as if doesn't access alias symbol in template but aliased one directly. ...I agree such semantics are sub-optimal but changing that can break quite some existing idioms. Consider this snippet for example: enum name ( alias sym ) = sym.stringof; Right now it evaluates to name of passed symbol. If we change lookup semantics to be non-transparent, it must always return `sym` for consistency.I completely disagree that this would need to happen. E.g. fullyQualifiedName should work with private symbols just as well as with public ones. Maybe this is helpful: https://en.wikipedia.org/wiki/Information_hiding
Jun 12 2016
On 06/12/2016 01:55 PM, Timon Gehr wrote:On 12.06.2016 10:28, Dicebot wrote:Yes, that is natural solution but it makes alias itself first-class symbol which leads to my example snippet question.On 06/07/2016 09:59 PM, Timon Gehr wrote:The lookup accesses the alias and is immediately rewritten to refer to the aliased symbol. Visibility checks should be applied during the lookup, but not after the rewrite.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.My understanding is that right now template alias argument means transparent symbol lookup. It acts as if doesn't access alias symbol in template but aliased one directly. ...Private or public is irrelevant here, it seems you have misunderstood my concern. The essential question is "what the alias is?", not how it is accessed. There must be no special cases for aliases regarding private/public symbol access, it is matter of defining actual alias semantics so that generic access rules start being useful.I agree such semantics are sub-optimal but changing that can break quite some existing idioms. Consider this snippet for example: enum name ( alias sym ) = sym.stringof; Right now it evaluates to name of passed symbol. If we change lookup semantics to be non-transparent, it must always return `sym` for consistency.I completely disagree that this would need to happen. E.g. fullyQualifiedName should work with private symbols just as well as with public ones. Maybe this is helpful: https://en.wikipedia.org/wiki/Information_hiding
Jun 12 2016
The language does not prevent taking the address of a private symbol and escaping it. The alias case isn't (ie shouldn't be) different. artur
Jun 12 2016
On 12.06.2016 13:05, Dicebot wrote:On 06/12/2016 01:55 PM, Timon Gehr wrote:In my mind it already is a first-class symbol (it can even be part of an overload set), but after you look it up, it is immediately rewritten to another symbol. https://github.com/tgehr/d-compiler/blob/master/semantic.d#L4670 Does DMD special-case it during lookup instead?On 12.06.2016 10:28, Dicebot wrote:Yes, that is natural solution but it makes alias itself first-class symbol which leads to my example snippet question. ...On 06/07/2016 09:59 PM, Timon Gehr wrote:The lookup accesses the alias and is immediately rewritten to refer to the aliased symbol. Visibility checks should be applied during the lookup, but not after the rewrite.I think it is obvious that this should work. Visibility checks need to happen during identifier lookup. This lookup is happening in the module where isFileNothrow is visible.My understanding is that right now template alias argument means transparent symbol lookup. It acts as if doesn't access alias symbol in template but aliased one directly. ...Probably I indeed misunderstood your concern, but what I disagree with is the notion that breaking code not directly checking for visibility is somehow a prerequisite for having the correct visibility checks in place. You may very well be right that it would be more consistent to return the name of the alias, but I think what .stringof returns is an independent concern. (Last time I checked, it was completely unspecified anyway btw.)Private or public is irrelevant here, it seems you have misunderstood my concern.I agree such semantics are sub-optimal but changing that can break quite some existing idioms. Consider this snippet for example: enum name ( alias sym ) = sym.stringof; Right now it evaluates to name of passed symbol. If we change lookup semantics to be non-transparent, it must always return `sym` for consistency.I completely disagree that this would need to happen. E.g. fullyQualifiedName should work with private symbols just as well as with public ones. Maybe this is helpful: https://en.wikipedia.org/wiki/Information_hidingThe essential question is "what the alias is?", not how it is accessed. There must be no special cases for aliases regarding private/public symbol access,There are no special cases in what I propose. The alias rewrite has nothing to do with lookup: https://github.com/tgehr/d-compiler/blob/master/scope_.d#L185 I guess this is precisely your proposal too?it is matter of defining actual alias semantics so that generic access rules start being useful.I agree. (Or maybe rather, it is a matter of defining both such that the resulting semantics are useful, I don't know precisely where DMD goes astray here.)
Jun 12 2016
On 12.06.2016 15:52, Timon Gehr wrote:semantics are usefulis useful
Jun 12 2016
On 12.06.2016 15:52, Timon Gehr wrote:You may very well be right that it would be more consistent to return the name of the alias, but I think what .stringof returns is an independent concern. (Last time I checked, it was completely unspecified anyway btw.)What do you think about the following? enum e=3; static assert(e.stringof=="3");
Jun 12 2016
On Tuesday, 7 June 2016 at 18:45:23 UTC, FreeSlave wrote:I want to bring up this unpleasant topic for discussion, because I'm really tired of hacks I need to do in my code. [...] How about allowing templates from other modules to have access to private functions? I think this would be pretty legal behavior, since template is instantiated in this module anyway.Yes, I agree. This is also a concern for me. I've encountered a more specific case when using traits (https://issues.dlang.org/show_bug.cgi?id=15371). One possible fix would be to allow templates to be instantiated in the module that uses them. But I have no idea on the fisability. The consequence now is that a lot of good templates can't be added to std.traits (for example to simplify the __traits() code) because introspection would only work on public symbols.
Jun 07 2016