I'm working through Web Development with Clojure and I noticed that the ClojureScript examples the author provides use the conventional app-name.core namespace, which is also being used by the Clojure part of the application for a lot of boilerplate code from Luminus.
ClojureScript and Clojure are often used to evaluate the same code for client and server sides of an app, respectively, so how does it differentiate between code in the ClojureScript core namespace and the Clojure core namespace? Does it use the directory structure? Can you use code from both w/o having to specify?
You program in JavaScript regardless of whether your code runs on Node.js or in a browser. Obviously depending on the platform, the API isn't the same.
My understanding is that ClojureScript is just a compiler. You write in plain Clojure (with a subset of the API) and then use ClojureScript to compile Clojure to JavaScript.
Therefore I don't think there's any difference in how namespaces are managed:
Replace . with /
Append clj or cljs
Replace - with _
Unless configured otherwise assume that src is the root directory
So app-name.core "resolves" to src/app_name/core.cljs for example.
I think (could be wrong) that on the JVM if a file doesn't exist on the disk, the compiler will look inside JARs (if any). Obviously that wouldn't happen with ClojureScript.
I have said in other answers that IMHO it is a mistake to include both frontend code (CLJS) and backend code (CLJ) in the same git repository. You fundamentally have two different programs that are running independently, are on separate hardware, and are communicating over a network. Any common utils used by both programs should be in a separate utility library, which would be a 3rd repo.
This organization provides the most independence and clarity for the 2 (or 3) codebases, independent of the language in use. It applies equally to any combination of languages used by the 2 programs:
Python & Python
Python & Java
JS (browser) & Python
CLJS (browser) & Java
CLJS (browser) & Clojure
any other combination...
So you use *.clj files for the backend code, and *.cljs files for the frontend code [1]. If you have any common utilities, make a 3rd repo and use *.cljc files for this shared library.
For frontend CLJS code, it is much easier IMHO to use the new figwheel-main and Clojure Deps tooling than the older lein tooling. Please see figwheel.org for details. This also makes it easier to keep the CLJ repl and the CLJS repl separate (no "piggieback" stuff required). It also keeps the CLJ compilation and CLJS compilation separate, which also simplifies things.
Having stated the above, I hope the answer to your original question becomes clearer. The CLJS code may have a namespace demo.core, that is compiled into JavaScript, that is running in a browser, on the user's computer. The CLJ code may also have a namespace demo.core, that is compiled into Java bytecode, that is running on a backend server in the cloud. So there is only one ns demo.core in each execution environment, so they never clash.
So, we see that the 2 compilers treat the CLJ and CLJS codebases as independent programs. This is why it is simpler IMHO to use two different git repositories to prevent conflating the two independent codebases.
Footnotes:
[1]. If you have macros in the CLJS frontend code, you will also need to define them in either *.clj or *.cljc files due to quirks in the CLJS compiler. We will ignore that complication here.
Related
It looks like exposing clojure library api to Java code requires the use of AOT compilation (at least when the exposed api is OO). If I'm wrong about that, I am happy to be revised. In the past, there have been multiple issues with AOT, thusly relying on it may have seemed a bit reckless or unstable.
What is the current state in that?
Is it a safe practice?
Would you use that as a means to expose an OO api to java applications?
You can use AOT to produce bytecode that will pass muster as a Java library. But it's not terribly pleasant, for you or for the Java programmers, who will rightfully ask: Where is the JavaDoc? Why are you using Object instead of generics? And other similarly awkward questions.
Instead, my preferred approach is to not make the Clojure code Java-friendly at all. Expose it as ordinary Clojure vars, and that's it. Then, write some Java code yourself, in the same library, that consumes the Clojure-based API and repackages it in terms of whatever Java constructs you want.
For one example, see my thrift-gen library. Using it from Clojure, you get a function that takes a map as input and produces a sequence; using it from Java, you get a builder pattern for configuration instead of the map, and you get a List<? extends T> as output. No JavaDoc, because I felt the usage documentation in the readme was sufficient, but if I were serious about using this there is a real .java source file to easily add JavaDoc to.
I understand that their is Clojure the sits on the JVM in which you can use Java libraries. Also, there is ClojureScript which allows you to use JavaScript libraries, but is it possible to mix libraries from each in one Clojure file / project?
You can write Clojure in .cljc files which can be read by both Clojure and ClojureScript. Any platform specific code can be wrapped in Reader Conditionals so it is only read on the host platform. Many libraries support cljc, though they do need to be converted, and it may not always make sense to do so if there is not a lot of common code between the two. See http://clojure.org/guides/reader_conditionals for more information.
I'm reading this page in my effort to determine if Clojurescript is appropriate for my use case.
I'm interested in using Clojurescript to create the Javascript code that will run in Qt 5 where JS is a native language that can access C++ functions exposed in Qt to the JS layer.
These functions will have names that can be called from Javascript within Qt, but of course they will not exist outside the Qt project, thus creating Javascript code via Clojurescript requires that the Clojurescript can call these functions even though they are outside the scope of the Clojurescript environment.
Does the "extern" method allow for Clojurescript to do this, while maintaining both successful compilation as well as no "munging" of those function names so they can operate in my Qt context fine?
Yes. If you do any optimizations but advanced, externs are not necessary.
If you plan on using the advanced mode, you will need to specify the externs, either manually, using a plugin like lein-externs, or a combination of both.
Another cool thing to do would be generating a full externs from the API docs and publishing them for other people to benefit too. Shouldn't be too hard.
This may be a totally noob question, but I've been experimenting with openGL in clojure via LWJGL, and while there are plenty of resources for learning both graphics programming and LWJGL, I've found it frustrating to port them to clojure. All of the different static methods representing openGL calls are associated with different java classes (ie. GL11, GL15, etc.), which presents no real problem in java as they can all be imported via something like "import static org.lwjgl.opengl.GL11.*". So I was wondering if there's a way to do the same in clojure (like the way "use" does for clojure namespaces)? And if not, is there an easier way to figure out which class a given method is associated with than stopping to search through the api for each one?
The functionality you describe is not included in clojure.core. It was included in the, now deprecated, clojure-contrib project, but including that as a dependency to your project may cause unintended dependency conflicts.
The code for the import-static macro is located in the old clojure-contrib github repository.
https://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/import_static.clj
You should be able to include the single macro in your project without issue.
My question is NOT about how to use ClojureScript to produce JavaScript code.
I am interested in ClojureScript because it implements Clojure \ {eval} within Clojure, and is able to compile it to another language. Thus, I'm interested in the possibility of having ClojureScript target other platforms.
Question: besides the source code, is the Design & Implementation of ClojureScript documented anywhere? I'd like a high level overview of how the various parts of the compiler work together:
* how are the
As far as the documentation for "Clojurescript pipeline and how you can hook into it" is concerned you can check out this blog entry.