Reagent tooling

the reagent doc about creating components mentions i couple of rookie mistakes:

https://cljdoc.org/d/reagent/reagent/0.10.0/doc/tutorials/creating-reagent-components

for example using ( instead of [… or not repeating params…

        :reagent-render        ;; Note:  is not :render
         (fn [x y z]           ;; remember to repeat parameters
            [:div (str x " " y " " z)])})))

also… if you do actually get it wrong and use ( instead of [… well then you will get a nice warning, for example when calling that function with the wrong number of args, on the other hand if you do a proper vector / component, that trivial mistake becomes a bit harder to spot.

so basically my question is this: since i am totally guilty of screwing up by committing one or the other of those rookie mistakes every so often, well… i couldn’t help but to wonder if by any chance there is a linter or something out there… which could help a bit with these kinds of silly blunders.

I’m not aware of any reagent-specific linter, but I’ve been thinking about pluggable linters too, perhaps based on clj-kondo and sci?

The idea being that you could write some code that takes the AST as analysed by kondo, and return warnings.

I think you can build this today by using kondo as a library, but then you need to do the editor integration all over again.

1 Like

I think clj-kondo already supports custom linters. See here: https://github.com/borkdude/clj-kondo/blob/master/analysis/README.md

Yep, that’s the use case that I referred to as the “using clj-kondo as a library”. I was kind of referring of a way to use clj-kondo as a framework, where you define extra linters in user code and clj-kondo will invoke them and report errors as if they were built-in.

This way, I need on only setup clj-kondo once in my editors, and depending on the project I’m using I could add context-specific linters on top using configuration, without having to package my own tool.

Ah I see. I think the linters being compiled to native is part of the speed of clj-kondo. I wonder what the story is for dynamic loading in that case.

Maybe there could be some dynamic DSL that gets interpreted via @borkdude’s other project sci :slight_smile:

1 Like

A linter for Reagent “function” calls in vectors has been considered:

But there is no reliable way of detecting whether something is a vector as a function call or just a vector with some functions.

As for repeating args, I think that could be linted more accurately. I welcome an issue for this. Reagent is something I want to support out of the box with clj-kondo.

1 Like

The way helix handles this is by using a macro to do linting instead. If reagent moved towards not using defn directly, then it might be easier for external tools to hook detect the context switch as well.

It would be a lot easier for clj-kondo too to add some specific linting for reagent, if reagent had not chosen to use clojure.core/defn directly.

The likelihood that you have a vector with a symbol in first position which resolves to a function when you also have required reagent in the namespace, and that you wouldn’t be making a reagent call seems super low to me no?

You could make it an opt-in linter as well. Like opt-in to have reagent linting. So even the rare FP cases would only affect people using reagent.

And you could always fix the warn by using the var instead if you did want to create a vector with a function as first arg: [#'the-fn 1 2] I think.

1 Like

I have a lot of namespace with reagent components where I don’t explicitly require reagent though. Opt-in linter could be an option indeed.

Hum, okay, didn’t know this could be a usage pattern.