Fork me on GitHub

🤯 I've managed to get shadow-cljs up and running! And followed some of Mozilla's SVG tutorials to get this! 🤯 It's not a lot to be excited by, but at least I'm finally starting to put the pieces together.

🎉 6

  [:filter {:id "myblur"                                                       
            :filterUnits "userSpaceOnUse"                                      
            :x 0                                                               
            :y 0                                                               
            :width 200                                                         
            :height 120                                                        
      [:feGaussianBlur {:in "SourceAlpha" :stdDeviation 4 :result "blur"}]     
      [:feOffset {:in "blur" :dx 4 :dy 4 :result "offsetBlur"}]                
      [:feSpecularLighting {:in "blur" :surfaceScale 5 :specularConstant ".75" 
                            :specularExponent 20 :lighting-color "#bbbbbb"     
                            :result "specOut"}                                 
        [:fePointLight :x -5000 :y -10000 :z 20000] ]                          
      [:feComposite {:in "specOut" :in2 "sourceAlpha" :operator "in"}]         
      [:feComposite {:in "SourceGraphic" :in2 "specOut" :operator "arithmetic" 
                     :k1 0 :k2 1 :k3 1 :k4 0 :result "litPaint"}]              
       [:feMergeNode {:in "offsetBlur"}]                                       
       [:feMergeNode {:in "litPaint"}]                                         
 [:circle {:r 50 :cx 100 :cy 60 :fill "green" :filter "url(#myblur)" } ]                                                                         
  ]                                                                            ]


I’m following @holyjak ’s, but having trouble implementing his catch-ex-as-data transducer. The arity-1 form of the transducer gets called when an error is caught (and (reduced…), and looks like this:

        (let [res (if (throwable? result)
                    result ; don't pass anomalies down
                    (err-or (xf result)))]
          (when (and on-error (throwable? res))
            (on-error res))
Here we directly test result to be throwable? (defined as #(instance? Throwable %)). Presumabley an error object is expected as result. The problem is that when using a transducer with a core.async channel, the result in transducers arity-1 form always seems to be a buffer (at least in CLJS?) It’s never testable as throwable?. I don’t understand how this example is ever supposed to work. Hoping someone can clarify for me!

👀 1
Jakub Holý (HolyJak)15:05:20

I know it works in Clojure @ JVM:

    (comp (catch-ex-as-data) (map inc))
    + 0 [1 "" 3]) 
; => #error{..} 

(transduce (comp (catch-ex-as-data) (map identity))
           (completing (fn [_ v] (inc v)))
           [1 "" 3])
; => #error{...}
Perhaps cljs does something different?

Jakub Holý (HolyJak)15:05:57

But it is very weird to me that the result would be a "buffer"

Jakub Holý (HolyJak)15:05:54

Testing in cljs w/o core-async, after de-javafication:

(def throwable? (partial instance? js/Error))

(defn catch-ex-as-data
  "Transducer that catches errors from the transducers below (catching errors
  both in the transducing and reducing functions) and returns the first one.

  It should be first, i.e. at the top of `(comp (catch-ex-as-data) ...)`)"
  ([] (catch-ex-as-data nil))
   (fn [xf]
       ([] (try (xf) (catch :default e e)))
        (let [res (if (throwable? result)
                    result ; don't pass anomalies down
                    (try (xf result) (catch :default e e)))]
          (when (and on-error (throwable? res))
            (on-error res))
       ([result input]
        (try (xf result input)
          (catch :default t
            (reduced t))))))))

(defn ++ [x y]
  (assert (int? x)) (assert (int? y))
  (+ x y))

  (comp (catch-ex-as-data) (map inc))
  ++ 0 [1 "" 3])
; => #object[Error ...]

(transduce (comp (catch-ex-as-data) (map identity))
  (completing (fn [_ v] (++ 1 v)))
  [1 "" 3])
; => #object[Error ...]

Jakub Holý (HolyJak)15:05:16

I am not able to replicate it in cljs, I thought I would just replace <!! with (take! ... println) but it never prints anything... :thinking_face:


Really appreciate you trying this out! I’ll give that a whirl when I’m back in Emacs later this morning.

Jakub Holý (HolyJak)15:05:57

No, sorry, it works:

(a/take! (a/transduce
           (comp (catch-ex-as-data) (map inc))
           ++ 0 (a/to-chan! [1 "" 3]))
  #(println "result=" %))
; OUT: result= #object[Error Error: Assert failed: (int? y)]

(a/take! (a/transduce (comp (catch-ex-as-data) (map identity))
           (completing (fn [_ v] (++ 1 v)))
           (a/to-chan! [1 "" 3]))
; ; OUT: result= #object[Error Error: Assert failed: (int? y)]


@neil.hansen.31 Throwable is a Java-ism


but maybe throwable? might be checking for that


Thanks for your reply! I realize that, and I’m replacing it with a js/Error for clojurescript. In either case, I don’t really understand how it’s support to work when result is a core.async buffer and not an exception.


Hi everybody! Happy to share the latest version of FlowStorm, a Clojure (and soon ClojureScript) debugger. It still doesn't support ClojureScript but I'm posting here anyway sin here is a video showing a "one liner" to instrument and debug the ClojureScript compiler as an example: Pretty interested in what do people think about this way of debugging/exploring the ClojureScript compiler. Here is the github repo:


Hi, Has anyone managed to debug ClojureScript code from within Spacemacs? (I have already asked in that channel - see below. Asking here just in case...)


If you mean directly from Emacs with Cider, Cider debugger doesn't support ClojureScript


Yeah, that part I already know 🙂 That's why I asked about ClojureScript...


(You will find more details in my linked message.)


oh sorry, no idea about debugging with lsp

Paavo Pokkinen20:05:11

Hello! I'm looking to get started playing with simple cljs backend, that uses NPM module to interact with API of air conditioner unit to adjust temperature, so nothing really heavy processing going on. I'm bit confused where to get started: nbb, shadow-cljs, or "vanilla" closurescript approach detailed Or are these even comparable options? 🙂 I know nbb works a bit differently with evaluation via SCI, but I'm bit unsure about practical differences for development.

Paavo Pokkinen20:05:29

If not using nbb, is option then shadow-cljs?

Paavo Pokkinen20:05:19

And does repl driven development work the same for all of these?


> so nothing really heavy processing going on It sounds like nbb might be a good choice there and you can always migrate to shadow-cljs later on.


nbb supports nREPL and socket REPL


Here is the migration story to shadow from nbb:


If you have any further nbb questions, come by in #nbb