Fork me on GitHub

this is neat:

user=> (let [index 0, x (doto (java.util.ArrayList.) (.add 1) (.add 2) (.add 0))] (doto x (.remove index)))
[2 0]
user=> (def index 0)
user=> (let [x (doto (java.util.ArrayList.) (.add 1) (.add 2) (.add 0))] (doto x (.remove index)))
[1 2]
the ArrayList’s remove overload is a bit of an awkward edge


What’s going on here? def’ing the index causes different behavior?


There are two methods of remove: one takes an integer index and removes the item at that index. One takes an object and removes the first occurrence of that item in the array list. When using a let binding , the clojure compiler is aware that it’s numeric and chooses the index version. When using the defed var, it sees it as an object and uses the remove item overload

😮 4

Put two distinct operations, with two distinct behaviors/docstring in the name name seems to be an awesome idea! saves a lot of naming space!! </ironic>


btw, it could happen in Java programming too. For example, removing the 0 + from the code, as the linter suggests, will make .remove switch from int to Object :melting_face:


what are the tradeoffs of web assembly? Should I care as clojure(script) developer?


You shouldn't care

😅 2

Web assembly is meant to allow compiled languages like Rust, C++, etc., to be used in a browser.

👀 2

ClojureScript transpiles to JavaScript, and JavaScript is still the defacto language and runtime for browsers. So there's no real reason to care about web assembly in this case.


I see. I suppose wasm works by building some bridge between a compiled program and the js vm?


No, web assembly is a new language supported by browsers. It's a lot more minimal, no memory management, no garbage collection, etc. Browsers need to have seperate support for it. So there's a separate web assembly VM.


It's a much lower level VM, with instructions closer to that of hardware assembly language, hence the name. The instructions let you do things like manipulate raw memory directly, etc, things the JS VM doesn't. Mapping a low level language like C++ to a high level VM like JS VMs is difficult and why no one did it. But mapping a low level language to a low level VM is a lot easier, which is why Web Assembly came to be, and why you see the C++ and Rust compilers now having support for Web Assembly.


The benefits of Web Assembly are the same as any low level VS high level language. It's performance and memory use. By allowing direct control over raw memory, you can produce a garbage collector free program, with mostly primitive data, and perform more compiler level optimizations. Thus a C++ program running in Web Assembly VM has the potential to be faster than a JS program running on JS VM. Similar to a C++ program is faster running on real hardware than a JS program.

✍️ 2

Since Clojure is a high level language, if you made it run over Web Assembly, it likely wouldn't run any faster or use any less memory, because you'd need to also re-implement your own high level memory management and runtime on top to allow for it's high level semantics. And chances are you'd not do a better job than what the JS VM has done.

✔️ 2

There's only one exception, if you made a Ahead of Time compiled Clojure that targeted Web Assembly, it might use less memory. It's hard to say, but for example if you GraalVM native compiled Clojure to Web Assembly, maybe, just maybe, it would use less memory than running on JS VM. It most likely wouldn't run faster though.

👍 2

Most experience reports of "we pivoted hard to wasm" I've seen have concluded that it's not worth it if you are just doing DOM manipulation. You lose most of the perf gains


Learning new technology is fun. Even if you have no practical application, learning is a good thing to do. There are all sorts of things the wasm world can offer you. For example, using a wasm build of sqlite or duckdb can enable you to work with volumes of data in the browser that would have been incredibly awkward in cljs. There are also ways to speed up computation that can feed into your visualizations, like this deep dive into speeding up graph layout. Clj/cljs are great, but we should box ourselves off from the rest of the world. GC is definitely a current problem for clj on wasm. But years from now that may well be possible. It is good to look at these new technologies and learn them early. Find out what you like and don’t like about them. Find out their uses and non-uses by trying them.

👍 2

If you put a GC back, you lose all the benefits. WASM's benefits lies in being lower level. It likely wouldn't perform any better than JS VMs otherwise. That said, there's a future where WASM might be an interesting target if a GC was added, it's as a truly ubiquitous VM with the highest reach. Imagine if the JVM was embedded into every browser for example, but could also run over Windows, Linux, MacOS, Android, iOS, etc. I think there could be a future where WASM achieves this. That could make it an interesting target for a language if it were the case.


It wouldn't be much different than V8 in that sense, which runs a JS VM in-browser and on multiple OSes with Node or Deno. But there's a possibility you could have a WASM VM that's closer to the performance of the JVM if you had it target something more in-the middle between JavaScript and C, like Java is. That's all hypothetical though. You'd also need it to have a common set of APIs, and that's often where these break down. Web APIs and native OS APIs are often very different, it's hard to build a common abstraction over them all.


Though to Jimmy's point, I guess it's relevant in that it opens up a set of C++/Rust, higher performance libraries, to be used from ClojureScript which weren't possible when browsers only supported JavaScript based code. And that's pretty cool. But for Clojure/Script itself, it doesn't mean much.


I pretty much agree with all of what is said here. But I want to add that there are some pretty cool, very practical applications for WASM: • in-browser SQLite • image processing and optimisation • collaborative design GUIs like Figma • video games • other computationally expensive functions like search, hashing, compilation etc. (typically on Node/Deno).


Also note that if you just need/want to control memory you have things like ArrayBuffer see:


Instead of going all the way to WASM.


> give another way to write things for the javascript virtual machine > This is wrong. Wasm is an alternate VM. Wasm code doesn't run on the JS VM. Even though V8 supports running both JS and WASM, it's not running both in the same exact VM. That's why Wastime and Wasmer can't run JavaScript for example. A WASM VM cannot run JavaScript, and a JS VM cannot run WASM byte code.


It's better to think of WASM like an open standard JVM, that browser vendors have agreed to bundle inside their browsers. Because the WASM VM doesn't support Garbage Collection, and has instructions to manipulate memory directly, it is relatively low effort to have non GC languages compile to it's bytecode, because it resembles assembly code which they are already targeting. The JVM bytecode is a lot higher level than assembly instructions, and it already comes with a set of defined high level types, objects, methods, garbage collection, etc. So it's much harder for the C++ compiler to compile itself to JVM bytecode. The abstractions don't map 1:1. But with WASM it maps more closely 1:1. Similarly, the reverse is true for high level languages, it's harder for them to map themselves to WASM bytecode, because it's missing a lot of higher level instructions, memory management, etc. There are proposals to extend WASM with support for higher level constructs, mostly a GC, and if that happens, it would open the door to say have Clojure hosted on WASM. This idea of an Open Standard JVM like virtual machine that is included inside all browsers is super cool. Maybe one day it's even bundled inside all OS. Again, imagine if Windows, MacOS, Linux, Android, iOS, Chrome, Edge, Firefox, Safari, etc. all bundled in the JVM? Meaning Clojure could just run everywhere, no need to even install the JVM. WASM could become this. If so, I think Clojure should really reconsider if it's default host shouldn't be WASM. But WASM isn't ready to handle a high level language like Clojure yet.