Fork me on GitHub
#clj-kondo
<
2020-11-13
>
didibus02:11:28

I'm using (create-ns) and (alias) manually to create some namespaces only for the purpose of spec. Wonder if there is a way I could do it so clj-kondo wouldn't show warning Unresolved namespace marketplace. Are you missing a require? (clj-kondo-clj)

dominicm03:11:06

@didibus are they top level calls?

didibus08:11:48

No they arn't.

didibus08:11:25

Though I could switch the function to a macro that returned an (alias 'foo 'bar) if that can help

dominicm08:11:46

@didibus are they dynamic?

dominicm08:11:57

Or maybe they can't be

didibus08:11:38

They're not dynamic. Like the namespace is in the code. I wrap a call to create-ns and alias in a function. And I call that function with a hard-coded symbol

didibus08:11:26

Maybe I could hook into clj-kondo and add symbols passed too my custom function to it's set of known alias? Is that possible?

dominicm08:11:35

The problem I think you have is the function.

dominicm08:11:09

It's worth testing with the function inlined to see if the magic already works.

didibus20:11:54

Hum, this makes me wonder, does inlining work with clj-kondo? Like with definline or :inline meta ?

didibus20:11:38

Doesn't look like it does

dominicm08:11:34

If it does, then I'd try hooks potentially.

dominicm08:11:23

@didibus

(ns foo)

(create-ns 'com.bar.baz)
(alias 'bar 'com.bar.baz)

::bar/foo
This lints fine. So I'd try hooks.

borkdude08:11:08

yes, a hook could work. but clj-kondo could also be tweaked to recognize the (alias 'foo (create-ns 'bar)) pattern is that is used a lot

didibus20:11:13

I'm doing:

(create-ns ns)
  (alias alias-sym ns)

didibus20:11:08

But I have this wrapped in a utility function which is in another namespace, which I call like so:

(defalias 'alias 'namespace)

borkdude08:11:50

and you can also do that yourself via a hook right now. or use #_{:clj-kondo/ignore [:unresolved-namespace]}. This is only needed in the first occurrence.

amorokh11:11:05

hi, I get error indications from clj-kondo when I use async/alt! in clojurescript, the errors report the binding symbol in a result-expression as unresolved symbol, anybody else seen this? works fine in clojure..

borkdude11:11:51

Can you make a small .cljs file / snippet that shows the problem?

amorokh11:11:59

hmm, I’m not really familiar with slack and how to send snippets, that was not what I intended

amorokh11:11:23

(ns repro
  (:require-macros [cljs.core.async.macros :refer [go alt!]])
  (:require [clojure.core.async :as async]))

(let [ch (async/chan)]
  (go
    (alt!
      ch ([value]
          (println value)))))

amorokh11:11:27

that was better

amorokh11:11:26

when I have that code in a cljs file in VS Code, I get error squiggly on the value binding symbol

borkdude11:11:18

Yeah, I see. If you write:

(let [ch (async/chan)]
  (go
    (async/alt!
      ch ([value]
          (println value)))))
then it goes away, but I'm not sure if that's valid in CLJS

borkdude11:11:16

I will ask in #clojurescript

amorokh11:11:17

ok, so it’s related to :require-macros ?

borkdude11:11:43

clj-kondo understands clojure.core.async/alt but it doesn't have a special rule for understanding the CLJS way of using that

borkdude11:11:56

but if you're lucky this is fixed in newer version of CLJS

borkdude11:11:57

You can fix it now with this config:

(ns repro
  {:clj-kondo/config '{:lint-as {cljs.core.async.macros/alt! clojure.core.async/alt!}}}
  (:require-macros [cljs.core.async.macros :refer [go alt!]])
  (:require [clojure.core.async :as async]))

(let [ch (async/chan)]
  (go
    (alt!
      ch ([value]
          (println value)))))

borkdude11:11:07

so:

{:lint-as {cljs.core.async.macros/alt! clojure.core.async/alt!}}

borkdude11:11:34

Maybe post that in an issue and then we can include that in clj-kondo itself

amorokh11:11:48

ok, thanks again

amorokh12:11:31

I guess that an issue for this is unnecessary then?

borkdude12:11:29

yeah, I think so

didibus21:11:34

Managed to fix it with :lint-as my/fn clojure.core/alias That was easy 😄

👍 3
didibus21:11:21

I had assumed :lint-as was only for macros for some reason, but ya, happy to see it works for functions as well

borkdude21:11:03

yeah, clj-kondo doesn't care about macro or function, it only cares about the surface form

👌 3
didibus21:11:31

Another question, for Alias consistency it seems you need to configure it. Would there not be a way that it just complained on alias that differed in a code base? Like if I had two namespace, one where foo.bar is foo and another where foo.bar is bar, then both alias would show a warning saying they are inconsistent with one another?

borkdude21:11:35

@didibus That has come up in the issue when writing that linter. The reason we didn't do that is that currently clj-kondo doesn't read information about other namespaces other than vars from the cache. And you would have to make a choice either way: like what if two namespaces have str and two other namespaces have s. You would have to specify one of both in the config then anyway. So it just made the most sense to just start out with a baseline

borkdude21:11:30

You can retrieve the aliases from all namespaces from the analysis config yourself and then spit out some baseline, probably

didibus21:11:14

That makes sense, though, I think an automatic one would be much more useful. Generally, I don't care if its s or str, but I care that whichever it is is the same everywhere. So I'd expect that the first one someone uses would become the standard, as the next person to alias it would see the warning: Inconsistent alias, aliased as s in foo And so they'd fix their inconsistent usage. But I recon the added complexity of doing so due to needing info from other namespaces for it.

borkdude21:11:53

The problem is that this requires knowledge of an entire code-base, while linting only one file (in editor usage)

borkdude21:11:49

You can write such a linter yourself based on the analysis output of course, but then you would not see it in your editor

borkdude21:11:53

Maybe useful for CI

didibus21:11:42

Hum, ya that's fair. Not something the cache could make use of?

borkdude22:11:19

We could write to a special cache file that this linter could read from which would be an index of namespace (clojure.string) -> frequency table of aliases, or something? I haven't thought this through in detail, but feel free to think more about it.

👍 3
didibus22:11:30

Seed is planted 😛 Its not my most important concern, just thought about it as I was reading on the linter

seancorfield22:11:08

Re: namespace aliases -- is there a linter for sanity-checking the alias (in the absence of configuration) based on the common guideline that a namespace should be aliased to the last segment of its name (if that wouldn't be ambiguous in a file)?

seancorfield22:11:39

Is that a common enough guideline to be worth implementing?

seancorfield22:11:10

Obviously there are exceptions (`clojure.spec.alpha :as s` and clojure.string :as str are the most common I've seen in books and tutorials and it seems that datomic.client.api :as d is canonical).

seancorfield22:11:36

Maybe some built-in (overridable) defaults for common nses?

borkdude22:11:24

yeah, there could be some predicate (that can be executed with sci) to determine the desired alias

borkdude22:11:38

with a good built-in default predicate

borkdude22:11:57

the linter already supports a config, which would be the overrides

borkdude22:11:21

> is there a linter for sanity-checking the alias No > Is that a common enough guideline to be worth implementing? Possibly

borkdude22:11:57

I tend to do edamame.core :as e as well

borkdude22:11:25

or sci.core :as sci, so I think it would maybe be hard to come up with a predicate that would satisfy the entire community

borkdude22:11:09

Also, the function would have to give a unique answer for a given lib. What if there is already an e in the config, what would it recommend: ed, e2 ?

seancorfield22:11:19

I'll give it some thought, and see if I can come up with a good heuristic. In the presence of ambiguity -- either against the config or other aliases in the current ns -- just not running the check would seem to be the safest option.