considerations of a "checked mode"-only cast ?

36 views
Skip to first unread message

Seth Ladd

unread,
Oct 19, 2015, 12:13:11 AM10/19/15
to Dart Core Development
Hi,

In looking at Flutter code, and later, code in dartdoc, I see cases where we are either really tempted to, or in fact did, use `as` to say "this variable should be of type Foo, so analyzer, don't worry, the method call will work". However, it feels weird to pay the runtime cost of `as` in almost all cases. My question for the group is: Has there been any discussion around a check-mode-only cast?

For example, here's some code that I just noticed:

return ((node as Declaration).element.source as FileBasedSource)
  .file
  .toString();


Ideally, we wouldn't have to introduce two local variables, just to get our intentions to be understood by the analyzer and avoid the runtime check of `as`.

Declaration decNode = node;
FileBasedSource fileSource = decNode.element.source;
return fileSource.file.toString();

Ideally, we could do an "inline" cast that would only introduce a type assertion in checked mode. Strawman:

return ((node asIf Declaration).element.source asIf FileBasedSource)
  .file
  .toString();

Here, the `asIf` word says "through a type assertion error in checked mode, but do nothing in production mode".


Any thoughts? Do others wish we had this?

Thanks for reading,
Seth

Kasper Lund

unread,
Oct 19, 2015, 12:22:02 AM10/19/15
to Seth Ladd, Dart Core Development

Is the cost of the cast a real or a perceived performance issue? Both can definitely be bad, but I am curious if you have been able to make something faster by not using 'as' casts. An interesting experiment would be to hack the Dart VM to ignore 'as' casts and see if the performance of some app or benchmark improves.

Cheers,
Kasper


--
You received this message because you are subscribed to the Google Groups "Dart Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to core-dev+u...@dartlang.org.

Seth Ladd

unread,
Oct 19, 2015, 12:29:30 AM10/19/15
to Kasper Lund, Dart Core Development
Thanks for the quick reply!

On Sun, Oct 18, 2015 at 9:21 PM, Kasper Lund <kas...@google.com> wrote:

Is the cost of the cast a real or a perceived performance issue?

Completely perceived/pondered. I totally admit that we don't have any numbers here, just a response from some internal conversations we've had when looking at code.
 

Both can definitely be bad, but I am curious if you have been able to make something faster by not using 'as' casts.


The vibe/sentiment has been to simply not use `as` if we care about the performance of that part of the code (which, in the case of Flutter, most of the code is written with an eye towards performance). But, we haven't benchmarked a before/after yet.
 

An interesting experiment would be to hack the Dart VM to ignore 'as' casts and see if the performance of some app or benchmark improves.

We'll try to bring this up if we feel we really want to use `as`, because it would be interesting to see what the cost really is. In the meantime, the evolving style is to not use `as` and introduce a local variable.

Lasse R.H. Nielsen

unread,
Oct 19, 2015, 2:17:56 AM10/19/15
to Seth Ladd, Dart Core Development
On Mon, Oct 19, 2015 at 6:12 AM, 'Seth Ladd' via Dart Core Development <core...@dartlang.org> wrote:
Hi,

In looking at Flutter code, and later, code in dartdoc, I see cases where we are either really tempted to, or in fact did, use `as` to say "this variable should be of type Foo, so analyzer, don't worry, the method call will work". However, it feels weird to pay the runtime cost of `as` in almost all cases. My question for the group is: Has there been any discussion around a check-mode-only cast?

The current behavior of the "as" operator isn't what anybody ever asked for. I think we should definitely change it in 2.0. Making it a checked-mode only check is probably the most compatible change - all checked mode programs keep working the same, some unchecked mode programs omits throwing, but will likely fail anyway soon after. 

/L
--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Brian Slesinsky

unread,
Oct 19, 2015, 12:12:41 PM10/19/15
to Seth Ladd, Dart Core Development

I find the version with local variables more readable than the ones with nested expressions since it can be read one line at a time, rather than inside-out.

I might use shorter local variable names (dec, src), to reduce repetition. When the only reference is on the next line, they can be really short.

Leaf Petersen

unread,
Oct 19, 2015, 7:28:15 PM10/19/15
to Brian Slesinsky, Seth Ladd, Dart Core Development
You could write this as a generic method:

T cast<T>(dynamic x) => x;

... cast<Declaration>(node)....

This implies a checked mode check, but no production mode check.  You have to rely on the VM to inline to avoid overhead, but it would be surprising to say the least if that did not happen 100% of the time.

I discussed this with ianh@ a while back - he was also quite interested in being able to write a down cast only version of this:

T downCast<F, T extends F>(F x) => x;

so that you get a static type warning if you try to cast sideways. 

-leaf


Bob Nystrom

unread,
Oct 19, 2015, 7:35:49 PM10/19/15
to Leaf Petersen, Brian Slesinsky, Seth Ladd, Dart Core Development

On Mon, Oct 19, 2015 at 4:28 PM, 'Leaf Petersen' via Dart Core Development <core...@dartlang.org> wrote:
T cast<T>(dynamic x) => x;

... cast<Declaration>(node)....

It would be nice if this was an actual method on Object because then you would have the right precedence and wouldn't need as many parentheses:

return ((node as Declaration).element.source as FileBasedSource)
  .file
  .toString();

return node.as<Declaration>.element.source.as<FileBasedSource>
  .file
  .toString();

– bob
Reply all
Reply to author
Forward
0 new messages