www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - a small study of "deprecate"

reply "monarch_dodra" <monarchdodra gmail.com> writes:
There is some talk going on right now of changing "deprecate" 
into a UDA. There are some people saying that deprecate is 
broken, and proposing some fixes (myself included). Instead of 
concentrating on how to "fix" it, and like to first study "what" 
is broken.

----
What exactly is supposed to be the lifetime of a deprecated 
function? What (default) behavior do we expect from deprecated?

**Timeline**
1. The function can be used normally.
Nothing to say here.

2. The function is *marked* for deprecation.
At this point, the user would like to be served with a warning, 
that he should consider migrating to a new function.

3. The function is fully deprecated. At this point, the user 
shouldn't be using it anymore, but if he really really wants to, 
he should be able to.

4. The function is blasted out of existenc.
----

The problem, IMO, comes from the fact that we actually have no 
way to implement "2". Because of this, there is a major gap in 
our deprecation process.

There is a proposal for "deprecate" to only do a warning. If we 
do this though, what actually happens is that we trade our "3" 
for "2", and we don't have a step were the user should *really* 
stop using the function. Just "that's fine, you can use me, here 
is a warning" to "too late! I don't even exist anymore!"

--------
At this point, I have no solution to propose, but I think I have 
analyzed the root of the problem: "deprecate" is a two-phase 
function: "Fine, you can use me no problem whatsoever" to "too 
late, I'm deprecated! (or even gone)".

The conclusion is that anything short of a "3-state solution" is 
bound to failure. We need a way to tell apart "2" from "3". 
Period.

I'm not going to propose a solution in this post, but I think 
this is a good starting point for more discussion. Thoughts?
Nov 07 2012
next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 07 Nov 2012 13:16:26 -0000, monarch_dodra <monarchdodra gmail.com>  
wrote:
 At this point, I have no solution to propose, but I think I have  
 analyzed the root of the problem: "deprecate" is a two-phase function:  
 "Fine, you can use me no problem whatsoever" to "too late, I'm  
 deprecated! (or even gone)".

 The conclusion is that anything short of a "3-state solution" is bound  
 to failure. We need a way to tell apart "2" from "3". Period.

 I'm not going to propose a solution in this post, but I think this is a  
 good starting point for more discussion. Thoughts?

I agree we want a 3 stage (at least) deprecation model. So the timeline would be.. 1. feature is usable (normal case) 2. feature is under deprecation "deprecate" (compiler issues a warning) 3. feature is "deprecated" (compiler issues an error) The warning in state 2 "deprecate" would point the user to the replacement feature. The error in state 3 "deprecated" would be a normal compiler error, but have an addition message to point the user to the replacement feature. In state 2 "deprecate" the code would be present, but annotated with "deprecate" to show that it was under deprecation. The compiler will still compile and use the code, but will issue the warning. In state 3 "deprecated" the code would no longer be present, instead a "deprecated" annotation would be present, giving the old feature name (symbol) and the additional message. The compiler will fail to compile - issuing the normal error for a missing symbol or what have you then output the deprecated annotation/message. This implies that for stage 3 the compiler has a symbol to deprecated message table which it searches on compile time errors (or similar). Is that the sort of behaviour we want? It could be more complicated, I'm sure, but this seems a nice and simple set of behaviour which would achieve the goal of allowing systematic deprecation. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 07 2012
prev sibling next sibling parent deadalnix <deadalnix gmail.com> writes:
Here is how I see it (and all language fail at that as far as my 
knowledge goes).

Deprecation comes with a date and a message.

Before the date, the dev is presented with the deprecation message when 
compiling. The message explain why the function is deprecated and what 
to use instead.

After the date, the message pops, but now it is an error (unless some 
flag is used).

At some point the function may be removed.
Nov 07 2012
prev sibling next sibling parent "Rob T" <rob ucora.com> writes:
On Wednesday, 7 November 2012 at 14:05:06 UTC, deadalnix wrote:
 Here is how I see it (and all language fail at that as far as 
 my knowledge goes).

 Deprecation comes with a date and a message.

 Before the date, the dev is presented with the deprecation 
 message when compiling. The message explain why the function is 
 deprecated and what to use instead.

 After the date, the message pops, but now it is an error 
 (unless some flag is used).

 At some point the function may be removed.

The message should refer the reader to a resource url for more details on the specific depreciation. --rt
Nov 07 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, November 07, 2012 14:16:26 monarch_dodra wrote:
 I'm not going to propose a solution in this post, but I think
 this is a good starting point for more discussion. Thoughts?

There's a relatively easy solution to this - just add the concept of soft and hard deprecation. Then, in additon to deprecate taking a message (which it finally does now), it could take a value indicating the level of deprecation. e.g. deprecated("use X instead", soft) void func(); or deprecated("use X instead", hard) void func(); or deprecated("use X instead", false) void func(); or deprecated("use X instead", warning) void func(); or whatever we decided to use for the argument to indicate the level of deprecation. But soft would mean that only a warning was given, whereas hard would mean that you'd get an error. Then you make either soft or hard the default (hard would keep the current behavior) so that if it's not provided, that's what's used. You then have normal -> soft -> hard -> gone. The problem is that when this was brought up before, Walter didn't want to do anything ilke this, because he thought that it complicated the feature too much. He liked deprecated being nice and simple. It probably doesn't help that he doesn't like the idea of anything being deprecated in Phobos, and Phobos was the main reason that such a feature change was being requested. So, I don't know what the odds of being able to get something like this are. It's certainly what _I_ would like to see implemented though. - Jonathan M Davis
Nov 07 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, November 07, 2012 15:05:05 deadalnix wrote:
 Here is how I see it (and all language fail at that as far as my
 knowledge goes).
 
 Deprecation comes with a date and a message.
 
 Before the date, the dev is presented with the deprecation message when
 compiling. The message explain why the function is deprecated and what
 to use instead.
 
 After the date, the message pops, but now it is an error (unless some
 flag is used).
 
 At some point the function may be removed.

Date-based stuff was discussed previously and rejected. One of the major reasons that it doesn't work is that there are times when you want to deprecate based on versions rather than dates. But the _really_ big reason not to do that is that if compile my code with version X of the compiler, it should _always_ compile with version X of the compiler. It would result in a big maintenance problem if you couldn't go back and rebuild older versions of a program (or just an older program) with the compiler that it was originally compiled with. It's one thing if it won't compile with a newer version of the compiler or a newer version of the library, but not compiling with the same version that it was developed with causes big problems later down the line, especially if you're dealing with a program that doesn't get worked on very often. So, while giving a message that a particular symbol is going to be deprecated on a certain date is fine, having the compiler deprecate it for you at that date is going to cause problems. - Jonathan M Davis
Nov 07 2012
prev sibling next sibling parent 1100110 <0b1100110 gmail.com> writes:
On Wed, 07 Nov 2012 15:26:20 -0600, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Wednesday, November 07, 2012 14:16:26 monarch_dodra wrote:
 I'm not going to propose a solution in this post, but I think
 this is a good starting point for more discussion. Thoughts?

There's a relatively easy solution to this - just add the concept of soft and hard deprecation. Then, in additon to deprecate taking a message (which it finally does now), it could take a value indicating the level of deprecation. e.g. deprecated("use X instead", soft) void func(); or deprecated("use X instead", hard) void func(); or deprecated("use X instead", false) void func(); or deprecated("use X instead", warning) void func(); or whatever we decided to use for the argument to indicate the level of deprecation. But soft would mean that only a warning was given, whereas hard would mean that you'd get an error. Then you make either soft or hard the default (hard would keep the current behavior) so that if it's not provided, that's what's used. You then have normal -> soft -> hard -> gone. The problem is that when this was brought up before, Walter didn't want to do anything ilke this, because he thought that it complicated the feature too much. He liked deprecated being nice and simple. It probably doesn't help that he doesn't like the idea of anything being deprecated in Phobos, and Phobos was the main reason that such a feature change was being requested. So, I don't know what the odds of being able to get something like this are. It's certainly what _I_ would like to see implemented though. - Jonathan M Davis

Walter seems to like simplicity to the point that you have to work around many of the 'simple' features. It's not 'simple' if you need to hack around it to get the same effect that it should have had in the first place. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 07 2012
prev sibling next sibling parent Don Clugston <dac nospam.com> writes:
On 07/11/12 14:16, monarch_dodra wrote:
 There is some talk going on right now of changing "deprecate" into a
 UDA. There are some people saying that deprecate is broken, and
 proposing some fixes (myself included). Instead of concentrating on how
 to "fix" it, and like to first study "what" is broken.

 ----
 What exactly is supposed to be the lifetime of a deprecated function?
 What (default) behavior do we expect from deprecated?

 **Timeline**
 1. The function can be used normally.
 Nothing to say here.

 2. The function is *marked* for deprecation.
 At this point, the user would like to be served with a warning, that he
 should consider migrating to a new function.

 3. The function is fully deprecated. At this point, the user shouldn't
 be using it anymore, but if he really really wants to, he should be able
 to.

 4. The function is blasted out of existenc.
 ----

 The problem, IMO, comes from the fact that we actually have no way to
 implement "2". Because of this, there is a major gap in our deprecation
 process.

You are quite wrong. The problem is 3. There's actually nothing wrong with "deprecated", the problem is the -d command line option. Suppose you want to continue using the function. There is no reasonable way of doing it. If you use the -d option, you will not be notified about 2. If something else is deprecated, you won't find out about it. Basically -- a warning should ALWAYS be printed for deprecated functions, even if you are using -d. It's that simple. There is a pull request to fix this situation. I don't know why this discussion is happening.
Nov 08 2012
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 8 November 2012 at 08:10:36 UTC, Don Clugston wrote:
 On 07/11/12 14:16, monarch_dodra wrote:
 There is some talk going on right now of changing "deprecate" 
 into a
 UDA. There are some people saying that deprecate is broken, and
 proposing some fixes (myself included). Instead of 
 concentrating on how
 to "fix" it, and like to first study "what" is broken.

 ----
 What exactly is supposed to be the lifetime of a deprecated 
 function?
 What (default) behavior do we expect from deprecated?

 **Timeline**
 1. The function can be used normally.
 Nothing to say here.

 2. The function is *marked* for deprecation.
 At this point, the user would like to be served with a 
 warning, that he
 should consider migrating to a new function.

 3. The function is fully deprecated. At this point, the user 
 shouldn't
 be using it anymore, but if he really really wants to, he 
 should be able
 to.

 4. The function is blasted out of existenc.
 ----

 The problem, IMO, comes from the fact that we actually have no 
 way to
 implement "2". Because of this, there is a major gap in our 
 deprecation
 process.

You are quite wrong. The problem is 3. There's actually nothing wrong with "deprecated", the problem is the -d command line option. Suppose you want to continue using the function. There is no reasonable way of doing it. If you use the -d option, you will not be notified about 2. If something else is deprecated, you won't find out about it. Basically -- a warning should ALWAYS be printed for deprecated functions, even if you are using -d. It's that simple. There is a pull request to fix this situation. I don't know why this discussion is happening.

So you are saying: keep the current behavior, but also print a warning in -d mode?
Nov 08 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, November 08, 2012 10:12:52 monarch_dodra wrote:
 So you are saying: keep the current behavior, but also print a
 warning in -d mode?

It makes far more sense for deprecated stuff to warn by default rather than give an error. It's the fact that it gives an error that makes it so hard to use in Phobos right now. If it just warned, deprecating stuff would encourage people to use new stuff but not break code. I do agree though that turning off deprecation messages entirely is ugly. The result at present if you have deprecated stuff in your code, you ethire get hit with errors due to deprecated stuff and fix your code, or you use -d to shut it up, and then see nothing and have no idea what you need to fix in your code. We've missed cases in Phobos where deprecated stuff was still being used because Phobos compiles with -d. -d really is not a great flag. If we want to fix the flags, it should be warn by default and error with a specific flag. I'd suggest making it -dw to match -w, but I don't much care what the name is so long as it's reasonable. - Jonathan M Davis
Nov 08 2012