webidl icon indicating copy to clipboard operation
webidl copied to clipboard

Making methods more future-proof

Open jakearchibald opened this issue 4 years ago • 8 comments

I've recently seen a couple of code examples that could create compatibility issues later:

const nextFrame = new Promise(requestAnimationFrame);

The above works because requestAnimationFrame only takes one arg. If we change it to take two, the above may behave differently and unexpectedly.

const controller = new AbortController();
el.addEventListener(name, callback, controller);

The above works because AbortController and AddEventListenerOptions share a signal property with the same intent. If we change either of these in a way that creates a cross-over that doesn't have the same intent, the above may behave differently and unexpectedly.

Our current strategy is to make changes to the platform, and be forced into different pattern if it creates a compatibility issue due to patterns like above. Should we do something more preemptive?

We could throw in cases where functions are called with more arguments than expected, and throw if option objects have unexpected properties (aside from the properties that already come with Object).

This would likely be breaking if applied to existing APIs, so it should only be applied to new APIs. Existing APIs could show a console warning instead.

jakearchibald avatar Feb 03 '21 10:02 jakearchibald

Unless JavaScript (i.e., TC39) acts here I don't think we should.

cc @littledan

annevk avatar Feb 03 '21 10:02 annevk

I guess the alternative is to continue outreach like https://jakearchibald.com/2021/function-callback-risks/ and hope developers follow it.

jakearchibald avatar Feb 03 '21 11:02 jakearchibald

It's not clear to me what JavaScript should do, beyond making sure that the safer idioms are ergonomic (which I believe they are, with arrow functions and object literals). We could add certain stricter checks to make the unsafe patterns more unlikely, but to preserve compatibility, we could really only do this for new APIs (both creating a discontinuity and leaving the greater part of the problem unsolved). I wonder if type systems can help encourage people to use future-proof patterns @rbuckton.

littledan avatar Feb 03 '21 13:02 littledan

we could really only do this for new APIs (both creating a discontinuity and leaving the greater part of the problem unsolved)

Agreed, although we can use console warnings for existing APIs. We may also choose to declare "we will never add an extra param to this" for particular functions, meaning things like array.filter(Boolean) would never show a warning.

jakearchibald avatar Feb 03 '21 13:02 jakearchibald

The first example is one of the motivations behind https://github.com/tc39/proposal-partial-application:

const nextframe = new Promise(requestAnimationFrame(?));

Type systems can help in some ways (informing the user if the type of the argument is incompatible), whereas Symbol-based protocols can help in others. I'm not sure there's a single solution given how flexible JavaScript is.

rbuckton avatar Feb 03 '21 16:02 rbuckton

@littledan I'm happy to present this idea at TC39 as a discussion point if you think it'd be useful. But totally get it if you think it's a no-go.

jakearchibald avatar Feb 03 '21 19:02 jakearchibald

@littledan is this true https://twitter.com/hrvbrs/status/1357425226309599232?

jakearchibald avatar Feb 05 '21 10:02 jakearchibald

@littledan ping.

annevk avatar Aug 02 '21 14:08 annevk