EzDev.org

clojurescript

Clojure to JS compiler


Client side web frameworks for Clojure

I am new to Clojure development but am interested in it. Right now I am looking to use it for web development. I ran across a bunch of different projects that could be used for a client side MVC. I was hoping to get a high level explanation of the similarities / differences / pros and cons and any other relevant information.

  1. WebFUI (https://github.com/drcode/webfui)
  2. Enfocus: (http://ckirkendall.github.io/enfocus-site/)
  3. Pedestal (http://pedestal.io)
  4. Ducttape (https://github.com/hozumi/ducttape.cljs)
  5. C2 (http://keminglabs.com/c2/) It seems this can be used as a DOM framework.

Also, I see people have tried to use AngularJS / Backbone in their clojurescript projects instead of these.

What I am hoping is just to get a comment on why the clojure ones may be better than using anguluar etc. And which of the Clojure ones complement each other or which ones would not work together etc. This will help me get a better understanding. Thanks a lot.


Source: (StackOverflow)

Accessing "this" in Clojurescript

Is there a way to access the "this" object in clojurescript?

I am having issues with event propagation when I wrap an icon with an anchor and try to attach a handlder to the anchor. Without access to "this" in the handler I am constantly dealing with the inner icon firing the event sometimes and the anchor firing other times.

edit:

As was suggested below, this-as is the way to do this. An example could be

(defn my-handler
  [e]
  (this-as this
    (let [data-attr (.data ($ this) "my-attr")]
      (log data-attr))))

Source: (StackOverflow)

How do I setup a Clojurescript REPL with emacs?

I'm trying to setup an environment for Clojurescript. The problem I'm having is not knowing how to set it up so that I can connect to a Clojurescript Browser REPL from emacs, so I can evaluate forms right from the editor and have it show up in the browser.

Things I've tried:

I tried using Cemerick's piggieback and piggybacking on nREPL. I don't really know how to configure it from the documentation. I was able to get it to work after figuring out I had to make an index.html file in the root of the project folder. Except the server doesn't serve my assets.

I tried setting up inferior-lisp with the bash script from the Clojurescript wiki. However, whenever I try to run the inferior-lisp-program I'm getting "Wrong type argument: stringp, nil".

Here's my ideal workflow:

I have a project folder/resources/public folder that has my assets and html files. I can start a web server that serves those files somehow, either by ring or using python's simple http server. I'd be able to connect to a REPL from emacs and evaluate forms into it.


Source: (StackOverflow)

What is the advantage of core.async in clojurescript?

Everybody is talking about how great core.async is, and how it will improve event handling in clojurescript. I've been following the ClojureScript 101 tutorial, and I don't see any clear advantage from these code examples. What am I missing?

Why is the use of core.async any better here?

(defn listen [el type]
  (let [out (chan)]
    (events/listen el type
      (fn [e] (put! out e)))
    out))

(defn dosomethingasync
  [e]
  (js/console.log "async: " e))

(let [clicks (listen (dom/getElement "search1") "click")]
  (go (while true (dosomethingasync (<! clicks)))))

vs.

(defn dosomethingcallback
   [e]
   (js/console.log "callback: " e))

(events/listen (dom/getElement "search2") "click" dosomethingcallback)

Source: (StackOverflow)

Javascript interop assignment in Clojurescript

Dumb question: how do I do Javascript assignment in Clojurescript ? I'm using a Javascript lib and need to set the value of an object's field like obj.this=that; - I don't know Javascript so maybe there's a .set method ?


Source: (StackOverflow)

What is the difference between application state and component local state in Clojurescript Om?

I have gone through David Nolen's basic Om tutorial but I am still a bit confused about the difference between application state and component local state. When cursors are referred to is it referring to one or both of these too?


Source: (StackOverflow)

Is it possible to use :refer :all in a ClojureScript :require?

I'm just trying out ClojureScript, starting out by converting something I wrote in Clojure into cljx.

When I try to compile it I get:

clojure.lang.ExceptionInfo: :refer must be followed by a sequence of symbols in :require 

I'm finding some oblique references online, but nowhere where it's spelled out whether I should be able to use a :refer :all in a ClojureScript program.

If I can't do it, what's the reason for this restriction?


Source: (StackOverflow)

Why are multi-methods not working as functions for Reagent/Re-frame?

In a small app I'm building that uses Reagent and Re-frame I'm using multi-methods to dispatch which page should be shown based on a value in the app state:

(defmulti pages :name)

(defn main-panel []
  (let [current-route (re-frame/subscribe [:current-route])]
    (fn []
      ;...
      (pages @current-route))))

and then I have methods such as:

(defmethod layout/pages :register [_] [register-page])

where the register-page function would generate the actual view:

(defn register-page []
  (let [registration-form (re-frame/subscribe [:registration-form])]
    (fn []
      [:div
       [:h1 "Register"]
       ;...
       ])))

I tried changing my app so that the methods generated the pages directly, as in:

(defmethod layout/pages :register [_]
  (let [registration-form (re-frame/subscribe [:registration-form])]
    (fn []
      [:div
       [:h1 "Register"]
       ;...
       ])))

and that caused no page to ever be rendered. In my main panel I changed the call to pages to square brackets so that Reagent would have visibility into it:

(defn main-panel []
  (let [current-route (re-frame/subscribe [:current-route])]
    (fn []
      ;...
      [pages @current-route])))

and that caused the first visited page to work, but after that, clicking on links (which causes current-route to change) has no effect.

All the namespaces defining the individual methods are required in the file that is loaded first, that contains the init function, and the fact that I can pick any single page and have it displayed proves the code is loading (then, switching to another page doesn't work):

https://github.com/carouselapps/ninjatools/blob/master/src/cljs/ninjatools/core.cljs#L8-L12

In an effort to debug what's going on, I defined two routes, :about and :about2, one as a function and one as a method:

(defn about-page []
  (fn []
    [:div "This is the About Page."]))

(defmethod layout/pages :about [_]
  [about-page])

(defmethod layout/pages :about2 [_]
  (fn []
    [:div "This is the About 2 Page."]))

and made the layout print the result of calling pages (had to use the explicit call instead of the square brackets of course). The wrapped function, the one that works, returns:

[#object[ninjatools$pages$about_page "function ninjatools$pages$about_page(){
return (function (){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About Page."], null);
});
}"]]

while the method returns:

#object[Function "function (){
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),"This is the About 2 Page."], null);
}"]

If I change the method to be:

(defmethod layout/pages :about2 [_]
  [(fn []
     [:div "This is the About 2 Page."])])

that is, returning the function in a vector, then, it starts to work. And if I make the reverse change to the wrapped function, it starts to fail in the same manner as the method:

(defn about-page []
  (fn []
    [:div "This is the About Page."]))

(defmethod layout/pages :about [_]
  about-page)

Makes a bit of sense as Reagent's syntax is [function] but it was supposed to call the function automatically.

I also started outputting @current-route to the browser, as in:

[:main.container
 [alerts/view]
 [pages @current-route]
 [:div (pr-str @current-route)]]

and I verified @current-route is being modified correctly and the output updated, just not [pages @current-route].

The full source code for my app can be found here: https://github.com/carouselapps/ninjatools/tree/multi-methods

Update: corrected the arity of the methods following MichaƂ Marczyk's answer.


Source: (StackOverflow)

How do I create a json in clojurescript

I have some clojurescript that I want to interop with some javascript libraries. In my clojurescript code I do some analysis and come up with a list of maps. something like

[{:prop1 "value1" :prop2 "value2"}, {:prop1 "something else" :prop2 "etc"}...]

I need to pass this to a javascript functions as

[{prop1: "value1", prop2: "value2}, {..} ...]

I'm not sure how to return a javascript object form my clojurescript function though. Is there a way to serialize nested maps and lists to javascript objects. Or a way to create a new javascript object and then set properties on it?


Source: (StackOverflow)

Any clojurescript tutorials? [closed]

Are there already some good tutorial on ClojureScript? I would like to try it out, but don't know where to start exactly.


Source: (StackOverflow)

Clojure & ClojureScript: clojure.core/read-string, clojure.edn/read-string and cljs.reader/read-string

I am not clear about the relationship between all these read-string functions. Well, it is clear that clojure.core/read-string can read any serialized string that is output by pr[n] or even print-dup. It is also clear that clojure.edn/read-string does read strings that are formatted according to the EDN specification.

However, I am starting with Clojure Script, and it is not clear if cljs.reader/read-string comply with. This question has been triggered by the fact that I had a web service that was emiting clojure code serialized that way:

(with-out-str (binding [*print-dup* true] (prn tags)))

That was producing the object serialization which includes the datatypes. However, this was not readable by cljs.reader/read-string. I was always getting error of this type:

Could not find tag parser for = in ("inst" "uuid" "queue" "js")  Format should have been EDN (default)

At first, I thought that this error was thrown by cljs-ajax but after testing the cljs.reader/read-string in a rhino REPL, I got the same error, which means it is thrown by cljs.reader/read-string itself. It is thrown by the maybe-read-tagged-type function in cljs.reader but it is not clear if this is because the reader only works with EDN data, or if...?

Also, from the Differences from Clojure document, the only thing that is said is:

The read and read-string functions are located in the cljs.reader namespace

Which suggests that they should exactly have the same behavior.


Source: (StackOverflow)

Why are clojure protocol methods often wrapped by functions?

Often when I see clojure protocols in a library, the protocol methods will be wrapped in a function, often with little added functionality. e.g.:

(defprotocol Pfoo
    (foo-method [this]))

(deftype Atype [x y]
    Pfoo
    (foo-method [this] (do-something)))

(defn foo [arg] (foo-method arg))

And clients are generally expected to call the function foo, rather than the foo-method from the protocol. (See the protocols at the top of clojurescript core for concrete examples of this kind of thing.

So why are protocols often shielded behind functions? Couldn't the protocol method become the client-facing part, rather than the wrapping function?


Source: (StackOverflow)

Which is faster, Clojure or ClojureScript (and why)?

If I had to guess, I'm pretty sure the answer is Clojure, but I'm not sure why. Logically (to me) it seems like ClojureScript should be faster:

Both are "dynamic", but ClojureScript

  • Compiles to JavaScript, running on V8
  • V8 engine is arguably the fastest dynamic language engine there is
  • V8 is written in C

whereas Clojure:

  • Is also dynamic
  • Runs in JVM, which has no built-in dynamic support, so I'm thinking thus JVM has to do whatever V8 is doing too, to enable dynamic support
  • and Java is slower than C

So how could Clojure be faster than ClojureScript? Does "dynamic" mean something different when saying JavaScript is dynamic and Clojure is dynamic? What am I not seeing?

(Of course if ClojureScript is indeed faster, then is the above reasoning correct?)

I guess, what does Clojure compile to....is at least part of the question. I know the JVM part can't just be a plain interpreter (otherwise ClojureScript would be faster), but Clojure can't compile to regular bytecode, as there's no "dynamic" in the JVM. So what's the difference between how ClojureScript is compiled/executed and how Clojure is compiled/excecuted and how plain Java is compiled/executed, and the performance differences implied in each?


Source: (StackOverflow)

ClojureScript, Om and Core.async: How to handle events properly

I have had a look at using Om for rich client website design. This also is my first time using core.async. Reading the tutorial https://github.com/swannodette/om/wiki/Basic-Tutorial I have seen the usage of a core.async channel to handle the delete operation (as opposed to doing all the work in the handler). I was under the impression that using that channel for deletion was merely done because the delete callback was declared in a scope where you have a cursor on an item-level where you actually want to manipulate the list containing that item.

To get more insights into channels I have seen Rich Hickey's talk http://www.infoq.com/presentations/clojure-core-async where he explains how its a good idea to use channels to get application logic out of event-callbacks. This made me wonder whether the actual purpose of the delete channel in the tutorial was to show that way of structuring an application. If so,

  • what are best practices associated with that pattern?

  • Should one create individual channels for all kinds of events? I.e. If I add a controller to create a new event, would I also create a new channel for object creations that is then used to get objects to be added to the global state at another place in the application?

  • Lets say I have a list of items, and one items has a detailed/concise state flag. If detailed? is true it will display more information, if detailed? is false it will display fewer information. I have associated a on-click event that uses om/transact! on the cursor (being a view to the list item within the global state object).

(let [toggle-detail-handler 
      (fn [e]
        (om/transact! (get-in myitem [:state])
                      #(conj % {:detailed? (not (:detailed? %))})))]
  (html [:li {:on-click toggle-detail-handler}
         "..." ])) 

I realize that this might be a very succinct snippet where the overall benefit of using channels as a means to decouple the callback event from the acutal logic changes does at first not seem worth the effort but the overall benefits with more complex examples outweigh this. But on the other hand introducing an extra channel for such detail-not-detailed toggling seems to add a fair amount of load to the source code as well.

It would be great if you could give some hints/tips or other thoughts on the whole design issue and put them into perspective. I feel a little lost there.


Source: (StackOverflow)