How much appetite is there for a :redundant-alias linter that detects (:require [foo :as foo])
I have doubts about this one since it is pretty harmless to introduce the alias and moreover, it breaks the visual pattern of (:require [x :as y]) when x happens to be equal to y
so you would get:
(:require [ns1 :as a]
[ns2]
[ns3 :as b])
https://github.com/clj-kondo/clj-kondo/issues/2822
Also not sure if using the alias vs namespace reference has any semantic changesproposed alternative name:
:alias-same-as-ns
I think I like that one the bestThat makes me think it may lint for this:
(ns foo (:require [bar :as foo])) ...
which interestingly clj-kondo doesnβt warn about by default. Maybe one for the todo list?
So to avoid confusion (and possibly future conflict) how about:
:alias-same-as-aliased-ns
?to be clear, I think :alias-same-as-ns could be misinterpreted as meaning :alias-same-as-this-ns
I'm not worried about that, an alias is for an ns, I think it's clear enough
OK. Iβll give it a few days to make sure this is settled before doing the renaming π
probably releasing clj-kondo on Monday
The message pretty much says the same thing: > alias same as namespace name Btw, the style for most linters are:
Alias same as namespace name:
So capital + colon with data
I'll add this to the PR as a comment tooalternative wording: :alias-equals-ns-name or
:alias-equals-ns
I'm fine with either of those three, I'm going to timebox my bikeshedding to 0 now ;)for whatever it is worth: I just implemented my own linter to yell at us if we use :as on short namespaces (2 segments or less disallow aliases). Doing so was partially motivated by [foo :as foo] being found more and more in the codebase as llms churn out code and folks miss things like this while reviewing
2 segments or less disallow aliases? what is a segment? can you give an example? foo.bar.baz is three segments?
That's the usual parlance isn't it?
I guess so, I was just surprised that people use segments in aliases at all that much
I think what they mean is that they are forbidding [foo.bar :as bar]
oh I re-read and now I see it
so (clojure.test/is ...) instead of (t/is ....)? that seems... tiring :)
Wow, I alias 2-segment nses all the time... and a 1-segment ns is problematic for other reasons.
tbh I like last segment aliases the best
maybe we could get back to the original issue since I don't like it but I don't want my personal taste guide every possible thing in clj-kondo
Makes me curious how often folks use 2+ segment aliases tho'? I really don't like those but I have seen cases where they are better for readability than inventing multiple similar aliases...
Perhaps a more realistic example for discussion would be (:require [my.ns :as my.ns]) then?
Yes, things like that would be what this linter would guard against to my understanding.
Yeah, I'd be in favor of a linter that flagged :as having the same alias as the namespace in that case.
(:require [my.ns]) generally indicates an ns loaded for side-effects (and therefore suppresses the "unused ns" linter). I think the "breaks the visual pattern" aspect there is important, since the unaliased ns is "special".
that's a very good point!
just the style of the team from before I joined and better to lock in something vs free for all. I simplified the description a bit, but we would allow [clojure.test :as t] if defined as a common alias in the :consistent-alias linter. Historically the team prefers not using :as for shortish namespaces but for those we allow, you have to define it as ok as a :consistent-alias .
it took a little while to get used to this and I also originally somewhat rebelled against it. then you get used to it and start thinking it ends up being nice. So then you make robots enforce it so tooling sticks with your conventions π
It's fascinating sometimes the weird little quirks individual teams fall into over time with Clojure... π€
not at all suggesting this becomes a built-in. Just a data point towards flagging foo :as foo
indeed. I've been writing clojure for a long time and first time I've come across this convention
@seancorfield you had an argument against this linter, yet you gave it a thumbs up. wanna explain?
I don't think I was arguing against the linter per se -- I was arguing against single-segment nses π and I was arguing in favor of the [my.ns] require form as specifically not needing :as my.ns because I think the argument that it "breaks the visual pattern" is wrong.
thanks for clarifying your position
What wasn't clear to me: you recognize that [my.ns] is usually used for side effects. But would you still be in favor of [my.ns] if it's not for side effects, but people actually use (my.ns/foobar)? I can see one downside of this: when removing (my.ns/foobar) it won't be clear thereafter, if the namespace was loaded for side effects or not, or simply unused.
> you recognize that [my.ns] is usually used for side effects
Correct.
> you still be in favor of [my.ns] if it's not for side effects
I wouldn't do it, no. I'd add :as ns (assuming "ns" is some real ns name, not literally ns)
I really, really don't like seeing (my.ns/foobar) in code.
And I really don't like dotted aliases.
then you are not in favor of the original issue, I think
If pushed, I might do (:require [my.ns :as my-ns])
at least, not in general. just when the namespace was used for side effects, but we already have that convention in clj-kondo, so that's not what the issue poster had in mind
The :redundant-alias would flag [my.ns :as my.ns] (good: I don't like that) but it would not flag [my.ns] (good: use for side-effects) or [my.ns :as my-ns] (good: non-redundant alias that is also non-dotted).
exactly. and this is why it's even encouraged to use an alias for a namespace that you're going to be calling functions from, rather than using the ns name directly. the proposed issue breaks that pattern
so this is why I was confused about your π
:redundant-alias suggests that you would remove the alias, which is clearly not what we want for this pattern. redundant = remove in clj-kondo.
I think using (my.ns/foobar) after (:require [my.ns]) is a separate issue and would warrant a separate linter at some point maybe.
This is one of those tough spots where there's a real subtlety in usage and intent.
In my code, I'd never trigger :redundant-alias but I'd be happy for it to be flagged in, say, AI-generated code.
For example, I'd also welcome a :no-dotted-alias linter since I do not like that style.
would you like the AI to switch to (:require [foo.bar]) + (foo.bar/baz) after seeing the warnings? because I think that's what's going to happen if the linter is called :redundant-alias :)
I'd want (:require [foo.bar :as bar]) or (:require [foo.bar :as foo-bar])
right. so you are in favor of the linter, but the name should probably change to :alias-same-ns-name or whatever (can't come up with a good one right now).
as in, the hint on how to deal with the issue, should be more neutral
π€ now
a nice vaguely related issue I once solved: https://github.com/clj-kondo/clj-kondo/issues/864