after a lot of notes, I'm feeling slightly less good about js js$ - also just not loving goog$global nor globalThis etc. as a convention. One thing that would be nice is if for global stuff we can maintain the convention of a proper namespace instead of the js/ workaround.
any thoughts about (:require [cljs.host :refer [HTMLElement]]) ?
I think it's worth coming up w/ something that is nice to look at - whatever we go w/ - we're gonna be stuck w/ it
I think I would prefer (:require [globalThis :refer [HTMLElement]]) instead, instead of a nested namespace name
and then (:require [globalThis$React :as react]) would also work (since $ is already a feature)
I don't like globalThis - nested namespace is not an issue for ClojureScript programmers
single segment namespaces always -1
yes, but in this case, it's a special thing, not a real namespace
but that is the difference in what I'm proposing, cljs.host we could preserve namespace semantics
cljs.host/HTMLElement etc. - which is natural, in the case of globalThis would have to special case
ok. will cljs.host$React also still work (like with JS libs)?
everything would work - under the hood cljs.host is just globalThis
I mean (:require [cljs.host$React :as react])?
yes, the intent would be to support all features
cool. that's the most important one to me personally. cljs.host feels a bit weird, but I could live with it
other things that would just work is that cljs.host.React/Element w/o :require the way that goog.string does etc.
wait, weren't we supposed to always require goog.* stuff since a few releases back?
well, that's because of the google.module misfeature
but also now we control GCL 🙂
only GCL modules have that restriction
in anycase, this isn't really a feature to highlight for CLJS-3233 - just pointing out that more Clojure semantics get coverage here
I disklike this variant very much. it should have clearer rules and the placement of the / should not be arbitrary. not exactly a fan of / in the first place. not sure if current specs even allow qualified symbols there
if anything cljs.host/React.Element and not cljs.host.React/Element
making cljs.host a special "namespace" is fine, although honestly it might as well be js/ then since we already have that
I think not having this in :require would just unnecessarily complicate tooling (and the analysis in the compiler itself) anyway?
hmm?
I agree with @thheller that I would find js more clear as well since this symbol is already in use for the global JS environment
@thheller I meant, I'd prefer writing (:require [cljs.host$React :as react]) + react/Element instead of cljs.host.React/Element anyway
I think there is value in having (:require [js/some.global.Thing :as x]) for (x/something) as opposed to the alternative of just (js/some.global.Thing.something) which gets tedious if there are repeated uses and (def x js/some.global.Thing) forces (.something x) syntax or the somewhat accidental (x.something)
yes, that's what I was saying :)
(:require [cljs.host/some.global.Thing :as x]) is just a new thing for no real reason I can think of
but this should be js$some.global.Thing in the :require imo since $ is already supported
js/ has precedence for many years now and it just extended to work in ns
that's a valid point although why introduce more syntax in ns for something that already exists (for accessing stuff from js libs)
it also goes against the clj JVM spec whereas $ doesn't:
user=> (ns foo (:require [js/bar :as z]))
Syntax error macroexpanding clojure.core/ns at (REPL:1:1).
((:require [js/bar :as z])) - failed: Extra input spec: :clojure.core.specs.alpha/ns-form
user=> (ns foo (:require [js$bar :as z]))
Execution error (FileNotFoundException) at foo/eval136$loading (REPL:1).
Could not locate js$bar__init.class, js$bar.clj or js$bar.cljc on classpath.$ is very meh to be honest. will lead to question as to why js$thing doesn't work in other places and has to be js/thing there
but yeah the spec thing might be blocker
or it will lead to: hey I can use $ for normal libs too ;)
sorry if I wasn't clear, we're not allowing / in (:require ...)
I was just talking about the fact that say you have a library loaded in the global environment, if you are lazy (which you should not be) - you can write cljs.host/React or cljs.host.React/Element as a var reference in a source file.
again I'm not talking about this is as some kind of big feature, rather just more generally pointing out that the behavior is more aligned w/ a namespace than what js/ gives us today which is kinda weird.
w/ js it's just hard to deliver the expected "symmetry" here
i.e. (:require [js$React ...]) whell js$React is a namespace so why not js$React/Element var ref in a source file?
if you take it to its logical conclusion - I hit this when writing down my notes - that's how I ended up at cljs.host idea
similar thoughts about (:require [$React ...]) why not $React/Element in a source file - I just don't this looks very good over a proper namespace for this stuff to go that isn't single segment.
$foo is a normal symbol and I have used such names in many places. making them somewhat magical now would break stuff.
why not js$React/Element
why not $React/Element in a source file
because those aren't known as aliases introduced in the ns formyes, so this is why I don't like the $Foo shorthand
anyways, it's really worth pondering the benefits of typing a little bit more here.
no one can take cljs.host except for ClojureScript
because those aren't known as aliases introduced in the ns form this is an after the fact explanation of this won't work.
so a strike against shorthands in the (:require ...) form
another way to evaluate what I'm proposing
1. All Closure / ClojureScript / global things follow the namespace conventions
huh? all I meant was that a in a/x in general should be an alias (introduced by the ns form) or class (`:import`)
I wasn't saying anything about how that alias was introduced. either js$Foo or cljs.host$Foo could work, but this is unrelated
2. Only foreign JS deps lose out
because of the module thing
to be extra clear - what I'm talking about is not just the syntax in the :require form, but also how you reference vars in source files because these are related.
Perhaps an excel sheet with the options would make it clearer what you're saying, a la Rich Hickey Design in Practice :)
sure I think that will help, will put one together and post it
I imagine it would be slightly easier for people to provide cljs/host.clj for mocks for testing their CLJC code on the backend. Not sure how important or desirable it is though.
so this really about bending all this global stuff into Clojure(Script) expectations