Re: DIP 1007 Preliminary Review Round 1

2017-05-16 Thread Mike Parker via Digitalmars-d

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.


Re: DIP 1007 Preliminary Review Round 1

2017-05-14 Thread Dicebot via Digitalmars-d

https://github.com/dlang/DIPs/pull/63



Re: DIP 1007 Preliminary Review Round 1

2017-05-14 Thread Dicebot via Digitalmars-d
On Thursday, 11 May 2017 at 17:35:31 UTC, Nick Sabalausky 
(Abscissa) wrote:
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.


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.


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.


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.


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.


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.



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.


Yeah, will do.


Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Steven Schveighoffer via Digitalmars-d

On 5/11/17 1:21 PM, Nick Sabalausky (Abscissa) wrote:

On 05/11/2017 07:19 AM, Steven Schveighoffer wrote:

On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:


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.



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?


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();
}


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 a

function 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.


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.



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.



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.


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.


-Steve


Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 05/11/2017 06:10 AM, Dicebot wrote:

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.



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.



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.


I definitely do. But even if you don't, see my "@new_func" alternate 
suggestion.





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.



This needs to go in the DIP.


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.



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?



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".




Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 05/11/2017 07:19 AM, Steven Schveighoffer wrote:

On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:


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.



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.


> 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 a 
function 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.




Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Steven Schveighoffer via Digitalmars-d

On 5/11/17 12:11 AM, Nick Sabalausky (Abscissa) wrote:

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.



* 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.



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.



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


Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Dicebot via Digitalmars-d
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/library-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".


Re: DIP 1007 Preliminary Review Round 1

2017-05-11 Thread Dicebot via Digitalmars-d
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 :)


-Steve


Sounds reasonable. I'll submit an update to the DIP.


Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

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.



* 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.



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.





Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 05/10/2017 11:04 PM, Nick Sabalausky (Abscissa) wrote:

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:



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".





Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

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 
disambiguate. But again, as in #2, the programmer will be told that 
*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.




Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d
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.


Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Steven Schveighoffer via Digitalmars-d

On 5/10/17 11:15 AM, Dicebot wrote:

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?


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 :)


-Steve


Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Dicebot via Digitalmars-d
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?





Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Leandro Lucarella via Digitalmars-d
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!


Re: DIP 1007 Preliminary Review Round 1

2017-05-10 Thread Leandro Lucarella via Digitalmars-d

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?


Re: DIP 1007 Preliminary Review Round 1

2017-04-30 Thread Steven Schveighoffer via Digitalmars-d

On 4/28/17 4:31 AM, Olivier FAURE wrote:

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)


Ah, OK. Sorry for the confusion, I wasn't sure where it came from.

-Steve


Re: DIP 1007 Preliminary Review Round 1

2017-04-28 Thread Olivier FAURE via Digitalmars-d
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)


Re: DIP 1007 Preliminary Review Round 1

2017-04-26 Thread Steven Schveighoffer via Digitalmars-d

On 4/26/17 4:32 AM, Olivier FAURE wrote:

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.


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.



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 may have missed it. There's a lot of text, it's hard to see what is 
actually being proposed and what isn't.





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.




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.


-Steve


Re: DIP 1007 Preliminary Review Round 1

2017-04-26 Thread Olivier FAURE via Digitalmars-d
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.




Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Steven Schveighoffer via Digitalmars-d

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:

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

[...]

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.


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 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 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.


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.


-Steve


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread H. S. Teoh via Digitalmars-d
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.md
[...]
> 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.

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


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Steven Schveighoffer via Digitalmars-d

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


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Steven Schveighoffer via Digitalmars-d

On 4/25/17 7:29 AM, Jacob Carlborg wrote:

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"?


__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.




* 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 __cmp


I 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


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread rikki cattermole via Digitalmars-d

On 25/04/2017 12:29 PM, Jacob Carlborg wrote:

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"?


Mitigation:

version(none) {
void foo() {
...
}
} else {
@future
void foo();
}


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Jacob Carlborg via Digitalmars-d

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


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Dominikus Dittes Scherkl via Digitalmars-d

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.


Re: DIP 1007 Preliminary Review Round 1

2017-04-25 Thread Ola Fosheim Grøstad via Digitalmars-d

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 
using namespace std::operator""s;  // Argh! My eyes!


You could just wrap that up in an application level string header.



Re: DIP 1007 Preliminary Review Round 1

2017-04-24 Thread Atila Neves via Digitalmars-d
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:

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.


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:


"
# Example

#include
#include
#include
#include
#include

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 
using namespace std::operator""s;  // Argh! My eyes!

No thanks. I even had to look that up, and I'll probably forget 
it.


Re: DIP 1007 Preliminary Review Round 1

2017-04-24 Thread rikki cattermole via Digitalmars-d

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.


Re: DIP 1007 Preliminary Review Round 1

2017-04-24 Thread Ola Fosheim Grøstad via Digitalmars-d

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.


Re: DIP 1007 Preliminary Review Round 1

2017-04-24 Thread Mike Parker via Digitalmars-d-announce

On Monday, 24 April 2017 at 15:14:44 UTC, Mike Parker wrote:

DIP 1006 is titled "'future symbol' Compiler Concept". This


Apologies, this is DIP 1007, not 1006.