This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-24
Channels
- # beginners (113)
- # boot (9)
- # cider (6)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (73)
- # clojure-italy (4)
- # clojure-russia (6)
- # clojure-spec (13)
- # clojure-uk (21)
- # clojured (1)
- # clojurescript (79)
- # core-async (6)
- # core-logic (4)
- # datascript (5)
- # datomic (5)
- # duct (12)
- # events (1)
- # figwheel (9)
- # fulcro (143)
- # garden (2)
- # leiningen (1)
- # luminus (24)
- # off-topic (1)
- # parinfer (7)
- # protorepl (12)
- # re-frame (4)
- # reagent (32)
- # rum (1)
- # shadow-cljs (46)
- # spacemacs (4)
- # specter (27)
- # sql (6)
- # unrepl (3)
- # videos (1)
ok, so help me out here. I understand that #js
is a reader tag, and that the conversion happens before macro expansion and compile. What, exactly, does this tag output?
I ask, because I’m doing some benchmarking of alternatives, and for some reason I’m seeing clj->js
run faster than #js
, and I’m trying to figure out if I’m losing my mind 🙂
it creates a string to insert into the source file
clj->js should do its work at runtim, #js should 100% happen while compiling
if you are measuring the runtime cost, what do you measure - load time for the text with the js data in it?
I’m measuring something more complicated: the effects of using #js
on props sent to react vs using clj->js
you know #js isn't a deep transform right?
My earlier measurements showed it at 8% slower in the expected direction, so this new measurement just has to be broken somehow
part of the deal is chrome’s js optimization improves very slowly, so getting to a stable number is painful
@tony.kay It would be interesting if you found a case where clj->js
on some Clojure values somehow ended up being faster than #js
literals.
Here are a couple relevant posts that might be useful
http://blog.fikesfarm.com/posts/2017-11-09-avoid-converting-javascript-objects.html
http://blog.fikesfarm.com/posts/2017-11-18-clojurescript-performance-measurement.html
In terms of the underlying generated JavaScript, fire up Lumo or Planck with -v
or enable :repl-verbose
.
(clj->js {:foo 1})
turns into
cljs.core.clj__GT_js.call(null,new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"foo","foo",(1268894036)),(1)], null))
(prior to Closure optimization)
while
#js {:foo 1}
turns into
({"foo": (1)})
Yeah, I’m looking at the source. I knew that’s what it did, but I’m clearly not measuring what I think I’m measuring. Probably some async thing going on I don’t realize that is throwing things off
It seems pretty impossible to do extra work in between A -> B, end up with B, and have that be faster than just using B to start with
For me, in Lumo (which also uses V8)
(simple-benchmark [] (clj->js {:foo 1}) 1e7)
-> 45522 msecs
(simple-benchmark [] #js {:foo 1} 1e7)
-> 20 msecs
no, it is an async thing…I’m measuring the time to submit the thing, not render it 😕
yeah, fixed my measurement. It is much more in line with expectations now: 2ms w/clj-js vs. .8ms without.
helloo, I'm having a problem with clojurescript and core.async, I keep getting the error "Invalid :refer, var cljs.core.async/!> does not exist"
(ns testing (:require [reagent.core :as reagent :refer [atom]] [clojure.core.async :as async :refer [chan go <! !>]]))
@raycar5 which Cljs version are you using?
oh, wrong async namespace, the correct one is cljs.core.async
okay, next guess, the name of the fn is wrong: http://clojuredocs.org/clojure.core.async/%3E!
@juhoteperi you are right, i wrote !> instead of >!
if I have two sets that I know that are disjoint, how can i use the data as a single set? so i don't have to union or map over a list of sets every time
@ashnur If you want to test for membership, some-fn
could be used to form a new function that looks at each set for you.
(let [s1 #{:a}
s2 #{:b :c}
f (some-fn s1 s2)]
(f :c))
What operation(s) do you want to support on the two disjoint sets?@mfikes i think what i want is impossible. i was wondering if i could literally reuse the memory space of 2 sets as a single set.
yeah, sets are not simple enough for that to be simple - but if you take a union, you will share memory between the added data and the original sets in most cases
has somebody worked with promises in clojurescript? either javascript promises, or implemented directly in clojurescript ?
@roti note that clojure has a "promise" which is just a container that can be given a value exactly once and doesn't have one by default - if clojurescript core ever got a promise it would likely be the same thing (and not at all what you are talking about)
hmm, I just found promise-chan, though I don't understand the doc completely ("Once full, puts complete but val is dropped (no transfer).")
@roti it's just like a clojure promise: it accepts exactly one value one time, after that every put is ignored, and every take returns the first value
it has nothing to do with js promise
I'll attempt another description - in clojure a promise is something that starts with no value in it, then gets a single value, and after that always has that value. It has no callbacks, triggers, watchers, failure states, etc.
that's good enough actually, I wonder if one could have a similar error behaviour like Javascript promise chains
which is all an aside if you want to use a promise from js via clojurescript - just making sure that distinction is understood
@roti there no way to put an error in a clojure promise or promise-chan because they don't represent state or execution
if your code (deliver p (/ 1 0))
errors, p doesn't get a value
the error isn't tied to p in any way
I mean you can use a data type that represents an error of course (deliver p (ex-info ...)) but I think you want something different
yes, I am looking to write asyncronous code in synchronous style 😛 , which also means that errors/exception should short circuit the execution steps and jump to the nearest error handler
right, clojure promises are not the right thing for this, and I'm sorry I mentioned them - just wanted to make sure you didn't get side tracked
For the record I’ve found regular Js promises with the threading macro to be serviceable
@lee.justin.m you mean the ones returned by google closure? or es6 promises?
fun side note, TIL that clojure reverses the original definition of "promise" and "future" https://en.wikipedia.org/wiki/Futures_and_promises
that article even mentions what core.async calls promise chans, but calls them futures - because clojure inverts the original naming
@zentrope yes the function future
directly creates a java Future and that's probably why the names are flipped
Hello cljs! I’d like to have a single-click
and a double-click
event handler where the single-click one will be fired only is no double-click event is fired. Would you know any snippet I code study?
Thanks!
It’s a JavaScript issue. https://stackoverflow.com/questions/25777826/onclick-works-but-ondoubleclick-is-ignored-on-react-component
@lee.justin.m Thanks! What do you think of that:
@ashnur In ClojureScript nearly everything about collections and how they are used is done indirectly via protocols, so you could in theory make a new (defrecord double-set [a b])
and then go through the trouble of implementing all of the protocols needed like ICollection
so conj
works, ISet
so disj
works (each presumably heavily reusing the memory of the passed sets making a new double-set
as needed). I wonder, though, if doing this would actually result in lower memory consumption than a new set produced via clojure.set/union
.