Any news for WebAssembly for Clojure?

A feature I’m concerned is to use wasm resource in ClojureScript, like now we doing for npm js modules.

Any news related to WebAssembly happened on Clojure recently?

2 Likes

You can already use wasm in clojurescript through normal JavaScript interop. What have you tried and what didn’t work?

The thing that doesn’t exist yet is compiling clojure(script) to wasm.

If you mean compile js/wasm with Webpack and call them with ClojureScript, no that’s not I’m thinking about. One can always compile ClojureScript to JavaScript and let JavaScript do the else. That’s not how ClojureScript supports it(although it can be viable option for code to run).

I’ve just noticed an interesting unofficial Google compiler https://github.com/google/schism from GNU’s Guile Scheme to WebAssembly and a search bought me back here.

I’d like to see a basic Clojure targeted at the Linux OS as it’s platform, instead of the JVM, to use for OS scripting. I remember when Unix was going to bridge all the hardware manufacturers into a single ‘platform’. How many platforms does Clojure now support? :slight_smile: I think Stallman only created GNU to run a Lisp.

I’m pretty sure that’d go against the (core) idea of Clojure being hosted and leveraging the hosts’ library ecosystem… However, if you want to use Clojure as a scripting language, you should have a look at @borkdude 's babashka.

1 Like

It isn’t clear what you are asking. I presume you are asking about using wasm with CLJS?

You can use .wasm files with ClojureScript today without any further support from any bundler. You just load it via regular js/WebAssembly. Either streaming or preloaded via regular XHR request, doesn’t really matter. Just plain interop will do.

Of course that is rather limited since most “generated” .wasm files today require some kind of “glue” JS code to make everything work. Unfortunately all those generated files complect “loading” the actual .wasm file with “using” it. Last time I checked the generated code was not loading properly via shadow-cljs or rather the Closure Compiler had issues with it.

Ideally the tools generating this boilerplate code should instead generate some data that can be used to generate custom CLJS boilerplate but I don’t see that happening unless someone starts working on it. This is also still evolving/changing and until a standard for this emerges (eg. WASI, module imports) I expect to see a lot of breaking changes.

So long story short if you write the wasm yourself you can use it today. If you want to use arbitrary generated WASM (eg. via Rust) that requires JS glue then it might take a bit longer for the related tools to mature.

1 Like

I got confused about what I wanted to ask as well. Maybe I was trying to figure out if there a natural way integrating wasm into ClojureScript workflows… but turned out that wasm is not for ClojureScript unless Clojure(Script) generated wasm code. Another thing may be, if there’s an npm package with .wasm files in it, can we just use that package in ClojureScript without any modifications?

Not as of today.

Mostly because there is no “standard” for it. So some packages I saw just embedded the wasm source as a base64 encoded string, which is terrible and makes it rather large. Others depend on exactly the webpack implementation, which we can’t do since the Closure Compiler doesn’t support it.

node works just fine but bundling for the browser does not.

I’d just wait for things to settle and standardize a bit. The rust related tools seem to be fairly active so we will see where that goes. IMHO wasm is still at a 0.1-preview stage, so much left to be done.

1 Like

Well yes, but if there’s a common system that can be ported to JVM, .Net, JS & the Erlang VM, and ‘C’ can function on just Linux libraries, if you didn’t need access to all the platform libraries, how big is the gap that would need to be bridged? I was wrong to call it “OS scripting”.

how big is the gap that would need to be bridged?

The gap is actually quite massive. You would need to write a native compiler and a native managed runtime. And then you’d need to re-implement a ton of standard features like thread management, date/time, IO buffers, etc. And if you wanted it to target Windows, Linux, MacOS, mobile, you’d need to repeat this work all over for each one.

1 Like

Saw a proposal that might be useful in the future:

This page describes WebAssembly as an ES module. With this proposal, WebAssembly could be loaded from a JavaScript import statement, or a <script type=module> tag.

Don’t Unix/Linux have most of hose things and are portable. Windows has a Linux CLI now. MacOS is Unix BSD under the shiny graphical shell. I accept that it’s a pity ‘*x’ still hasn’t settled on a GUI library but neither has Java :slight_smile:

If you mean: “can’t Clojure leverage existing GNU cli commands to perform scripting, like by calling into mkdir, ls, cd, cp, rm, chmod, etc.” the answer is yes it can, and quite easily at that. This is exactly what you’d be doing when using Joker and to some extent babashka. Or if just using conch https://github.com/clj-commons/conch or even clojure.java.shell directly.

If you mean: “can’t Clojure be implemented in C and the OS included C libraries”, the answer is the same as what I gave above. It can, but the amount of effort is huge. I can go into more details if you’d like here, but C is not a portable platform the way Java is, and lacks a ton of the necessary constructs that Clojure requires, such as a good GC and reflection. On top of that, the OS C libraries are not portable, so you need to target each platform, and even the standard exposed features might vary, requiring platform specific re-implementation of a lot of that stuff.

We only need JVM to be portable because the world failed to pick an OS. I’m thinking of an alternate universe in which we pick Linux. It didn’t actually solve the problem to pick JVM because most functional languages picked a different VM. Now we’re going through it all again with multiple container formats running on competing cloud platforms.

Duplicate effort went into developing Java and Python libraries and didn’t go into standardising Scheme, so SICP got replaced by Python, even at MIT. We waste so much effort and keep killing off good ideas. It makes me sad occasionally :slight_smile:

The JVM provides a lot more than “portability” in this context. Clojure (and ClojureScript) rely on managed memory (GC), compile to a relatively high-level bytecode, and have a number of libraries that wrap host interop so there’s a pretty good layer of functionality available on all platforms without actually having to do host interop directly.

To have a variant of Clojure/Script that targets native Linux, you’d have to write all that stuff as a portable runtime library (in C, or similar), and then you’d have to build for each target Linux that isn’t binary compatible with other Linux flavors (e.g., for different chipsets) – and you’d have to have variants of the Clojure/Script compiler that targeted each of those flavors at a bytecode level.

And I suspect you might be giving up the REPL, since live, on-the-fly compilation to native machine code in memory, followed by execution of that new native code is likely to be denied by O/S/chip security layers?

If Clojure’s AOT targeted machine code, you have a chipset portability issue, regardless of O/S.

So, yeah, there’s a portability issue across O/S that VMs address, but they also address portability across chipsets, and they provide managed memory and host interop and a number of other very important features that higher-level languages rely on.

Duplicate effort went into developing Java and Python libraries and didn’t go into standardising Scheme, so SICP got replaced by Python, even at MIT. We waste so much effort and keep killing off good ideas. It makes me sad occasionally

Well, its tricky, on one hand yes, if everything was x64 and unix, things would be simpler, and less effort would be wasted on porting things. On the other hand, competition drives innovation. So there’s a balance to have here.

That’s why it’s so smart that Clojure embraces existing platforms. No point in wasting any more effort rebuilding the same things over and over. The JVM already has everything we’d want to build for Clojure on Linux.

1 Like

Surely Unix was written to give hardware independence and written in C so that only a tiny bit of minimal C compiler was needed to port it to a new chip set. JVM has to be re-written to address each different OS more than different hardware. I’m probably wrong when it comes to specialist drivers for graphics hardware but I’d guess that’s mostly addressed by GUI libraries.

I’m not pretending it wouldn’t be hard but I’m ‘only’ suggesting trying to get back to where Common Lisp was, with ‘few libraries’. I understand the practicalities of the Clojure design decisions to give a much richer environment. I was just thinking of a skate-board rather than a luxury car.

I appreciate the thoughtful comments on a fairly random idea. I ‘came straight here’ from a simpler time and I’m still struggling to understand how things got so complicated for so little benefit. OOP seems to have been an unnecessary diversion and the web looks far more trouble than it’s worth as a development environment :slight_smile:

FWIW, my background was in compilers and I co-wrote one of the first ANSI-validated C compiler/runtime systems (and one of my early jobs was porting the Microfocus COBOL compiler to the SPARC and Motorola RISC chipsets). User expectations on programs have changed dramatically since then, and the systems we are building embrace several orders of magnitude more complexity now. Those “simpler times” have gone away, for the most part.

When “the web” happened (I think my first website went online in '94?) it was also a simpler landscape but, again, user expectations on websites – and, later, web applications – have changed dramatically too. I worked at Macromedia from '99 to '07 (a year after Adobe bought us) and saw the rise of “Rich Internet Applications” on the web, with Flash Player, Flex, and AIR (for web apps on the desktop). Post-Adobe, I worked on a team that built a business collaboration desktop app that incorporated document sharing, chat, and video conferencing (with Flex/AIR on the front, Groovy, Spring, Hibernate on the back). As Flash has been overtaken by the power of JS engines in browsers, we’ve seen interactive applications become much more complex than old desktop apps used to be!

Today’s applications have multiple layers from the UI back through myriad services to storage and search technology, often spread over tens, hundreds, or even thousands of servers. It’s a crazy world we live in – and few of us could have predicted what our jobs would look like today, from back in the '80s…

1 Like