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

List swap method #22306

Open
azenla opened this issue Feb 6, 2015 · 11 comments
Open

List swap method #22306

azenla opened this issue Feb 6, 2015 · 11 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. core-2 type-enhancement A request for a change that isn't a bug

Comments

@azenla
Copy link
Contributor

azenla commented Feb 6, 2015

I would like to propose a 'swap' method on List, which would have the following functionality:

void swap(int x, int y) {
  var tmp = this[x];
  this[x] = this[y];
  this[y] = tmp;
}

Of course there would probably be some range checks, but this would greatly enhance the List class for me, and I'm sure others.

@sethladd
Copy link
Contributor

sethladd commented Feb 6, 2015

Added Area-Library, Triaged labels.

@azenla azenla added Type-Enhancement area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. labels Feb 6, 2015
@andrey-zakharov
Copy link

Especially this will be useful with ObservableList, to get only one change record, with added and removed fields simultaneously.

@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed triaged labels Mar 1, 2016
@floitschG floitschG added core-2 and removed core-m labels Aug 24, 2017
@vogella
Copy link

vogella commented Feb 18, 2020

+1, would be nice to have this method in the core SDK.

@andredsnogueira
Copy link

+1

1 similar comment
@nishiths23
Copy link

+1

@lrhn
Copy link
Member

lrhn commented Sep 10, 2020

We have no current plans to change the List API. It's a very central API, and adding a method to it will break all classes currently implementing List. The benefit has to be very great for us to do that (no matter how convenient such a method would be).

@jodinathan
Copy link

We have no current plans to change the List API. It's a very central API, and adding a method to it will break all classes currently implementing List. The benefit has to be very great for us to do that (no matter how convenient such a method would be).

can it be done with extensions so it don't break implementations?
I know there may be a package that does this, but I have the feeling that this kind of stuff should be in the core

@lrhn
Copy link
Member

lrhn commented Sep 10, 2020

You can definitely write an extension, but then ObservableList won't be able to intercept the operation (as suggested above) unless the target is statically typed as ObservableList.

(Again, interface default methods would allow us to add members to an interface without (necessarily) breaking classes implementing the interface. We can break classes which already uses the same name, but that's still less than breaking all classes implementing an interface. Until we get interface default methods, I don't see a big urge to add swap in the platform libraries, because anyone can add it just as efficiently).

extension ListSwap<T> on List<T> {
  void swap(int index1, int index2) {
    var length = this.length;
    RangeError.checkValidIndex(index1, this, "index1", length);
    RangeError.checkValidIndex(index2, this, "index2", length);
    if (index1 != index2) {
      var tmp1 = this[index1];
      this[index1] = this[index2];
      this[index2] = tmp1;
    }
  }
}

@fabiancrx
Copy link

Are "interface default methods" being considered or tracked in any issue?

@eernstg
Copy link
Member

eernstg commented Feb 6, 2023

dart-lang/language#884 outlines a proposal for interface default methods. There's a different proposal with similar properties in dart-lang/language#2510: class extension members.

Interface default members are real instance members, which means that if a class C has an implementation of a member m because there's a (direct or indirect) superinterface S of C that declares an interface default member named m, then a subclass class D extends C can declare its own implementation of m, and that implementation will override C.m just like regular instance members.

Class extension members are more like extension members. This means that they are resolved statically, and there's no way you could write a declaration which will dynamically override the statically known declaration for any given call site.

The other side of that coin is that interface default member conflicts are more difficult to handle: If C has superinterfaces S1 and S2, and both of them provide an interface default member named m (and C doesn't have an implementation of m), then there must be some mechanism to decide which one of those two implementations is copied down into C (if any). Moreover, if those two variants of m have incompatible signatures (say, S1.m is a getter and S2.m is a method) then it's not obvious that there is a solution at all (e.g., what should (myC as dynamic).m do, should it invoke the getter or tear off the method?). With a class extension member you can just declare whatever kind of member you want in C, because every call site will invoke the statically known declaration: When the static type is S1 it will call S1.m, when it's S2 then it will call S2.m, and when it's C it will call C.m. They can have completely unrelated signatures, because there is never a dynamic dispatch step where we don't know which one we're calling.

@lrhn
Copy link
Member

lrhn commented Feb 6, 2023

Conflicts between interface default methods are like conflicts between any other interface methods, if a subclass can't define a member signature that satisfies both, it cannot implement both interfaces.
On top of that, a conflict may also prevent automatic introduction of the default implementation.

Interface default methods exist to solve the software engineering problem of adding members to interfaces that are already implemented by third-party classes, without those classes suddenly not satisfying the interface. It's just about providing a default implementation of new members, it can't solve API conflicts.
(Traits, on the other hand, might be able to.)

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. core-2 type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests