EcmaTC53 / spec

Ecma TC53 spec work
23 stars 11 forks source link

Async across the board? #36

Closed tve closed 1 year ago

tve commented 1 year ago

Is there interest to define async or easily promisifiable versions of various ECMA-419 class patterns and classes or is it deemed that this is outside the scope of the standard and should be pursued as ad-hoc layers on top of ECMA-419?

For example, looking at the TCP class, defining async read and write methods seems natural. In order to implement this as a layer on top of the current class I believe one has to maintain a queue of read/write promises and use onReadable/onWritable/onError callbacks to resolve/reject these promises.

phoddie commented 1 year ago

This was discussed in great depth at the start of the committee's work. The result is what we have today. "Async across the board" was expressly rejected. There is no consensus in JavaScript of a single model of asynchronous programming, making standardization impractical at best.

That said, making it straightforward to support various asynchronous programming models -- promises and events, for example -- was a goal. The committee reviewed examples that did exactly that.

dtex commented 1 year ago

My favorite argument for this approach was that not all embedded JS runtimes support modern ES features. We wouldn't want to box them out of an ECMA-419 conformant implementation.

tve commented 1 year ago

We wouldn't want to box them out of an ECMA-419 conformant implementation.

Totally agreed. Nowhere did I suggest an async-exclusive standard, in fact, I wrote "promisifiable versions of"...

I would have appreciated seeing an optional promises/async interface being specified or at least a consistent pattern for promisifing methods as done in the async I2C proposal. Being able to see the mentioned examples reviewed by the committee would also be helpful.

As an example, looking at the 2nd edition proposal, the base class defines a pattern for async methods because (as far as I understand) it is easily promisifiable in a consistent manner. The TCP class (which precedes the async proposal) onRead/read onWrite/write methods do not follow that new pattern. The proposed HTTP class does neither. The TCP class has an onError callback, the HTTP class doesn't and I'm not sure how transport/protocol errors are signalled (I'm probably not seeing something obvious).

When I wrote "async across the board" I was really looking for the standard to view a promises/async interface as a first-class citizen equal to the callback interface and include an optional promises/async interface in the spec. If that interface can be layered on top of the callback interface, then all-thumbs-up. At the end of the day one of the purposes of the standard is to enable writing portable code and that kind'a gets defeated if everyone creates their own promisified version of the APIs.

dtex commented 1 year ago

Have you been reviewing the 1st edition or the working draft of the 2nd edition?

edit: Sorry, I read the whole comment, but my brain only processed the first two paragraphs.

I'll defer on TCP and HTTP, but with regards to Async across the board... More explicit documentation of the async methods throughout the IO classes instead of just one mention in the IO class pattern is what it needs to achieve "first-class citizen status", correct?

tve commented 1 year ago

More explicit documentation of the async methods throughout the IO classes instead of just one mention in the IO class pattern is what it needs to achieve "first-class citizen status", correct?

Purely my opinion: I wouldn't call anything short of a proper spec of a promises/async interface "first-class citizen status". I can, however, understand that the committee may not want to take that on. In that case, more explicit documentation would at least provide some sort of second-class status and would help avoid having incompatible promisified layers being written.

phoddie commented 1 year ago

If that interface can be layered on top of the callback interface, then all-thumbs-up.

It can. That is a goal, as already stated.

At the end of the day one of the purposes of the standard is to enable writing portable code and that kind'a gets defeated if everyone creates their own promisified version of the APIs.

This comment is about code reuse, not code portability.

Different developers will likely make different design choices for APIs they layer on top of the standard. There are many valid reasons for doing so. That the specification encourages that is a feature, not a bug.There are many strong opinions on asynchronous API design. That is a good indication that consensus does not exist for standardization yet.

TC53 takes inspiration from the Extensible Web Manifesto which encourages standardization work to focus on low-level functions, leaving room to innovate above that. Should popular patterns emerge for asynchronous APIs, that would be a hint that perhaps further standardization is appropriate.