-
Notifications
You must be signed in to change notification settings - Fork 213
What's the right syntax for an implicit cast/inline cast operator? #193
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
Comments
That looks completely impenetrable to me. I can't imagine showing new users this syntax. At least |
I like the idea of adding an |
I'm with @Hixie. We already have a two-letter token that users understand means "cast" ->
|
I did a little poking around to see how breaking it would be to add a Inside google, I see only a couple of uses of I also pulled down the most recent versions of all 5,176 packages on pub. In 74,376 parseable files, I found 415 'as' identifiers out of 17,728,837 total identifiers (0.00234%). Those are scattered across 53 different packages. 8 of those packages start with "m4d_" and 9 start with "angel_". That's a little more than I expected, but possibly within the range of things we could conceivably cope with. |
We have the option of doing nothing, and still disallow implicit downcasts, which would mean that all casts would require the I would like to have a good cast operator that works well with chaining. (I also want a suffix I don't particularly like If we introduce suffix I'm not worried about the suffix operator precedence. There is nothing new about that, we already have suffix operators (the increment and decrement operators, the index operator). !foo[1]
++i[1]
await foo[1];
foo ? bar : bang[1] Neither of these are hard to read because we have learned that For example:
So, all in all, I don't think the examples are representative of actual code, and any problem with them should also apply to the single suffix |
Me too. Leaf and I spent a little time noodling on a more uniform syntax that would cover postfix
I don't either, but that's also not a representative example. Idiomatic code would be: var x = foo as int; I'm also not super crazy about: functionThatExpectsInt(foo as); But, then, I would be OK with not having a "cast to expected type" operator at all, so this may just be a specific case of that general feeling. :) I think this looks even worse: functionThatExpectsInt(foo!!);
The difference is that most of the other operators we have have sixty years of programming history and millions of users behind them already. The times when we have added new operators ( point..x = 1..y = 2; Worse: true ? a : b..add("added") I had to try this out because even I didn't know what this did and I work on the language. (Answer: it adds to So, I do think we should be very careful around new operators and precedence. I'm somewhat worried about the single suffix |
Yeah personally I am not a fan of suffix-! and would rather we didn't add it either. But that's a topic for another bug, probably. |
If the goal is to get rid of the parens, I'd like to suggest a similar idea as I did in issue #25: Use the pipeline operator from #43. (a as Whatsit)
|. frobIt(3)
|> (as Whosit)
|. fizzle(); There's one difference to my suggestion on #25. The If the problem is that the target type of a cast is too long to write out, could it be an option to introduce a special identifier or keyword that denotes the context type of the current expression? For example, if we chose int extractId(Map<String, dynamic> json) => int.parse(json['id'] as $); And maybe even use it here? List<num> nums = [1, 2, 3];
List<int> ints = [...nums.cast<$>()]; |
A concrete example of a package using |
An inline cast operator can be considered separately. For implicit downcasts only, possibilities would be:
The later potentially generalizes also |
There is a longstanding desire to have better syntax for casts that appear inline in a method chain:
If we move ahead with #192 there is also a desire to have a short syntax for implicitly casting to the context type (see for example the hand-rolled
cast
function used in this cl removing implicit casts).It seems likely that we can solve both of these with a single piece of syntax. For example, we could add a postfix cast operator
!!
which casts to the context type, also usable in the form!!<T>
which casts toT
. Code that formerly used an implicit cast:could be rewritten as follows:
And the example from above with inline casts could be written more cleanly as well:
We might wish to specify it to be an error to use
!!
to perform a side cast when the type is not explicitly written.An alternative syntax which would be more consistent with existing Dart code would be to use
.as
and.as<T>
.Unfortunately this would be a breaking change, since
as
is not a reserved word in Dart. In practice this is likely non-breaking, @munificent is proposing to scrape some code to verify this.If we had extension methods + generic getters, we could specify this as a generic extension method:
This doesn't capture a side cast restriction, but it may avoid the breaking change issue. It seems unlikely that we will have both of these features in place in a suitable time frame to use this encoding though.
Other ideas for syntax that have been put out for consideration:
x.(as T)
and something likex.(as)
orx.(as _)
await a
->a.await
,a + b
->a.+(b)
, possibly alsofoo(x, y)
->x.foo(y)
- a prefix version of our existing cast operator
x.cast<T>
cast
methods on various core library types.The text was updated successfully, but these errors were encountered: