@dnolen about referring global things https://clojurians.slack.com/archives/C03S1L9DN/p1756384244216269?thread_ts=1756298300.319249&cid=C03S1L9DN - maybe continue here?
would love to know more
:refer-global :only
@dnolen I see there is also a variant without :only?
(ns foo.core
(:refer-global [Date] :rename {Date MyDate})thats commented out, so probably not 😛
yeah, no
no variants
oh ok. values going into :rename don't have to be :only 'd first?
with :require + :refer that is the case AFAIK?
I'm inclined not to support that - at least initially
FWIW:
user=> (require '[clojure.set :rename {union xunion}])
nil
user=> (xunion #{1 2 3} #{4 5 6})
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: xunion in this context
My expectation is that this would work the same in CLJS for :require-globalwhy not? seems redundant to name things twice
but this test seems to suggest otherwise:
(deftest test-parse-global-refer
(let [parsed (ana/parse-global-refer-spec {}
'((:refer-global :only [Date] :rename {Symbol JSSymbol})))]
(is (= parsed
'{:use {Date js}
:rename {JSSymbol js/Symbol}}))))oh hrm sorry, I switched gears to the lite mode stuff - I think you all are right, only and rename gets combined - so it works
why not? it seems CLJS already works that way:
$ plk
ClojureScript 1.11.132
cljs.user=> (require '[clojure.set :rename {union xunion}])
Unexpected error (ExceptionInfo) compiling at (<cljs repl>:1:1).
Renamed symbol union not referred at line 1and this agrees w/ what was done before
but the important thing to note here ... is that what's driving this is Clojure refer
not require
because nothing is being required here
only is the counterpart to refer here?
so require expectations do not need to be fulfilled
yeah so I'm correct in that you probably need :only
I'm not sure if we're on the same page.
Do you think that the renamed value should also occur in :only ? yes or no
you do see how :refer works and what it means in Clojure?
I'm starting from there, I'm not concerned about convenience or anything else really
aaah I see now:
user=> (refer 'clojure.set :rename '{join x}
)
nil
user=> (x #{1 2 3})
Execution error (ArityException) at user/eval8 (REPL:1).
Wrong number of args (1) passed to: clojure.set/joinI ran aground of this problem once I started working on the macro for the REPL
you just referred the whole clojure.set namespace
see the clojure.docs for the conflict warnings example
right, so it should be:
user=> (refer 'clojure.set :only '[join] :rename '{join x})
nil
user=> (x #{1 2 3} #{4 5 6})
and this is how require-globals should also work - right?sorry, `:refer-globals` :refer-global
yes
then we are on the same page since my original message, thank you for clearing this up.
the test-parse-global-refer seemed to indicate otherwise
oh yeah sorry, that needs to be fixed up
I'm not totally against sugar because of course refer-global w/o :only doesn't mean anything - we cannot know what's in the global ns
but can be done trivially after people play around w/ it
(:refer-global :rename {Date Foo}) we also know that Date is something global, so the extra :only [Date] is just redundant. that can be inferred
that could be a nice thing
if we can auto known things
(but that's why I kind of like these decisions later since the design space opens up fast)
but we know it just by the fact that its mentioned in this form. it can't rename something from another form or so
The point that it can be inferred seemed not to be an argument for :require + :refer in JVM Clojure and CLJS so far. I'm not totally against it, but I think it's nice to keep to the defacto standard which is JVM Clojure as well
(CLJ doesn't have refer-global so no "standard" to adhere to)
I find the implication of :only a bit confusing, since that kinda seems to imply there is a way to :refer :all for all globals, which we can't know
(:refer js/globalThis :only [Date] :rename {Date x})I had the same feeling about :only but I dropped that objection since :refer is a standard
but if you argue that there is no standard to adhere to since this is a completely new feature, I'd buy that too
:only as used in current places means actual "only", as in that thing but nothing else. not using :only meaning everything. but in :refer-global not using it doesn't mean all globals, since we can't know that
dunno its bikeshedding. doesn't really matter what it is as long as its consistent
:only+`:rename` seems redundant but also doesn't really matter
One additional question. Will :refer-global also support the property syntax, like:
(:refer-global :only [Library$Module])
like is supported in :require with e.g. $default ?
I think this is a must have when using CLJS with script tags that pull in other libraries that define a nested library structure. Even more compelling with :lite-mode .
I don't think the :refer-global syntax lends itself well for this at the moment. In :require you can give such a property-accessed object an alias, e.g. (:require ["foobar$default" :as foobar]) but this doesn't work with :refer-global(I removed my "ship it" message since this seems kind of important!)
there's a separate thing I haven't worked on yet :require-global which supports require syntax.
The idea here is to distinguish between browser builtins and other scripts you added to the page. :require-global is for the later.
why distuingish?
and how would one refer window.Intl.NumberFormat for example? (this is just an example, there might better ones)
Intl/NumberFormat - any real properties in the browser can be inferred properly
you never need to write window that's just global stuff
haven't seen any compelling argument for complecting into one thing here.
another thing here is validation logic
for browser globals we can check lots of things that aren't going to work
for libs, maybe a couple of runtime asserts in dev
I mean when you want to have NumberFormat itself referred, not with the Intl prefix. So you can write (NumberFormat/supportedLocalesOf ...) .
Maybe this isn't the strongest example, but maybe down the road there will be browser APIs where this makes more sense.
Complected: I'm agnostic to the difference between a host global or something defined by a polyfill or just a normal library. To me it doesn't matter. This also isn't browser specific, could also be node, Bun, etc.
browser apis are not that nested - it's inconvenient, really not concerned about that.
polluting the global ns is not a thing JS runtimes do that much for the obvious reasons
unlike the browser
Looks like a bug in CLJS. As I mentioned in my response to that thread, no clue how Transit would be related, but cljs.analyzer/cache-file can return either File or URL while cljs.analyzer/write-analysis-cache expects it to always be File.
https://clojurians.slack.com/archives/C03S1L9DN/p1756400705732949