Phobos - breaking existing code

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Fri Nov 28 15:53:17 PST 2014


On Fri, Nov 28, 2014 at 03:33:51PM -0800, Walter Bright via Digitalmars-d wrote:
> Just for fun, I've decided to try and get MicroEmacs in D added to the
> dub registry. The last time it compiled was 2 years ago.
> 
> I wound up with at least a dozen references to Phobos names that have
> disappeared. No corrective action was indicated, just "undefined
> symbol". I have to go refigure out what the code was trying to do, and
> go poking through the Phobos documentation to see what will work
> today.
> 
> I know there's been a lot of "break my code" advocacy lately, but this
> code was only 2 years old.
> 
> I fully understand how unfriendly this is to users and how
> discouraging it can be to have their recently working code shattered
> and scattered. We need to do a lot better.

I think we may have been a little trigger-happy in implementing the
deprecation cycle. While technically the deprecation cycle lasts 2 years
(?), I think it's probably a good idea to keep deprecated symbols around
for far longer than that. You never know when somebody decides to dust
off some 5-y.o. code that references an obscure Phobos symbol that has
since been deleted after a full deprecation cycle.

Perhaps what we need is, after a symbol has passed the deprecation
cycle, replace its original definition with a static assert(0).
Something like this:

	// Original implementation:
	/**
	 * Original docs
	 */
	auto mySymbol(A...)(A args) { /* original implementation */ }

	// Some time later we decide to deprecate it. Before marking it
	// deprecated, label it with a big fat warning:
	/**
	 * Original docs
	 *
	 * Warning: This function is slated for deprecation by May 2015.
	 */
	auto mySymbol(A...)(A args) { /* original implementation */ }

	// Afterwards, the deprecated tag is added (ddocs are removed so
	// that new users will stop using it).
	deprecated("Please use myOtherSymbol instead.")
	auto mySymbol(A...)(A args) { /* original implementation */ }

	// Full deprecation cycle passes. Using this symbol should now
	// be an error, even if -d is being used. But don't delete it
	// just yet:
	deprecated("Please use myOtherSymbol instead.")
	auto mySymbol(A...)(A args) {
		static assert(0, "Please use myOtherSymbol instead.");
	}

	// After a REALLY long time, I dunno, maybe 4 years? 5 years?
	// We can finally remove it.

This does mean, though, that once released, symbols will stick around
for a LONG time, which means some overloads cannot be used if it
conflicts with a deprecated symbol, etc.. So std.experimental becomes
even more important, to sort out APIs before they essentially get frozen
in stone and need >=5 years of proverbial laser scrubbing before they
can be erased again.

There's also the issue of symbols being moved into a different module --
existing code will expect to find it in the old place, so any aliases /
public imports / etc., will have to stay around for quite a long time
before they can be gotten rid of. Ditto for currently monolithic modules
that eventually gets split into saner-sized chunks.


T

-- 
Acid falls with the rain; with love comes the pain.


More information about the Digitalmars-d mailing list