www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Thoughts about deprecation

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Deprecation is a nice feature.  There doesn't seem to be any doubt about it.

But it's by no means perfect, compiler bugs aside.  I have identified these
ideals of 
deprecation:

(a) Code that compiles without -d compiles and behaves the same with -d.

(b) Code that compiles without -d compiles and behaves the same if all entities
declared 
as deprecated are removed from the code.

(c) Code that compiles with or without -d compiles and behaves the same if all
deprecated 
entities are de-deprecated.

(d) Code that compiles without -d either compiles and behaves the same, or
fails to 
compile at all, if any entities are newly deprecated (i.e. does not silently
change its 
behaviour).

(e) Validity checking through compile-time reflection is always consistent with
whether 
the compiler actually accepts the code.

(OK, so the switch used to enable deprecated entities might vary between brands
of 
compiler, but I've used "-d" here for simplicity.)


But these ideals cannot all be satisfied at once.

The main reason for this seems to be compile-time reflection.  My experiment
(under DMD 
1.071 and 2.057) shows that an IsExpression evaluates to false if the compiler
would 
reject it because of deprecation.  This satisfies ideals (b) and (e), but
violates (a), 
(c) and (d).

If we changed it to evaluate to true even if compiling without -d, then it
would satisfy 
(a), (c) and (d), but violate (b) and (e).  Moreover, when/if we get -di
http://d.puremagic.com/issues/show_bug.cgi?id=7041
what would it do if we have deprecation-dependent behaviour?

But deprecated entities aren't always treated as though they're not there if
compiling 
without -d.  For example, deprecated functions take part in overload
resolution.  This is 
necessary in order to satisfy (a), (c) and (d).  Though it doesn't seem to make
any 
difference to (b) or (e).


Maybe DDB is useful at times.  The use case that comes to mind is suppressing
the handling 
of a deprecated property as part of a non-deprecated method.  But still, is
accidentally 
programming DDB in something that needs to be guarded against?  Or do we just
accept DDB 
as a natural, unpreventable consequence of reflection?

I'm not sure whether all ideals would be satisfied in the absence of CTR, or if
there are 
other aspects of D that prevent it from being so.

I suppose the overall point is: Is the current compiler behaviour the best that
can be 
done?  Which ideals of deprecation do we really need to follow, and which can
we do without?


Stewart.
Feb 11 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/12/2012 03:21 AM, Stewart Gordon wrote:
 Deprecation is a nice feature. There doesn't seem to be any doubt about it.

 But it's by no means perfect, compiler bugs aside. I have identified
 these ideals of deprecation:

 (a) Code that compiles without -d compiles and behaves the same with -d.

 (b) Code that compiles without -d compiles and behaves the same if all
 entities declared as deprecated are removed from the code.

 (c) Code that compiles with or without -d compiles and behaves the same
 if all deprecated entities are de-deprecated.

 (d) Code that compiles without -d either compiles and behaves the same,
 or fails to compile at all, if any entities are newly deprecated (i.e.
 does not silently change its behaviour).

 (e) Validity checking through compile-time reflection is always
 consistent with whether the compiler actually accepts the code.

 (OK, so the switch used to enable deprecated entities might vary between
 brands of compiler, but I've used "-d" here for simplicity.)


 But these ideals cannot all be satisfied at once.

 The main reason for this seems to be compile-time reflection. My
 experiment (under DMD 1.071 and 2.057) shows that an IsExpression
 evaluates to false if the compiler would reject it because of
 deprecation. This satisfies ideals (b) and (e), but violates (a), (c)
 and (d).

 If we changed it to evaluate to true even if compiling without -d, then
 it would satisfy (a), (c) and (d), but violate (b) and (e). Moreover,
 when/if we get -di
 http://d.puremagic.com/issues/show_bug.cgi?id=7041
 what would it do if we have deprecation-dependent behaviour?

 But deprecated entities aren't always treated as though they're not
 there if compiling without -d. For example, deprecated functions take
 part in overload resolution. This is necessary in order to satisfy (a),
 (c) and (d). Though it doesn't seem to make any difference to (b) or (e).


 Maybe DDB is useful at times. The use case that comes to mind is
 suppressing the handling of a deprecated property as part of a
 non-deprecated method. But still, is accidentally programming DDB in
 something that needs to be guarded against? Or do we just accept DDB as
 a natural, unpreventable consequence of reflection?

 I'm not sure whether all ideals would be satisfied in the absence of
 CTR, or if there are other aspects of D that prevent it from being so.

 I suppose the overall point is: Is the current compiler behaviour the
 best that can be done? Which ideals of deprecation do we really need to
 follow, and which can we do without?


 Stewart.
I think (e) is not an ideal of deprecation. If a feature is deprecated, then checking whether it compiles should be deprecated too.
Feb 12 2012
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 12/02/2012 14:44, Timon Gehr wrote:
<snip excessive quote>
 I think (e) is not an ideal of deprecation. If a feature is deprecated, then
checking
 whether it compiles should be deprecated too.
Oh yes, that's another possibility. Make an IsExpression on something deprecated emit a deprecation error instead of returning either true or false. This satisfies (a), (b), (c) and (d). And it satisfies a variant of (e): validity checking through compile-time reflection is always either consistent with whether the compiler accepts the code or an error in itself. This already covers the cases where the body of the IsExpression isn't syntactically valid. Though there's a difference there in that the error happens at the parsing stage, rather than the semantic analysis stage. But there's also a difference here in that syntax doesn't depend on code elsewhere in the source file or in other source files, and so there isn't much of a use case for syntactic validity checking as a form of reflection. Stewart.
Feb 12 2012