www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - if (auto x = cast(C) x)

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
For a class/interface type `A` and a class `C` inheriting from 
`A` one can do

   A a = getA();
   if (auto c = cast(C) a)
   { .. use c .. }

to get a `C` view on `a` if it happens to be a `C`-instance.

Sometimes one cannot find a good new name for `c` while there is 
no advantage of accessing `a` when `c` is available. D does not 
allow to shadow `a` in the if-auto declaration for good reasons. 
How about relaxing the rule for cases like these, where the rhs 
is the lhs with a cast to derived?

   if (auto a = cast(C) a)
   { .. use a typed as C .. }

One can think of `a` being *statically* retyped to `C` as this is 
a (strictly) better type information. Internally, it would be a 
shadowing, but it does not matter as the disadvantages don't 
apply (if I didn't miss something).
Aug 09 2017
next sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 9 August 2017 at 21:54:46 UTC, Q. Schroll wrote:
 For a class/interface type `A` and a class `C` inheriting from 
 `A` one can do

   A a = getA();
   if (auto c = cast(C) a)
   { .. use c .. }

 to get a `C` view on `a` if it happens to be a `C`-instance.

 Sometimes one cannot find a good new name for `c` while there 
 is no advantage of accessing `a` when `c` is available. D does 
 not allow to shadow `a` in the if-auto declaration for good 
 reasons.
How often do you need this? I wouldn't go as far as saying downcasting is (always) evil, but it can be indicative of suboptimal abstractions [1].
 How about relaxing the rule for cases like these, where the rhs 
 is the lhs with a cast to derived?

   if (auto a = cast(C) a)
   { .. use a typed as C .. }

 One can think of `a` being *statically* retyped to `C` as this 
 is a (strictly) better type information. Internally, it would 
 be a shadowing, but it does not matter as the disadvantages 
 don't apply (if I didn't miss something).
While I can't see an obvious semantic issue, I would vote against such syntax because it introduces more special cases (and in this case an inconsistency w.r.t. variable shadowing) into the language and I don't see it providing enough of a benefit (downcasting should be used rarely) to justify that. [1] http://codebetter.com/jeremymiller/2006/12/26/downcasting-is-a-code-smell/
Aug 09 2017
prev sibling next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/9/17 5:54 PM, Q. Schroll wrote:
 For a class/interface type `A` and a class `C` inheriting from `A` one 
 can do
 
    A a = getA();
    if (auto c = cast(C) a)
    { .. use c .. }
 
 to get a `C` view on `a` if it happens to be a `C`-instance.
 
 Sometimes one cannot find a good new name for `c` while there is no 
 advantage of accessing `a` when `c` is available. D does not allow to 
 shadow `a` in the if-auto declaration for good reasons. How about 
 relaxing the rule for cases like these, where the rhs is the lhs with a 
 cast to derived?
 
    if (auto a = cast(C) a)
    { .. use a typed as C .. }
 
 One can think of `a` being *statically* retyped to `C` as this is a 
 (strictly) better type information. Internally, it would be a shadowing, 
 but it does not matter as the disadvantages don't apply (if I didn't 
 miss something).
Just FYI, swift implemented something like this, and I find it completely awful. In Swift, they made all parameters to functions immutable (head immutable), and if you want to modify the variable, you have to do: var x = a But for existing code that declared parameters to be mutable (so you don't have to change too much), they allow: var a = a Which is terrible. I find this proposal would look equally terrible. Sorry, I would be against it. -Steve
Aug 09 2017
prev sibling parent Meta <jared771 gmail.com> writes:
On Wednesday, 9 August 2017 at 21:54:46 UTC, Q. Schroll wrote:
 For a class/interface type `A` and a class `C` inheriting from 
 `A` one can do

   A a = getA();
   if (auto c = cast(C) a)
   { .. use c .. }

 to get a `C` view on `a` if it happens to be a `C`-instance.

 Sometimes one cannot find a good new name for `c` while there 
 is no advantage of accessing `a` when `c` is available. D does 
 not allow to shadow `a` in the if-auto declaration for good 
 reasons. How about relaxing the rule for cases like these, 
 where the rhs is the lhs with a cast to derived?

   if (auto a = cast(C) a)
   { .. use a typed as C .. }

 One can think of `a` being *statically* retyped to `C` as this 
 is a (strictly) better type information. Internally, it would 
 be a shadowing, but it does not matter as the disadvantages 
 don't apply (if I didn't miss something).
One option is to use https://dlang.org/library/std/algorithm/comparison/cast_switch.html
Aug 09 2017