ideas icon indicating copy to clipboard operation
ideas copied to clipboard

JSDoc + JavaScript to WebAssembly

Open brettz9 opened this issue 3 years ago • 4 comments

Project description

Originally raised on https://github.com/AssemblyScript/assemblyscript/issues/1837 .

Plain JavaScript, if supplemented with JSDoc (what I'll call "JJ"), is capable of holding type information which could be used by a compiler to convert such code into WebAssembly, offering the promise of high performance to wide swathes of the web with a minimum of refactoring pain and lower barrier to entry for adding such functionality relative to other languages.

Relevant Technology

As mentioned in the referenced issue, there is already https://github.com/esmbly/esmbly (see https://github.com/esmbly/esmbly/blob/master/docs/using-the-jsdoc-transformer.md ) an unmaintained package which can apparently convert JSDoc+JavaScript (JJ) into TypeScript. With (a subset of) TypeScript, one can compile this into WebAssembly using AssemblyScript: https://github.com/AssemblyScript/assemblyscript .

However, if the mentioned package is not maintained, it is questionable how well this can be done. Maintaining this would be one proposed course of action, the other would be a compiler which directly translated from JJ to WebAssembly.

I would be more eager to see the latter, as I would tend to believe it would keep into mind the special needs of JJ users, would keep good compile times (and would not burden users if source maps failed to trace back the resulting TypeScript to their source code).

While TypeScript has become fairly popular, it still comes with a few costs relative to JavaScript:

  1. It currently is verbose, requiring types everywhere, and making code harder to read
  2. It creates a barrier to entry whereas jsdoc, though also requiring training, can be progressively applied by the original developer or others.
  3. JavaScript is supported in more tooling without extra support.

Other technologies worth looking at are https://github.com/ternjs/tern which similarly uses JJ and turns it into type awareness.

My sense in working on eslint-plugin-jsdoc is that with jsdoc's slow development, we ought to standardize on the TypeScript flavor, specifically its use of import() to be able to get at third party types as would be crucial to ensure JJ could be used with third-party npm packages. (It might be made to interoperate with TypeScript declaration files, and/or have its own mechanism for discovering a jsdoc typedefs file (e.g., via a property in package.json.

Our eslint-plugin-jsdoc project has recently added support for detecting JSDoc AST, so one can easily make ESLint rules which could complement this proposed compiler, e.g., to require that specific number types were used, in addition to any validation by the compiler to ensure enough type information was present to compile it into WebAssembly.

Complexity and required time

Complexity

  • [ ] Beginner - This project requires no or little prior knowledge of the technolog(y|ies) specified to contribute to the project
  • [ ] Intermediate - The user should have some prior knowledge of the technolog(y|ies) to the point where they know how to use it, but not necessarily all the nooks and crannies of the technology
  • [x] Advanced - The project requires the user to have a good understanding of all components of the project to contribute

Required time (ETA)

  • [ ] Little work - A couple of days
  • [ ] Medium work - A week or two
  • [x] Much work - The project will take more than a couple of weeks and serious planning is required

Categories

  • [ ] Mobile app
  • [ ] IoT
  • [ ] Web app
  • [ ] Frontend/UI
  • [ ] AI/ML
  • [ ] APIs/Backend
  • [ ] Voice Assistant
  • [x] Developer Tooling
  • [ ] Extension/Plugin/Add-On
  • [ ] Design/UX
  • [ ] AR/VR
  • [ ] Bots
  • [ ] Security
  • [ ] Blockchain
  • [ ] Futuristic Tech/Something Unique

brettz9 avatar May 07 '21 13:05 brettz9

This is definitely a difficult task. I've tried out tooling to turn JSDoc into Typescript in the past and it turns out that the Typescript compiler is one of the best tools for said task. Which, I suppose, aligns with your statement of

we ought to standardize on the TypeScript flavor

After all, not standardizing on the TypeScript flavor means that one would have to invent a proper, well done type-system that can encode all the weirdness of Javascript just for JSDoc. Or accepting that even simple things sometimes simply cannot be encoded in JSDoc.

And once someone uses the TypeScript compiler for understanding JSDoc, one might as well build a multi-step toolchain which does JJ --> TypeScript --> WebAssembly. While this might not be the most performant option, it's probably one of the more maintainable options.

stefnotch avatar Jul 13 '21 19:07 stefnotch

Not a very good idea. Browser JS engines already use type information they infer from source code and its executions in order to jit it properly. And calls between wasm and even asm.js and ordinary JS are expensive, and asm.js and wasm don't have access to WebAPI. In other words, they are just optimizations for the ones who want build Qt or Dear Imgui or SDL and use them in browser because they already have a complex and already debugged native app relying on them which is infeasible to rewrite into JS.

KOLANICH avatar Jul 13 '21 20:07 KOLANICH

@KOLANICH I was under the impression that WebAssembly calls aren't that expensive anymore, based on post like https://hacks.mozilla.org/2018/10/calls-between-javascript-and-webassembly-are-finally-fast-%F0%9F%8E%89/

Then again, I do suspect that most Javascript code won't magically become faster after compiling it to WASM, otherwise browsers would already be doing it. It would/should only benefit rather simplistic, CPU-intensive Javascript code.

stefnotch avatar Jul 13 '21 20:07 stefnotch

Here's my understanding.

  1. JIT compilers have not been able to deliver native performance
  2. Specifying type information in JavaScript + JSDoc at optimal positions in the code, e.g., above every function or where it would otherwise be more costly for a JIT compiler to detect, could in theory avoid the costs required by a JIT compiler for spending computation power discerning types, and deliver near-native performance.
  3. One could get native or near-native performance in this manner without specifying types on every usage of a variable (even if JSDoc could be made to do this if necessary).
  4. There is no form of type annotation which JSDoc could not be provide (as a multiline comment, there are many positions where such blocks can be placed).

The idea is specifically to use JSDoc to deliver this extra performance, not that any vanilla JS file could get native performance. However, even for vanilla JS, one might wonder whether one could use a JIT compiler outside of the browser to analyze an application so as to compile plain JavaScript into a form including JSDoc type annotations such that a browser-based compiler of the resulting JJ syntax (especially if flagged to go into a special mode via a directive) could avoid the run-time type detection costs that operating on plain JS would require.

brettz9 avatar Jul 15 '21 10:07 brettz9