-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Replace 'Dynamic' with 'var' #2050
Comments
Humor me with the following thought experiment:
Unless I am missing something, the converted Dart' programs should behave just like the original Dart programs.
The difference between Dart and Dart' is that in Dart' it is sometimes necessary to use a type to introduce a declaration, whereas Dart has an extra feature using the 'var' keyword for the purpose. It is not necessary to confuse the distinction between 'introducing a declaration' and 'a type'. A type may be used to 'introduce a declaration' as in 'int x;', and now there is no distinction between 'var x;' and 'int x;'. |
final var x; |
I'm not sure of your point. neither of (I would still permit the type to be omitted so 'final x = ...' would be allowed.) |
final var x; would make sense if you allowed final var x: int; which makes var get f() => 3; and for that matter var f(x){return x;} I don't see anyone complaining about final not being a type. The confusion |
Gilad, I think there are two reasons for this: (1) The language encourages this confusion by letting us use var and types interchangeably in most situations. Even though we know they are different, we often forget. :-) (2) "Dynamic" is out of sight and out of mind. A quick grep of all our samples as well as the frog compiler shows 1 use of Dynamic in about 100,000 lines of code (and that one use could be replace by var). Cheers, Vijay |
Vijay, Oddly, I was going to raise that very point. It doesn't matter that the So why are we wasting time on it? |
Because the current confusion is causing programmers (jimhug, sra, me) to waste time when writing Dart code. It's only fair we waste your time as well. :-) Cheers, Vijay |
I think the confusion about the role of 'var' is caused by the shortcut when defining a variable. Instead of "int x" we should be writing "var int x". In Dart, the following is (or will be legal): var x; and with types: int x; // means var int x; Making var, final or const to be a type does not makes much sense to me and I believe would be very surprising to many programmers (it would be to most of us in MTV). I understand that there are practical problems that this request is attempting to solve. I do not think that is the right way of solving it, though. IMHO, the solution to Jim's problem (locate all untyped declarations) is easily implementable in the tools, and should be done there. P.S.: "final var x" is not legal Dart syntax. |
Added this to the M1 milestone. |
This comment was originally written by @tomyeh If type casting is implemented, Dynamic can be removed completely (use Object or var instead). For example, void f(List<Object> foos) { |
After a long discussion, we decided to close this bug. However, the function dynamic() used for casting will be replaced with the 'as' operator. Below is a detailed discussion of the considerations that led to this decision: The proposal is not really about renaming Dynamic, but about changing the meaning of 'var'. To make the point clear, I will start with a discussion of what 'var' means today. To do this, I will deliberately start from the semantics, with a concrete syntax that is not Dartesian, and migrate to one that is. Afterwards, we'll deal with the question of why we should not change that meaning. Semantically, variable declaration specifies the following: Whether the variable is mutable or immutable; what the variable's name is; and what its type is. A clean, unambiguous syntax captures this structure very directly: varDecl -> mutabilitySpeciifer varName varType We'll throw in semicolons as terminators as well. So, we could write mutable v1: int; Now, lets replace those verbose, if unambiguous, keywords 'mutable' and 'immutable' with something more familiar: 'var' for mutable and 'final' for immutable: var v1: int; Now we make the type annotation optional; if the type isn't specified we mean the unknown type, Dynamic. So we can also write var v3; // really var v3: Dynamic; Next, we'll move to a C-style type specification; again, trading clarity for familiarity: var int v1; Lastly, but crucially, we'll decide that variables are mutable by default (even though it is in a sense the wrong default for two reasons: immutable variables are more common (at least for fields) and we should encourage functional style). This last change only works if there is a type specifier, otherwise we cannot distinguish variable declaration from variable usage. So we can write int v1; // shorthand for var int v1; At this point, our various shortcuts have brought us to the point where the keyword 'var', intended to introduce a mutable variable, appears syntactically in the same position as a type annotation. Readers who don't think this through become confused and decide that 'var' is a type, leading to the proposal of renaming Dynamic to var. Hopefully, the above makes it clear that 'var' is no more a type than 'final' is. However, that alone would probably not have caused this proposal to be rejected. The deciding factor is readability. So, what could possibly go wrong? If we decide that 'var' is a type, we must allow it in every position where a type is currently allowed: var f(x) => 42; All of the above are confusing and undermine program readability. In practice, there is rarely a need to write the type Dynamic explicitly, and it is bad style to do so unless it is essential (which can happen when using multi-argument generics, e.g., Map<String, Dynamic>), as it makes code more verbose without adding information. Added WontFix label. |
…ctor, browser_launcher, characters, cli_util, clock, collection, convert, crypto, csslib, dartdoc, ecosystem, ffi, fixnum, glob, html, http, http_multi_server, http_parser, json_rpc_2, leak_tracker, lints, logging, markdown, matcher, mime, mockito, native, package_config, path, pool, protobuf, pub_semver, shelf, source_map_stack_trace, source_maps, source_span, sse, stack_trace, stream_channel, string_scanner, term_glyph, test, test_descriptor, test_process, test_reflective_loader, tools, typed_data, usage, watcher, web_socket_channel, webdev, yaml Revisions updated by `dart tools/rev_sdk_deps.dart`. args (https://github.com/dart-lang/args/compare/a9543c0..da56b18): da56b18 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#249) async (https://github.com/dart-lang/async/compare/a506993..b65622a): b65622a 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#247) bazel_worker (https://github.com/dart-lang/bazel_worker/compare/f7b714e..c29d162): c29d162 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#77) benchmark_harness (https://github.com/dart-lang/benchmark_harness/compare/e717ad4..fde73cb): fde73cb 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#91) boolean_selector (https://github.com/dart-lang/boolean_selector/compare/3a1c982..303635d): 303635d 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#49) browser_launcher (https://github.com/dart-lang/browser_launcher/compare/40e4315..27ec600): 27ec600 2023-07-05 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#46) dd8df9c 2023-07-05 Devon Carew update formatting for recent lints (#47) characters (https://github.com/dart-lang/characters/compare/3ef8883..ec844db): ec844db 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#84) cli_util (https://github.com/dart-lang/cli_util/compare/5a49947..9b7ce78): 9b7ce78 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#84) clock (https://github.com/dart-lang/clock/compare/21caac1..263e508): 263e508 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#54) collection (https://github.com/dart-lang/collection/compare/a37bd51..db343da): db343da 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#295) convert (https://github.com/dart-lang/convert/compare/9a387f0..79ee174): 79ee174 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#84) crypto (https://github.com/dart-lang/crypto/compare/216931a..8b704c6): 8b704c6 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#150) csslib (https://github.com/dart-lang/csslib/compare/be2e11e..7e91228): 7e91228 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#187) dartdoc (https://github.com/dart-lang/dartdoc/compare/c2ed703..2522559): 25225596 2023-06-29 Sam Rawlins Migrate some simple tasks to a simple package:args command (#3456) ecosystem (https://github.com/dart-lang/ecosystem/compare/19fa443..b34db4f): b34db4f 2023-07-10 Moritz Allow empty coverage (#128) 5944328 2023-07-04 Moritz Prepare for publish (#127) c0701c9 2023-07-04 dependabot[bot] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#122) 9bf3a10 2023-07-03 Moritz Fix bug by switching `reduce` to `fold` (#126) fdfa528 2023-07-01 dependabot[bot] Bump actions/cache from 3.2.6 to 3.3.1 (#121) 238444c 2023-07-01 dependabot[bot] Bump actions/checkout from 3.3.0 to 3.5.3 (#123) ca1e1ae 2023-06-30 Moritz Add coverage workflow (#119) cf02b4a 2023-06-30 Lasse R.H. Nielsen Make Changelog class eagerly load and parse file. (#120) ffi (https://github.com/dart-lang/ffi/compare/f582ca0..f01dfca): f01dfca 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#199) fixnum (https://github.com/dart-lang/fixnum/compare/d9b9a2a..00fa120): 00fa120 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#113) glob (https://github.com/dart-lang/glob/compare/109121d..5b24393): 5b24393 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#79) html (https://github.com/dart-lang/html/compare/b3b820b..4060496): 4060496 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#218) 8cb99e4 2023-07-01 Devon Carew address new analysis issues (#219) http (https://github.com/dart-lang/http/compare/d68081f..c148a3a): c148a3a 2023-07-07 Alex James Java http BaseClient implementation (#980) 474999f 2023-07-05 Brian Quinlan Document that the network entitlement is required when running in the macOS sandbox (#979) 98e4112 2023-07-05 Brian Quinlan Fix a bug where ...WebSocketClosed had two different initializer signatures (#981) 9833a20 2023-07-05 Brian Quinlan Support Steam<List<int>> as a provider of request data (#975) d3e78a0 2023-07-01 dependabot[bot] Bump actions/labeler from 4.0.4 to 4.2.0 (#976) http_multi_server (https://github.com/dart-lang/http_multi_server/compare/a209cd5..aa128cf): aa128cf 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#56) http_parser (https://github.com/dart-lang/http_parser/compare/19466c0..c14fbf6): c14fbf6 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#75) json_rpc_2 (https://github.com/dart-lang/json_rpc_2/compare/73467f3..509f71e): 509f71e 2023-07-05 Nate Bosch Fix the example to act as a server (#100) d80cbd0 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#99) leak_tracker (https://github.com/dart-lang/leak_tracker/compare/c75b0a7..85bd7fb): 85bd7fb 2023-07-05 Polina Cherkasova - (#87) lints (https://github.com/dart-lang/lints/compare/89f9519..e03dc04): e03dc04 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#138) logging (https://github.com/dart-lang/logging/compare/f2fe2ac..5214987): 5214987 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#144) markdown (https://github.com/dart-lang/markdown/compare/4674d09..b4bdde2): b4bdde2 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#549) matcher (https://github.com/dart-lang/matcher/compare/7e10117..ce8f409): ce8f409 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#225) mime (https://github.com/dart-lang/mime/compare/2444840..bdb66bd): bdb66bd 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#99) mockito (https://github.com/dart-lang/mockito/compare/974226e..451f756): 451f756 2023-07-10 Nate Bosch Add example of mocking callbacks c13496c 2023-07-05 Googler Rollback of "Use `FunctionTypedElement.type` while generating method overrides" 60e619a 2023-07-05 Ilya Yanok Use `FunctionTypedElement.type` while generating method overrides 93b69ef 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#669) a926a63 2023-06-30 Ilya Yanok Add a note on only running codegen on files under `test/` by default 9f40189 2023-06-30 Ilya Yanok Require analyzer 5.12.0 native (https://github.com/dart-lang/native/compare/e12d3e6..de1b0cc): de1b0cc 2023-07-10 Daco Harkes [c_compiler] Pass the correct SDK for iOS simulator builds (#77) 21d7270 2023-07-01 dependabot[bot] Bump coverallsapp/github-action from 2.1.2 to 2.2.0 (#72) 23a9b62 2023-07-01 dependabot[bot] Bump nttld/setup-ndk (#74) 44073a8 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#75) 6f01604 2023-07-01 dependabot[bot] Bump actions/labeler from 4.0.4 to 4.2.0 (#73) package_config (https://github.com/dart-lang/package_config/compare/203de20..be0c441): be0c441 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#138) path (https://github.com/dart-lang/path/compare/592505f..282dd18): 282dd18 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#147) pool (https://github.com/dart-lang/pool/compare/c6b1b2c..7700102): 7700102 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#72) protobuf (https://github.com/dart-lang/protobuf/compare/7bebbc6..a912f76): a912f76 2023-07-04 Ömer Sinan Ağacan Add more message set tests, fix a bug (#859) pub_semver (https://github.com/dart-lang/pub_semver/compare/3930557..028b435): 028b435 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#90) shelf (https://github.com/dart-lang/shelf/compare/ce379aa..bd59ead): bd59ead 2023-07-06 Kevin Moore router_generator: allow latest pkg:analyzer, request Dart 3 (#368) bebc801 2023-07-06 Jonas Finnemann Jensen Fix 244 (#268) 1617efa 2023-07-02 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#366) c037bb6 2023-07-02 dependabot[bot] Bump actions/labeler from 4.0.4 to 4.2.0 (#365) 1ae4d4e 2023-07-01 Devon Carew address a new lint (#367) source_map_stack_trace (https://github.com/dart-lang/source_map_stack_trace/compare/b83af01..16e54fd): 16e54fd 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#40) source_maps (https://github.com/dart-lang/source_maps/compare/58eef30..97c4833): 97c4833 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#80) source_span (https://github.com/dart-lang/source_span/compare/4dc78fb..37735ae): 37735ae 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#99) sse (https://github.com/dart-lang/sse/compare/bfcbcd7..e241085): e241085 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#85) stack_trace (https://github.com/dart-lang/stack_trace/compare/8b2046e..4ddd86d): 4ddd86d 2023-07-05 Slava Egorov Prepare 1.11.1 release (#137) d3e4c4d 2023-07-04 Slava Egorov Use awaiter-link pragma to guide VM's builtin awaiter stack unwinding (#135) 44aafa3 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#136) stream_channel (https://github.com/dart-lang/stream_channel/compare/34804a1..e54234f): e54234f 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#93) string_scanner (https://github.com/dart-lang/string_scanner/compare/6bb314f..35657e2): 35657e2 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#59) term_glyph (https://github.com/dart-lang/term_glyph/compare/4daa34e..423700a): 423700a 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#40) test (https://github.com/dart-lang/test/compare/021667a..3429712): 3429712b 2023-07-06 Nate Bosch Drop usage of window.testRunner (#2059) dc6b8236 2023-06-29 dependabot[bot] Bump actions/checkout from 3.1.0 to 3.5.3 (#2051) b6dc3f8d 2023-06-29 dependabot[bot] Bump dart-lang/setup-dart from 1.3.0 to 1.5.0 (#2052) 5fa2572f 2023-06-29 Jacob MacDonald regenerate mono_repo with the latest (#2055) 56584627 2023-06-29 dependabot[bot] Bump github/codeql-action from 2.3.5 to 2.20.1 (#2053) 050fe2d6 2023-06-29 dependabot[bot] Bump ossf/scorecard-action from 2.1.3 to 2.2.0 (#2054) ba6ccfc2 2023-06-29 Devon Carew config dependabot to send daily PRs for major version bumps (#2050) test_descriptor (https://github.com/dart-lang/test_descriptor/compare/be7ce07..54a4c59): 54a4c59 2023-07-03 Devon Carew update formatting for recent lints (#54) test_process (https://github.com/dart-lang/test_process/compare/5ff2122..b360784): b360784 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#46) test_reflective_loader (https://github.com/dart-lang/test_reflective_loader/compare/40d61b1..0bfaad9): 0bfaad9 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#50) tools (https://github.com/dart-lang/tools/compare/8db0aa1..af38b2b): af38b2b 2023-07-02 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#119) 8b8ccab 2023-07-01 Devon Carew update formatting based on the recent lints (#121) 30b50ff 2023-07-01 dependabot[bot] Bump coverallsapp/github-action from 2.1.2 to 2.2.0 (#118) 74979c1 2023-07-01 dependabot[bot] Bump actions/labeler from 4.0.4 to 4.2.0 (#120) typed_data (https://github.com/dart-lang/typed_data/compare/8d29573..a20be90): a20be90 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#69) usage (https://github.com/dart-lang/usage/compare/6ee0908..09bb847): 09bb847 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#196) watcher (https://github.com/dart-lang/watcher/compare/3f17faa..7457413): 7457413 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#148) web_socket_channel (https://github.com/dart-lang/web_socket_channel/compare/7fb82f2..7ae4d0f): 7ae4d0f 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#274) webdev (https://github.com/dart-lang/webdev/compare/8360d50..f0ba743): f0ba7438 2023-07-07 Elliott Brooks Reset webdev to version 3.0.7-wip (#2170) 2fcc1ba9 2023-07-06 Anna Gringauze Add option of running frontend server tests in canary mode (#2169) 632763a5 2023-07-06 Elliott Brooks Prepare webdev for release to 3.0.6 (#2167) fa7b6d44 2023-07-05 dependabot[bot] Bump actions/checkout from 3.5.0 to 3.5.3 (#2163) 2a6a457b 2023-07-05 Devon Carew regenerate from the latest mono_repo (#2165) cbb0d76a 2023-07-05 Anna Gringauze Run instance tests with frontend server (#2160) b672e98a 2023-07-05 Elliott Brooks Reset DWDS after release (#2168) 8ef92d71 2023-07-05 Elliott Brooks Prepare DWDS for release to version 19.0.2 (#2166) 77e5b373 2023-07-05 Elliott Brooks Handle potential `null` value in `setUpChromeConsoleListeners` (#2162) 5081dff0 2023-07-01 dependabot[bot] Bump actions/labeler from 4.0.4 to 4.2.0 (#2164) yaml (https://github.com/dart-lang/yaml/compare/0b9041d..7930148): 7930148 2023-07-01 dependabot[bot] Bump actions/checkout from 3.5.2 to 3.5.3 (#148) Change-Id: I095a2479946e13d8499f1b3a58dc5a82688063f6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313020 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Devon Carew <devoncarew@google.com>
It is surprising that 'var' cannot be used in the position of the return type of a method or getter.
Multiple people find this surprising which indicates that it is a widespread problem.
I recently had to translate a bunch of fields to getters:
final int foo;
final var bar;
-->
int get foo() => ...;
var get bar() => ...;
This doesn't work because there is a type called Dynamic that is confusingly the type associated with the keyword 'var'.
The correct translation is
int get foo() => ...;
get bar() => ...;
or
int get foo() => ...;
Dynamic get bar() => ...;
The thing that feels right is wrong and both of the right things look worse that the wrong thing.
I think having 'var' and 'Dynamic' is a mistake and we should make 'var' behave like 'Dynamic' in this context and in parameterized types.
Further evidence comes from a discussion from a month ago:
Jim:
I was just surprised (for the nth time) to find that 'var' is not allowed as a return type for functions and methods in dart. I often like to use var when I'm half-way through moving code from dynamically typed to statically typed for those areas that are explicitly still dynamic. I realize that I could use "Dynamic" instead, but that feels very awkward - and it doesn't feel consistent with the fact that I can use var for the parameter positions. I understand the theoretical rationales for this choice. My question is about whether or not this is the most useful behavior for developers.
Here's an example of the kind of place that I hit this and get confused as my code evolves:
// starting truly dynamic
createNode(parent, kind) => ...;
// 1st step towards types - works in Dart
createNode(var parent, String kind) => ...;
// blows up - but feels consistent with the code above
var createNode(var parent, String kind) => ...;
Can we please allow 'var' to be used as a type name and remove the much more verbose 'Dynamic' from the language? Unless we want to make a much more radical change to types in dart away from the current C-style syntax, I believe that this would make our syntax and semantics feel both simpler and more consistent to most developers.
If we want to keep this behavior, then the VM and compilers need to be updated to give good error messages for this very common and easy to make mistake - right now they blow-up with a hoard of confusing messages instead. And the editor should get a quick fix button to change 'var' to either 'Dynamic' or to erase it when it breaks the grammar.
Thanks - Jim
Vijay:
I'd like to add a general +1 to Jim's note below on var vs Dynamic.
My general style is to use types for return values from the start, so I haven't hit this so much. This weekend, I started teaching my 9 year old programming (with Dart of course :-)), and I made a conscious effort to avoid types. I kept finding myself writing:
var foo (n) { ... }
Yes, I'll just get used to omitting the "var", but I agree with Jim - it's surprising that this doesn't work.
Cheers,
Vijay
The text was updated successfully, but these errors were encountered: