Git Product home page Git Product logo

Comments (18)

jimka2001 avatar jimka2001 commented on June 12, 2024 1

without my fix, clj-kondo will treat calls such as (template a b ~c (x ~@y)) as a normal function call, and of course give inaccurate results. With my fix, cli-kondo will be able to lint code containing such calls to template.

Currently I have a fix in my own personal project. But any other user of your library might like to also be able to lint his code.

from backtick.

Invertisment avatar Invertisment commented on June 12, 2024 1

https://clojurians.slack.com/archives/CHY97NXE2/p1695300527633279

This is my config that I included into my project's .clj-kondo/config.edn:

{:lint-as
 {backtick/defquote clojure.core/def}
 :linters {:unresolved-symbol {:exclude [(backtick/template)]}
           :unresolved-var {:exclude [backtick/template]}}}

It's a little naive and my needs were basic but this worked for me.

from backtick.

jimka2001 avatar jimka2001 commented on June 12, 2024

added first commit in proposed fix: 06f8a33

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

I'm not at all familiar with clj-kondo. What does it mean for a macro to be not compatible with it? What does the proxy macro do differently than the normal macro?

from backtick.

jimka2001 avatar jimka2001 commented on June 12, 2024

See: https://github.com/clj-kondo/clj-kondo

So clj-kondo is a static code analyzer. It does not fully support macros implemented in user code. As I understand (I'm not an expert) it avoids expanding macros, because that would be executing untrusted code. However, users can request particular macros to be expanded in sort of a sandbox.

To do this, there must be a copy of the macro code somewhere. In the simplest case this can be an exact copy. but for more complex macros (such as template) some massage has to be done. For example, clj-kondo's macro expander cannot handle explicit references to java classes. The template code has a line like (instance? x Boolean) which fails. I have changed this to (boolean? x). However, in order for template to be compatible with old clojure code, it cannot directly call the boolean? function. Alas, so you cannot update template to use boolean? if I understand correctly.

So what is the proxy macro? It basically tells clj-kondo, when you need to expand the macro, use this code to expand, even if the runtime expansion is very different. The proxy expander has to be similar enough to enable static checks, but need not be exact enough to maintain semantics.

I hope that helps, and doesn't make it more confusing.

from backtick.

borkdude avatar borkdude commented on June 12, 2024

@brandonbloom @jimka2001 already explained it quite well. Clj-kondo is a static analyzer / linter for Clojure and doesn't actually execute your code, it just analyzes it. A recent feature got added that allows macro-expansion in an interpreter.
More info here: https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md#macroexpand

Users can configure this in their own projects, but it's also possible to move this config to the library itself, so it will be automatically copied when you lint the library.
More info here: https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md#exporting-and-importing-configuration

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

OK, I now understand the context, and can have an intelligent conversation about the specific issue :) Thanks.

The template code has a line like (instance? x Boolean) which fails.

Where? I don't see an explicit boolean check here: https://github.com/brandonbloom/backtick/blob/b927924949a86eb3706dec3f6c224ff79b1de7ae/src/backtick.clj

However, in order for template to be compatible with old clojure code, it cannot directly call the boolean? function. Alas, so you cannot update template to use boolean? if I understand correctly.

There is no such constraint. Given Clojure's strong commitment to backwards compatibility, I'd be totally OK using a Clojure 1.9-only function. If for some reason, folks can't upgrade to Clojure 1.9, they can use an old version of backtick too.

it's also possible to move this config to the library itself, so it will be automatically copied when you lint the library

My strong preference would be to not have to include any Kondo-specific code or configuration in my projects. However, if there is some small tweak I can make to the code to make it friendlier to a static analyzer, I'd be happy to consider it.

from backtick.

borkdude avatar borkdude commented on June 12, 2024

My strong preference would be to not have to include any Kondo-specific code

Note that the config lives in a separate directory resources/clj-kondo.exports and doesn't force you to use clj-kondo in whatever way. But I understand and respect that stance.

@jimka2001 Feel free to PR the config to https://github.com/clj-kondo/config if you want.

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

I assume https://github.com/clj-kondo/config is akin to https://github.com/DefinitelyTyped/DefinitelyTyped ? That's one of the bits of the TypeScript ecosystem that works quite well & seems like the appropriate solution here in the absence of improvements to Kondo's analyzer. However, as mentioned, if a small change is possible on my end to workaround a need for prohibitive analyzer complexity, I'd consider it.

@jimka2001 Where did you find that copy of the backtick code? It does not match this repository and it has someone elses' copyright on it:

Copyright (c) 2021 EPITA Research and Development Laboratory

I've neglected to put a LICENSE on this code (which I will now remedy), so whoever copied it did so without permission (though I would have provided it).

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

Ah, correction, it was mentioned as EPL v2 in the README as per the Lein template. I've now added a LICENSE file, so I guess the new copyright on top is within the constraints of the license, although should probably also carry a line including my copyright, but I don't really care all that much.

from backtick.

jimka2001 avatar jimka2001 commented on June 12, 2024

I think the backtick code I started with is what I got from M-. in cider.

I removed the type-hints such as

(defn- var-symbol [^clojure.lang.Var v]
  (symbol (var-namespace v) (var-name v)))
;; vs
(defn- var-symbol [ v]
  (symbol (var-namespace v) (var-name v)))

used predicate functions

 (instance? java.lang.Class x) (class-symbol x)
        (instance? clojure.lang.Var x) (var-symbol x)
vs
        (class? x) (class-symbol x)
        (var? x) (var-symbol x)

I also removed references to particular exception classes which clj-kondo could not handle.

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

If you want to submit a PR to backtick that uses functions from clojure.core, happy to accept those. Same for using (throw (ex-info ...)) instead of (throw (Exception. )). But it seems like clj-kondo should be able to safely ignore type hints at least.

However, sounds like getting these changes added to backtick won't actually help you, since somehow some fork of backtick is in cider. I'm not a cider user, so somebody would have to track down where and why that fork happened if they want to upstream whatever fixes they introduced too. Let me know how I can help.

from backtick.

jimka2001 avatar jimka2001 commented on June 12, 2024

Agree, that clj-kondo should be able to ignore type hints, even ones it does not understand.

I don't think the version of backtick is a cider issue. I have the following line in my project.clj file

(defproject clojure-rte "0.1.0-SNAPSHOT"
  ...
  :dependencies [ ...
                 [backtick "0.3.4"]
                 ...]
...)

I don't really understand the use of fixed version numbers. What version number should I be using?

from backtick.

borkdude avatar borkdude commented on June 12, 2024

Even if the clj-kondo interpreter would ignore your type hints, you would still have copy your macro to the config, so this isn't really solving the original problem of this issue: finding a home for the config.

from backtick.

brandonbloom avatar brandonbloom commented on June 12, 2024

I'm going to close this issue for the following reasons:

  1. There is a workaround in the form of the global clj-kondo registry.
  2. I don't want to add kondo-specific config to backtick.
  3. Even if I did, it wouldn't help you, as you're somehow hitting some fork I don't maintain.
  4. Backtick is a very simple macro and kondo can probably be easily extended to support it without modification to the code itself.

Feel free to open new issues if you want to help resolve item (3) or if you think there are small changes to backtick that would resolve cases where item (4) is not true.

Thanks!

from backtick.

Invertisment avatar Invertisment commented on June 12, 2024

I have a question. Would it be possible to lint the template macro as syntax-quote?
Does the behavior differ that much?

from backtick.

jimka2001 avatar jimka2001 commented on June 12, 2024

from backtick.

borkdude avatar borkdude commented on June 12, 2024

You can lint code as syntax code in clj-kondo by writing a hook that creates a node with :tag :syntax-quote:

https://github.com/nextjournal/clerk/blob/0dae460df026080b1b3c923784af579ce7a6bc00/resources/clj-kondo.exports/nextjournal/clerk/nextjournal/clerk/viewer.clj_kondo#L11

I don't know how backtick differs from regular syntax-quote but perhaps this is better than nothing.

from backtick.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.