Why does "var" force type inference?

Asked

Viewed 95 times

3

Performing some tests with the language I noticed that when we use the keyword var Dart will "force" the type inference, but when we use a type to declare variables this does not happen.

The test I took:

main(){
  Map a = {
    '6': 6,
  };
  var b = {
    '6': 6,
  };
  a[7] = '7'; // Executa sem erros
  b[7] = '7'; //Erro
}

Why a statement with a type does not force inference while with var force?

1 answer

2


Let’s see what kind he inferred and what kind he caught when he was explicit:

import 'dart:io';
import 'dart:mirrors'; 

void main() {
    Map a = {
        '6' : 6,
    };
    var b = {
        '6' : 6,
    };
    print(reflect(a).type.reflectedType.toString());
    print(reflect(b).type.reflectedType.toString());
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

In the first you specified what the type was, but not it complete, lacked the key types and value. For some reason the language decided (if not a bug compiler, but I think it was planned anyway) that you should use the full type, so say what kind of key and the value of the map, or else it would consider that you don’t want a specific type and then it would assume that you want something dynamic.

When you establish that you will use something dynamic a lot becomes free, the compiler does not detect type errors there and allows you to run, even if it does not produce what you expect. In case it allowed to change the type of the key and value data because you accepted that the compiler infers that you want, what we understand by your question to be mistaken, dynamic. It’s more or less like a variable that its value is 0 if you don’t put any value. If you want it to be 1 then you have to be explicit.

When ordered to infer the compiler inferred the three possible types there, and there could not execute something irregular because the key and the value have specific type, so the key was inferred as string and you’re using a number, and the value has been inferred as int and you’re trying to put a character.

Dart has shown a language with questionable decisions and for being a modern language that can learn from the mistakes of others makes think about the quality it (not that it affects the future, many very poorly thought-out languages have succeeded, including it will succeed because of a framework and not because it is good, it never works very well). It’s even bad because it’s inconsistent, and it raises questions like this.

Even worse is that it requires you to be explicit that you want the inference when you force the use of var, and in the case of Map without you saying anything she inferred the inner types. So there are two mistakes, if you wanted him to infer what he inferred you should make a Map<var, var>, and should use the same criteria and find the specific type, the dynamic should never be the compiler’s main option. Or it should always be the main option, but then the language would tend to be more dynamic, and all the rules should reflect this, in the absence of something explicit should be dynamic, should never force the use of var.

It seems Dart doesn’t know if he wants to be a dynamic or a static language. If she wanted to be static she would infer the part that is not explicit, or else she would make a mistake saying that she does not have the complete type and forcing you to put a dynamic if that’s what you want. I prefer the first, and if you want the dynamism to be explicit.

For me it was a mistake of design the language, but they must have a justification to do this, even if it is one to justify after the mistake was made. There’s language that loves to do it.

Bug, Feature and By Design, baratas, uma pelada, outra vestindo terninho e ainda terninho remendado

The lesson is never to use a statement with incomplete type, or let it infer everything or put all type. This would be correct:

Map<string, int> a = {
    '6': 6,
};

or, of course, to infer everything.

Knowing the rule can be used correctly, just can not forget it, that is not intuitive.

  • I think the reason "Map A" has the dynamic types is because: "The Static type of a map literal of the form const {K1 : E1,...,kn : en} or the form {K1 : E1,...,kn : en} is Map<Dynamic, Dynamic>." and if you take the following sentence to the letter "... you can use var and Let Dart infer the type: ..." everything is explained..

Browser other questions tagged

You are not signed in. Login or sign up in order to post.