Jump to page: 1 2
Thread overview
[Suggestion] More deprecation features
Jul 17, 2008
Stewart Gordon
Jul 17, 2008
Robert Fraser
Jul 17, 2008
Stewart Gordon
Jul 18, 2008
Robert Fraser
Jul 18, 2008
Stewart Gordon
Jul 18, 2008
Koroskin Denis
Jul 18, 2008
Stewart Gordon
Jul 17, 2008
BCS
Jul 17, 2008
Stewart Gordon
Jul 17, 2008
BCS
Jul 18, 2008
Michel Fortin
Jul 18, 2008
Don
Jul 18, 2008
superdan
Jul 18, 2008
Robert Fraser
Jul 18, 2008
BCS
Jul 18, 2008
Stewart Gordon
Jul 18, 2008
Stewart Gordon
July 17, 2008
Now that most of the rusty old deprecation bugs have finally been squashed (if you'll excuse the mixed metaphor), here are a few ideas I've had for a while for taking the concept of deprecation further.


1. Sometimes it's useful to deprecate something, but keep it for internal use.  So effectively it's private, except if compiling with -d, in which case it will be public.  The notation might look something like

   private deprecated public void qwert() { ... }

The error message on trying to use it from outside might look something like

   qwert.d(42): function qwert is deprecated for public access

Other combinations of access levels would be similarly allowed, of which these make sense IMM:

   private deprecated package
   private deprecated protected *
   private deprecated public *
   private deprecated export *
   package deprecated public *
   package deprecated export *
   protected deprecated public
   protected deprecated export
   public deprecated export

Overriding of methods with the asterisked protection settings would be allowed only if the derived class method is also deprecated (or -d is specified).  To declare a method with the same name and parameters in a derived class, without specifying either the deprecated attribute or the -d switch, would be an error.  This is necessary to the principle of deprecation, i.e. code that compiles without -d doesn't change its behaviour when -d is specified, and existing code can still compile.

Of course, implementing this would affect how attributes are parsed.  I suppose the best idea would be to treat each possible case of the word "deprecated" immediately between two protection attributes as a protection attribute in its own right in terms of the way they override each other.


2. A means of deprecating callbacks.  That is, deprecating overriding of a method rather than using it.  This makes sense as callbacks are going to want replacing from time to time, just as callforwards :-) are.  The base class would keep its calls to the method, so that old code will still work, but new or modernised code would not be overriding it anymore.

(This would be provided at least to some extent by idea 1....)


3. Deprecating modules.  Currently, the compiler doesn't allow modules to be declared as deprecated.  A module being deprecated may signify:

- that the whole API area that it is there to support is deprecated, either because it's an obsolete technology or because it's been superseded by another module

- that the module has been renamed, and all the old one does is imports the new one for compatibility

- that it was used for development/testing purposes and is no longer needed


4. Deprecated imports.  So effectively, any attempt to use anything from the imported module would throw a deprecation error, unless a non-deprecated import of the same module is also visible from the scope where the use occurs.  This might be to prevent the compiler error that would otherwise be caused by importing a deprecated module for use by deprecated code.  Or to phase out a public import that was figured to be a bad idea.


Comments?

Stewart.

-- 
My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit. 

July 17, 2008
Stewart Gordon Wrote:

> Now that most of the rusty old deprecation bugs have finally been squashed (if you'll excuse the mixed metaphor), here are a few ideas I've had for a while for taking the concept of deprecation further.
> 
> 
> 1. Sometimes it's useful to deprecate something, but keep it for internal use.  So effectively it's private, except if compiling with -d, in which case it will be public.  The notation might look something like
> 
>     private deprecated public void qwert() { ... }
> 
> The error message on trying to use it from outside might look something like
> 
>     qwert.d(42): function qwert is deprecated for public access
> 
> Other combinations of access levels would be similarly allowed, of which these make sense IMM:
> 
>     private deprecated package
>     private deprecated protected *
>     private deprecated public *
>     private deprecated export *
>     package deprecated public *
>     package deprecated export *
>     protected deprecated public
>     protected deprecated export
>     public deprecated export
> 
> Overriding of methods with the asterisked protection settings would be allowed only if the derived class method is also deprecated (or -d is specified).  To declare a method with the same name and parameters in a derived class, without specifying either the deprecated attribute or the -d switch, would be an error.  This is necessary to the principle of deprecation, i.e. code that compiles without -d doesn't change its behaviour when -d is specified, and existing code can still compile.
> 
> Of course, implementing this would affect how attributes are parsed.  I suppose the best idea would be to treat each possible case of the word "deprecated" immediately between two protection attributes as a protection attribute in its own right in terms of the way they override each other.
> 
> 
> 2. A means of deprecating callbacks.  That is, deprecating overriding of a method rather than using it.  This makes sense as callbacks are going to want replacing from time to time, just as callforwards :-) are.  The base class would keep its calls to the method, so that old code will still work, but new or modernised code would not be overriding it anymore.
> 
> (This would be provided at least to some extent by idea 1....)
> 
> 
> 3. Deprecating modules.  Currently, the compiler doesn't allow modules to be declared as deprecated.  A module being deprecated may signify:
> 
> - that the whole API area that it is there to support is deprecated, either because it's an obsolete technology or because it's been superseded by another module
> 
> - that the module has been renamed, and all the old one does is imports the new one for compatibility
> 
> - that it was used for development/testing purposes and is no longer needed
> 
> 
> 4. Deprecated imports.  So effectively, any attempt to use anything from the imported module would throw a deprecation error, unless a non-deprecated import of the same module is also visible from the scope where the use occurs.  This might be to prevent the compiler error that would otherwise be caused by importing a deprecated module for use by deprecated code.  Or to phase out a public import that was figured to be a bad idea.
> 
> 
> Comments?
> 
> Stewart.
> 
> -- 
> My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit.
> 

All good ideas, but I fear that it's simply too much complication to make it worth doing.
July 17, 2008
Reply to Stewart,

> Now that most of the rusty old deprecation bugs have finally been
> squashed (if you'll excuse the mixed metaphor), here are a few ideas
> I've had for a while for taking the concept of deprecation further.
> 
> 1. Sometimes it's useful to deprecate something, but keep it for
> internal use.  So effectively it's private, except if compiling with
> -d, in which case it will be public.  The notation might look
> something like
> 
> private deprecated public void qwert() { ... }
> 
> The error message on trying to use it from outside might look
> something like
> 
> qwert.d(42): function qwert is deprecated for public access
> 
> Other combinations of access levels would be similarly allowed, of
> which these make sense IMM:
> 
> private deprecated package
> private deprecated protected *
> private deprecated public *
> private deprecated export *
> package deprecated public *
> package deprecated export *
> protected deprecated public
> protected deprecated export
> public deprecated export
> Overriding of methods with the asterisked protection settings would be
> allowed only if the derived class method is also deprecated (or -d is
> specified).  To declare a method with the same name and parameters in
> a derived class, without specifying either the deprecated attribute or
> the -d switch, would be an error.  This is necessary to the principle
> of deprecation, i.e. code that compiles without -d doesn't change its
> behaviour when -d is specified, and existing code can still compile.
> 
> Of course, implementing this would affect how attributes are parsed.
> I suppose the best idea would be to treat each possible case of the
> word "deprecated" immediately between two protection attributes as a
> protection attribute in its own right in terms of the way they
> override each other.
> 
> 2. A means of deprecating callbacks.  That is, deprecating overriding
> of a method rather than using it.  This makes sense as callbacks are
> going to want replacing from time to time, just as callforwards :-)
> are.  The base class would keep its calls to the method, so that old
> code will still work, but new or modernised code would not be
> overriding it anymore.
> 
> (This would be provided at least to some extent by idea 1....)
> 
> 3. Deprecating modules.  Currently, the compiler doesn't allow modules
> to be declared as deprecated.  A module being deprecated may signify:
> 
> - that the whole API area that it is there to support is deprecated,
> either because it's an obsolete technology or because it's been
> superseded by another module
> 
> - that the module has been renamed, and all the old one does is
> imports the new one for compatibility
> 
> - that it was used for development/testing purposes and is no longer
> needed
> 
> 4. Deprecated imports.  So effectively, any attempt to use anything
> from the imported module would throw a deprecation error, unless a
> non-deprecated import of the same module is also visible from the
> scope where the use occurs.  This might be to prevent the compiler
> error that would otherwise be caused by importing a deprecated module
> for use by deprecated code.  Or to phase out a public import that was
> figured to be a bad idea.
> 
> Comments?
> 
> Stewart.
> 


Another solution would be to rename the old function (foo -> foo_int) patch up all internal references and then make a deprecated wrapper function or alias to make the external calls work. That patch up should be doable because if you don't have that code in hand. it probably isn't internal.


July 17, 2008
"Robert Fraser" <fraserofthenight@gmail.com> wrote in message news:g5ofbp$teb$1@digitalmars.com...
<snip excessive quoting>
> All good ideas, but I fear that it's simply too much complication to make it
> worth doing.

If you consider each of my ideas individually, _then_ which do you think are simple enough to be worth doing?

Stewart.

-- 
My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit. 

July 17, 2008
"BCS" <ao@pathlink.com> wrote in message news:55391cb32f4938cab635e371a9d8@news.digitalmars.com...
<snip excessive quote>
> Another solution would be to rename the old function (foo -> foo_int) patch up all internal references and then make a deprecated wrapper function or alias to make the external calls work.

Yes, that's one way of achieving some cases of idea 1....

> That patch up should be doable because if you don't have that code in hand. it probably isn't internal.

What do you mean by this?

Stewart.

-- 
My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit. 

July 17, 2008
Reply to Stewart,

> "BCS" <ao@pathlink.com> wrote in message
> news:55391cb32f4938cab635e371a9d8@news.digitalmars.com... <snip
> excessive quote>
> 
>> Another solution would be to rename the old function (foo -> foo_int)
>> patch up all internal references and then make a deprecated wrapper
>> function or alias to make the external calls work.
>> 
> Yes, that's one way of achieving some cases of idea 1....
> 
>> That patch up should be doable because if you don't have that code in
>> hand. it probably isn't internal.
>> 
> What do you mean by this?
> 

excluding the cases of code going from export to public the programmer who is deprecating the old function more than likely also maintains any code that legitimately should have access to the new non deprecated version. Therefor they can patch up the names them self. For that one exception, that above trick would be a breaking change.

> Stewart.
> 


July 18, 2008
Stewart Gordon Wrote:

> "Robert Fraser" <fraserofthenight@gmail.com> wrote in message
> news:g5ofbp$teb$1@digitalmars.com...
> <snip excessive quoting>
> > All good ideas, but I fear that it's simply too much complication to make
> > it
> > worth doing.
> 
> If you consider each of my ideas individually, _then_ which do you think are simple enough to be worth doing?
> 
> Stewart.
> 
> -- 
> My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit.
> 

Idea 1 -- A workaround has already been posted for that one.

Idea 2-- I don't get this one. By "callback" do you mean deprecating the virtualitry/overridability of a function. I don't think I've ever needed to do that.

Idea 3 -- Okay, that one (deprecating modules) is cool enough; I'm down.

Idea 4 -- If you need to deprecate private imports, your modules are too big. Public imports seem to be sort of iffy to me anyway (except for an "all" module), but is your idea that:

module a;
public struct Foo { };
----
module b;
deprecated public import a;
----
module c;
import b;
Foo foo; // <-- deprecation error here

Then why can't module c just change it to:
----
module c;
import a;
Foo foo;

Unless the public import was exposing some internal functionality...? It just seems like bad design in the first place if you need this.
July 18, 2008
"Robert Fraser" <fraserofthenight@gmail.com> wrote in message news:g5onid$1s64$1@digitalmars.com...
<snip>
> Idea 1 -- A workaround has already been posted for that one.
>
> Idea 2-- I don't get this one. By "callback" do you mean deprecating the
> virtualitry/overridability of a function. I don't think I've ever needed to do
> that.

Effectively yes.  I think I've wanted to do this for SDWF on occasion.

> Idea 3 -- Okay, that one (deprecating modules) is cool enough; I'm down.
>
> Idea 4 -- If you need to deprecate private imports, your modules are too
> big.

You mean bloated with deprecated stuff that should've been deleted ages ago, or what?

> Public imports seem to be sort of iffy to me anyway (except for an
> "all" module), but is your idea that:
>
> module a;
> public struct Foo { };
> ----
> module b;
> deprecated public import a;
> ----
> module c;
> import b;
> Foo foo; // <-- deprecation error here

Yes.

> Then why can't module c just change it to:
> ----
> module c;
> import a;
> Foo foo;

Suppose I acquire the code of an application written using some library. Now suppose that the library has been updated since the application was written.  The library author wanted to deprecate some public imports, but because D doesn't currently let you do this, removed them instead.  Then I cannot compile the application without going through its modules working out how to fix the masses of undefined symbols.  If the imports were merely deprecated, I would need only to add the -d switch in the makefile or whatever.

> Unless the public import was exposing some internal functionality...? It just
> seems like bad design in the first place if you need this.

If that's the case, it's a bigger problem than just a public import.

Stewart.

-- 
My e-mail address is valid but not my primary mailbox.  Please keep replies on the 'group where everybody may benefit. 

July 18, 2008
On 2008-07-16 21:18:01 -0400, "Stewart Gordon" <smjg_1998@yahoo.com> said:

> 3. Deprecating modules.  Currently, the compiler doesn't allow modules to be declared as deprecated.  A module being deprecated may signify:
> 
> - that the whole API area that it is there to support is deprecated, either because it's an obsolete technology or because it's been superseded by another module
> 
> - that the module has been renamed, and all the old one does is imports the new one for compatibility
> 
> - that it was used for development/testing purposes and is no longer needed

I'm with you with that one. You can deprecate everything within a module, but if you have a module which just pose as a group of public imports and you want to deprecate that, then you're somewhat stuck if you can't deprecate the module itself.

   module foo;

   public import bar.a;
   public import bar.b;

So yeah, I think modules should be allowed to be deprecated.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

July 18, 2008
Stewart Gordon wrote:
> Now that most of the rusty old deprecation bugs have finally been squashed (if you'll excuse the mixed metaphor), here are a few ideas I've had for a while for taking the concept of deprecation further.
> 
> 
> 1. Sometimes it's useful to deprecate something, but keep it for internal use.  So effectively it's private, except if compiling with -d, in which case it will be public.  The notation might look something like
> 
>    private deprecated public void qwert() { ... }
> 
> The error message on trying to use it from outside might look something like
> 
>    qwert.d(42): function qwert is deprecated for public access
> 
> Other combinations of access levels would be similarly allowed, of which these make sense IMM:
> 
>    private deprecated package
>    private deprecated protected *
>    private deprecated public *
>    private deprecated export *
>    package deprecated public *
>    package deprecated export *
>    protected deprecated public
>    protected deprecated export
>    public deprecated export
> 
> Overriding of methods with the asterisked protection settings would be allowed only if the derived class method is also deprecated (or -d is specified).  To declare a method with the same name and parameters in a derived class, without specifying either the deprecated attribute or the -d switch, would be an error.  This is necessary to the principle of deprecation, i.e. code that compiles without -d doesn't change its behaviour when -d is specified, and existing code can still compile.
> 
> Of course, implementing this would affect how attributes are parsed.  I suppose the best idea would be to treat each possible case of the word "deprecated" immediately between two protection attributes as a protection attribute in its own right in terms of the way they override each other.
> 
> 
> 2. A means of deprecating callbacks.  That is, deprecating overriding of a method rather than using it.  This makes sense as callbacks are going to want replacing from time to time, just as callforwards :-) are.  The base class would keep its calls to the method, so that old code will still work, but new or modernised code would not be overriding it anymore.
> 
> (This would be provided at least to some extent by idea 1....)
> 
> 
> 3. Deprecating modules.  Currently, the compiler doesn't allow modules to be declared as deprecated.  A module being deprecated may signify:
> 
> - that the whole API area that it is there to support is deprecated, either because it's an obsolete technology or because it's been superseded by another module
> 
> - that the module has been renamed, and all the old one does is imports the new one for compatibility
> 
> - that it was used for development/testing purposes and is no longer needed
> 
> 
> 4. Deprecated imports.  So effectively, any attempt to use anything from the imported module would throw a deprecation error, unless a non-deprecated import of the same module is also visible from the scope where the use occurs.  This might be to prevent the compiler error that would otherwise be caused by importing a deprecated module for use by deprecated code.  Or to phase out a public import that was figured to be a bad idea.
> 
> 
> Comments?
> 
> Stewart.
> 

Suppose there was version(deprecated), which is set only if -d is used on the command line. Wouldn't that let you do most of these things?

Eg, point 3 and 4:

module reallyold;
version(deprecated) {
import anotherdeprecatedmodule;
} else static assert(0, "This module is deprecated");

Sure, it's a bit ugly, but it's simple and would give a lot of flexibility. BTW this could be added to D1.0.
« First   ‹ Prev
1 2