Closed GerjanOnline closed 7 years ago
There seems to be a lot of hype (and confusion) about WebAssembly ;) I've read a bit about it, but I haven't fully understand it yet and even if it's out of preview now (which just means browsers can enable it by default), I don't think it means that WebAssembly is already a finished product.
According to its high level goals right now WebAssembly only has the same functionality as asm.js, and if you look at its specs you'll see that's mainly designed to crunch numbers: only numeric types (no string, etc), no garbage collection, etc. This makes it very difficult to target WebAssembly from a higher level language like F#. For reference, see why Typescript cannot be compiled to asm.js.
The goals also say that there'll be more features coming and support for other languages than C/C++. I think also Icaza commented they want to port the .NET platform to WebAssembly someday. So I guess it's in the horizon, but we still have to wait :) Anyway, now that WebAssembly is supported by the browsers, there'll be more libraries coming for intensive computations and you should be able to use them from F#/JS.
Thanks for your answer, I also read https://github.com/scala-js/scala-js/issues/1747 that was also mentioning the lack of GC.
Conclusion is: little more patience :)
Yes, we must wait. But that's OK, we programmers are always waiting for the "next big thing" :)
Anyway, although any performance promise is always very appealing, take into account that the main benefits of WASM will be in the parsing and compilation times, which are not that bad for most applications (and JS execution performance in V8 keeps getting better and better). And as commented above, I'm pretty sure that there'll be many libraries coming for computational intensive tasks that'll you be able to consume from your JS/F# apps (three.js comes to mind).
I understand that TypeScript is not intented to be compiled to asm.js, C/C++ or WebAssembly (and I expect that), the ability to export a language like Flow or TypeScript to typed AST in some way or another would be a good first start. With the TypeScript core devs not interested in this feature, it would at least open up the possibility for other teams to implement TypeScript to WebAssembly, TypeScript to C/C++ or TypeScript to asm.js conversion wherever possible.
Those also interested in converting staticly typed variations of JavaScript to asm.js, WebAssembly or C might want to take a look at ThinScript, TurboScript or AssemblyScript.
ThinScript compiles to JavaScript, WebAssembly, and C. TurboScript compiles only to JavaScript and WebAssembly. AssemblyScript compiles to WebAssembly only.
Each of these languages have been inspired by TypeScript, and the latter is a subset of TypeScript.
I'd like to thank @RReverser for pointing me in the direction of these languages.
@jslegers Now that's something very interesting :wink: If we just have a language very similar to typed JS/Typescript it should be easy to target it using Fable. We just need an AST specification like this one and a function to transform that AST to actual code.
I like where TurboScript is heading :
AssemblyScript is only two weeks old, so it's still too early to see where that one is heading... but that one sure does look promising as well!
Any news?
@ShalokShalom Compiling Fable to WASM is not a priority at the moment, if it happens it would be, as discussed above, compiling to a JS-like language that targets WASM. Apparently the languages mentioned above haven't evolved much so I'm not sure. Recently I had a look at https://github.com/ballercat/walt but it seems to also be in an early stage too.
You may also want to have a look at https://github.com/ncave/dna-redux
https://caniuse.com/#feat=wasm
Most browsers now support it by default. Rust compiled to wasm seems to be of fairly easy todo as of now.
@7sharp9 A possible path forward (aside of completely rewriting Fable to target Rust, which is a large undertaking) will be to produce output that AssemblyScript can consume, and rewrite the Fable BCL to target it too. Unfortunately AssemblyScript
is still missing important features like closures and iterators.
Wouldn’t targeting assemblyscript be just as large an undertaking?
@7sharp9 In theory should not be that big, once it supports a sufficiently large subset of javascript.
But as usual In theory there is no difference between theory and practice. In practice there is.
Rust targets wasm but also seems to have quite advanced support, I think all sorts of rust syntax can be represented. e.g: https://rustwasm.github.io/wasm-bindgen/examples/closures.html
@alfonsogarciacaro From some study in certain areas it seems a wasm solution could be around 40% faster on desktop and even up to 60% faster on mobile devices. I just benchmarked some cpu emulator code and it was 47% faster than a typescript implementation. Its food for thought anyway.
Is performance actually causing issues for end users currently? While cool and interesting, this definitely sounds like a nice to have. Someone should work it, but that someone in my opinion shouldn't be the core team...
@7sharp9 Closures in Rust and JavaScript are pretty different. I suggest read this article: https://stevedonovan.github.io/rustifications/2018/08/18/rust-closures-are-hard.html
@7sharp9 See also #1601.
I haven't actually looked into generating Rust from AST, so I may be completely wrong, but I tend to agree with @alfonsogarciacaro that a Fable port to target Rust would be a larger effort, as I'm not sure how much of the Fable code base can be reused. Of course that shouldn't be stopping anybody from trying it, if they have the time.
IMO (only), as discussed above, in terms of effort an easier path forward to support webasm
as a target without changing Fable too much can be explored in 2 gradual steps:
1) First, target TypeScript with strict types (not any
), see #1887.
2) then target AssemblyScript, working around missing features.
Some missing features like closures can be worked around by lambda lifting, others like iterators we have to figure out if their usage can be replaced.
@voronoipotato It depends if 40% increase in desktop and 60% increase in mobile speed is important to you. You could re-quantify this to saving money on cloud due to being more efficient.
@7sharp9 Right now, for me it's not but I imagine that could make a big difference to some people. For the record, I do think someone should work on it, I just also have concerns that if the core fable team worked it that they would become spread too thin. Perhaps if someone could spearhead an effort that others could contribute to (not implying you, obviously).
I don't see why it is even interesting for Fable to compile down to Wasm in the first place. Fable is great because of interop with JS and the ability to use the vast javascript ecosystem from a typed language such as F#. Assuming that this wasm target will be implemented, you wouldn't be able to compile JS bindings to wasm because they are not typed (try writing any Fable app without bindings and tell me about your experience)
If you are aiming to "run F# on wasm" then Bolero is much more interesting solution that already exists, works and maintained.
I think it is far more interesting to focus on how to make Fable easily consume wasm modules for use from within Fable application (again, integration ftw) and write docs with examples for that.
I guess you don't have to deal with the .net runtime environment, which does sound kinda interesting. Makes it almost like KreMLin.
@Zaid-Ajaj Well Im the opposite, I don't know why you would not be interested in having Fable be able to compile down to wasm. I don't think I would want to use anything razor oriented like Blazor.
You mean Bolero?
Where do you see the benefits of a Fable specific implementation?
Where do you see the benefits of a Fable specific implementation?
By giving F# syntax WebAssembly benefits.
Unfortunately, I'm not sure Rust->WASM benchmarks would be comparable to an hypothetical F#->WASM with Fable, as this would require to include some garbage collection mechanism (which is out of scope for Fable anyways). For reference, please see this article (Garbage Collection section) or this comment. Until WASM includes an efficient garbage collector, the best (and only) solution to compile F# to WASM is Bolero.
This is a bit off-topic, but I've been considering several languages that could be targeted by Fable (taking in consideration that Fable is basically just a syntax translator with some code injection), and my conclusion is right now the most valuable one would be Dart.
I've been considering to start working on this. But it would have to be a professional project for me now, so I'd need to find some sponsors or collective funding in order to allocate time for it.
I think its unfortunate that the F# language cant be established in this area, apart from the Bolero/Blazor oriented type ideas which for me doesn't mesh particularly well with the whole concept of WebAssembly in its performance oriented idiom. I guess Rust is a perfect fit which is why there is so much activity in this area especially with respect to linear allocation and performance computing. I think F#/Fable would bring an elegance of language to WebAssembly its just the current ecosystem of F# is not so good a fit.
Why doesn't just use LLVMSharp binding and compile direct to LLVM IR? See this as basic example
Such a thing would be an interesting concept, Im guessing the GC oriented aspect of F# is where there would be trouble as @alfonsogarciacaro stated.
Porting Fable to be a native compiler instead of language transpiler would be too far off from what it does, it would be like an entire new F# compiler, and environment, that's too low level. Fable is not a backend compiler that target a virtual machine. But the TypeScript or Dart path looks like a good alternative. Fable should remain a transpiler, but adding support for other languages like Dart would solve the problem with having to implement the environment, you just run on top of another language (as we already do, although Babel could be a problem). That keeps the usefulness of Fable, otherwise we already have several ways to natively run F#.
I will be using both DNA-redux and Fable in my porting of the React that I'm planning to do, because I'm done with using JS renders on top of Elmish, I want something custom. (Inferno is pretty small, the real problem we have to solve is Tree-Diffing, the other things that React does are incidental to the way JS is used) I'm thinking about using DNA to optimize the hot paths, so I need both a "native" WebAssembly compiler and a High-level Transpiler. What's blocking me from doing this, is that WebAssembly has no native support for accessing the DOM, and I think the overhead would make it useless, so first we only need a fully F# React Implementation. something like "Freact" for F# react transpiled to JS. And the Garbage Collector is not an issue, we can use some C++ GC library compiled to WebAssembly by the Emscriptem LLVM compiler, real problem is WebAssembly interop is still shitty, that makes it less useful for non-numeric processing.
@Luiz-Monad There's ongoing effort already to create a tree-diffing in F# for Fable (well the approach is somewhat different): https://github.com/krauthaufen/Fable.Elmish.Adaptive
Maybe the llvm output from F# via out could be used for a rust like wasm experience...
There is a lot of stuff going on in the wasm area, this was interesting: https://hacks.mozilla.org/2019/03/fast-bump-allocated-virtual-doms-with-rust-and-wasm/
@Luiz-Monad Heyo! An actual user of DNA-redux, respect!
Unfortunately it shares some of the downsides of other dotnet based interpreter
runtimes compiled to webasm
, namely lower performance than direct webasm
code (until webasm gets a JIT), which negates some of the webasm
benefits, and also it runs regular F# dotnet binaries (which tend to be on the bigger side), but with the upside of it being relatively easy to tinker with the runtime.
Those are conflicting goals, obviously, (smallest webasm code
vs webasm performance
vs smallest overall dist bundle
), so some forms of AOT compilation to webasm
will probably do better than others on that spectrum. There was an article on the net comparing webasm
code sizes produced by different compilers.
Yeah a Rust Hello world is 864 bytes including version metadata. A C# one was 2.4MB with all the aot jangly bits rattling around in there.
You could compare wasm size in this project: https://boyan.io/wasm-wheel. C# Dna take ~180 kb for glue code and ~150 kb for wasm which is not bad. wasm modules from mono usually takes several megabytes
It would give access to Flutter, which would be a very interesting alternative for mobile development to Xamarin and React Native.
Qml.NET is another alternative. GPU acceleration, desktop support, designing the GUI without coding at all and so on.
Now that WebAssembly is out of preview (https://lists.w3.org/Archives/Public/public-webassembly/2017Feb/0002.html), is this something you consider as an alternative output?
Personally, I think it can give F# a head start and maybe drive the F# adoption as a whole. You guys have done incredible job by building this "new webstack" but supporting WebAssembly may give it an extra enormous boost.
It is just a question, I have not read the specs of WebAssembly and did not look at the limitations. I am just curious what you think about this matter.