Fork me on GitHub
#clojurescript
<
2016-07-01
>
henry00:07:51

@pat: building without figwheel works. Anyone know how to use js libs with fw? I’d like to do this with fw if possible

blance00:07:16

BUG: not sure If I should put it here or at #C1B1BB2Q3 When trying out the example from official spec doc, (s/conform (s/coll-of keyword?) [:a :b :c]) would not work for cljs.spec saying wrong number of args passed to spec/coll-of

blance00:07:31

by testing, I find it only takes 2 args

blance00:07:16

(s/explain ::sp/vnum3 #{1 2 3}) would succeed if I define it with 2 args (s/def ::vnum3 (s/coll-of number? {:kind vector? :count 3 :distinct true :into #{}}))

blance00:07:26

though the doc says it would fail

blance00:07:34

so taking 2 args is not correct either.

blance00:07:05

Not sure I missed something or coll-of is not working at all

novakboskov10:07:32

I have some issues with reader conditionals in clojurescript. I have following in a .cljc file:

(defn str->int [s]
  #?(:clj  (java.lang.Integer/parseInt s)
     :cljs (js/parseInt s)))
And
(str->int "1")
always evaluates to
nil
in clojurescript since it works well in clojure.

dominicm10:07:42

@novakboskov: (js/parseInt "1") works in my cljs repl.

novakboskov10:07:15

@dominicm: It works for me too but

(str->int "1")
as a whole yields
nil

metametadata10:07:45

@novakboskov: your function seems to work fine for me :thinking_face: Also a minor note: it's recommended (e.g. by MDN) to always provide a radix explicitly: (js/parseInt s 10)

novakboskov10:07:46

@metametadata: Which CLJS do you use and which REPL?

metametadata10:07:49

I used Cljs 1.9.36 and runned a unit test (using doo)

novakboskov10:07:05

@metametadata: I presume you evaluated both

(defn str->int ...)
and
(str->int ...)
in a CLJS REPL?

metametadata10:07:45

I didn't start a REPL at all because in my project at hand it's not set up )

metametadata10:07:18

ok, did a quick check in planck and lein figwheel REPLs - still seems to work fine

turbopape10:07:00

We just published a new book on ClojureScript !

novakboskov11:07:59

@metametadata: Yup, it works if you evaluate it all in CLJS. If I got it right, the value of reader conditionals shows when you define single function in a .cljc file and use it from both clojurescript and clojure. For me, it works when I use it from clojure but yields nil when it been evaluated through clojurescript.

novakboskov11:07:24

@metametadata: I mean it fails when

(str->int ...)
is evaluated from clojurescript.

metametadata11:07:08

@novakboskov: I'd suggest creating a minimal github project with exact steps to reproduce an issue, maybe someone would then explain why it works this way

hurrah11:07:41

@turbopape: Book looks nice. Will there be a table of content and free sample?

turbopape11:07:07

Yes I think so

novakboskov12:07:32

@metametadata: It's looks like there was a mash somewhere between compilation process of figwheel and REPLs (I use CIDER with a clj and a cljs-through-`figwheel` REPLs started at once). When I've deleted target (`figwheel` output dir) and started environment again everything was fine. Thanks & sorry for the noise

kino12:07:01

Hey Folks! Are there any online ClojureScript compilers around for me to test some code? Would anyone be able recommend one?

bovoid12:07:16

@kino: so you'll be able to run cljs in chrome web dev console (actually new 'ClojureScript' tab would appear)

kauko12:07:22

there's http://cljsfiddle.com, but that's only for Reagent right now

kino12:07:30

@bovoid & @kauko Thank you both 🙂

dominicm13:07:27

@novakboskov: I'll remember to look out for that in future. I've done something similar before: After you've run lein uberjar it's important to clean first, else clojure.tools.namespace.repl/refresh will fail without the most useful error message

turbopape14:07:07

@kino try the excellent klipse:

kino16:07:21

@turbopape: that is perfect. Thank you.

blance16:07:09

quick question. Wrong number of args (1) passed to cljs.analyzer/macroexpand-1

blance16:07:13

does it not take 1 argument?

blance16:07:21

thats what it says on the doc

kino16:07:18

Back again... 😞 Just wondering, as far as I know, there are no real shorter more concise alternatives to doing something like the following method below?

;; DEFINE a method that simply appends HTML to DOM.
(defn append-todos-ui []
  ;; We 'set!' our atom and then locate the DOM element 'todo-list'
  ;; within the index.html file.
  (set! (.-innerHTML (by-id "todo-list")) "")
  ;; Is this copying the `input-todo' <input> element already present
  ;; in the index.html file?
  (dom/set-value (by-id "todo-input") "")
  (dorun ;; Here we materialize a lazy list returned by map below:
   (map  ;; Returns the map with the vals mapped to the keys.
    (fn [todo]
      (let [
        id          (todo "id")
        li          (elemt "li" {"id" "todo-item"})
        checkbox    (elemt "input" {"class" "toggle" "data-todo-id" id
                                   "type" "checkbox"})
        label       (elemt "label" {"data-todo-id" id})
        delete-link (elemt "button" {"class" "destroy" "data-todo-id" id})
        div-display (elemt "div" {"class" "view" "data-todo-id" id})
        input-todo  (elemt "span" {"id" (str "input_" id) "class" "edit"})]

        (dom/set-text label (todo "title"))
        (dom/set-value input-todo (todo "title"))

        (event/listen checkbox "change" checkbox-change-handler)
        (event/listen delete-link "click" delete-click-handler)

        (dom/append div-display checkbox label delete-link)
        (dom/append li div-display input-todo)

        (if (todo "completed")
          (do
            (dom/set-properties li {"class" "complete"})
            (dom/set-properties checkbox {"checked" true})))

        (dom/append (by-id "todo-list") li)))
    @todo-list)))
It seems a bit hefty for what it is actually computing... I understand appending anything to the DOM using keys and maps can be long in general. Especially when creating HTML elements on the go. I also understand there may not be a concrete answer for this but worth a shot in order to see if anyone has any ideas.

bronsa16:07:12

@blance: no, it takes an env and a form

bronsa16:07:19

the docstring is explicit about that

bronsa16:07:27

Given a env, an analysis environment, and form, a ClojureScript form, macroexpand the form once.

pat16:07:50

Have any bootstrappers run into 'could not parse ns ... ... No protocol method IDeref defined for type null'

pat16:07:40

Seems like an analysis problem. I cannot use the cljs.reader cache whatsoever, always have to re analyze the source and re eval it

pat16:07:24

But problem still occurs when I remove reader from dependencies. Its bizarre

metametadata17:07:11

@kino: have you looked at Reagent or any other React wrappers?

kino17:07:17

@metametadata: I have played around with Om & React, but not in great detail and I wouldn’t really know where to begin implementing? Would it be a case of just importing and extending?

metametadata17:07:58

Sorry, I'm not sure what you mean by "just extending" 🙂 Your snippet looks a lot like a todo list and there's this handy list of TodoMVC apps implemented using different libraries (mostly React based): https://github.com/gadfly361/cljs-todomvc

kino17:07:43

Perfect! Will have a look over the source code you have provided 🙂 Yeah, I am building a Todo app in order to learn clojurescript from scratch. So Just looking over numerous implementations and seeing if there are any alternatives out there that are more stripped down when it comes to DOM manipulation so to speak...

kino17:07:01

@metametadata: but thank you 🙂

novakboskov17:07:27

How do you manipulate DOM in CLJS? Do I need a lib for it (is there any widely adopted)?

wilkerlucio18:07:32

they come with cljs already (no new dependencies) and are heavly tested

wilkerlucio18:07:13

if you really wanna something more "clojury", Domina is a cool one: https://github.com/levand/domina

jjfine18:07:21

Is it fair to say that these days most projects aren't manipulating the dom w/ something like ^^ and are instead using reagent or om to do the dom manipulation for us?

jjfine18:07:09

...thinking there might be two ways to answer @novakboskov 's question

novakboskov18:07:29

@jjfine: I'm using reagent too and your answer made me rethink about this little simple thing I need to do.

aengelberg21:07:47

It looks like re-seq is very slow on large strings in clojurescript:

;; in planck
cljs.user=> (def word-blob (slurp "/Users/alex/Downloads/words.txt"))
#'cljs.user/word-blob
cljs.user=> (time (count (take 2000 (re-seq #"\S+" word-blob))))
"Elapsed time: 4076.000000 msecs"
2000

aengelberg21:07:03

is this because re-seq uses subs after every match to get the next string to search on?

aengelberg21:07:03

This is fast:

cljs.user=> (time
       #_=>  (let [re (js* "/\\S+/g")]
       #_=>    (count (take-while identity (repeatedly #(.exec re word-blob))))))
"Elapsed time: 187.000000 msecs"
173139

amashi22:07:27

I haven't done a lot of Clojurescript yet, and have yet to get paid to do it, but in JS-land... actually a lot of stuff is still bashed out in jQuery, but my personal opinion, and I think the consensus among a lot of people, is that if you are writing a web application (something that pretty much takes over the page, does its own in-browser routing, etc.) and it's at all complicated, and code you want to hang onto, you're better off not manipulating the DOM too much directly. I'm inclined to think the same applies in Clojurescript.

amashi22:07:44

The thing is- while frameworks like React with redux, etc. (or re-frame or om in clojurescript) are great for full-blown apps, if you just want a bit of behavior in an otherwise static html page you're probably better off just bashing the DOM around.

darwin22:07:36

indeed, but before selecting right technology I recommend to consult a crystal ball, many project start as “a bit of behaviour in a static html page” and then grow into "a frankenstein ball of jquery mud"

amashi22:07:10

Yeah- the problem is that there's a bit of a gap between SPAs, where you are letting js/clojurescript drive the whole thing, and bits of js/clojurescript that can be added component-wise to a page, but that need complicated behavior, to communicate with servers, etc. It's something I've been thinking about lately, because I want to write some authoring software that lets you make data-driven graphics, but then let you just drop them simply into existing sites/pages in a pretty simple fashion. And it would be nice if the code used in the authoring system could be re-used, to some degree, in the drop-in components. But that turns out to be a bit tricky. There's always IFrames, but it's 2016....