Skip to content
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

Please consider support ImmutableList, and List should extends it #43332

Open
Silentdoer opened this issue Sep 4, 2020 · 4 comments
Open

Please consider support ImmutableList, and List should extends it #43332

Silentdoer opened this issue Sep 4, 2020 · 4 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. type-enhancement A request for a change that isn't a bug

Comments

@Silentdoer
Copy link

consider following code:

class Fruit {
  final String color;

  Fruit(this.color);

  void printColors(List<Fruit> fruits) {
    fruits.add(Orange());  // TODO will be error in runtime not in static analysis
    for (var fruit in fruits) {
      print('${fruit.color}');
    }
  }
}

class Apple extends Fruit {
  Apple() : super("red");
}

class Orange extends Fruit {
  Orange() : super("orange");
}

void main() {
  List<Apple> apples = <Apple>[];
  apples.add(Apple());
  // it is ok, because dart is default covariant
  Fruit('none').printColors(apples);
}

if support Immutable like MyImmutableList, and MyList is List like following code:

class Fruit {
  final String color;

  Fruit(this.color);

  // TODO in base class, printColors can not add
  void printColors(MyImmutableList<Fruit> fruits) {
    //fruits.setFirst(Orange());  // Now it will be error in static analysis
    fruits.getFirst();  // mock iterate
    /*for (var fruit in fruits) {
      print('${fruit.color}');
    }*/
  }
}

class Apple extends Fruit {
  Apple() : super("red");

  // TODO in sub class, printColors can add it's concrete type element
  // mention apples is List not ImmutableList
  @override
  void printColors(covariant MyList<Apple> apples) {
    apples.setFirst(Apple());  // Now it's ok, and just can add Apple obj
    apples.getFirst();  // mock iterate
    /*for (var fruit in fruits) {
      print('${fruit.color}');
    }*/
  }
}

class Orange extends Fruit {
  Orange() : super("orange");
}

void main() {
  var tmp = MyList<Apple>();
  tmp.setFirst(Apple());
  // it's ok, because dart is default covariant
  MyImmutableList<Apple> apples = tmp;
  Fruit('none').printColors(apples);

  // it's ok
  Apple().printColors(tmp);
}

// MyImmutableList is should support ImmutableList in dart core, and List extends ImmutableList
class MyImmutableList<E> {
  E _firstEle;
  // not support add method

  // like list[index]
  E getFirst() {
    return this._firstEle;
  }
}

// MyList is core List
class MyList<E> extends MyImmutableList<E> {

  // like list[index] = ele;
  void setFirst(E ele) {
    this._firstEle = ele;
  }
}
@lrhn lrhn transferred this issue from dart-lang/language Sep 4, 2020
@lrhn
Copy link
Member

lrhn commented Sep 4, 2020

Dart has so far deliberately not introduced immutable interfaces for collections.

The problem with having both a, say, Sequence (readable list) and subclass List (modifiable list), is that every operation which now takes a List will need to choose between the two. If you end up with a Sequence where you need a List, you are stuck.
The type name would not be ImmutableList because a mutable List would be a subclass, and mutableList is ImmutableList sounds wrong. That means that something being a Sequence does not guarantee that it doesn't change. It just restricts you to not being able to change it through the available API. You are no better off than if you just accepted a List and don't try to modify it.

What could possibly help you here is variance control (dart-lang/language#213), but an immutable list is not likely to be how we'll address this issue.

@Silentdoer
Copy link
Author

Ok, thank you for your response

@leafpetersen
Copy link
Member

You are no better off than if you just accepted a List and don't try to modify it.

But you are better off than if you just accepted a List and did try to modify it. List is claiming capabilities that it doesn't have. By accepting Sequence I'm agreeing to a narrower (and statically enforced) contract.

@Silentdoer
Copy link
Author

You are no better off than if you just accepted a List and don't try to modify it.

But you are better off than if you just accepted a List and did try to modify it. List is claiming capabilities that it doesn't have. By accepting Sequence I'm agreeing to a narrower (and statically enforced) contract.

this will support? so i should reopen this issue.

@Silentdoer Silentdoer reopened this Jan 19, 2021
@mit-mit mit-mit added the area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. label May 5, 2021
@lrhn lrhn added the type-enhancement A request for a change that isn't a bug label May 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants