This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-28
Channels
- # admin-announcements (1)
- # aleph (3)
- # bangalore-clj (4)
- # beginners (167)
- # boot (14)
- # cider (4)
- # cljs-dev (24)
- # cljsjs (21)
- # cljsrn (33)
- # clojure (214)
- # clojure-greece (2)
- # clojure-italy (2)
- # clojure-korea (16)
- # clojure-russia (29)
- # clojure-spec (31)
- # clojure-uk (86)
- # clojurescript (144)
- # core-matrix (2)
- # cursive (37)
- # datascript (5)
- # datomic (104)
- # devcards (2)
- # events (2)
- # jobs (2)
- # luminus (8)
- # midje (1)
- # nyc (4)
- # off-topic (1)
- # om (39)
- # om-next (1)
- # onyx (47)
- # perun (1)
- # planck (6)
- # proton (2)
- # re-frame (25)
- # reagent (40)
- # spacemacs (9)
- # vim (71)
- # yada (3)
(let [svg-root (.-ownerSVGElement (.-target e))] (. js/console log e) (. js/console log svg-root) (set! (.-onclick svg-root (fn [_] (println "* yay we can overwrite"))))) I get an error of: Unknown dot form of (. svg-root -onclick ((fn [_] (println "* yay we can overwrite")))) What is going on here?
(when something happens on an inner svg element, I want to overwrite the handler on the root svg element)
Is there a way to use a goog-define in a ClojureScript macro for the purposes of DCE?
The question above as phrased doesn't make sense, as the goog-define is 'injected' after macro compilation has taken place. The answer I came up with is to put the goog-define
d value inside the macro templated code, and let the Closure Compiler to eliminate it
@danielcompton You just need to make sure that you tell cljs that the var is a boolean, otherwise it'll wrap it in truth_
calls and Closure wont DCE it.
Anyone here used https://github.com/magnars/optimus
@urbanslug It ends up in memory, served by the process. If you want it on disk, use the export utilities.
see https://github.com/magnars/optimus#yeah-we-are-using-a-content-delivery-network-how-does-that-work
One sec let me figure out if it’s caching. We have changes reflecting locally but not on staging servers
Hey, so I can see the compiled scss to css files but I can’t quite see the single css file e.g styles.css number 7 here https://github.com/magnars/optimus#usage
ah, that isn't quite clear in that part of the readme. All bundles are served under /bundles/
so you'll find that under /bundles/styles.css
- but don't use that directly, you'll want to use the cache busted version as served by optimus' link
namespace.
I saw @mfikes benchmark of reduce compared to C (https://www.youtube.com/watch?v=LopU-kMpe8I&feature=youtu.be) and played with it locally and it worked and was awesome, BUT I noticed that (reduce + 0 (range 1E7))
runs in 10ms where (reduce + (range 1E7))
runs in 500ms, while (reduce + (lazy-seq (range 1E7)))
also runs in 10ms. I checked the implementation and noticed that while (reduce + 0 (range 1E7))
runs a tight loop, without the init value it falls back to ci-reduce
which is inefficient for range (it’s calling nth
on the range at each iteration which should be super inefficient)
this is the place that’s problematic btw: https://github.com/clojure/clojurescript/blob/01149751ae129ab01f5d427a48c5cedae9386f64/src/main/cljs/cljs/core.cljs#L8918
still seeing a massive slowdown compared to wrapping the range in a lazy-seq, so I guess my analysis is wrong but the observation still holds?
I agree, somebody more familiar shoudl chime in why -reduce
of Range
doesn't call seq-reduce
or even just itself
ok yeah I see that nth and count are O(1), but they still do a bunch of math that’s unnecessary in that loop https://github.com/clojure/clojurescript/blob/01149751ae129ab01f5d427a48c5cedae9386f64/src/main/cljs/cljs/core.cljs#L8897-L8915
Does anyone know offhand why the keys :doc, :file, :arglists, :line, :end-line, :column, :end-column
for a def
are duplicated in the cljs compiler state, under both the def itself and also within its :meta
key? eg. the value of (get-in @cstate [:cljs.analyzer/namespaces ‘cljs.core :defs ‘rand-int])
contains all of the keys above, as well as a :meta key where those keys/vals are duped
@mhuebert there’s no particular reason - it just means in the compiler emission for :var-special
we don’t need to figure anything out - it could easily be done differently
@jell it probably doesn’t matter to the JS VM since some of those checks are loop invariant
@dnolen I am seeing a major slow-down though? the diff between (reduce + (range 1E7))
and (reduce + (lazy-seq (range 1E7)))
is 50x (granted, +
is probably the cheapest reduction step one can have)
it’s nice that @mfikes (higher order) case competes with an imperative loop - but this isn’t the kind of case we spend much time on
thank you for taking the time, and I understand your time is precious 🙂 if you don’t mind me asking, why are we not using ci-reduce for both reduce cases on range if we do not care about this kind of optimization? (if the answer is more than a 10s thing forget it and I’ll try to figure it out later)
because we copied implementation approaches over from Clojure when we ported all the transducers stuff
just pointing out that we don’t spend much time on it since it’s all low hanging fruit
@thheller the person who is asking me has all of their js "modules" in separate github repos. they were thinking about rewriting them in ClojureScript one at a time. but if each had an overhead of 95k, it would not be a win
but it seems like they're going to have to require all of those repos into one project and do module splitting through closure
OMG, cljsjs is great
thanks to everyone who's contributed!! 🍺 🍺
@ericnormand if you mean they want to write their JS modules in ClojureScript but ship the JS - not a good idea
Google Closure is oriented around whole program optimization - so the tradeoffs start right there
@thheller @dnolen thanks for the info. I’m packaging analysis caches for self-hosted cljs, and dissocing the superfluous :meta
key from each def
shaves 20-30% off the (zipped) file sizes. I’m not sure if it’s better to dissoc :meta, or dissoc all the keys direct from the def
- the only place I know I’ll be using this stuff is for an implementation of doc
@mhuebert you can submit a patch, remove the duping and only combine in the :var-special
emission
@dnolen: yeah, that's what I'm trying to convince them of
@ericnormand right sounds like they think ClojureScript is like CoffeeScript - sugar to generate JS
@mhuebert it’s actually pretty desirable since that probably means it’s also 20%-30% faster to read the caches back
@dnolen for sure
@dnolen: they are publishing each module to npm separately, so I don't think it will work without a major change
@ericnormand yeah not interested in this “goal"
@dnolen ok, i’m taking a look at it. some of the values differ between the :meta map and the def (for the keys #{:column :arglists :line :end-line :end-column :file}
, example printout http://pastebin.com/hc7C7Rqa) and I haven’t tracked down exactly where all of those changes come from yet.
@jell FWIW, I took a look at the code path involved when you add the val
argument. You can see that without it, it follows a more generic code path that essentially calls nth
on the result of range
, while with it, it follows a code path that “knows” about range
and avoids ever calling nth
and simply increments numbers.
Hey guys quick question about namespaces in a cider CLJS REPL. It seems that whenever I try to require
a namespace that is in my project at the figwheel REPL, i.e. (require project.websocket)
the REPL complains about that namespace not existing. However if I reference that namespace directly it seems to work just fine i.e. (project.websocket/test-fn)
. I am guessing this has to do with the closure compile step or figwheel reloading the page on save but I am kind of lost on how to proceed. Any hints, help, or ideas as to why this is the case and a way to reload my namespaces in the REPL would be much appreciated.
@royalaid After getting the exception from require
it might be possible to do pst
to learn more about where it is coming from. (I don’t recognize that one.)
@bbloom Btw. There exists a simple Socket REPL client for Vim: https://github.com/jebberjeb/clojure-socketrepl.nvim
Quite simple compared to Fireplace, there is no eval->response, only buffer of output
@mfikes thanks looking up the reduce implementation! I did gather that much on reading the code although I did not lookup the nth implementation (sorry about that, got too much excited with my findings). I personally think that (reduce + 0 (range 1e7))
looks more impressive than (apply + (range 1e7))
, and I thought if (reduce + (range 1e7))
was running as fast it would have been even more epic 😛 (looks so much higher level than apply, even though it’s the same thing under the hood in that case). I now know it is indeed possible, but not the case just incidentally because that path was not optimised. Anyway, thanks for your time and the cool stuff you do! 🙂
Has anyone used NPM packages (like react
or exponent
) via CLJS? Apparently, Google Closure now supports CommonJS/ES6 modules (https://github.com/google/closure-compiler/wiki/JS-Modules) but I haven't seen it used via CLJS yet.
@domkm supporting CommonJS/ES6 isn’t actually good enough, you need to support Node.js module resolution - that’s a pending PR on Google Closure though so ClojureScript will likely have that soon enough
@royalaid it can’t find that namespace - it probably means you haven’t placed the source file in the correct place
It looks like this (https://github.com/google/closure-compiler/pull/2130) may be the PR, for anyone interested.
@domkm React and its dependencies do LOTS OF strange things like dynamically creating module.exports
which Closure doesn't currently support
So even if Closure supports basic npm modules, supporting React is much more complicated
Oh well, seems like I'm just repeating what @thheller already said 😄
seems as though node doesn't have the optimization that makes (apply + (range 1e7)))
fast
although, it's kinda interesting that clojure and cljs (on nashorn) are comparable in speed
is there a way I'm supposed to be able to drop directly into a nashorn-hosted cljs repl? This was the shortest invocation I could figure out java -jar cljs.jar -e "(require 'cljs.repl.nashorn) (cljs.repl.nashorn/-main)"
@domkm @thheller Here is my test with trying to use module processing with React: https://github.com/Deraen/circle-color/tree/object-assign
Thanks @juhoteperi and @thheller
@dnolen worth adding as an alias I suppose. thanks! (I mean a personal alias for me in my ~/.bashrc)
I’d like to check which protocols functions (methods?) are implemented by an object. satisfies?
only checks that an object implements at least one method. Is there a simple way to check for a particular function having been implemented?
@wildermuthn satisfies?
doesn’t actually check anything other than that you said you satisfied the protocol
and no there is no simple way to test that a specific protocol method has been implemented
Ok thanks. Is it a bad practice to only implement part of a protocol?
(I’m adding a method to a protocol is the issue)
@chancerussell see above. Thanks @dnolen. 🙂
I would think really long and hard about changing a protocol if people already depend on it
Ahhhh, ok. I should have just made another protocol. I began writing this before realizing what satisfies?
does:
(this was just the start here… not necessarily well though out)
so I’m making a library as I use the library, dog-fooding it. And I’m adding a protocol method I didn’t realize I needed.
I’ve done this a few times now. And end up just adding stubbed functions to a lot of types. But it seems, if some types don’t need those methods, perhaps those methods need to be a different protocol entirely?
(i.e., the event listeners)
K, thx, very helpful
@bja: I verified the same thing. (time (apply + (range 1e7)))
in Lumo takes more than 1 second. It seems to take much less in Chrome (which also runs V8). I still haven't figured out yet, though Lumo is faster than Planck for other stuff. Most probably related to different optimizations by different JS engines
@bja: can you share some specific numbers?
Also what machine you're on
I'd be very interested
One thing that Lumo does over plain Node.js is the startup snapshot
So every CLJS function is already compiled (though lazily) when you start up the REPL
probably why you're seeing perf increase