New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a strict type checking mode #20443
Comments
Marked this as blocking #20441. |
This comment was originally written by @zoechi This would be incredible! |
Please see my response in issue #20441.
But you just said that they both failed in checked mode and succeeded in production mode, so there is a difference. In checked mode, the runtime types of the actual values are compared against the declared (static) types. In production mode they are not.
Correct.
Actually, the answer to your question is "yes": 'Object is assignable to 'int'. But according to section 15.19: In checked mode, it is a dynamic type error if o is not null and the interface of the class of o I think you're assuming that the static type checks are defined to be the same as the dynamic type checks, but they are not.
Again, the real answer is "yes": a superclass is assignable to a subclass. But it will produce a runtime error in checked mode.
Again, the answer is "yes".
Which is the correct behavior according to the specification.
Which is also the correct behavior.
There is a difference in behavior.
I don't. But you reported that there is a difference in behavior.
Please see my response in issue #20441 for references to the specification sections that lead to this conclusion. |
This comment was originally written by @Emasoft Thank you, this is a long awaited feature. I know so many developers that would consider adopting Dart if this happens. |
This comment was originally written by @Emasoft The only reason to keep a non strict type checked is to allow code like this: Object lookup(String key) { /* ... */ } // a lookup method in a heterogenous table or list Unlike a classic mandatory type system, in Dart code like this will not cause any complaints from the checker. But there are ways to solve this without loosing strict type checking. You should consider for example a simple solution like pattern matching. doSomething (DivNode n) = does something with a div node or a visitor pattern in C++: struct visit_node : static_visitor<void> { void operator ()(TableNode const& n) { template <typename T> or the use of reflection or a dynamic typeOf method like C# for checking the type: Object s = lookup('Frankenstein'); In more general terms, the answer to the problem: foreach (element T of mixed_or_untyped_set A) This is why I don't see any reasons to renounce type checking. All we need is to add a way to inject objects with informations about their original types. Then with a method like "typeOf" and a type comparer operator we can be as flexible in a strict type checked language as in any dynamically or optionally typed script language. |
In reply to comment 7.
Neither. In Dart there is a distinction between the static type checking performed by the analyzer and the dynamic type checking that is performed by the runtime (Dart VM or dart2js) when running in checked mode. Production mode disables the dynamic type checking. Think of it this way: in production mode all type annotations are erased, as if everything had been defined as 'dynamic'. Static type checking does not attempt to report all errors that might occur at runtime. In fact, it was explicitly and intentionally designed to not report some things that are usually errors but which might in some rare cases not be errors. Whether or not you agree with the philosophy followed by the language designers, the fact is that you won't understand the language unless you first understand that the rules used for static checking and the behavior at runtime (under either mode) are intentionally not the same.
The concept "is assignable to" is defined for the purposes of static type checking. It does not apply at runtime and it does not mean "an assignment can be performed without throwing an exception". Furthermore, it applies to static type information. That is, we say that one type T either is or is not assignable to another type S. At runtime, under checked mode, a different rule is used: the rule that an exception will be thrown when an object is assigned to a variable if the class of the object being assigned is not a subtype of the static type of the variable. (Note the use of "subtype" rather than "assignable to"; this distinction is critical.) So it is true that the static type 'String' is not assignable to the static type 'int'. It is also true that an exception will be thrown in checked mode if an instance of class String is assigned to a variable of type 'int'.
Nope. The type 'String' is not a subclass of 'int', nor is 'int' a subclass of 'String', therefore 'String' is not assignable to 'int'.
If you mean that the purpose of the static type checking defined by the specification is not to ensure that no exceptions will be thrown at runtime under checked mode as a result of a dynamic type checking rule, then you are absolutely correct.
Under the static type checking rules defined by the specification, you can't. I believe that a desire for this kind of validation is the primary reason for the request for a strict mode. |
This comment was originally written by @Emasoft You can make the language as dynamic as you want at runtime. Ok. But at compile time, everything must be statically type checked. And the type checking must be done in a strict and sound way. No base classes must be assigned to derived classes without throwing errors. No List<T> would ever be allowed to accept types different from T. And so on. |
I have long contended that people should be free to define different analyses with whatever rules they want. See, e.g., http://bracha.org/pluggable-types.pdf In particular, one can certainly choose to interpret Dart type annotations in a sound manner. I'm not sure it would make anyone more productive, or be more pleasant to work with, and I am quite skeptical about claims that it would improve software quality. However, I am pretty sympathetic to the idea in principle. Whatever rocks your boat. Whether we should expend resources in putting this into the analysis engine is a separate debate. I think not. Instead, we should provide an extensible API which people could use to define their own analyses in general and plug them into the IDE. |
This comment was originally written by @Emasoft Wow, the Bracha himself! :) |
Issue #20693 has been merged into this issue. |
Well I'm new in Dart and I just discovered that - I agree with run-time approach, but IMO lack of such warnings at compilation time - well at least for me it's kind of show stopper. I see it's P2 - medium - but it looks like 2 years after not much has moved. Any updates on that? |
See https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md . There are several ways to activate it :
|
Yes, strong mode is the answer to these requests, so I'm closing this issue. |
Thanks - much much better!:) Question - apart from all good hints I get one which I don't understand. class A<T extends Node> {
T element;
A(this.element);
}
class B<T extends HtmlElement> extends A<T> {
B(HtmlElement element) : super(element);
} At B constructor I got warning: IMO above construction is right. Side question - I'm trying to learn Dart using material on the web - however more detailed knowledge I look for I'm finding more and more out of date articles (including official ones) - what is the most up to date reference? |
At the point of
@Sfshaza Can you address the question about documentation? |
There have been a number of requests recently (many on the mailing lists) to have a strict type checking mode that acts as if Dart had a sound type system. I'm creating this issue to give people a single place to record their interest, and as a blocking issue for more specific requests related to how such a mode should operate.
The text was updated successfully, but these errors were encountered: