tc39 / proposal-first-class-protocols

a proposal to bring protocol-based interfaces to ECMAScript users
352 stars 9 forks source link

Implementation selection #37

Open TitanNano opened 3 years ago

TitanNano commented 3 years ago

I read the proposal a couple of times now, but I'm still failing to see who implementation selection is going to work.

Let's say I create my own ToString protocol:

Protocol ToString {
    symbol;

    toString() {
       return this[ToString.symbol];
    } 
}

const myObject = {
    [ToString.symbol]: 'myObject',
};

console.log(myObject.toString());

How is the implementation of .toString() being selected? Will this run Object.prototype.toString() or ToString.toString()?

ljharb commented 3 years ago

In your case, myObject doesn’t fully implement the protocol, so it’ll fall back to the Object.prototype method. If it did fully implement it, it’d use the ToString.toString method.

TitanNano commented 3 years ago

@ljharb you are right, I forgot

Protocol.implements(myObject, ToString);

But what if I have two competing Protocols which both implement toString()? And how would I select the original Object.prototype.toString() implementation?

ljharb commented 3 years ago

Generally speaking, there'd only be two options: to have the last one win, or to throw. I assume that rather than silently doing the wrong thing, this proposal would choose to throw, so that you couldn't mix competing protocols.

If a protocol you want to use provides a toString implementation, then either you use its toString, or you don't use that protocol.

TitanNano commented 3 years ago

@ljharb I see, so a library can not use its own protocol internally without affecting the consuming application...

After I opened this, I saw PR #32 which appears to propose using myObject[ToString].toString(), that would avoid this issue, but also feels clunky.