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.
Related
Something is puzzling me after reading the this great answer to a related question:
There are two possibilities to share a function that I wrote in Clojure with Java developers
The first one is providing it in a JAR file so that they can call it as if I had written it in Java. Sounds great for Clojure advocacy.
The second one, the purportedly better way, requires those Java developers to use things like clojure.lang.IFn or clojure.lang.RT and invoking functions by passing their names as strings (!) instead of just calling them.
Why is the second approach "the better one"?
You are sorta setting up a false dichotomy here. Every approach involves creating a jar file: that is just how JVM programs are distributed. But there are 3 different ways for Java code to invoke Clojure code contained in a jar:
Use methods in clojure.lang.RT to initialize the runtime, load files, and then look up vars. This is the old, deprecated approach.
Use methods in clojure.java.api.Clojure to look up functions and invoke them. This is the newer version of (1), and hides some of the messy stuff you could accidentally get wrong.
Use gen-class in the Clojure library to define a more Java-friendly interface to the Clojure functions.
You can still do (3) - there's nothing wrong with it exactly. But gen-class is a pretty clunky tool, and except for the simplest examples like exposing a number of static methods, it's just not a lot of fun, and it's not easy to provide an API that "feels" like a Java API using Clojure.
But you know what's great at providing an API that feels like Java? Java! So what I recommend if you want to make a Clojure library easy to use in Java is to include some Java code in your Clojure library. That Java code, written by you, bridges the language gap. It accesses your Clojure code by mechanism (2) above, and presents a Java-friendly facade so the outside world doesn't have to know there's Clojure underneath.
amalloy/thrift-gen is an example of a library I wrote years ago following this approach. It would not be at all easy to write this in pure Clojure, just because traditional Java idioms are very foreign to Clojure, and it doesn't support them all very well. By writing my own Java shim instead, Java clients get a very comfortable interface to work with, and I can just write Clojure that feels like Clojure instead of a bunch of gen-class nonsense.
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.
are there any documentation on clojure built-in java method?
for example, .toUpperCase from java.lang.String and .indexOf from clojure.lang.PersistantVector.
Is there anyway I can find useful java method without looking at the source code?
As others have pointed out, you can get the java.* and javax.* documentation online pretty easily as it is part of core Java.
For the clojure.*, your best reference is the source. Even so, I'd recommend not relying on it since this code should really be considered an implementation detail of Clojure. You have no guarantee that the functionality won't change in future versions of Clojure and break any code that depends on it.
How about the Java API? All of Java's classes and methods are listed there. That covers all of the "clojure built-in java methods".
On the other hand, Clojure's classes are documented in here, Clojure's API. You have to learn to distinguish between Clojure's classes and Java's classes. All packages starting with java.* or javax.* belong to Java and are documented in the first link. The packages starting with clojure.* are from Clojure, you'll find their documentation in the second link.
If the package for the class starts with java or javax then you can look it up in the Java documentation on Oracle's website.
For Clojure implementation classes (where the package name starts with clojure) you are probably stuck with looking at the source code. There is documentation for the intended API (the Clojure language) but not for the Java classes implementing it. You may be able to find some articles (like this one) depending on if what you're looking for is something a blogger has taken an interest in.
Clojure is written mainly in Clojure, but there had to be a "first" version of a clojure compiler that was written in something else, presumably Java.
Is the code of that compiler available anywhere?
My interest is purely academic, not productional, I'd like to see the way that Rich Hickey handled the chicken/egg problem.
The clojure compiler is written in java, not clojure. So the current version is the one that will satisfy your curiosity. Of course it's a reasonable point of view to say that macros are part of the compiler, and those are indeed written in clojure, but they are not relevant to the chicken/egg problem you mention, which is solved by having the compiler in Java.
Compiler bootstrapping is a common issue when you write your compiler in the same language as that which you are compiling.
In the case of Clojure, however, the compiler is written in Java, so no tricky games required.
For fun historcal reference, GHC, the Haskell compiler (written in Haskell), was originally compiled via Lazy ML.
Not sure if this relates to your interests, but Rich had originally worked on a language called DotLisp and for that he began with a study of JScheme, which he used as a basis for the original code and eventually replaced completely.
DotLisp is here: http://dotlisp.sourceforge.net/dotlisp.htm
JScheme is here: http://jscheme.sourceforge.net/jscheme/main.html
(Trivia: one of the authors of JScheme is Brandeis professor Tim Hickey, no known relation to Rich.)
I'd like to look at some examples of well-architected, complete Clojure applications (not libraries, but completed applications that accomplish real-world tasks for end users rather than for other developers.) Are there any such open source projects out there that are recommendable as examples of how to structure and write a user-facing application in Clojure?
Edit: I'd like to see a substantial full-blown application of some complexity as opposed to a prototype or a demo. Is there anything like that out there yet?
Lau Jensen has some idiomatic clojure source for a DB-backed reddit clone on github, which makes for interesting reading. Here's the corresponding blog post.