how does jvm bytecode get converted to js in cljs build - clojure

As I understand most clojure and java libraries can be included in cljs code. How does the cljs compiler accomplish this ?
I understand that if I have a source file, the cljs compiler takes the source and outputs javascript. However how about if I am using java libraries such as joda-time for which I have included its clojure wrapper clj-time. So in this case it only has the java byte code for joda-time. So how will the cljs build tool, generate js code from the byte code of the java jar (joda-time)?

As I understand most clojure and java libraries can be included in cljs code. How does the cljs compiler accomplish this ?
You are mistaken. Many clojure libraries can be compiled for CLJS, with only minimal changes (sometimes even none), but there is no way to use classfiles: it must be .clj source files, compiled to javascript instead of to classfiles.

You cannot use Java libraries in cljs code.

Related

Can clojure/clojurescript compile down to webassembly?

Thinking about writing a game using web assembly. Is there a good way of doing that using Clojure or clojurescript?
Clojure compiles all functions to JVM bytecode.
Clojurescript to javascript.
You can't change that part.
But you can use .wasm files with clojurescript, just load it via regular js/WebAssembly.

Under the hood of Clojure repl execution

I understand Clojure code is compiled into classes and executed by JVM. For a Java project, I'm able to see a Jar gets created with .class files in it. But how exactly it works in case of a REPL?
Clojure code is compiled using the ASM library into class files. Those class files are loaded into a custom DynamicClassLoader.
Good talk on the compilation process: https://www.youtube.com/watch?v=-Qm09YiUHTs

Is there a way to look into jvm/Clojure source code from repl?

As some parts of Clojure are written in Java is there a way to look into these parts of source code from repl? I'm looking for something like this :
(source clojure.lang.Numbers/add)
As this part is implemented with Java
source prints Source not found and returns nil.
It depends on the environment you're using.
With plain REPL, you are quite limited.
Two most popular IDEs are Cursive and Emacs Cider.
As #Carcigenicate already pointed out, Cursive has an excellent Java support and allows you to jump to clojure java sources (or any other 3rd party lib sources - providing the sources have been published) easily.
It also allows you to debug Clojure compiler itself quite easily.
Emacs Cider has some support for Java.
Out of the box you can jump to JDK sources (with some caveats, see https://github.com/clojure-emacs/cider/issues/2687).
For other artifacts (like clojure.lang itself or other 3rd party java libs) you should be able to jump to the source code as long as you add the corresponding source jar to :resource-paths (assuming leiningen-based project here).
See here for more info about Cider's support.

Creating & using libraries in both Clojure and ClojureScript

I've just written some ClojureScript code, only to find out that I couldn't access one of the libraries listed in my project.clj's dependencies. Is this correct, i.e. that you can't use Clojure libraries from CLJS unless they're specifically designed to allow it?
If so, how much extra work is required to take a Clojure library that doesn't use any Java interop, and would itself be valid ClojureScript code, and make it useable from ClojureScript? From looking around GitHub, many libs appear to have separate source directories for clj and cljs code. Can such a library be added to my project.clj and be used immediately from either platform?
There are some ClojureScript differences from Clojure.
Dependecies from "project.clj" can be applicable / visible / usable by ClojureScript, for example, take a look at "jayq". You would include it in "project.clj":
(defproject xyz/xyz "0.1.0-SNAPSHOT"
:dependencies [[clj-time "0.4.3"]
[jayq "2.2.0"]
....
And then use it in the ClojureScript file:
(ns xyz.some.cljs
(:require ...
...
[clojure.browser.repl :as repl]
[jayq.core :as jq])
While "jayq" is not a "Clojure" library in the "backend" sense since it just wraps JavaScript, it is an example of using a "project.clj" dependency on the ClojureScript side.
In addition most of the core and several non core libraries are already ported to the ClojureScript side:
clojure.set
clojure.string
clojure.walk
clojure.zip
clojure.core.reducers
fold is currently an alias for reduce
core.match
core.logic (in works)
Other Clojure libraries will have to conform to the ClojureScript subset in order to work in ClojureScript.
It is worthwhile to clone ClojureScript repo and get a sense of what it supported (plus add your own features if you feel adventurous :)
ClojureScript dependencies are usually "front end" based (included the ones ported from backend). In other words, the end goal is to be compiled by V8 and run as JavaScript, hence anything that can be compiled by the ClojureScript compiler (repo above) can be used.
I see that the answers were given in 2013, but as of 2020, this is still the case with CLJS version 1.10. Its still not possible to use just any Clojure library, unless the library has been made CLJS compatible.Building with shadow-cljs will give build error like:
The required namespace "clojure.data.json" is not available, it was required by "bharati/binita/frontend/demo3/main.cljs".
"clojure/data/json.clj" was found on the classpath. Should this be a .cljs file?
I could not see any solution to that,other than using any other alternative library that is CLJS compatible.

simple tool for compiling Clojure .clj into .class / .jar

I've found two ways of compiling Clojure *.clj files into *.class files, and while they both work, I have some gripes with both of them.
The first one uses a REPL and so cannot be automated (or can it?)
The second one uses lein. To be frank I don't see why I should use a dependency management tool for something that should be part of the core tool-chain of the language. But in any case, using lein soon forces you to use a local Maven repository if your Clojure code needs to access local jars (which is highly likely).
Is there a better way to generate *.class or *.jar files from Clojure code that involves only core Clojure tools and that can be employed in a scripted, non-interactive way?
Clojure provides clojure.core.Compile, which can be used to compile Clojure code from the command-line.
java -Dclojure.compile.path=<targetdir> -cp <targetdir>;clojure.jar <list of namespaces>
For an example of how to use this from ant, look at the compile-clojure task in Clojure's own build.xml file.
clojure.core/compile can be automated via Clojure