Discussion:
[dart-misc] List.cast<Type>() doesn't actually cast the list (in Dart 2)?
Ryan Gonzalez
2018-04-03 00:26:34 UTC
Permalink
This is something kind of weird I've run into in my Flutter app:


class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}


The add operation gives me:

Unhandled exception:
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart

#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)


This seems rather odd, since it kind of kills the point of List.cast<Type>
*and* makes it so that you can have a generic type that isn't actually that
type (since the assignment works, so according to the type system, the
operation should be valid).

Tested with Dart 2.0.0-dev.44.0.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mNOctG0tDN4VOCHR2f3KLO_%3D5JM6kSFR6j4yURxHiLSsw%40mail.gmail.com.
'Bob Nystrom' via Dart Misc
2018-04-03 00:57:00 UTC
Permalink
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.

List.cast<T>() gives you back a list that is *still backed by the original
list*. It's a live view into that list. Because your original list is a
List<Derived1>, you can't add a Derived2 to it, even through the view given
to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
isolate/isolate_patch.dart:279)
isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.

The normal use case is that you have a list of some wide type (say num),
but you happen to know that it only contains elements of some narrow type
(say int). You can use cast<T>() to cast it down to that narrower type and
then pass the result to code that expects a list whose static type is that
narrow type.

For upcasting, you don't need .cast<T>() at all. You can just cast the
original list:

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}


This is allowed because all generics are covariant in Dart.

*and* makes it so that you can have a generic type that isn't actually that
Post by Ryan Gonzalez
type (since the assignment works, so according to the type system, the
operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as you can
see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the same for
all generics.)

Cheers!

– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com.
Ryan Gonzalez
2018-04-03 01:28:12 UTC
Permalink
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...

On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc"
<***@dartlang.org> wrote:
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.


List.cast<T>() gives you back a list that is still backed by the original
list. It's a live view into that list. Because your original list is a
List<Derived1>, you can't add a Derived2 to it, even through the view given
to you by List.cast<Base>().

On Mon, Apr 2, 2018 at 5:26 PM, Ryan Gonzalez <***@gmail.com> wrote:

This is something kind of weird I've run into in my Flutter app:


class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}


The add operation gives me:

Unhandled exception:
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart

#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)


This seems rather odd, since it kind of kills the point of List.cast<Type>

List.cast<T>() is only ever useful for downcasting a list.

The normal use case is that you have a list of some wide type (say num),
but you happen to know that it only contains elements of some narrow type
(say int). You can use cast<T>() to cast it down to that narrower type and
then pass the result to code that expects a list whose static type is that
narrow type.

For upcasting, you don't need .cast<T>() at all. You can just cast the
original list:

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}

This is allowed because all generics are covariant in Dart.

*and* makes it so that you can have a generic type that isn't actually that
type (since the assignment works, so according to the type system, the
operation should be valid).

Yeah, the problem is that covariance isn't statically type-safe, as you can
see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat arrays as covariant. Dart does the same for
all generics.)

Cheers!

– bob


--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com.

--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com.
'Bob Nystrom' via Dart Misc
2018-04-03 16:02:56 UTC
Permalink
The behavior you want is probably there, but I'm not sure what you mean by
"like this". What code would you like to be able to write and what would
you have it do?

– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your original
list is a List<Derived1>, you can't add a Derived2 to it, even through the
view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/dart:isola
te/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of
List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say num),
but you happen to know that it only contains elements of some narrow type
(say int). You can use cast<T>() to cast it down to that narrower type and
then pass the result to code that expects a list whose static type is that
narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast the
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't actually
Post by Ryan Gonzalez
that type (since the assignment works, so according to the type system, the
operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as you
can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the same
for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/
dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_
kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/
dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413c
e6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com.
Ryan Gonzalez
2018-04-03 22:27:46 UTC
Permalink
By "like this", I mean something like:

derived1List.mapCast<Base>()
// which does:
derived1List.map((c) => c as Base)

Except it wouldn't give off analyzer errors about redundant casts and would
be more readable.

On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you mean by
"like this". What code would you like to be able to write and what would
you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your original
list is a List<Derived1>, you can't add a Derived2 to it, even through the
view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/dart:isola
te/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of
List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say num),
but you happen to know that it only contains elements of some narrow type
(say int). You can use cast<T>() to cast it down to that narrower type and
then pass the result to code that expects a list whose static type is that
narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast the
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't actually
Post by Ryan Gonzalez
that type (since the assignment works, so according to the type system, the
operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as you
can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the same
for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8
_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e
9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/
dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%
3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com.
tatumizer-v0.2
2018-04-03 22:36:24 UTC
Permalink
Maybe you are looking for constructor List.from(anotherList)?
https://api.dartlang.org/stable/1.24.3/dart-core/List/List.from.html
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/295e1ca8-923a-44ea-98e4-a875c1024b95%40dartlang.org.
'Bob Nystrom' via Dart Misc
2018-04-04 00:35:35 UTC
Permalink
Post by Ryan Gonzalez
derived1List.mapCast<Base>()
derived1List.map((c) => c as Base)
Except it wouldn't give off analyzer errors about redundant casts and
would be more readable.
I'm probably missing something. derived1List is already a List<Base> as far
as the static type system is concerned. List<Base> is a supertype of
List<Derived1>. This code is fine:

expectListBase(List<Base> list) {}

void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}


You can just use a List<Derived1> directly anywhere a List<Base> is
expected.

– bob
Post by Ryan Gonzalez
On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you mean
by "like this". What code would you like to be able to write and what would
you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your original
list is a List<Derived1>, you can't add a Derived2 to it, even through the
view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of
List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say
num), but you happen to know that it only contains elements of some narrow
type (say int). You can use cast<T>() to cast it down to that narrower type
and then pass the result to code that expects a list whose static type is
that narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast the
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't actually
Post by Ryan Gonzalez
that type (since the assignment works, so according to the type system, the
operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as you
can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the
same for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8
_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e
9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZs
dR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/
dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%
3DGQQuVUJSik-nbcAg%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com.
Ryan Gonzalez
2018-04-04 01:06:15 UTC
Permalink
On April 3, 2018 7:36:09 PM "'Bob Nystrom' via Dart Misc"
<***@dartlang.org> wrote:


On Tue, Apr 3, 2018 at 3:27 PM, Ryan Gonzalez <***@gmail.com> wrote:

By "like this", I mean something like:

derived1List.mapCast<Base>()
// which does:
derived1List.map((c) => c as Base)

Except it wouldn't give off analyzer errors about redundant casts and would
be more readable.

I'm probably missing something. derived1List is already a List<Base> as far
as the static type system is concerned. List<Base> is a supertype of
List<Derived1>. This code is fine:

expectListBase(List<Base> list) {}


void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}

You can just use a List<Derived1> directly anywhere a List<Base> is expected.

– bob



On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc
<***@dartlang.org> wrote:
The behavior you want is probably there, but I'm not sure what you mean by
"like this". What code would you like to be able to write and what would
you have it do?

– bob


On Mon, Apr 2, 2018 at 6:28 PM, Ryan Gonzalez <***@gmail.com> wrote:
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...

On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc"
<***@dartlang.org> wrote:
Oof, that is confusing. I believe the behavior here is deliberate, but
unintuitive.


List.cast<T>() gives you back a list that is still backed by the original
list. It's a live view into that list. Because your original list is a
List<Derived1>, you can't add a Derived2 to it, even through the view given
to you by List.cast<Base>().

On Mon, Apr 2, 2018 at 5:26 PM, Ryan Gonzalez <***@gmail.com> wrote:

This is something kind of weird I've run into in my Flutter app:


class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}


The add operation gives me:

Unhandled exception:
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart

#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)


This seems rather odd, since it kind of kills the point of List.cast<Type>

List.cast<T>() is only ever useful for downcasting a list.

The normal use case is that you have a list of some wide type (say num),
but you happen to know that it only contains elements of some narrow type
(say int). You can use cast<T>() to cast it down to that narrower type and
then pass the result to code that expects a list whose static type is that
narrow type.

For upcasting, you don't need .cast<T>() at all. You can just cast the
original list:

void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}

This is allowed because all generics are covariant in Dart.

*and* makes it so that you can have a generic type that isn't actually that
type (since the assignment works, so according to the type system, the
operation should be valid).

Yeah, the problem is that covariance isn't statically type-safe, as you can
see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat arrays as covariant. Dart does the same for
all generics.)

Cheers!

– bob


--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.

To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com.

--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/



--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.

To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com.


--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.

To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com.




--

Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/


--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.

To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com.


--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to misc+***@dartlang.org.
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com.

But then trying to add an item of type Derived2 still fails, since the
runtime checked mode doesn't see things that way.

I guess I could just use List.from as mentioned, since this whole thing was
mostly just me misunderstanding what List.cast does, and I was expecting a
method for this (kind of like x.toList() is a neater-ish way of writing
List<T>.from(x)).

--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/1628e30a358.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com.
'Bob Nystrom' via Dart Misc
2018-04-04 16:02:54 UTC
Permalink
On April 3, 2018 7:36:09 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Post by Ryan Gonzalez
derived1List.mapCast<Base>()
derived1List.map((c) => c as Base)
Except it wouldn't give off analyzer errors about redundant casts and
would be more readable.
I'm probably missing something. derived1List is already a List<Base> as
far as the static type system is concerned. List<Base> is a supertype of
expectListBase(List<Base> list) {}
void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}
You can just use a List<Derived1> directly anywhere a List<Base> is expected.
– bob
Post by Ryan Gonzalez
On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you mean
by "like this". What code would you like to be able to write and what would
you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate,
but unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your
original list is a List<Derived1>, you can't add a Derived2 to it, even
through the view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main (file:///home/ryan/stuff/Downl
oads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say
num), but you happen to know that it only contains elements of some narrow
type (say int). You can use cast<T>() to cast it down to that narrower type
and then pass the result to code that expects a list whose static type is
that narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't
Post by Ryan Gonzalez
actually that type (since the assignment works, so according to the type
system, the operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as
you can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the
same for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8
Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/162891
e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZs
dR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit https://groups.google.com/a/da
rtlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R
%3DGQQuVUJSik-nbcAg%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit https://groups.google.com/a/
dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%
3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
But then trying to add an item of type Derived2 still fails, since the
runtime checked mode doesn't see things that way.
That's always going to fail if you are trying to add the Derived2 to the
original list since the original list is declared as List<Derived1>. If you
could get a Derived2 in there, it would break the type system.
I guess I could just use List.from as mentioned, since this whole thing
was mostly just me misunderstanding what List.cast does, and I was
expecting a method for this (kind of like x.toList() is a neater-ish way of
writing List<T>.from(x)).
Ah, so you want a *copy* of the list, not a view into the original list. In
that case, yes, new List<Base>.from(derived1List) is the way to go.

Cheers!

– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lzn_f3WxthJBnwieHXCPX1RjhX2anf8CjRhGBROvsN_NA%40mail.gmail.com.
Günter Zöchbauer
2018-04-07 09:24:53 UTC
Permalink
what's the difference between cast and retype?
Post by 'Bob Nystrom' via Dart Misc
On April 3, 2018 7:36:09 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Post by Ryan Gonzalez
derived1List.mapCast<Base>()
derived1List.map((c) => c as Base)
Except it wouldn't give off analyzer errors about redundant casts and
would be more readable.
I'm probably missing something. derived1List is already a List<Base> as
far as the static type system is concerned. List<Base> is a supertype of
expectListBase(List<Base> list) {}
void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}
You can just use a List<Derived1> directly anywhere a List<Base> is expected.
– bob
Post by Ryan Gonzalez
On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you
mean by "like this". What code would you like to be able to write and what
would you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate,
but unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your
original list is a List<Derived1>, you can't add a Derived2 to it, even
through the view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add (dart:core-patch/dart:core/growable_array.dart:149)
#1 main
(file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say
num), but you happen to know that it only contains elements of some narrow
type (say int). You can use cast<T>() to cast it down to that narrower type
and then pass the result to code that expects a list whose static type is
that narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't
Post by Ryan Gonzalez
actually that type (since the assignment works, so according to the type
system, the operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as
you can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the
same for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
But then trying to add an item of type Derived2 still fails, since the
runtime checked mode doesn't see things that way.
That's always going to fail if you are trying to add the Derived2 to the
original list since the original list is declared as List<Derived1>. If you
could get a Derived2 in there, it would break the type system.
I guess I could just use List.from as mentioned, since this whole thing
was mostly just me misunderstanding what List.cast does, and I was
expecting a method for this (kind of like x.toList() is a neater-ish way of
writing List<T>.from(x)).
Ah, so you want a *copy* of the list, not a view into the original list.
In that case, yes, new List<Base>.from(derived1List) is the way to go.
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/6ed36080-7f6b-42d9-b150-3ab42abe44ff%40dartlang.org.
Patrice Chalin
2018-04-08 11:18:38 UTC
Permalink
Post by Günter Zöchbauer
what's the difference between cast and retype?
FYI, Bob will be addressing that exact question in Effective Dart; to
track progress see https://github.com/dart-lang/site-www/issues/736.
Post by Günter Zöchbauer
Post by 'Bob Nystrom' via Dart Misc
On April 3, 2018 7:36:09 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Post by Ryan Gonzalez
derived1List.mapCast<Base>()
derived1List.map((c) => c as Base)
Except it wouldn't give off analyzer errors about redundant casts and
would be more readable.
I'm probably missing something. derived1List is already a List<Base> as
far as the static type system is concerned. List<Base> is a supertype of
expectListBase(List<Base> list) {}
void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}
You can just use a List<Derived1> directly anywhere a List<Base> is expected.
– bob
Post by Ryan Gonzalez
On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you
mean by "like this". What code would you like to be able to write and what
would you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate,
but unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your
original list is a List<Derived1>, you can't add a Derived2 to it, even
through the view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from
file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from
file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add
(dart:core-patch/dart:core/growable_array.dart:149)
#1 main
(file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say
num), but you happen to know that it only contains elements of some narrow
type (say int). You can use cast<T>() to cast it down to that narrower type
and then pass the result to code that expects a list whose static type is
that narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't
Post by Ryan Gonzalez
actually that type (since the assignment works, so according to the type
system, the operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe, as
you can see in the above example. Dart addresses that by checking covariant
operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does the
same for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
But then trying to add an item of type Derived2 still fails, since the
runtime checked mode doesn't see things that way.
That's always going to fail if you are trying to add the Derived2 to the
original list since the original list is declared as List<Derived1>. If you
could get a Derived2 in there, it would break the type system.
I guess I could just use List.from as mentioned, since this whole thing
was mostly just me misunderstanding what List.cast does, and I was
expecting a method for this (kind of like x.toList() is a neater-ish way of
writing List<T>.from(x)).
Ah, so you want a *copy* of the list, not a view into the original list.
In that case, yes, new List<Base>.from(derived1List) is the way to go.
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/4715d078-1b9a-4c63-bc10-605f848fee4c%40dartlang.org.
Günter Zöchbauer
2018-04-22 14:00:21 UTC
Permalink
A bit late. Thanks for the link anyway :)
Post by Patrice Chalin
Post by Günter Zöchbauer
what's the difference between cast and retype?
FYI, Bob will be addressing that exact question in Effective Dart; to
track progress see https://github.com/dart-lang/site-www/issues/736.
Post by Günter Zöchbauer
Post by 'Bob Nystrom' via Dart Misc
On April 3, 2018 7:36:09 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Post by Ryan Gonzalez
derived1List.mapCast<Base>()
derived1List.map((c) => c as Base)
Except it wouldn't give off analyzer errors about redundant casts and
would be more readable.
I'm probably missing something. derived1List is already a List<Base>
as far as the static type system is concerned. List<Base> is a supertype of
expectListBase(List<Base> list) {}
void main() {
var derived1List = <Derived1>[new Derived1()];
expectListBase(derived1List);
}
You can just use a List<Derived1> directly anywhere a List<Base> is expected.
– bob
Post by Ryan Gonzalez
On Tue, Apr 3, 2018 at 11:02 AM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
The behavior you want is probably there, but I'm not sure what you
mean by "like this". What code would you like to be able to write and what
would you have it do?
– bob
Post by Ryan Gonzalez
Ah...what are the changes of getting a mapCast or similar that does
something like this? It'd be a nice feature for the strong mode Dart world...
On April 2, 2018 7:57:34 PM "'Bob Nystrom' via Dart Misc" <
Post by 'Bob Nystrom' via Dart Misc
Oof, that is confusing. I believe the behavior here is deliberate,
but unintuitive.
List.cast<T>() gives you back a list that is *still backed by the
original list*. It's a live view into that list. Because your
original list is a List<Derived1>, you can't add a Derived2 to it, even
through the view given to you by List.cast<Base>().
Post by Ryan Gonzalez
class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List.cast<Base>();
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
type 'Derived2' is not a subtype of type 'Derived1' of 'value' where
Derived2 is from
file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
Derived1 is from
file:///home/ryan/stuff/Downloads/dart-sdk/x.dart
#0 List.add
(dart:core-patch/dart:core/growable_array.dart:149)
#1 main
(file:///home/ryan/stuff/Downloads/dart-sdk/x.dart:8:12)
#2 _startIsolate.<anonymous closure>
(dart:isolate-patch/dart:isolate/isolate_patch.dart:279)
#3 _RawReceivePortImpl._handleMessage
(dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
This seems rather odd, since it kind of kills the point of
List.cast<Type>
List.cast<T>() is only ever useful for *downcasting* a list.
The normal use case is that you have a list of some wide type (say
num), but you happen to know that it only contains elements of some narrow
type (say int). You can use cast<T>() to cast it down to that narrower type
and then pass the result to code that expects a list whose static type is
that narrow type.
For upcasting, you don't need .cast<T>() at all. You can just cast
void main() {
// Create a List<Derived1>.
var derived1List = <Derived1>[new Derived1()];
// Cast to a List<Base> (note that this assignment succeeds).
List<Base> baseList = derived1List;
// Try adding a Derived2 to the list (fails!).
baseList.add(new Derived2() as Base);
}
This is allowed because all generics are covariant in Dart.
*and* makes it so that you can have a generic type that isn't
Post by Ryan Gonzalez
actually that type (since the assignment works, so according to the type
system, the operation should be valid).
Yeah, the problem is that covariance isn't statically type-safe,
as you can see in the above example. Dart addresses that by checking
covariant operations at runtime, which is the exception you're seeing. (For
comparison, Java and C# treat *arrays* as covariant. Dart does
the same for all generics.)
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8Lyn%3DxiBVK3jEP%3Dv23CTObDCYA8_9Lo8a1J_kaPmwkRtUw%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/162891e5bf8.2837.db5b03704c129196a4e9415e55413ce6%40gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyS4iRprvZE%2BhE04DWYAV9eVFQZsdR4%2BRYPT%3DtQDuCJ7w%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAO41-mMri%3DK9HEJJmEot8sO6RwketJ61R%3DGQQuVUJSik-nbcAg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com
<https://groups.google.com/a/dartlang.org/d/msgid/misc/CAF8T8LyLqh5gbOTm7SgO5N4yaFkB%3D69hiqBNHuQM5F5xVzr8oA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
But then trying to add an item of type Derived2 still fails, since the
runtime checked mode doesn't see things that way.
That's always going to fail if you are trying to add the Derived2 to the
original list since the original list is declared as List<Derived1>. If you
could get a Derived2 in there, it would break the type system.
I guess I could just use List.from as mentioned, since this whole thing
was mostly just me misunderstanding what List.cast does, and I was
expecting a method for this (kind of like x.toList() is a neater-ish way of
writing List<T>.from(x)).
Ah, so you want a *copy* of the list, not a view into the original
list. In that case, yes, new List<Base>.from(derived1List) is the way
to go.
Cheers!
– bob
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/5e8fa1f1-03fc-41ac-81eb-b88834da72ba%40dartlang.org.
Continue reading on narkive:
Loading...