This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-12
Channels
- # arachne (1)
- # aws (2)
- # beginners (123)
- # boot (22)
- # boot-dev (8)
- # chestnut (3)
- # cider (38)
- # clara (36)
- # cljs-dev (148)
- # clojars (2)
- # clojure (76)
- # clojure-austin (2)
- # clojure-greece (1)
- # clojure-italy (6)
- # clojure-russia (5)
- # clojure-spec (8)
- # clojure-uk (65)
- # clojurescript (45)
- # core-async (38)
- # cursive (9)
- # data-science (5)
- # datomic (28)
- # docs (1)
- # emacs (2)
- # fulcro (34)
- # hoplon (18)
- # jobs-discuss (7)
- # keechma (8)
- # lumo (5)
- # om (3)
- # onyx (31)
- # parinfer (1)
- # pedestal (1)
- # re-frame (20)
- # reagent (5)
- # ring-swagger (16)
- # shadow-cljs (56)
- # spacemacs (11)
- # specter (8)
- # sql (5)
- # unrepl (29)
- # yada (6)
@ajs If you dig into the dot notation subject, an argument could be made that js
is a pseudo-namespace and the symbol console.log
is an abuse that embeds JavaScript nested property syntax into ClojureScript code. But perhaps this is the ClojureScript analog of the legitimate use of dots in symbols in Clojure to designate fully-qualified class names, and is really nothing more than "interop" (a pragmatic view, opposed to a prescriptive or pedantic one.) A (perhaps fallacious) argument is that all this is OK because Rich is employing that very construct here https://github.com/clojure/clojurescript/commit/954e8529b1ec814f40af77d6035f90e93a9126ea#diff-a9cce52f0bf5a7b9afccbec54e4a0e4bR39
my response when I see (js/console.log ...)
is "what? why? how? that's not even a valid clojure symbol!"
but I knew clojure for a while before learning cljs so it might be that I'm just a grouchy old man
@noisesmith Yes. Consistency in the idioms employed between ClojureScript and Clojure can be a good thing. I had the same reaction initially as well. My story was that ClojureScript allowed me to, starting from knowing Clojure, produce a JavaScript app while not knowing JavaScript.
I probably should understand why it ok better. I briefly thought about it once then forgot
On a pragmatic note, there was a recent case (trying to recall the details), where, if you avoid playing these interop games, and write code that is "Clojure", then the ClojureScript analyzer can help avoid some mistakes you might make.
There is actually this blog: http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/ that went into some depth on these “frankenstein lang” interop forms I belive. Been a while since I read it and not sure how dated it is now since it was from a while back.
That’d be cool to see a case where you made more “Clojure” code to get analyzer benefits. Your next blog post perhaps?! 😛
I'll try to recall the example. It was a simple one, where you are left scratching your head as to why it doesn't work. I recall it being fairly easy to see why if you look closely at the code, but if you were to just write it without dots then the analyzer just "tells you".
If instead you write (fn [_] ,,, (.debounce js/_ ,,,))
then the analyzer throws you a bone:
WARNING: js/_ is shadowed by a local at line 1
cool! - glad to have a proper argument to back up my stodgy preference 😄
Yeah, in our current conversation
((fn [console] ,,, (js/console.log "hi")))
produces a pause-inducing
undefined is not an object (evaluating 'console.log')
while
((fn [console] ,,, (.log js/console "hi")))
gives you a clue:
WARNING: js/console is shadowed by a local at line 1
undefined is not an object (evaluating 'console.log')
For those interested, the older conversation on this subject was here https://clojurians-log.clojureverse.org/clojurescript/2017-10-27.html
Yeah, it is consistent with the view that, by doing js/foo.bar.baz
, you are really writing JavaScript and bypassing the analyzer.
That makes sense that when you start writing what doesn’t even look like cljs, that it may bypass
intuitively. I think I’m going to try to stick to avoiding that sort of syntax more than I have before.
In the blog I posted earlier: http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/ there is a section (can’t link) called “Nested scopes” There it is shown a case where this “dotted access” pattern seems necessary.
Based on the example there, if you want the JS:
var m = new Microsoft.Maps.Map();
You use CLJS:
(def m (js/Microsoft.Maps.Map.))
It’s a constructor, so it you can’t do
(def m (new (.-Map (.-Maps js/Microsoft))))
or something like that (or with .Map
(no hyphen))Yeah, interestingly, I think you can get away with
(def m3 (let [ctor (.. js/Microsoft -Maps -Themes -BingTheme)] (new ctor))
but I think this is a different abuse.@mikerod In terms of new
with the dotted symbol, I believe that is at least treading on thick ice with https://dev.clojure.org/jira/browse/CLJS-697