titzer / virgil

A fast and lightweight native programming language
1.24k stars 48 forks source link

Idea: TS Transpiler to Virgil #66

Closed syrusakbary closed 2 years ago

syrusakbary commented 2 years ago

Since TypeScript can have programs with fully statically defined types, I wonder if it may be possible to have a transpiler that transforms TS codebases into Virgil and then we use it to compile to very lean Wasm code.

There are already some projects that do static compilation of Typescript:

Could it be possible to achieve with Virgil? Where you think may be the limitations?

syrusakbary commented 2 years ago

Some context: why this may be useful? If we are able to transpile TS projects into Virgil, and Virgil can be self-hosted and Wasm/WASI powered... then we can have a full TS to Wasm compiler (that just requires a WASI runtime!) almost for free :)

MaxGraey commented 2 years ago

If we are able to transpile TS projects into Virgil, and Virgil can be self-hosted and Wasm/WASI powered... then we can have a full TS to Wasm compiler (that just requires a WASI runtime!) almost for free :)

So you're suggesting take a AssemblyScript or TS to LLVM IR compiler which can compile to WebAssembly with WASI reuse it somehow for transpile to Virgil and compile to WebAssembly with WASI? Does it make sense at all?

syrusakbary commented 2 years ago

So you're suggesting take a AssemblyScript or TS to LLVM IR compiler which can compile to WebAssembly with WASI reuse it somehow for transpile to Virgil and compile to WebAssembly with WASI

Not really. I was asking if it could make sense to create a TS to Virgil transpiler, so we can get from: TS -> Virgil -> Wasm/WASI :) (in a way that the full spec of TS is covered)

MaxGraey commented 2 years ago

Foremost, there is no TypeScript specification (it was once tried to be created and maintained but later abandoned). Second, TypeScript as it exists does not allow it to be compiled into AOT. Or otherwise have to compile another runtime compatible with QuickJS to take into account all the dynamic nature of TypeScript. Third. Most of the projects written in TS and published in npm are actually JavaScript + d.ts file. Which will not allow to use such packages. That's why AssemblyScript is a subset of TypeScript, which allows it to be compiled in Ahead Of Time. So if you want to compile any TS code to WebAssembly you will find it easier to compile it to JS and run it on QuickJS (compiled to WebAssembly).

syrusakbary commented 2 years ago

Foremost, there is no TypeScript specification (it was once tried to be created and maintained but later abandoned)

Yup, you are right on this one. What I was referring on this, is: if passes the tests then it "complies with the spec".

Second, TypeScript as it exists does not allow it to be compiled into AOT

I kindly disagree. I don't see any reason for which it would be impossible to compile strict Typescript to Wasm (please see PXT or TypescriptCompiler links I previously posted). It's true that to make that possible, the perceived speed improvements of running such compiled Wasm file in JIT-able JS engines will be negligible (that is, if we run TS directly vs TS -> Wasm in a JS jitted browser). However, in non-JIT environments (such as QuickJS, or any other JS runtime compilable to Wasm), the speed improvements of running TS compiled to Wasm vs Running it inside a JS environment can be an order of magnitude better.

Most of the projects written in TS and published in npm are actually JavaScript + d.ts file

Yup, this one is one that is going to be hard to pass by!

MaxGraey commented 2 years ago

I don't see any reason for which it would be impossible to compile strict Typescript to Wasm (please see PXT or TypescriptCompiler links I previously posted)

Microsoft's PXT is interpreter ASDAlexander77/TypeScriptCompiler has JIT and AOT But I'm not sure about this. Did you try AOT mode of this project? I once saw a talk by the author of StaticScript (also TS -> LLVM compiler) and he described in great detail why he stopped working on it. In short, he would have had to completely recreate the browser's runtime and it was much slower than the same V8. Basically it wouldn't have made any sense. You can also look at NectarJS which tries to translate everything from JS to C++. Basically just wrapping every js value in a Variant. But that's not enough. In JS/TS any field of any object (includes builtin) can be deleted, added, changed, hooked (e.g. via Proxy). I'll tell you more, because of this many minifiers can't even minimize JS optimally. Compile it in AOT is much bigger challenge.

titzer commented 2 years ago

I agree that a TypeScript -> Virgil transpiler would be a very involved project. It seems like TypeScript -> AssemblyScript -> Wasm captures the statically-typeable part of TS well.

diakopter commented 2 years ago

also, virgil would need a much more robust GC, regardless of "static typeability"

titzer commented 2 years ago

I'm going to close this because I don't think it's actionable in the Virgil repo. A TS transpiler would be a significant undertaking, as discussed above, and I think that undertaking wouldn't necessarily live best in this repository.

Thanks for the idea, keep them coming!

syrusakbary commented 2 years ago

Makes sense! I tried to play a bit with WASI as target for Virgil a few weeks ago but I was not able to get it fully working. Will try to open more issues/suggestions soon!

titzer commented 2 years ago

Yes, there are still some issues in rt/wasi_snapshot_preview1/System.v3 that need to be ironed out. I had misunderstood how several of those calls work and didn't understand the concept of pre-opens. Any help you could offer there would be greatly appreciated.