Fork me on GitHub
#cljs-dev
<
2018-11-25
>
mfikes03:11:25

Wait... so if you use that to, for example look at [goog string trim], you get {:tag Function, :ret-tag string}, which seems to imply we ultimately have a way to infer the return type of clojure.string/trim as string (and if that existed, no need to manually hint as in https://dev.clojure.org/jira/browse/CLJS-2868)

favila21:11:48

I have a macro that expands to a call to react/createElement using (:require [react]) via :global-exports. Users of this macro would need to require react in the calling namespace; to make this easier to use, I alias createElement in a cljs namespace of the same name as the macro namespace (def createElement react/createElement); then the macro can expand to (my-ns/createElement ...) instead

lilactown21:11:06

sounds right

favila21:11:31

however calling the alias always emits the conditional "is this an IFN" test

favila21:11:05

e.g. x.cljs$core$IFn$_invoke$arity$2 ? x.cljs$core$IFn$_invoke$arity$2.call(...) : x.call(...)

favila21:11:25

calling react/createElement directly does not do this

favila21:11:39

I can't find any combination of hinting that will get rid of this

favila21:11:47

I thought of making a fn wrapper instead so that cljs would see the type correctly, but unfortunately I sometimes need to call with var-args

favila21:11:02

(js var-args, not cljs var-args)

dnolen21:11:16

@favila there's really no way to avoid that with ClojureScript fns, but I don't really see how this could be much of a problem

dnolen21:11:24

that property check is ridiculously cheap

favila21:11:18

it seems a strange asymmetry. If a symbol is known to be js, it emits a direct invocation (no .call even); but if you alias it in cljs-land, it's impossible to get that back?

thheller21:11:58

you can fake get it back via (js/your.ns.createElement ...)

thheller21:11:09

js/ never does the property check

favila21:11:48

so this isn't operating at the type level, it's the "namespace" of the symbol that determines the invocation style

thheller21:11:30

nah js/ is just a shortcut to opt out of all other "optimizations"

thheller21:11:15

IMHO there should be a typehint or something that has the same effect but I don't think there is

lilactown21:11:47

I have a dumb question. is there a way to differentiate between a CLJS function and a JS function? e.g. one defined via defn vs an external JS lib

favila21:11:21

if it's multi-arity there will be some extra properties on it; all bets are off in advanced compile of course

dnolen22:11:09

like I said I don't think it's worth spending any time on this

dnolen22:11:45

last time I checked the property check adds less than 10% overhead over fn call

thheller09:11:24

FWIW I think a 10% overhead at runtime for something that gets called as often as React.createElement is quite expensive and probably worth optimizing

dnolen22:11:58

way less than .call which is like 2X worse

favila22:11:48

without aliasing .call isn't used either

favila22:11:08

@thheller has the best workaround I think

bbrinck23:11:25

Is there a JIRA ticket tracking the CLJS equivalent to https://dev.clojure.org/jira/browse/CLJ-2373? It has come to my attention that https://github.com/clojure/clojurescript/commit/5f0fabc65ae7ba201b32cc513a1e5931a80a2bf7 makes CLJS spec errors like CLJ (which is great to have parity!) but I don’t believe CLJS yet has an equivalent of this code https://github.com/clojure/clojure/blob/b182982007df934394f0bc68b3a238ca9f200dd1/src/clj/clojure/main.clj#L268-L279

bbrinck23:11:45

as as result, I believe users can no longer install a custom spec reporting e.g. expound in CLJS 1.10.439 https://gist.github.com/bhb/6bd51f798f9eaa50850fb18c44aaa733

😱 4
bbrinck23:11:36

@mfikes Excellent, this is exactly what I needed. I’ll add a comment

bbrinck23:11:05

Thank you for all your hard work on CLJS! Much appreciated 😄