Closed michaelficarra closed 7 years ago
Interesting! ๐ค
I always thought clause 16 was about extensions at an engine level and not transpilations like TS, Flow, CS, LiveScript, Babel plugins, etc. This means transpilations are very much like libraries in the ecosystem, which have roadblocked built-in additions in the past.
@jdalton You're right, clause 16 is about engine level extensions, but it's complicated when an "extension" language is meant to always support everything in ECMAScript and becomes really popular. It restricts how ECMAScript can grow. See https://twitter.com/jspedant/status/871875746041446400. I will probably start a thread with a proposal for a normative recommendation on the ecma262 issue tracker soon.
The feature set described by this proposal does more closely resembles Rust's trait
or Swift's protocol
than TypeScript's interface
(the Symbol
-based approach ensures that it's orthogonal).
I like protocol
, but don't see a strong argument in preferring one over the other.
@michaelficarra are you reconsidering implements
as well?
@gabejohnson No, I think that still works fine.
Personally I find the x implements b
syntax more misleading than anything else, it feels more like a question akin to instanceof
. Having a binary operator that mutates the left operand just feels weird.
Personally I think a Object.
/Reflect.
method would be fine for extending objects, x implements y
would be really nice for the question form you mentioned you wanted to add into the spec e.g.:
class Tuple implements Iterator {
...
}
const value = new Tuple([1,2,3,4])
...
// This seems the most intuitive interpretation of binary
// implements to me
if (value implements Iterator) {
for (const item of value) {
...
}
}
// But we should still support adding interfaces to existing objects
Object.addInterface(x, someInterface)
@Jamesernator I agree with you, but let's not bikeshed other syntax in this issue.
๐ for protocol
.
I vastly prefer interface
and really dislike the idea that "not JavaScript" might yet again force the direction of a language proposal.
interface
is a reserved word. TypeScript chose to use it at their own risk. They should accept the consequences of that choice.
@ljharb It is a conversation that we need to have within the committee. See my comment above.
I will probably start a thread with a proposal for a normative recommendation on the ecma262 issue tracker soon.
I've already talked with @bterlson and the TypeScript team about this issue, and I have some ideas. Would you like to get on a call soon to go over the possible solutions? Would you like to help prepare a presentation for the committee for July/September?
Happy to discuss and help! I mainly think renaming the proposal prior to committee is a bad idea when motivated by "not web" compat issues.
Closing. The syntax has been changed to protocol
for its first presentation to the committee. I will bring up the ecosystem compatibility issue, which has also been addressed in the README.
@michaelficarra I don't understand; you never reached out to set up a call, and I feel quite strongly that it's a dangerous precedent to let TypeScript impose any constraint on JS. TypeScript isn't JS, and that's not the ecosystem we need to be concerned with.
@ljharb Sorry for the lack of communication on my part there. I ended up deciding that it wasn't worth putting up an unnecessary barrier for this proposal, and just wanted to get initial (stage 1 level) feedback from the committee. If using the interface
keyword was going to make that difficult, I'd rather just avoid it.
For my presentation to the committee, I will make sure to request to withhold any syntax related discussion until after we can agree that it is a feature the committee would like to pursue (stage 1). I am with you on both points: interface
is better, and we shouldn't allow TypeScript to inhibit ECMAScript language growth. But I'd like to know whether this proposal is a non-starter before we have those discussions.
In my mind, not using interface
is the barrier.
That's fair - I am totally fine to withhold discussion until stage 1; but I think you'd have been able to defer that discussion regardless of what it's called initially.
I am with you on both points: interface is better, and we shouldn't allow TypeScript to inhibit ECMAScript language growth
Should this be added as a specific agenda item to discuss?
@jdalton once the proposal is stage 1, absolutely - but it'd be counterproductive to discuss it prior to that.
With or without this proposal the question of how transpiled languages effect TC39 language design remains. I've watched other items, like a formal process for adding built-ins, get forgotten nearly a year later. I wouldn't want this to get lost as well.
I'm not aware of any way "the question of how transpiled languages affect TC39" has constrained other proposals besides this thread, and my failed "sigil swap" attempt. A "formal process for adding builtins" simply has lacked a champion to date.
From an ecosystem standpoint it would prolly be good to know (sooner than later) if transpilers could be an anti-pattern in much the same way extending built-ins with non-standard methods are.
@jdalton Brian and I are both really passionate about addressing the ecosystem issue. I'm sure we'll follow up with it in future meetings, and I'm also sure it will be a big part of the informal discussions at this one.
By the way, the solution I'm currently envisioning for this problem is a normative recommendation for all language extensions to be done through a permanently reserved section of the grammar, similar to how the :
following BindingIdentifiers is reserved in ยง16.2 Forbidden Extensions.
The Syntactic Grammar must not be extended in any manner that allows the token
:
to immediately follow source text that matches the BindingIdentifier nonterminal symbol.
๐ \cc @leobalter since this discussion may be relevant to JS Foundation projects.
Clojure explains protocols and how they differ from interfaces. What TypeScript implements as an interface is not the same as what Clojure calls a protocol.
For one the the object implements an interface so that it can be invoked as a method call. Where as a protocol is executed, normally, from the outside. And the same behavior can be implemented as a interface, a protocol, or both.
const fib = new Promise(...);
fib.then(console.log.bind(console)); //as an interface it's called as a method
Thenable.then(fib, console.log.bind(console)); //as a protocol it's called as a function
The latter is more functional.
In a world of duck typing calling then
makes no contractual guarantees where a protocol does. And different vendors can implement their own versions of Thenable
with nuanced difference and not clobber one another, nor risk invoking the other's implementations.
To avoid ecosystem incompatibilities with TypeScript and to give this proposal the best chance of succeeding, we should change the name/syntax. Using a
[no LineTerminator here]
, we can use any Identifier we want as an alternative tointerface
. After thinking on it, I preferprotocol
since that's the terminology we use when talking aboutSymbol.iterator
and similar. Others have suggestedtrait
. Let me know your thoughts/opinions.