Open jappeace opened 1 year ago
What would you imagine the support to look like? Would the javascript be run in the client's browser, or on the server, and if the latter in what runtime? (Sorry, I'm not yet familiar with how the new backends work)
I'd say add a js button next to asm for example:
I care not much for execution, I just want to see what it produces, to execute I can paste it into file to run in a browser.
While this would be possible, I'm not sure it would be terribly useful. Following this page, I compiled the quicksort example to JS and looked at the outputs. We have:
rts.js
: generated RTS code. I'd assume not relevant to you. 282KiBlib.js
: js-sources
output, including some RTS stuff. Same. 212KiBout.js
: compiled Haskell sources, including your own code but also stuff in used libraries such as base
. 1.7MiBrunmain.js
which contains literally h$main(h$mainZCZCMainzimain);
all.js
which is just the concatenation of the above, in-order. 2.2MiBAnd some other files, description copied from the link above (ghc wiki):
all.js.externs
are exported references from the JS backend RTS.out.frefs.js
and out.frefs.json
are used for foreign references. out.frefs.js contains only a single unused function h$checkForeignRefs
and out.frefs.json
is empty. These files will be used once the FFI is implemented.out.stats
provides some metadata on the number of modules used in the program and their size.Amusingly, all.js.externs
is identical to the output of the following bash script, both for a hello world example and for quicksort: echo '// GHCJS RTS externs for closure compiler ADVANCED_OPTIMIZATIONS'; echo; for i in $(seq 7 16384); do echo '/** @type {*} */'; echo "Object.d$i;"; done
. Also it's 502KiB.
So what would you like to see? Putting all.js
in a browser works, it seems, but it contains such a gigantic amount of cruft in addition to the code you're interested in that I'm not sure showing that in the playground output is helpful to anyone. To be noted is that the current output size limit is 100 000 bytes, whereas all.js is almost 23x that.
lol, yeah, that'd be the entire runtime ported to JS for us.
yeah, clearly I've not thought trough all implications of this request, but still having to build a custom ghc just to play around with javascript is kind of bad user experience.
Maybe it'd be possible to offer the files for download?
Perhaps we can do some explicit post-processing like stripping the RTS stuff and piping through the Closure Compiler ? Yes it's not necessarily a faithful exact representation of what will be be output but:
gzip
'ing all.js
reduces the initial 2.2 MiB to 269 KiBall.js
through the closure compiler with --assume_function_wrapper --warning_level QUIET
produces 493 KiBHowever, the closure compiler takes about 4.5 seconds to do so. And that's on a processor running at >5 GHz, which is more than your average VPS.
However, stripping RTS stuff is clearly something we can do -- if anything, we can transfer it to the client once instead of on every compile. But rts.js
is just 282 KiB out of the full 2.2 MiB, so that doesn't help much.
@Kleidukos
It's for an online visualisation
Depends on what we want the goal of this to be. If the goal is what @jappeace said, which is to just offer the files for download: this would be possible, but it's only tangentially related to the goal of the playground, and we only sort-of by accident have some infrastructure for that. (Though not all.) So I'm not terribly enthousiastic about this, while I would be happy to give some tips/pointers on how to set up a very simple sandboxed compilation server.
If the goal is to run the code in the client's browser, we need all the code there, and it isn't very important how the code looks. But sending over multi-megabyte downloads for every run is a bit much -- and the closure compiler is apparently far too slow to be useful here.
If the goal is to let the user look at the code: closure compiler wouldn't help, and honestly I have no clue where to look even in the 1.7 MiB that is out.js
, allegedly containing the user's haskell code. (It also includes compiled code from base
, which perhaps is what makes it large.)
So I'm not terribly optimistic currently. :D But if your opinion differs on any of these points, please speak up! My opinions here are weakly held.
For the JS dump (which is thankfully not the same as executing in the browser, which is fairly dangerous anyway), we have to find a way to isolate the user code, prettify it a bit and display it. Which means that we remove RTS, base and such.
If the goal is to run the code in the client's browser, we need all the code there, and it isn't very important how the code looks. But sending over multi-megabyte downloads for every run is a bit much -- and the closure compiler is apparently far too slow to be useful here.
In my professional opinion, this is not a thing we should aim to do.
Feature request
Recently I tried helping a someone on discord, however it's rather difficult to get a specific version of ghc compiler since I'm on nixos, I could only get ghc 9.7.1 but it didn't have the javascript backend. It'd be great if the playground would have the javascript backend supported as well so I can play around with FFI.