Noob question... shouldn't __traits(compile) enable us to handle the situation correctly?So, a recent Phobos deprecation introduced a fun regression:https://issues.dlang.org/show_bug.cgi?id=13257 While the bug was filed specifically for the use caserange.splitter.map, the problem is actually much more general, and farfrom obvious how to address.First, let's consider the following setup. Start with this examplerange: struct MyRange(T) { // input range @property bool empty() { ... } @property T front() { ... } void popFront() { ... } // forward range @property MyRange save() { ... } // bidirectional range @property T back() { ... } void popBack() { ... } }Suppose we write an algorithm that operates on ranges in general, including MyRange. The current convention is to forward as many range methods as possible, so that if you give it a bidi range, it will, wherepossible, give you a wrapped bidirectional range. So we do this: auto myAlgo(R)(R range) if (isInputRange!R) { struct Result { // input range methods @property bool empty() { ... } @property U front() { ... } void popFront() { ... } // N. B. if we got a forward range, and we can // implement .save, then do so. static if (isForwardRange!R && canDoForwardRange) { @property Result save() { ... } } // N. B. if we got a bidirectional range, and we // can implement .back and .popBack, then do so. static if (isBidirectionalRange!R && canDoBidirectionalRange) { @property U back() { ... } void popBack() { ... } } } return Result(...); }Now suppose, for whatever reason, we decide that implement MyRange as a bidirectional range was a bad idea, and we decide to deprecate it:struct MyRange(T) { ... // input & forward range API heredeprecated("Use of MyRange as bidirectional range is now deprecated"){ @property T back() { ... } void popBack() { ... } } } Now the fun begins. Currently, isBidirectionalRange usesis(typeof(...)) to check if .back and .popBack exist in target type. So when myAlgo() checks MyRange, this check passes, because even though .back and .popBack have been deprecated, they obviously still exist, so they do have a valid type. So that check passes. Therefore, myAlgo()will try to export a bidirectional interface in its result.However, inside Result.back and Result.popBack, when it actually tries to use MyRange.back and MyRange.popBack, the compiler throws up itshands and say, Wait!! .back and .popBack are deprecated!!Note that this happens *regardless* of whether .back and .popBack are actually used by the user code that calls myAlgo(). This means that if user code only ever uses forward range capabilities of myAlgo(), users will *still* get irrelevant deprecation messages -- for bidirectionalrange features that they never use! Furthermore, the only reason myAlgo() added .back and .popBack which trigger the deprecationmessages, is because the is(typeof(...)) check tests positive forbidirectional range support.This problem, obviously, is not specific to bidirectional ranges, or, for that matter, *any* range based code. It's a general problem withwrapped types, of the form: struct Wrapped { deprecated void method(); } struct Wrapper(T) { T t; static if (is(typeof(t.method()))) { void func() { t.method(); } } }The problem here is that t.method() is generic, and it has specifically tested for the usability of t.method(), yet when it tries to actually use t.method(), it hits a deprecation message. How is it supposed toknow if t.method() has been deprecated? Currently we have no__traits(deprecated) test. And even if we did, this may not be the best solution (are we going to now insert __traits(deprecated) all over generic code, on the off-chance that some random user type somewherewill get deprecated in the unforeseeable future?).So the question now is: how do we deal with this issue? Currently, this problem already exists in Phobos 2.067a, and random user code that callssplitter(...).map(...) will hit this problem. So far the following have been suggested, none of which seem particularly satisfactory:1) Make Wrapper.func() a template function, so that the deprecation message is not triggered unless the user actually calls it (in which case the deprecation message *should* be triggered). The problem is that when the deprecation message *is* triggered, it comes from deep inside Phobos, and users may complain, why did you export a bidirectional rangeAPI if that support is already deprecated?2) Add a __traits(deprecated) or is(T == deprecated) test, and update all affected sig constraints in Phobos to check for this. Doesn't soundlike an appealing solution.3) Have std.algorithm.map specifically check for a specific overload of std.algorithm.splitter, and omit .back and .popBack in that one case. Very hackish, solves the immediate problem, but leaves the general problem unsolved. User code that wraps around splitter in a similar wayto map will *still* be broken (even if they never actually use bidirectional features).4) Shorten the deprecation cycle of splitter. Doesn't even solve the immediate problem, just shortens it, and still leaves the general problem unsolved. User code that wraps around splitter is still broken(even if they never actually use bidirectional features).Since no obvious acceptable solution seems forthcoming, I thought we should bring this to the forum for discussion to see if anyone has abetter idea. T
On Monday, 11 August 2014 at 22:59:34 UTC, H. S. Teoh via
Digitalmars-d wrote:
- Fun with range deprecations H. S. Teoh via Digitalmars-d
- Re: Fun with range deprecations ketmar via Digitalmars-d
- Re: Fun with range deprecation... H. S. Teoh via Digitalmars-d
- Re: Fun with range deprecation... Meta via Digitalmars-d
- Re: Fun with range depreca... H. S. Teoh via Digitalmars-d
- Re: Fun with range dep... ketmar via Digitalmars-d
- Re: Fun with range depreca... ketmar via Digitalmars-d
- Re: Fun with range depreca... Jonathan M Davis via Digitalmars-d
- Re: Fun with range deprecations Fra via Digitalmars-d
- Re: Fun with range deprecation... H. S. Teoh via Digitalmars-d
- Re: Fun with range deprecations Dicebot via Digitalmars-d
- Re: Fun with range deprecation... H. S. Teoh via Digitalmars-d
- Re: Fun with range deprecation... Dicebot via Digitalmars-d
- Re: Fun with range depreca... H. S. Teoh via Digitalmars-d
- Re: Fun with range depreca... H. S. Teoh via Digitalmars-d
- Re: Fun with range deprecation... John Colvin via Digitalmars-d
- Re: Fun with range depreca... H. S. Teoh via Digitalmars-d
- Re: Fun with range depreca... Dicebot via Digitalmars-d
- Re: Fun with range dep... H. S. Teoh via Digitalmars-d
