Fork me on GitHub

newbie question, which ecmaVersion does the self-host compiler produce?


The self-host generated code should be the same as the JVM-based, as far as that goes.


ClojureScript compiles to ES3-compliant code.


I am half-thinking of using something like Tern for code completion, especially of JS objects...but I am still exploring what is the best approach


maybe I don't need Tern at all, I just need a better way to understand the object type of locals


It appears to be possible to infer the return type of functions (for “outward” type inference propagation). A motivating example is

(defn foo? [x] (or (string? x) (number? x)))
where, with an experimental patch, it is not necessary to explicitly add a ^boolean hint. The patch I'm trying out detects the following is ^number:
(def baz (fn ([x] 1) ([x y] 2)))
but doesn't infer for defn-based multi-arity functions (simply because they are constructed as a dispatch to multiple single-arity functions, and I haven't spent the time to suss out the defn macro for that case.) The patch is here It adds a :inferred-ret-tag to the AST only because the arguments to or on line 18 in the patch are not reversed (only to allow explicit hints to override inferred hints, but perhaps that is overcomplicating things and the inferred tag could be dropped directly into :ret-tag.) I'm going to make use of it for a while (maybe a few weeks) to see if I can find any defects or negative consequences before considering attaching it to a JIRA. If anyone has any feedback, happy to revise the patch.


@mfikes the reason that outward inference is not done in clojure is that it potentially breaks redefinition, not sure if that's something you need to take into account for cljs


@bronsa Interesting. I'll see if I can dig up some info on that on the Clojure side to better understand what would break.


@mfikes essentially if that propagation were to be automatic, stuff like

(defn foo [] 1)
(defn bar [] (String/valueOf (foo)))
(defn foo [] "foo")
would break (I think this concern is mostly for repl use but you get the point)


@bronsa Yes, perhaps an analog in ClojureScript

(defn foo? [] true)
(defn bar [] (if (foo?) :t :f))
(defn foo? [] "")
Yields :f with the experimental patch and :t without it.


Hrm. Perhaps a new option (along the lines of :static-fns) could make outward inference a useful feature (defaulting to off at the REPL, on for :advanced).


that sounds reasonable to me


Interestingly, ClojureScript already infers (outside of the scope of fn returns) in a way which exhibits the issue:

(def foo? true)
(defn bar [] (if foo? :t :f))
(def foo? "")
This yields :f