This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (1)
- # beginners (171)
- # cider (51)
- # clj-kondo (40)
- # cljsrn (5)
- # clojure (68)
- # clojure-dev (42)
- # clojure-europe (2)
- # clojure-italy (20)
- # clojure-spec (2)
- # clojure-uk (141)
- # clojurescript (19)
- # community-development (4)
- # core-async (17)
- # core-logic (3)
- # cursive (11)
- # data-science (1)
- # datomic (7)
- # defnpodcast (2)
- # figwheel (9)
- # figwheel-main (2)
- # fulcro (15)
- # graphql (21)
- # jackdaw (3)
- # joker (11)
- # juxt (1)
- # luminus (12)
- # off-topic (2)
- # pathom (73)
- # pedestal (2)
- # re-frame (41)
- # reagent (14)
- # reitit (4)
- # shadow-cljs (39)
- # tools-deps (4)
is this intended behavior by Clojure? https://gist.github.com/nathanmarz/6c3461fd9f45e28248ace85eaee5a4f5
There are only a few people who can answer that question as you asked it, and I am not one of them, unfortunately. You probably already know that it is intended behavior to munge dash characters in namespace symbols into underscores before looking for resources/files on the classpath, because the JVM does not support dashes. Given that, it seems that there might be unavoidable naming issues in this area, like what you have found? I haven't thought deeply about it, but perhaps such issues would be avoidable if
*loaded-libs* only contained the post-munged names, but that sounds likely to cause upset for any Clojure tooling that peeks inside
the context is we had a bug caused by unexpected redefinitions from a typo in a
require for a namespace containing a
I don't know the history here, but it surprises me a little that you can even successfully do a
test_ns, when the
ns form inside the file is
test-ns. It seems reasonable that such a
require should fail.
you'd imagine that it loads the file and then errors because
test_ns hasn't been defined as a namespace?
Although my quick REPL testing is not matching my memory of code that I thought was present that checks whether the namespace exists near the end of the
require. Double-checking to see where my memory is going wrong here.
which in our case would have caught the typo immediately rather than cause a very difficult debugging session
Ah, if you do
test_ns with an
:as clause, and the file has
test-ns, then you get an error. Without the
:as, it does not.
The error checking is also enabled via
use, but understood if you wouldn't want to go there.
when you read a lot of this code you start wondering whether the term
lib was (or still is?) used to mean something slightly different from either "namespace" or "source file"
I think I mentioned that here once a year ago but can't remember if anybody said anything useful about that
but I could imagine that being a barrier to assuming that the arg to
require is a namespace symbol
require (which describes its args as libs, not namespaces) docstring:
A 'lib' is a named set of resources in classpath whose contents define a library of Clojure code. Lib names are symbols and each lib is associated with a Clojure namespace and a Java package that share its name. A lib's name also locates its root directory within classpath using Java's package name to classpath-relative path mapping. All resources in a lib should be contained in the directory structure under its root directory. All definitions a lib makes should be in its associated namespace.
I do not recall whether linters like Eastwood or clj-kondo would catch that kind of thing.
summarized: the check should be: if there is an ns foo-bar, but you require with foo_bar, it should give a warning?
I would think the most accurate check would be: the symbol naming the namespace in a require/use, and the ns form name symbol, should be equal.
Eastwood definitely has checks already for compatibility between ns form symbols and the file name it is inside of on the file system.
Both namespace symbols? They can't be both used in a single ns form, of course. And for require to work, they would both have to be in the same file.
Two ns forms in the same file is not illegal, but pretty strange in most code.
I mean, you cannot require a namespace which is not in a file, but defined in the REPL
so you could have either foo_bar with (ns foo-bar ..) or (ns foo_bar), so a check would have to know about that and then emit a warning. that's something clj-kondo could easily do.
Well, require with :as, or use, both give an error if loading the file it finds does not end up causing the target namespace to exist.
A file foo_bar with either of those ns forms are legal, and would work if you did a require + :as with a matching symbol to name the namespace.
this is a very rare case I would say. stylistically, I'd say: avoid underscores in namespaces names
The warning that would have saved time in the scenario above cannot be caught by looking at the contents of only one file, but across files.
Stylistically forbidding underscores in namespace names could be adopted as a project convention, of course.
this kind of check would probably be just a few lines of scripting using the data that clj-kondo spits out: https://github.com/borkdude/clj-kondo/tree/master/analysis#data
Project style/convention-wise, mandating :as for all requires would also prevent this.
I agree. We have a number of namespaces where
:require ... :refer [...] is the appropriate usage (because they declare operator-like symbols and using an alias makes them harder to read).