digitalmars.D - DIP 1007 Preliminary Review Round 1
- Mike Parker (13/13) Apr 24 2017 DIP 1007 is titled "'future symbol' Compiler Concept".
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/8) Apr 24 2017 «In all the mentioned languages but D, a common convention is to
- Atila Neves (25/34) Apr 24 2017 In headers. Not in source files, and I don't know why anyone
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (11/17) Apr 25 2017 C++ is increasingly becoming dependent on templates so header
- rikki cattermole (10/22) Apr 24 2017 This DIP concerns me, for any other language I would go so far as to
- H. S. Teoh via Digitalmars-d (25/35) Apr 25 2017 Initially I also had the same concern, but after reading the DIP in its
- Steven Schveighoffer (16/43) Apr 25 2017 I missed this part. Now that I read that, I think we aren't going to
- Olivier FAURE (5/20) Apr 26 2017 The way I understood it, the feature will only stay internal to
- Steven Schveighoffer (14/31) Apr 26 2017 The question I have is: who is going to adjust this list? If the answer
- Olivier FAURE (3/4) Apr 28 2017 That was a quote from the DIP. (guess I should have used a colon)
- Steven Schveighoffer (3/6) Apr 30 2017 Ah, OK. Sorry for the confusion, I wasn't sure where it came from.
- Leandro Lucarella (41/44) May 10 2017 This is not the intended usage of this DIP. The intention here is
- Dominikus Dittes Scherkl (4/6) Apr 25 2017 +1
- Jacob Carlborg (12/24) Apr 25 2017 How is this supposed to be used?
- rikki cattermole (10/32) Apr 25 2017 Mitigation:
- Steven Schveighoffer (39/66) Apr 25 2017 __symbol is reserved by the language. I don't think we need to worry
- Leandro Lucarella (5/35) May 10 2017 This is a very good point. We'll send a PR with a proposed
- Dicebot (14/28) May 10 2017 Right now I have two possible approaches in mind.
- Steven Schveighoffer (12/40) May 10 2017 I prefer the first one. The reason is simply because it doesn't require
- Nick Sabalausky (Abscissa) (18/25) May 10 2017 This is a pointless limitation. What is the benefit of requiring the
- Steven Schveighoffer (31/60) May 11 2017 The idea (I think) is to have a version of the library that functions
- Nick Sabalausky (Abscissa) (41/67) May 11 2017 Yes, I'm aware that's the idea the author had in mind, but that still
- Steven Schveighoffer (38/81) May 11 2017 How does this work?
- Steven Schveighoffer (10/22) Apr 25 2017 As I mentioned elsewhere, an intermediate step for a symbol that will
- Nick Sabalausky (Abscissa) (6/6) May 10 2017 This is what FQNs are for. At least, it was before FQNs were broken,
- Nick Sabalausky (Abscissa) (43/49) May 10 2017 I guess that's my overview. More specifically, what I mean is this:
- Nick Sabalausky (Abscissa) (27/36) May 10 2017 Ugh, frustrating... Seems like every time I try to clarify something I
- Dicebot (28/53) May 11 2017 It is already addressed in the DIP. FQNs only help if they are
- Nick Sabalausky (Abscissa) (20/47) May 11 2017 I didn't see that. Certainly not in the "Existing solutions" section. It...
- Dicebot (22/51) May 14 2017 It is mostly discussed in "Comparison with other languages"
- Mike Parker (3/10) May 16 2017 This review round is now closed. Thanks to everyone who
DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!
Apr 24 2017
On Monday, 24 April 2017 at 15:03:53 UTC, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept".«In all the mentioned languages but D, a common convention is to only use unqualified access for symbols in the standard library.» Not quite right for C++. The common convention in modern C++ is to use full std::name qualification for the standard library. It is common to use unqualified access for the local namespace(s) only.
Apr 24 2017
On Monday, 24 April 2017 at 15:22:15 UTC, Ola Fosheim Grøstad wrote:On Monday, 24 April 2017 at 15:03:53 UTC, Mike Parker wrote:In headers. Not in source files, and I don't know why anyone would want to keep typing `std::` all the time. Do some people do what you're describing? Yes, but I see no evidence that that's the common convention in modern C++. In fact, from the core guidelines: " #include<string> #include<vector> #include<iostream> #include<memory> #include<algorithm> using namespace std; // ... Here (obviously), the standard library is used pervasively and apparently no other library is used, so requiring `std::` everywhere could be distracting." Never mind the monstrosity that would be trying to use the C++ user-defined literal without `using namespace std`: #include <string> using namespace std::operator""s; // Argh! My eyes! No thanks. I even had to look that up, and I'll probably forget it.DIP 1007 is titled "'future symbol' Compiler Concept".«In all the mentioned languages but D, a common convention is to only use unqualified access for symbols in the standard library.» Not quite right for C++. The common convention in modern C++ is to use full std::name qualification for the standard library. It is common to use unqualified access for the local namespace(s) only.
Apr 24 2017
On Monday, 24 April 2017 at 22:22:14 UTC, Atila Neves wrote:In headers. Not in source files, and I don't know why anyone would want to keep typing `std::` all the time.C++ is increasingly becoming dependent on templates so header files are expanding at the cost of ".cpp source files". If more than half the code base is in header files then it makes little sense to not use "std::" fully qualified, both for clarity, name-resolution and usability reasons (cut and paste). (For templates the core guidelines says that one should use "std::" and only use unqualified names for situations where you want to override the "std::" provided definition with a local implementation if it exists.)Never mind the monstrosity that would be trying to use the C++ user-defined literal without `using namespace std`: #include <string> using namespace std::operator""s; // Argh! My eyes!You could just wrap that up in an application level string header.
Apr 25 2017
On 24/04/2017 4:03 PM, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!This DIP concerns me, for any other language I would go so far as to saying, I would expect people to overuse this to the extreme. Going by what they "think" they may need in the future instead of what they definitely will need. On the flip side, it would be great for development, feature not yet done but planned? Annotate it. Even before a release ever happens. Although I would prefer to see a unifying syntax to merge deprecated and this into it, making it more user configurable. More complex to design but most importantly less special rules in language.
Apr 24 2017
On Mon, Apr 24, 2017 at 04:58:12PM +0100, rikki cattermole via Digitalmars-d wrote:On 24/04/2017 4:03 PM, Mike Parker wrote:[...]DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.mdThis DIP concerns me, for any other language I would go so far as to saying, I would expect people to overuse this to the extreme. Going by what they "think" they may need in the future instead of what they definitely will need.Initially I also had the same concern, but after reading the DIP in its entirety, I think it may be worth considering. The DIP, as it stands, proposes to make this feature available *only to the compiler* as a hard-coded list of symbols, meaning that in its first incarnation it will only be used for adding new symbols to e.g., druntime. *If* it passes this first round of implementation / general usage in the D community, then a followup DIP can be made to make this feature available to the general user. But if any major issues arise in this first stage, we can simply forego further implementation, perhaps even revert the feature. I think this is a perfectly acceptable implementation plan. IMO it's worth a try. (And I would make it a point that IMO the first implementation of this DIP should NOT make this feature generally available to the user; that should be done only as a followup DIP.)On the flip side, it would be great for development, feature not yet done but planned? Annotate it. Even before a release ever happens.[...] This is good and bad. If overused, it could lead to the situation you described, where people aggressively "reserve" future symbols that eventually turn out to be unnecessary, thus potentially "wasting" good names in the namespace. T -- WINDOWS = Will Install Needless Data On Whole System -- CompuMan
Apr 25 2017
On 4/25/17 12:24 PM, H. S. Teoh via Digitalmars-d wrote:On Mon, Apr 24, 2017 at 04:58:12PM +0100, rikki cattermole via Digitalmars-d wrote:I missed this part. Now that I read that, I think we aren't going to gain much by having this language feature internal to the compiler. If we want to limit usage, what I'd *rather* see is that the future (or TBD attribute) only has special meaning inside object.d. Having to adjust a hard-coded compiler list seems like it will result in zero PR changes (save the one that prompted this DIP) that might give us any insight into whether this is a useful feature. If this DIP does not address the actual language, I would vote no. You can always make a special case solution in the compiler without a DIP.On 24/04/2017 4:03 PM, Mike Parker wrote:[...]DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.mdThis DIP concerns me, for any other language I would go so far as to saying, I would expect people to overuse this to the extreme. Going by what they "think" they may need in the future instead of what they definitely will need.Initially I also had the same concern, but after reading the DIP in its entirety, I think it may be worth considering. The DIP, as it stands, proposes to make this feature available *only to the compiler* as a hard-coded list of symbols, meaning that in its first incarnation it will only be used for adding new symbols to e.g., druntime. *If* it passes this first round of implementation / general usage in the D community, then a followup DIP can be made to make this feature available to the general user. But if any major issues arise in this first stage, we can simply forego further implementation, perhaps even revert the feature.I think this is not really that big of a deal. Other than object.d, there's nothing people absolutely have to include. Just don't import libraries that abuse this, and you won't have this problem. I'd also hazard to guess that a very popular project that abused this feature would simply develop forks which didn't. -SteveOn the flip side, it would be great for development, feature not yet done but planned? Annotate it. Even before a release ever happens.[...] This is good and bad. If overused, it could lead to the situation you described, where people aggressively "reserve" future symbols that eventually turn out to be unnecessary, thus potentially "wasting" good names in the namespace.
Apr 25 2017
On Tuesday, 25 April 2017 at 18:32:09 UTC, Steven Schveighoffer wrote:I missed this part. Now that I read that, I think we aren't going to gain much by having this language feature internal to the compiler.The way I understood it, the feature will only stay internal to the compiler until it's deemed "safe" for general use.If we want to limit usage, what I'd *rather* see is that the future (or TBD attribute) only has special meaning inside object.d. Having to adjust a hard-coded compiler list seems like it will result in zero PR changes (save the one that prompted this DIP) that might give us any insight into whether this is a useful feature.The proposal does include something like that.Alternatively, if it proves to be simpler to implement, the feature can be added as an attribute with reserved double-underscore prefix (i.e. __future) with compiler checks ensuring that it is not used outside of core.*/std.*/object modules. If that course of action is chosen, such an attribute should be defined in the core.attribute module of DRuntime.
Apr 26 2017
On 4/26/17 4:32 AM, Olivier FAURE wrote:On Tuesday, 25 April 2017 at 18:32:09 UTC, Steven Schveighoffer wrote:The question I have is: who is going to adjust this list? If the answer is nobody, then when is it deemed "safe" for general use? How do we judge whether it's safe to allow others to use it, when nobody is using it? What's more useful to me is to require the future attribute on all new symbols in object.d, and then see how that process works. Given that the very nature of future is that it's supposed to be temporary, then if we decide it's not worth the hassle, we can just abandon the feature.I missed this part. Now that I read that, I think we aren't going to gain much by having this language feature internal to the compiler.The way I understood it, the feature will only stay internal to the compiler until it's deemed "safe" for general use.I may have missed it. There's a lot of text, it's hard to see what is actually being proposed and what isn't.If we want to limit usage, what I'd *rather* see is that the future (or TBD attribute) only has special meaning inside object.d. Having to adjust a hard-coded compiler list seems like it will result in zero PR changes (save the one that prompted this DIP) that might give us any insight into whether this is a useful feature.The proposal does include something like that.I'm wondering if you actually wrote this? It seems to be quoted. Sure, we can allow such a thing, and prepending double underscores seems like a reasonable thing, since this should be used lightly and infrequently. -SteveAlternatively, if it proves to be simpler to implement, the feature can be added as an attribute with reserved double-underscore prefix (i.e. __future) with compiler checks ensuring that it is not used outside of core.*/std.*/object modules. If that course of action is chosen, such an attribute should be defined in the core.attribute module of DRuntime.
Apr 26 2017
On Wednesday, 26 April 2017 at 11:26:19 UTC, Steven Schveighoffer wrote:I'm wondering if you actually wrote this? It seems to be quoted.That was a quote from the DIP. (guess I should have used a colon)
Apr 28 2017
On 4/28/17 4:31 AM, Olivier FAURE wrote:On Wednesday, 26 April 2017 at 11:26:19 UTC, Steven Schveighoffer wrote:Ah, OK. Sorry for the confusion, I wasn't sure where it came from. -SteveI'm wondering if you actually wrote this? It seems to be quoted.That was a quote from the DIP. (guess I should have used a colon)
Apr 30 2017
On Monday, 24 April 2017 at 15:58:12 UTC, rikki cattermole wrote:On the flip side, it would be great for development, feature not yet done but planned? Annotate it. Even before a release ever happens.This is not the intended usage of this DIP. The intention here is to only mark symbols that are already implemented but to avoid breakage without a clean (non-breaking) update path in a development branch. This is not to "reserve" symbols for future plan. Even when at first this is intended to be used only internally by the compiler (and runtime), I will give a more general example: In semver terms, suppose that you have a library at v1.0.0 release and you want to add a symbol to a base case that is supposed to be subclassed by user code. Normally you will do this in a v1.1.0 release, since you are adding a new feature, but since adding a new method to a base class is not really a non-breaking change, because if user code added a method with the same name in a subclass, then it will break. So this change needs to be delayed for v2.0.0, you write the code in that branch to add the method. You don't just plan it. Then you go to v1.x.x branch add the ` future` declaring that the symbol will appear in an upcoming release. So when you release v1.1.0 your user gets a nice warning and can plan how to adapt his code to the upcoming v2.0.0. At some point the user upgrades to v2.0.0 and since he had a clean non-breaking update path, what in essence will be a breaking change actually never really broke the user's code (if he incrementally upgraded from v1.0.0 to v1.1.0 and then v2.0.0). Boom! This not only allows the user to do incremental upgrades without *ever* breaking his code, it also *encourages* users to stay up to date, since doing so guarantees no breaking changing, while making a big jump from an old version to a newer one will in fact break his code. This is the spirit of this DIP. Of course it could be abused, as many other features, this is why it is suggested that at first it's only available to the compiler. But even if it makes it to the user (which I think it will be very beneficial for D), if a library author abuses this feature, just educate them, ask not to reserve arbitrary symbols as reserving symbols that are not used in the short term just annoys the users for no reason. Is like if a library author would change the name of the functions in every release just for fun. Of course he could do it, but what would be the point to it?
May 10 2017
On Monday, 24 April 2017 at 15:03:53 UTC, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md+1 I like the idea of beeing warned about new symbols in libraries, so that I can change my symbols ahead.
Apr 25 2017
On 2017-04-24 17:03, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!How is this supposed to be used? * Take the example of the recent __cmp addition to object.d, would we say: "this PR has to wait one year because we need to add the future attribute and let users update their code"? * When the future attribute is added, would one add it on a dummy symbol or would one provide the implementation as well? * If the implementation is provided, is it possible to use the symbol by the users the symbol was added for in the beginning? In the above example that would be the compiler generating a code to __cmp -- /Jacob Carlborg
Apr 25 2017
On 25/04/2017 12:29 PM, Jacob Carlborg wrote:On 2017-04-24 17:03, Mike Parker wrote:Mitigation: version(none) { void foo() { ... } } else { future void foo(); }DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!How is this supposed to be used? * Take the example of the recent __cmp addition to object.d, would we say: "this PR has to wait one year because we need to add the future attribute and let users update their code"?
Apr 25 2017
On 4/25/17 7:29 AM, Jacob Carlborg wrote:On 2017-04-24 17:03, Mike Parker wrote:__symbol is reserved by the language. I don't think we need to worry about those. In the general case, one year is too long. A couple compiler releases should be sufficient.DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!How is this supposed to be used? * Take the example of the recent __cmp addition to object.d, would we say: "this PR has to wait one year because we need to add the future attribute and let users update their code"?* When the future attribute is added, would one add it on a dummy symbol or would one provide the implementation as well?dummy symbol. Think of it as disable, but with warning output instead of error.* If the implementation is provided, is it possible to use the symbol by the users the symbol was added for in the beginning? In the above example that would be the compiler generating a code to __cmpI would think the implementation should not be provided. The idea is to reserve the symbol for future use, not to implement it. If you add an implementation and the compiler allows using that implementation, then you potentially break code. This DIP should aim not to break any code. Really, what you are doing is reserving the overload spot. In cases where the overload would have selected your local function, then you should get no warning (as the additional symbol won't conflict). In cases where your function conflicts with a newly-reserved base class function, then the warning should be that you will eventually need to include the `override` keyword. Actually, that brings up a problem with this, what is the mechanism to say "maybe override"? Let's say you have: // in imported library class Base { void foo() future; } // in user library class Derived : Base { void foo() {...} // triggers warning } What is the next step the user has to take to remove the deprecation warning, but still have valid code? If you put override on foo, it's not really overriding anything as Base.foo doesn't really exist (right?). Basically, we need a way to write Derived such that it works with both the future reserved Base.foo, and the permanent Base.foo. With deprecation, the path is clear, you just stop using that symbol. This is not as clear. If adding override is allowed even when base symbol doesn't really exist, that might work, but it needs to be explicit in the DIP. -Steve
Apr 25 2017
On Tuesday, 25 April 2017 at 12:33:44 UTC, Steven Schveighoffer wrote:Really, what you are doing is reserving the overload spot. In cases where the overload would have selected your local function, then you should get no warning (as the additional symbol won't conflict). In cases where your function conflicts with a newly-reserved base class function, then the warning should be that you will eventually need to include the `override` keyword. Actually, that brings up a problem with this, what is the mechanism to say "maybe override"? Let's say you have: // in imported library class Base { void foo() future; } // in user library class Derived : Base { void foo() {...} // triggers warning } What is the next step the user has to take to remove the deprecation warning, but still have valid code? If you put override on foo, it's not really overriding anything as Base.foo doesn't really exist (right?). Basically, we need a way to write Derived such that it works with both the future reserved Base.foo, and the permanent Base.foo. With deprecation, the path is clear, you just stop using that symbol. This is not as clear. If adding override is allowed even when base symbol doesn't really exist, that might work, but it needs to be explicit in the DIP.This is a very good point. We'll send a PR with a proposed solution to address this issue soon. Thanks!
May 10 2017
On Tuesday, 25 April 2017 at 12:33:44 UTC, Steven Schveighoffer wrote:Actually, that brings up a problem with this, what is the mechanism to say "maybe override"? Let's say you have: // in imported library class Base { void foo() future; } // in user library class Derived : Base { void foo() {...} // triggers warning } What is the next step the user has to take to remove the deprecation warning, but still have valid code?Right now I have two possible approaches in mind. One is to simply allow overriding ` future` symbol which doesn't require any extra stuff but can be viewed sub-optimal because it couples two loosely related concepts and would require special cases in how future symbols are handled inside compiler (they stop being completely ephemeral). Other would be an accompanying DIP to be able to specify `overide(strict)` (default, same as plain `override`) vs `override(optional)` to be able to define methods that may or may not override base one, with no specific relation to ` future`. I don't have any hard opinion on the matter of my own, what do you think?
May 10 2017
On 5/10/17 11:15 AM, Dicebot wrote:On Tuesday, 25 April 2017 at 12:33:44 UTC, Steven Schveighoffer wrote:I prefer the first one. The reason is simply because it doesn't require any new grammar. The override requirement is already a protection against changing base class. In this case, we have two possible outcomes: 1. The base class finally implements the method and removes future. In this case, the derived class continues to function as expected, overriding the new function. 2. The base class removes the method. In this case, the override now fails to compile. This is not as ideal, as this does not result in a version that will compile with two consecutive versions of the base. But there is a possible path for this too -- mark it as deprecated future :) -SteveActually, that brings up a problem with this, what is the mechanism to say "maybe override"? Let's say you have: // in imported library class Base { void foo() future; } // in user library class Derived : Base { void foo() {...} // triggers warning } What is the next step the user has to take to remove the deprecation warning, but still have valid code?Right now I have two possible approaches in mind. One is to simply allow overriding ` future` symbol which doesn't require any extra stuff but can be viewed sub-optimal because it couples two loosely related concepts and would require special cases in how future symbols are handled inside compiler (they stop being completely ephemeral). Other would be an accompanying DIP to be able to specify `overide(strict)` (default, same as plain `override`) vs `override(optional)` to be able to define methods that may or may not override base one, with no specific relation to ` future`. I don't have any hard opinion on the matter of my own, what do you think?
May 10 2017
On Thursday, 11 May 2017 at 00:04:52 UTC, Steven Schveighoffer wrote:I prefer the first one. The reason is simply because it doesn't require any new grammar. The override requirement is already a protection against changing base class. In this case, we have two possible outcomes: 1. The base class finally implements the method and removes future. In this case, the derived class continues to function as expected, overriding the new function. 2. The base class removes the method. In this case, the override now fails to compile. This is not as ideal, as this does not result in a version that will compile with two consecutive versions of the base. But there is a possible path for this too -- mark it as deprecated future :) -SteveSounds reasonable. I'll submit an update to the DIP.
May 11 2017
On 04/25/2017 08:33 AM, Steven Schveighoffer wrote:In the general case, one year is too long. A couple compiler releases should be sufficient.This is a pointless limitation. What is the benefit of requiring the author to *not* provide an implementation until the transition period is over? It runs counter to normal workflow. Instead, why not just say "Here's a new function. But !!ZOMG!! what if somebody is already using a function by that name??!? They'd have use FQNs to disambiguate! Gasp!!! We can't have that! So, fine, if it's that big of a deal, we'll just instruct the compiler to just NOT pick up this function unless it's specifically requested via FQN". That sounds FAR better to me than "Here's a new function, but we gotta keep it hidden in a separate branch/version/etc and not let anyone use it until we waste a bunch of time making sure everyone's code is all updated and ready so that once we let people use it nobody will have to update their code with FQNs, because we can't have that, can we?" Pardon me for saying so, and so bluntly, but honestly, this whole discussion is just stupid. It's full-on C++-grade anti-breakage hysteria. There are times when code breakage is a legitimate problem. This is not REMOTELY one of them.* When the future attribute is added, would one add it on a dummy symbol or would one provide the implementation as well?dummy symbol. Think of it as disable, but with warning output instead of error.
May 10 2017
On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:On 04/25/2017 08:33 AM, Steven Schveighoffer wrote:The idea (I think) is to have a version of the library that functions *exactly* like the old version, but helpfully identifies where a future version will not function properly. This is like deprecate. You don't put a deprecate on a symbol and at the same time remove the symbol's implementation -- you leave it as it was, and just tag it so the warning shows up. That's step one.In the general case, one year is too long. A couple compiler releases should be sufficient.This is a pointless limitation. What is the benefit of requiring the author to *not* provide an implementation until the transition period is over? It runs counter to normal workflow.* When the future attribute is added, would one add it on a dummy symbol or would one provide the implementation as well?dummy symbol. Think of it as disable, but with warning output instead of error.Instead, why not just say "Here's a new function. But !!ZOMG!! what if somebody is already using a function by that name??!? They'd have use FQNs to disambiguate! Gasp!!! We can't have that! So, fine, if it's that big of a deal, we'll just instruct the compiler to just NOT pick up this function unless it's specifically requested via FQN".The point is not to break code without fair warning. This is the progression I have in mind: In Library version 1 (LV1), the function doesn't exist. In LV2, the function is marked as future. In LV3, the function is implemented and the future tag is removed. LV1 + user code version 1 (UCV1) -> works * library writer updates his version LV2 + UCV1 -> works, but warns that it will not work in a future version. * user updates his code to mitigate the potential conflict LV2 + UCV2 -> works, no warnings. LV3 + UCV2 -> works as expected. The important thing here is that the library writer gives fair warning that a breaking change is coming, giving the user time to update his code at his convenience. If he does so before the next version of the library comes out, then his code works for both the existing library version AND the new one without needing to rush a change through.That sounds FAR better to me than "Here's a new function, but we gotta keep it hidden in a separate branch/version/etc and not let anyone use it until we waste a bunch of time making sure everyone's code is all updated and ready so that once we let people use it nobody will have to update their code with FQNs, because we can't have that, can we?"It depends on both the situation and the critical nature of the symbol in question. I'd say the need for this tag is going to be very rare, but necessary when it is needed. I don't think there's a definitive methodology for deciding when it's needed and when it's not. Would be case-by-case.Pardon me for saying so, and so bluntly, but honestly, this whole discussion is just stupid. It's full-on C++-grade anti-breakage hysteria. There are times when code breakage is a legitimate problem. This is not REMOTELY one of them.This is not anti-breakage. Code is going to break. It's just a warning that the breaking is coming. -Steve
May 11 2017
On 05/11/2017 07:19 AM, Steven Schveighoffer wrote:On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:Yes, I'm aware that's the idea the author had in mind, but that still doesn't begin to address this: What is the *benefit* of requiring of requiring the author to *not* provide an implementation until the transition period is over? I maintain there is no benefit to that. Drawing a parallel to "how you do it with deprecated symbols" is not demonstrating a benefit. For that matter, I see the parallel with deprecated symbols as being "The deprecation tag goes with an implemented function. Symmetry would imply that a 'newly added' tag also goes on an implemented function." So the symmetry arguments goes both ways. But regardless, what we *don't* usually do is develop functionality *after* first finalizing its name. That's just silly.This is a pointless limitation. What is the benefit of requiring the author to *not* provide an implementation until the transition period is over? It runs counter to normal workflow.The idea (I think) is to have a version of the library that functions *exactly* like the old version, but helpfully identifies where a future version will not function properly. This is like deprecate. You don't put a deprecate on a symbol and at the same time remove the symbol's implementation -- you leave it as it was, and just tag it so the warning shows up. That's step one.The point is not to break code without fair warning. This is the progression I have in mind: In Library version 1 (LV1), the function doesn't exist. In LV2, [the lib author makes a guess that they're going to write afunction with a particular name and the] function is marked as future.In LV3, the function is implemented and the future tag is removed.Fixed step 2 for you. And yes, that *is* the progression suggested by this DIP, but one of my key points is: that's a downright silly progression. This is better: - In Library version 1 (LV1), the function doesn't exist. - In LV2, the new function is marked as new_symbol to prevent the (somehow) TERRIBLE HORRIBLE AWFUL consequence of the new symbol causing people to be required to toss in a FQN, but there's no harm in STOPPING people from actually using the new functionality if they request it unambiguously, now is there? No, there isn't. - In LV3, the new_symbol tag is removed.The important thing here is that the library writer gives fair warning that a breaking change is coming, giving the user time to update his code at his convenience.Or, if the tag is added to the actual implementation then there IS NO FREAKING BREAKING CHANGE until the new_func or whatever tag is removed, but the library user is STILL given fair (albiet useless, imo) warning that it will be (kinda sorta) broken (with a downright trivial fix) in a followup release.I'd say the need for this tag is going to be very rare,That's for certain.but necessary when it is needed.I can't even begin to comprehend a situation where a heads-up about a mere "FQN needed here" qualifies as something remotely as strong as "necessary". Unless the scenario hinges on the current brokenness of FQNs, which seriously need to be fixed anyway.I don't think there's a definitive methodology for deciding when it's needed and when it's not. Would be case-by-case.Sounds like useless cognitive bother on the library author for extremely minimal (at best) benefit to the library user. Doesn't sound like sufficient justification for a new language feature to me.This is not anti-breakage. Code is going to break. It's just a warning that the breaking is coming.It's going out of the way to create and use a new language feature purely out of fear of a trivial breakage situation. Actual breakage or not, it's "all breakages are scary and we must bend over backwards because of them" paranoia, just the same.
May 11 2017
On 5/11/17 1:21 PM, Nick Sabalausky (Abscissa) wrote:On 05/11/2017 07:19 AM, Steven Schveighoffer wrote:How does this work? class Base { void foo() future { ... } } class Derived : Base { void foo() { ... } } void bar(Base b) // could be instance of Derived { // which one is called? Derived.foo may not have been intended for // the same purpose as Base.foo b.foo(); }On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:Yes, I'm aware that's the idea the author had in mind, but that still doesn't begin to address this: What is the *benefit* of requiring of requiring the author to *not* provide an implementation until the transition period is over?This is a pointless limitation. What is the benefit of requiring the author to *not* provide an implementation until the transition period is over? It runs counter to normal workflow.The idea (I think) is to have a version of the library that functions *exactly* like the old version, but helpfully identifies where a future version will not function properly. This is like deprecate. You don't put a deprecate on a symbol and at the same time remove the symbol's implementation -- you leave it as it was, and just tag it so the warning shows up. That's step one.No, an implementation is in mind and tested. Just not available. You could even have the implementation commented out. In Phobos/Druntime, we wouldn't accept such a prospect without requiring a fleshing out of the details ahead of time. If it makes sense to just add the symbol with an implementation, then I'd rather do that. Otherwise, we create a new way to overload/override, and suddenly things work very differently than people are used to. Suddenly templates start calling the wrong thing and code actually breaks before a change is actually made.The point is not to break code without fair warning. This is the progression I have in mind: In Library version 1 (LV1), the function doesn't exist. In LV2, [the lib author makes a guess that they're going to write afunction with a particular name and the] function is marked as future.In LV3, the function is implemented and the future tag is removed.Fixed step 2 for you.And yes, that *is* the progression suggested by this DIP, but one of my key points is: that's a downright silly progression. This is better: - In Library version 1 (LV1), the function doesn't exist. - In LV2, the new function is marked as new_symbol to prevent the (somehow) TERRIBLE HORRIBLE AWFUL consequence of the new symbol causing people to be required to toss in a FQN, but there's no harm in STOPPING people from actually using the new functionality if they request it unambiguously, now is there? No, there isn't. - In LV3, the new_symbol tag is removed.It's also possible to implement the symbol with a different temporary name, and use that name if you need it before it's ready. I'm just more comfortable with a symbol that changes absolutely nothing about how a function can be called, but is a warning that something is coming than I am with a callable symbol that acts differently in terms of overloading and overriding. I'll admit, I'm not the DIP author, and I don't know the intention of whether the implementation is allowed to be there or not.Not sure I agree there would be no breakage. The symbol is there, it can be called in some cases. This changes behavior without warning. I've had my share of is(typeof(trycallingThis())) blow up spectacularly in ways I didn't predict. To change what happens there is a bad idea IMO. -SteveThe important thing here is that the library writer gives fair warning that a breaking change is coming, giving the user time to update his code at his convenience.Or, if the tag is added to the actual implementation then there IS NO FREAKING BREAKING CHANGE until the new_func or whatever tag is removed, but the library user is STILL given fair (albiet useless, imo) warning that it will be (kinda sorta) broken (with a downright trivial fix) in a followup release.
May 11 2017
On 4/24/17 11:03 AM, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language authors. Thanks in advance to all who participate. Destroy!As I mentioned elsewhere, an intermediate step for a symbol that will eventually need an override needs to be outlined. When you create a base class member that conflicts with existing derived class members, the mitigation may not simply be "you have to remove the derived function", it could also be to override the future function. How do you override a function that doesn't really exist? I like the general idea, and it makes sense, even if it only affects a small set of files (those that are heavily imported). -Steve
Apr 25 2017
This is what FQNs are for. At least, it was before FQNs were broken, first by an incomplete "package.d" system and second by a goofy half-baked change to import rules. FQNs need fixed. This DIP is just a questionable workaround for our borked FQNs that that smacks of C++-style "no breakage at all costs" design philosophies being applied to both D language and D libraries.
May 10 2017
On 05/10/2017 09:51 PM, Nick Sabalausky (Abscissa) wrote:This is what FQNs are for. At least, it was before FQNs were broken, first by an incomplete "package.d" system and second by a goofy half-baked change to import rules. FQNs need fixed. This DIP is just a questionable workaround for our borked FQNs that that smacks of C++-style "no breakage at all costs" design philosophies being applied to both D language and D libraries.I guess that's my overview. More specifically, what I mean is this: D's system of fully-qualified names ("FQNs") was intended to address the matter of conflicting symbols: When a symbol name is ambiguous, instead of blindly choosing one, the compiler errors and forces the programmer to clarify. For this DIP to be convincing, I would need to see this DIP address the following: 1. Why it would be insufficient to simply rely on D's system of FQNs (if fixed from their current admittedly half-broken state)? Currently, FQNs are not addressed, or even mentioned at all, in the "Existing solutions" section. 2. Why having to disambiguate a symbol with a FQN when upgrading a library is a sufficiently large problem to justify a new language feature. (This would seem very difficult to justify, since with or without this DIP, programmer will be informed by the compiler either way that they need to disambiguate which symbol they want). Aside from FQNs, I have additional concerns: 3. Can we even except a library's author to *reliably* know ahead of time they're going to add a symbol with a particular name? Seems to me a library author would need a magic crystal ball to make effective use of this feature... 4. Unless...once they've developed a new version of their lib that's sufficiently close to release that they know that their API changes won't...umm...change any further, then they retroactively create an interim "transition" release which adds these "future" declarations...so that the programmer knows they need to adjust their code to *anyway* when compiling with the new version. So what's the point? 5. Once the programmer *is* informed they need to disambiguate a symbol (via this DIP or via a normal ambiguous symbol error), it's an inherently trivial (and inherently backwards-compatible) fix (which can't always be said of fixing removed-symbol deprecations - as this DIP tries to draw parallels to). So, unlike deprecated symbols, I fail to see what non-trivial benefit is to be gained by an "early notification" of a to-be-added symbol. I think this DIP would have merit in a language that had a tendency for symbols to hijack each other. But D's module system already eliminates that, so AFAICT, the only thing this DIP is left "improving" is to allow lib authors, only under very select circumstances, to go out of their way to provide ahead-of-time notice of a guaranteed-trivial fix they must make (at least once FQNs are actually fixed). Therefore, I find the whole idea extremely unconvincing.
May 10 2017
On 05/10/2017 11:04 PM, Nick Sabalausky (Abscissa) wrote:On 05/10/2017 09:51 PM, Nick Sabalausky (Abscissa) wrote:Ugh, frustrating... Seems like every time I try to clarify something I manage to make a jumbled mess of it. Lemme see one last time if I can distill that down my basic counter-arguments: 1. Why are FQNs alone (assume they still worked like they're supposed to) not good enough? Needs to be addressed in DIP. Currently isn't. 2. The library user is already going to be informed they need to fix an ambiguity anyway, with or without this DIP. 3. Updating code to fix the ambiguity introduced by a new symbol is always trivial (or would be if FQNs were still working properly and hadn't become needlessly broken) and inherently backwards-compatible with the previous version of the lib. 3. Unlike deprecations, this only provides a heads-up for trivial matters that don't really need a heads-up notice: Unlike when symbols being added to a lib, the fix in user-code for a deprecation *can* be non-trivial and *can* be non-backwards-compatible with the previous version of the lib, depending on the exact circumstances. Therefore, unlike added symbols, the "deprecation" feature for removed symbols is justified. 4. Unlike deprecation, this feature works contrary to the actual flow of development and basic predictability: When a lib author wants to remove a symbol, they already what the symbol is, what it's named and that they have X or Y reason to remove it. But when a lib author wants to add a symbol, it's more speculative: They don't actually KNOW such details until some feature is actually written, implemented and just about ready for release. At which point it's a bit late, and awkward, to go putting in a "foo *will* be added".This is what FQNs are for. At least, it was before FQNs were broken, first by an incomplete "package.d" system and second by a goofy half-baked change to import rules. FQNs need fixed. This DIP is just a questionable workaround for our borked FQNs that that smacks of C++-style "no breakage at all costs" design philosophies being applied to both D language and D libraries.I guess that's my overview. More specifically, what I mean is this:
May 10 2017
On Thursday, 11 May 2017 at 03:46:55 UTC, Nick Sabalausky (Abscissa) wrote:1. Why are FQNs alone (assume they still worked like they're supposed to) not good enough? Needs to be addressed in DIP. Currently isn't.It is already addressed in the DIP. FQNs only help if they are used and current idiomatic D code tends to rely on unqualified imports/names.2. The library user is already going to be informed they need to fix an ambiguity anyway, with or without this DIP.Only if you consider "after compiler/library upgrade your project doesn't work anymore" a sufficient "informing" which we definitely don't.3. Updating code to fix the ambiguity introduced by a new symbol is always trivial (or would be if FQNs were still working properly and hadn't become needlessly broken) and inherently backwards-compatible with the previous version of the lib.Trivial compilation error fixup that takes 5 minutes to address in a single project takes up to one month to propagate across all our libraries in projects per my experience. Actually fixing code is hardly a problem with breaking changes, ever. It is synchronization between developers and projects that makes it so painful. And in override case, there is no backwards compatible solution available at all (see Steven comment).Unlike when symbols being added to a lib, the fix in user-code for a deprecation *can* be non-trivial and *can* be non-backwards-compatible with the previous version of the lib, depending on the exact circumstances. Therefore, unlike added symbols, the "deprecation" feature for removed symbols is justified.Please elaborate. User code fix is always either using FQN or renaming, what non-trivial case comes to your mind?4. Unlike deprecation, this feature works contrary to the actual flow of development and basic predictability: When a lib author wants to remove a symbol, they already what the symbol is, what it's named and that they have X or Y reason to remove it. But when a lib author wants to add a symbol, it's more speculative: They don't actually KNOW such details until some feature is actually written, implemented and just about ready for release. At which point it's a bit late, and awkward, to go putting in a "foo *will* be added".You describe a typical library that doesn't follow SemVer and generally doesn't bother much about providing any upgrade stability. Naturally, such library developer will ignore ` future` completely and keep following same development patterns. Not everyone is like that though. This document (https://github.com/sociomantic-tsunami/neptune/blob/master/doc/lib ary-maintainer.rst) explains the versioning/development model we use for all D libraries and within such model feature that is written in one major version can be added as ` future` in the previous major version at the same time. And for druntime object.d case it is pretty much always worth the gain to delay merging already implemented addition for one release, putting ` future` stub in the one before. There can never be any hurry so there is no way to be "late".
May 11 2017
On 05/11/2017 06:10 AM, Dicebot wrote:On Thursday, 11 May 2017 at 03:46:55 UTC, Nick Sabalausky (Abscissa) wrote:I didn't see that. Certainly not in the "Existing solutions" section. It needs to be there. But in any case, I'm not talking about the "existing solution" of projects *already* using FQNs for things, I'm talking about the "existing solution" of just letting a library user spend two seconds adding an FQN when they need to disambiguate.1. Why are FQNs alone (assume they still worked like they're supposed to) not good enough? Needs to be addressed in DIP. Currently isn't.It is already addressed in the DIP. FQNs only help if they are used and current idiomatic D code tends to rely on unqualified imports/names.I definitely do. But even if you don't, see my " new_func" alternate suggestion.2. The library user is already going to be informed they need to fix an ambiguity anyway, with or without this DIP.Only if you consider "after compiler/library upgrade your project doesn't work anymore" a sufficient "informing" which we definitely don't.This needs to go in the DIP.3. Updating code to fix the ambiguity introduced by a new symbol is always trivial (or would be if FQNs were still working properly and hadn't become needlessly broken) and inherently backwards-compatible with the previous version of the lib.Trivial compilation error fixup that takes 5 minutes to address in a single project takes up to one month to propagate across all our libraries in projects per my experience. Actually fixing code is hardly a problem with breaking changes, ever. It is synchronization between developers and projects that makes it so painful.And in override case, there is no backwards compatible solution available at all (see Steven comment).This needs to be made explicit in the DIP. Currently, I see nothing in the DIP clarifying that FQNs cannot address the override case.For *added* symbols, yes. Which is why I find this DIP to be of questionable value compared to " deprecated". That's what my quoted paragraph above is referring to: *removed* (ie, deprecated) symbols. When a symbol is *removed*, the user code fix is NOT always guaranteed to be trivial. That's what justifies the existence of deprecated. future, OTOH, doesn't meet the same criteria strength because, as you say, when a symbol is added, "User code fix is always either using FQN or renaming".Unlike when symbols being added to a lib, the fix in user-code for a deprecation *can* be non-trivial and *can* be non-backwards-compatible with the previous version of the lib, depending on the exact circumstances. Therefore, unlike added symbols, the "deprecation" feature for removed symbols is justified.Please elaborate. User code fix is always either using FQN or renaming, what non-trivial case comes to your mind?
May 11 2017
On Thursday, 11 May 2017 at 17:35:31 UTC, Nick Sabalausky (Abscissa) wrote:It is mostly discussed in "Comparison with other languages" section - it is not a solution for the DIP problem, it is one of problems the DIP tries to solve. You put it kind of backwards in my opinion.It is already addressed in the DIP. FQNs only help if they are used and current idiomatic D code tends to rely on unqualified imports/names.I didn't see that. Certainly not in the "Existing solutions" section. It needs to be there.This suggestion seems considerably more complex - it requires either additional tools to specify "yes, I truly want to use that new function" or forcing developer to always use FQN to do it. Required compiler changes are likely to be more convoluted too because same symbols would have to be interpreted as regular of "fake" ones depending on the context. Most importantly, I don't see motivation behind it. For conservatively maintained libraries defining no-op stub one version before introducing actual implementation is hardly a problem. Everyone else won't bother about it at all and just add new symbols in a regular manner.Only if you consider "after compiler/library upgrade your project doesn't work anymore" a sufficient "informing" which we definitely don't.I definitely do. But even if you don't, see my " new_func" alternate suggestion.No, it does not. That paragraph is a generic rationale why _any_ breaking changes without deprecation paths are so painful. I have no interest in trying to convince anyone who doesn't get it by now.Trivial compilation error fixup that takes 5 minutes to address in a single project takes up to one month to propagate across all our libraries in projects per my experience. Actually fixing code is hardly a problem with breaking changes, ever. It is synchronization between developers and projects that makes it so painful.This needs to go in the DIP.Yeah, will do.And in override case, there is no backwards compatible solution available at all (see Steven comment).This needs to be made explicit in the DIP. Currently, I see nothing in the DIP clarifying that FQNs cannot address the override case.
May 14 2017
On Monday, 24 April 2017 at 15:03:53 UTC, Mike Parker wrote:DIP 1007 is titled "'future symbol' Compiler Concept". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1007.md All review-related feedback on and discussion of the DIP should occur in this thread. Due to DConf taking place during the review period, the period will be extended by a week. The review period will end at 11:59 PM ET on May 15 (3:59 AM GMT May 16), or when I make a post declaring it complete.This review round is now closed. Thanks to everyone who participated.
May 16 2017