Fork me on GitHub

@benzap give it a look-see some time when you get a chance. It'd be cool to iron out the kinks.


Wow neat! I'll have to read it over, it looks like a really good idea


I've been looking into it a bit, and .Net Core and just recently, the go-lang, have released wasm implementations


I think the standardized gc that is being proposed is just to reduce the amount of wasm sent, since languages like go and c# need to include the runtime in wasm. A lot of what is included in the runtime consists of the gc


Yeah and like you said rust too


It would be cool to see a WAST DSL in CLJS that could implement that algorithm from the gist


I kinda wonder if a port of clojure to wasm is really a good idea


not that it isnt potentially useful


but what would the constraints be for a project to chose clogasm over cljs


nevermind again, I see the appeal


what if the DSL just output ASMJS


would a ASMJS -> WASM compiler be easier than a CLJS -> WASM compiler?


these are all unhelpful questions


and uninformed ones


Yeah, I wonder what the shortest path is between getting wast compiled into a wasm module in the browser


just as a synchronous function you can wrap a dsl around


devils idiot: what if we just wrote a macro system for wat


how deep can we lisp it?


in my head im unclear on how once we go into wasm territory (by whatever magic), how do we write our code to be callable from JS?


slash CLJS


and do the tradeoffs from that (would their be any?) negate the performance gains from being on WASM


maybe this is a short path, for some exploration:


You can export functions from wasm into your js code, I think


But either way, we can send messages in and call functions on SharedArrayBuffers that we have synchronous access to. So you can have the WASM side doing some major matrix operations on a matrix and just dereference it as often as you want from the js side, as long as you structure all reads as wait free.


I'm guessing that if the same alloc/free, swap/deref algo can be implemented in a cljs dsl on the wasm side, then the swap and deref functions can then be exposed to the wasm side code to interoperate with the structure safely.


Just looking at that hello world example, it seems like there is one fairly glaring issue for interop


WAST doesnt really have the concept of "many of a thing"


not that its a unique problem to clojure interop


just something that needs to be solved


ive seen examples of passing the size and start in the wasm buffer for a string then decoding that here


but generalizing something like that to maps is something I would need to pull out an expert for


and whether or not this kind of effort is neccisary is the kind of thing i would need to know more about the use cases of wasm for


and if i am being honest with myself, I don't fully understand them


You can stick an ffmpeg tool in there and just blast frames through a filter on the wasm side, while just derefing on the js side


It's mostly for doing fast, time-deterministic ops on large datasets that would be slow in js


(more time-deterministic than js)


if the LLVM compiler toolchain was compiled to wasm, maybe we could target wasm from ferret lol


It makes no assumptions about gc


Yeah, that's Windows 2000 running in the browser 😂


looks like these two libs that use fressian may make it easier to work with Clojure data on both the wasm and js sides: and


the wasm one, through rust


So we can have a typed fressian object pool on a SAB and persistent data structures can be special reference tries that allow for cheap immutable transformations within transactions on the SAB. Then different threads from different languages can interoperate on the same SAB if they adhere to the protocol, I'm thinking.


Any host holding a top level reference to a clj-persistent trie of references will have incremented a reference counter on each of those references when it obtained the top level reference. If a host does a transformation on that trie and any references are dissoced, their reference counters will be decremented and if they have reached 0, the reference will be freed from memory (by the thread completing the transformation).


It's kinda like a thread-safe append-only log, but it's insert instead of append, and where the log auto-collapses as it's being used. But in a thread-safe way, so that different hosts adhering to the protocol and the SAB model will always see a consistent view.


And this would essentially allow languages with different memory and gc models to operate over a shared data structure that handles its own allocation and gc


It's up to host environments to manage top level references. Javascript has weakmaps where we can monitor whether a top level reference has been GC'd locally, to trigger a dec on its structures in the SAB. So I guess any leaf node (a typed fressian value) on a persistent structure will be a top level reference in at least one host environment: the one that created it (for at least a step during allocation, escape analysis notwithstanding). Persistent reference tries would have a top level reference that references itself and a tail of 32 references, along with its root of up to 32 old tails, and so forth, in the Bagwellian sense


But top level reference containers in clojure, like atoms, are usually never designed to be disposable, commonly GCed things. We usually keep atoms around throughout the life of our program, letting our host environment collect ephemeral data that gets dissoced from the structures within those atoms anyway. So for some programs, you could get away with using a host environment that has no GC at all, and just be judicious with the top level references.


Taking the SAB idea a bit further. One could implement a synchronous SAB interface over a distributed memory system, and the above abstraction would work over it, as a kind of distributed computation and memory coordination thing.