This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-14
Channels
- # adventofcode (20)
- # arachne (11)
- # beginners (53)
- # boot (342)
- # cider (54)
- # cljs-dev (39)
- # cljsrn (4)
- # clojure (78)
- # clojure-brasil (2)
- # clojure-italy (5)
- # clojure-nl (4)
- # clojure-quebec (1)
- # clojure-russia (90)
- # clojure-sanfrancisco (4)
- # clojure-spec (55)
- # clojure-uk (27)
- # clojurescript (170)
- # core-async (1)
- # core-logic (1)
- # css (1)
- # cursive (8)
- # datomic (83)
- # dirac (5)
- # hoplon (24)
- # lambdaisland (1)
- # lein-figwheel (23)
- # midje (2)
- # off-topic (1)
- # om (4)
- # om-next (7)
- # onyx (74)
- # proton (1)
- # protorepl (22)
- # rdf (2)
- # re-frame (105)
- # reagent (15)
- # ring-swagger (3)
- # rum (4)
- # slack-help (17)
- # spacemacs (14)
- # untangled (62)
- # vim (4)
- # yada (18)
I was browsing core.cljs
and came across a bunch of metadata that I assume are hints to the compiler: ^native
, ^not-native
, ^clj
, ^clj-or-nil
... what do these do? are they documented anywhere?
@plexus they let the compiler optimize some things. For example if you tag something as ^boolean the compiler can elide the truth check
For example if you compile (if (my-predicate? some-data) ...)
the resultant javascript will likely have wrapped the result of that expression in the truthy check but if you tag it: (if ^boolean (my-predicate? some-data) ...)
it won't as it now knows the function returns a javascript boolean.
The truthy check is at line 881 of clojure/cljs/core.cljc btw. You can see its a template for some javascript.
@plexus as tmulvaney said: they are internal compiler optimizations that you should almost never have to worry about. don't think they are documented anywhere though.
usually the compiler will check for a protocol before calling it .. x.my$super$Protocol$Fn ? x.my$super$Protocol$Fn(...) : my.super.protocol-fn(x, ...)
with not-native
this check will be skipped and directly call x.my$super$Protocol$Fn
@dnolen Sorry to bother again: So I noticed there is quite a few usages of declare
in core. I also noticed s a (def ^{:declare true, :arglists '(...)} foo-fn)
isn't respected by the compiler and will still generate the check if the arity actually exists. So:
1. Should the compiler respect the arglists
and generate the optimal code?
2. Should there be a "better" declare for cljs to provide arglists (declare-fn get [m x] [m x nf])
?
Besides the generated check being never invoked, which might be completely optimized away by most engines, I found 3 cases where cljs.core always goes thru the .call
syntax in potential hotspots:
- cons
used in IndexedSeq.conj
and Rseq.conj
- key+val
in conj!
of ITransient
hmm I don't even know if clojure does some of the tricks cljs does, probably not 😛
@thheller I'm no JVM expert, but arent' they all eventually methods of a Java class? So if they get invoked it'll invoke the right arity fn and will throw if that arity doesn't exist (JS will be ok with calling fns with the wrong arity).
I always wondered if CLJS could optimize some expressions more (ie. (def x (fn []))
(def x (let [priv (atom {})] (fn [...]))
) but never bothered enough to investigate
@rauh not interested in solutions until first it’s demonstrated there will be some significant performance benefits, so I would collect some numbers first
I do not expect it will matter for anything except declare
for single arity fns, and probably even then possibly not significant enough
@plexus not documented anywhere and you should avoid them - ^boolean is the only one close to “official"
@plexus with the exception of ^boolean they are all half-baked, I don’t think you’ll discover anything consistent 🙂
@dnolen on my Chrome v54, it looks like the difference is less 5%, 😕 . So the only benefit would be slightly smaller code size, but that's probably even less than 1% difference
@rauh we do factor in other browsers, if you have time to test Safari/Firefox that’s useful
So you mean a (def ^{:declare true :arglists ...} get)
should be understood by the compiler?
@rauh I took a quick browse, it’s not a simple patch, you can definitely expect to be a moderate ClojureScript compiler expert after your done 🙂
@dnolen Sounds good, thanks. I might take a stab at this in the new year at some point. http://dev.clojure.org/jira/browse/CLJS-1871