Do Java at the core Interfere with Clojure/<not-JVM>?


#1

As an example, the function partition-by: will it work on ClojureScript regardless of it being using java.util.ArrayList?


#2

No, “Clojure” has a distinct and idiomatic implementation for each host (e.g., the JVM). There are a few differences between Clojure and ClojureScript - see https://clojurescript.org/about/differences.


#3

Yes. It looks like in ClojureScript the partition-by implementation uses its own simple implementation of ArrayList, which roughly mimics the interface from Java’s standard library.


#4

To be clear, my “yes” is in reply to the question if partition-by works in ClojureScript, Phill’s “no” to the question if it is a problem that partition-by is implemented using ArrayList in Clojure. I agree with Phill of course.


#5

Thank you all.

While reading the code the word Java ringed a bell to me, for a language that is supposed to be hosted.

What if the code, instead of saying Java.util.ArrayList would have say hostSystem.arrays.arrayImplementedWithList or something like that?

In fact, the only difference between Clojure and Clojurescript partition-by implementation is that line abour the array-list. It’s kind of sad.


#6

There are lots of implementation differences. That are far fewer differences at the level of functionality and abstractions. The core functions of Clojure are often implemented in terms of Java code (a lot of Clojure itself is written in Java). The core functions of ClojureScript are often implemented in terms of JavaScript. More of ClojureScript is implemented in terms of ClojureScript, than of Clojure implemented in terms of Clojure, but that’s much more an artifact of ClojureScript coming along later and being able to take advantage of newer Clojure features natively – when Clojure was originally created, Clojure itself “didn’t exist” and so the core had to be implemented in the host language.


#7

Why do you consider it kind of sad that there is a tiny difference in the Clojure vs. ClojureScript implementations of partition-by? Because you believe it would be better in some way if they were completely identical?

If they return the same values in most/all situations to users of the partition-by function, is that somehow not good enough?


#9

The “kind of sad” part is to have 2, 3 or N codebase (consider Clojure-CLR) for almost the same thing.

But there are historical reasons for that, as @seancorfield explained. And not only that, there are much more differences than the one the simple case of ‘partition-by’ expose.

I fell like there is a possibility to actually parametrize the sourcecode of Clojure with a HostLanguage adapter, or something.

But I know there is much more I don’t understand, and a lot of specific details to each hosts that probably make this impractical, and that … makes me sad :’( … that is the kind of “sadness” I wanted to express.


#10

I understand a bit of sadness - after all, in this elegant and concise language, it would be only fitting to have a unified codebase!

I‘d like to bring two aspects to your attention, however. First, it wouldn’t make any difference to a user of Clojure, and likely even make understanding core code harder when reading (in case you have an issue in your JVM app, why dig through browser based implementation details?).

Second, both Javascript (node/browser) and the JVM are immensely complex platforms. They‘re similar enough in a ‚universal computation‘ sense to implement Clojure, but different enough to warrant different code bases. Aside from the actual implementations, think about the execution models, tests and other build environments - there‘s really no end to the differences and edge cases that need to be considered. Performance is obviously another big aspect here, but I guess that just follows from the above.


#11

Thank you for the insights.

I understand now better. And yes, it is meaningless to the user of Clojure, and in fact, adding one more Indirection would make it harder for them.

Now, digging in the idea (the reader could stop JUST HERE, the rest is just extending and mind loud speaking freely)…

For what you describe, I would see it backwards: Having not 3 but 4 codebases.

  1. Clojure/Java
  2. Clojure/CLR
  3. Clojure/Javascript
  4. Clojure(core)

1,2,3 depends on 4. So when debugging Clojure/Java, you don’t know about Javascript code nor tooling.

Of course, how do you “test” the core?.. probably repeating the tests by combining 4 with 1, 2 and 3? And what about the N platforms?..

Anyway, all this is hypothetical thinking.

Just thank you for the warning on the complexities of the Platforms.


#12

Well it‘s sort of already like this. I don‘t claim to be knowledgeable about this, but there‘s the Clojure core part written in Java, the core part written in Clojure itself (clojure.core etc.), ClojureScript (which itself comes in a variant that requires Clojure/Java, and one that is ‚self-hosted‘, i.e. it compiles CLJS with a Clojure compiler written in CLJS itself), and the CLR version, which is (I think) something different altogether. So we already have 4-ish codebases (but in practice, it‘s really Clojure or ClojureScript, so far as your choices go, with .cljc being a convenience format).

Yes, Clojure/Java and clojure.core are closely coupled, since the JVM was the original host, and cljs.core is largely a direct port with many adjustments for JavaScript. But that‘s a good thing! Imagine reading 2 clojure.core implementations and you couldn‘t even recognize them.


#13

Thank you @madbonkey. There is a lot to learn about the Clojure Ecosystem.


#14

I also recommend going through the overviews and guides on clojure.org. Together they make for a very good outline of „the Clojure package“, its structure and some important aspects.