Skip to content

Instantly share code, notes, and snippets.

@mfikes
Last active September 12, 2019 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfikes/ec4a3fef7e52f3e634efa23b03cdd841 to your computer and use it in GitHub Desktop.
Save mfikes/ec4a3fef7e52f3e634efa23b03cdd841 to your computer and use it in GitHub Desktop.

Note we are using :static-fns, and also note we are using master to get inferrence for implements? CLJS-3140.

At its core is an (arguably internal) optimization surrounding the notion of ^not-native, which is also effectively enabled if a value is tagged with a protocol type.

Note that compiler enables inference for implements? but not satisfies? because the later would break things.

And, if a user type hints with a protocol type, while the user code is arguably correct, it would provoke the same bug surrounding satisfies?.

$ clj -Sdeps '{:deps {org.clojure/clojurescript {:git/url "https://github.com/clojure/clojurescript" :sha "b38ded99dc0967a48824d55ea644bee86b4eae5b"}}}' -m cljs.main -co '{:static-fns true}' -re node -r
cljs.user=> (extend-type number IAssociative (-assoc [n a b] (+ n a b)))
nil
cljs.user=> (assoc 1 2 3)
6
cljs.user=> (set! *print-fn-bodies* true)
true
cljs.user=> (defn f [x] (-assoc x 5 7))
#'cljs.user/f
cljs.user=> f
#object[cljs$user$f "function cljs$user$f(x){
return cljs.core._assoc(x,(5),(7));
}"]
cljs.user=> (f 1)
13
cljs.user=> (f {:a 2})
{:a 2, 5 7}
cljs.user=> (defn g [x] (-assoc ^not-native x 5 7))
#'cljs.user/g
cljs.user=> g
#object[cljs$user$g "function cljs$user$g(x){
return x.cljs$core$IAssociative$_assoc$arity$3(null,(5),(7));
}"]
cljs.user=> (defn g [x] (-assoc ^cljs.core/IAssociative x 5 7))
#'cljs.user/g
cljs.user=> g
#object[cljs$user$g "function cljs$user$g(x){
return x.cljs$core$IAssociative$_assoc$arity$3(null,(5),(7));
}"]
cljs.user=> (g {:a 2})
{:a 2, 5 7}
cljs.user=> (g 1)
Execution error (TypeError) at (<cljs repl>:1).
x.cljs$core$IAssociative$_assoc$arity$3 is not a function

cljs.user=> (defn h [x] (if (implements? cljs.core/IAssociative x) (-assoc x 5 7) (-assoc x 5 7)))
#'cljs.user/h
cljs.user=> h
#object[cljs$user$h "function cljs$user$h(x){
if((((!((x == null))))?(((((x.cljs$lang$protocol_mask$partition0$ & (512))) || ((cljs.core.PROTOCOL_SENTINEL === x.cljs$core$IAssociative$))))?true:false):false)){
return x.cljs$core$IAssociative$_assoc$arity$3(null,(5),(7));
} else {
return cljs.core._assoc(x,(5),(7));
}
}"]
cljs.user=> (h {:a 2})
{:a 2, 5 7}
cljs.user=> (h 1)
13
cljs.user=> (defn k [x] (if (satisfies? cljs.core/IAssociative x) (-assoc x 5 7) (-assoc x 5 7)))
#'cljs.user/k
cljs.user=> k
#object[cljs$user$k "function cljs$user$k(x){
if((((!((x == null))))?(((((x.cljs$lang$protocol_mask$partition0$ & (512))) || ((cljs.core.PROTOCOL_SENTINEL === x.cljs$core$IAssociative$))))?true:(((!x.cljs$lang$protocol_mask$partition0$))?cljs.core.native_satisfies_QMARK_(cljs.core.IAssociative,x):false)):cljs.core.native_satisfies_QMARK_(cljs.core.IAssociative,x))){
return cljs.core._assoc(x,(5),(7));
} else {
return cljs.core._assoc(x,(5),(7));
}
}"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment