What Are The Semantics Of Multiple Implicitly Typed Declarations? Part One
In my earlier series on inferring a unique "best" type from a set of expressions I mentioned that one potential application of such an algorithm is in implicitly typed variables. This led to some good questions and concerns posted in the comments - questions and concerns which echo similar feedback we've been receiving from a variety of sources since we released the first technology preview of C# 3.0 last year.
I'd like to run a quick unscientific poll to see what your intuitions and expectations about implicitly typed variables with multiple declarations are. Please leave a comment describing what you think should happen here, and why you think that.
1: local variable declaration var x = 1, y = 2.0; has the same semantics as:
(a) double x = 1, y = 2.0;
(b) int x = 1; double y = 2.0;
(c) object x = 1, y = 2.0;
(d) this should be a compile-time error
(e) something else, please specify
2: local variable declaration var q = 0, r = (short)6; has the same semantics as:
(a) int q = 0; short r = 6;
(b) int q = 0, r = 6;
(c) short q = 0, r = 6;
(d) object q = 0, r = 6;
(e) this should be a compile-time error
(f) something else, please specify
Thanks! Next time I'll describe some of the pros and cons of each and what our current thinking is in this area.
Comments
- Anonymous
June 26, 2006
Definitely 1b, 2a. The general rule I'm going with here is that
var a=A, b=B;
should be exactly equivalent to:
var a=A;
var b=B;
In a sense this is exactly equivalent to the way that other multiple declarations work - if you replace "var" with any real type, this equivalence holds. So I think it passes the "intuitive" test a lot better than any of the other options. - Anonymous
June 26, 2006
I'd agree with 1b, 2a also. Though I come to that from interpreting what the coder was thinking of when declaring variables. If lacking type information then I'd presume that things are typed into the most restrictive logical data type given information about the initialisation value. Thus leaving the programmer to explicitly define alternative types, as per the syntax of question 2. I'd also agree that var a=B, b=B is equivalent to var a=A; var b=B. - Anonymous
June 26, 2006
1e, 2e
Ambiguity, as I've found, is the primary cause of subtle bugs in code. Given that it should be illegal to put yourself in to a position like that. Or, it should be a compile-time warning, though given that you can't get rid of the warning unless you change the type, it might as well be an error.
"In a sense this is exactly equivalent to the way that other multiple declarations work - if you replace "var" with any real type, this equivalence holds. So I think it passes the "intuitive" test a lot better than any of the other options."
Except under that logic you could put:
int a = 2, b = "hello";
I think intuitive tests have to pass both directions here. Since I can't translate:
int a = 2;
string b = "hello";
into
int a = 2, b = "hello";
or
string a = 2, b = "hello";
I shouldn't, intuitively, be able to translate the var equivalents. Hence, it fails the bidirectional argument. - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
My answers (without looking at any other comments) would be:
1 (b)
2 (a)
I think there should be no difference between:
var x = 1, y = 2.0;
and
var x = 1;
var y = 2.0;
And similarly, no difference between:
var q = 0, r = (short) 6;
and
var q = 0;
var r = (short) 6;
Applying the type inference rules: 0 -> int, 1 -> int, 2.0 -> double, (short) 6 -> short leads to my given answers. That said, I could definitely live with flagging both as compilers errors, so answer (d). - Anonymous
June 26, 2006
1 = b and 2 = a, if only because this is what I'm used to from every other language I know of that uses type inference. - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
1b 2a
Yeah it's a bit annoying at first glance, but I think it works the best. - Anonymous
June 26, 2006
1a, 2b: We should be able to do x = y and y = x. A valid reason to use multiple declarations (the only readon I can think of) is to be sure that we end up with two locals with the same type. - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
- b
2) a
- Anonymous
June 26, 2006
1a, 2b
I think it would be tedious to debug code where expressions are used to initialise the variables if multiple type can be initialised implicitly in a single statement. In the interest of mainatiablility, I feel this should be flaged as an error / warning, or the largest data type would be used. Having said that, it would be a problem if var x = 1, y = 2.0, z="abc"; has to be parsed and hence my answer applies if we are dealing with similar data type. - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
1b
2a
I think a good reason to avoid options 1a, 2b and 2c is that if the author wants the same type they need only write it instead of var. Therefore treating it the same as multiple var declarations makes more sense to me. - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
The comment has been removed - Anonymous
June 26, 2006
My first intuition is also 1b, 2a.
But since not everybody agrees about what is intuitively correct, I would actually recommend 1d, 2e. Like some have said before, it's just a bug waiting to happen. - Anonymous
June 27, 2006
The comment has been removed - Anonymous
June 27, 2006
That's interesting. In VB6 if you say
Dim Curly, Larry, Moe as Stooge
of course that means that Curly and Larry are Variant, Moe is a Stooge.
My guess would be that your VB6 veterans are familiar with the pain that this "gotcha" causes and would like C# to not add a similar gotcha to the language.
(.NET versions of VB will treat all three as Stooges.) - Anonymous
July 05, 2006
Of course
1(b)
2(a)
If you give only a number to the compiler, e.g. 2.0, the compiler will recognize the const as a double. Except you explictly specify 2.0f to make it a float. The type is clear even though it is under C# 1.0 specification.
And I think the "var" keyword should better be used with anonymous class. You cannot specify any other class type to the variables except itself and object. We certainlly don't want the compiler to cast it to an object. Of course we also don't want compiler to change 0(int) into float, double or object.