Is there a compiler / translator for a Clojure-like Syntax into dependency-free Javascript?

To be clear.

I’m NOT looking for standard ClojureScript with all its dependencies.

I’m looking for a box on a web-site somewhere where I can paste a couple of hundred lines of really basic ClojureScript (just function definitions etc.) and have it translate that to a stand-alone block of Javascript. The block of Javascript can be big and doesn’t necessarily need to be easy to read. But it must be independent of any other compile-chain / external libraries. Something that could be pasted into a web-page and just work.

Has anyone written anything like this?

A kind of “Clojure Flavoured Javascript”?

1 Like

Sort of: http://app.klipse.tech/. It uses self-hosted CLJS to compile to JS. But the output won’t be independent, e.g. you will still see references to cljs.core in it. If you want a standalone single file output, there is no alternative to compiling it with the CLJS compiler with simple or advanced optimizations.

2 Likes

https://github.com/Gozala/wisp seems close to what you’re looking for

2 Likes

The problem is that JavaScript doesn’t have the features of Clojure, so any Clojure that is transpiled to JS will need to include a considerable amount of additional JavaScript code to implement all the missing features such as the persistent data-structures, and all that.

But in theory, you could probably ship a self-hosted ClojureScript compiler that produced a single JS file as output and just make a webpage out of it. I don’t know if that’s what you want though? Like the output JS will contain lots of code, it won’t just be your code that’s contained in the output.

That said, I don’t know if any, Kilpse is the closest, but it doesn’t output the full JS, just your code transpiled, but the code will reference the rest of the JS dependencies.

1 Like

Not an expert of CLJS, and maybe I don’t get the question, but as CLJS requires a “runtime”, you just compile to CLJS, add the runtime on top, and there you go! big single file.

1 Like

Wisp looks neat, however it’s based on raw JavaScript objects and has no implementation of persistent data. I wished a lot we had a ClojureScript to JavaScript single file compiler when I was first learning ClojureScript. But turned out ClojureScript relies persistent data(mori), and relies on macros, which makes compiling single file ClojureScript really hard. It’s always great if we could finally achieve that, like BuckleScript, then learning curve can be gentler to beginners when they want to migrate.

1 Like

This kind of reminds me, I always wanted a way to have ClojureScript in Clojure, so say I use hiccup to render some server side html, and I just needed a simple on-click handler instead of doing JavaScript inside a string, if there was a simple Clojure to JS which didn’t change any of the semantics of JavaScript, just allowed a Clojure DSL to write it, similar to how hiccup writes HTML for example, that would be pretty neat.

1 Like

I’ve seen this before and I think it isn’t accurate - Mori was an attempt to export the ClojureScript persistent data structures with a JavaScript API, to be consumed from plain JavaScript code, something like Immutable.js.

ClojureScript itself doesn’t rely on mori, it’s the other way round :slight_smile:

1 Like

same piece of code, but bundled differently? or even a different copy of the cljs code?

It looks like to be just plain ClojureScript code exported as JS-friendly functions:

1 Like

Here’s some code that I’ve been playing around with to get this to work. Mostly just so that I can embed javascript in my hiccup templates without having to use external files or js strings.

(ns mattsum.wisp
  (:require [me.raynes.conch :as ch]
            [backtick :as bt]))

(ch/programs npx)

(defn to-js [code]
  (npx "wisp" "-c" "--no-map" {:in (str code)}))

(defmacro js [code]
  `(to-js (bt/template ~code)))


(comment
  (let [msg "button clicked"]
    (js ($ (fn []
             (-> ($ ".button")
                 (.on :click
                      (fn []
                        (alert ~msg))))))))
  ;; => "$(function () {\n    return $('.button').on('click', function () {\n        return alert('button clicked');\n    });\n});"
)

This requires npm install wisp in the project directory.

1 Like

Oh that’s neat, didn’t realize wisp syntax was so similar to Clojure’s down to thread first and using (fn ) for functions.

Neat indeed! You could even do a macroexpension pass before passing the code to wisp, so you can still have clojure macros.

Hum, wisp is implemented in wisp itself it seems. I wonder if that means porting it to Clojure wouldn’t be too hard.

2 Likes