eastwood

All things realted to eastwood - the Clojure linter
slipset 2019-07-13T08:16:19.115100Z

What I figured I can have a look at is which macros are being expanded, and marking some of them as safe from fiddling with ns’s. I’d imagine that let/and/or, and a bunch of other core macros should fall into this category.

slipset 2019-07-13T20:56:59.115300Z

This shows promise:

slipset 2019-07-13T20:57:02.115600Z

(def ns-safe-symbol #{#'clojure.core/fn
                      #'clojure.core/defn
                      #'clojure.core/defn-
                      #'clojure.core/let
                      #'clojure.core/delay
                      #'clojure.core/when
                      #'clojure.core/when-let
                      #'clojure.core/or
                      #'clojure.core/and
                      #'clojure.core/->>
                      })

(defn macroexpand-1
  "If form represents a macro form or an inlineable function,returns its expansion,
   else returns form."
  ([form] (macroexpand-1 form (empty-env)))
  ([form env]
     (env/ensure (global-env)
       (cond

        (seq? form)
        (let [[op & args] form]
          (if (specials op)
            form
            (let [v (resolve-sym op env)
                  m (meta v)
                  local? (-> env :locals (get op))
                  macro? (and (not local?) (:macro m)) ;; locals shadow macros
                  inline-arities-f (:inline-arities m)
                  inline? (and (not local?)
                               (or (not inline-arities-f)
                                   (inline-arities-f (count args)))
                               (:inline m))
                  t (:tag m)]
              (cond

               macro?
               (let [res (apply v form (:locals env) (rest form))] ; (m &form &env & args)
                 (when-not (ns-safe-symbol v)
#_                   (println "symbol" v)
                   (update-ns-map!))
                 (if (obj? res)
                   (vary-meta res merge (meta form))
                   res))

               inline?
               (let [res (apply inline? args)]
                 (update-ns-map!)
                 (if (obj? res)
                   (vary-meta res merge
                              (and t {:tag t})
                              (meta form))
                   res))

               :else
               (desugar-host-expr form env)))))

        (symbol? form)
        (desugar-symbol form env)

        :else
        form))))

slipset 2019-07-13T20:59:09.116Z

That’s from analyzer/jvm.clj

slipset 2019-07-13T21:14:53.116300Z

This is the count of macros in our project:

slipset 2019-07-13T21:15:08.116400Z

slipset 2019-07-13T21:16:28.117800Z

So given that let doesn’t alter the namespace (which I don’t think it does), I could save 20586 calls to build-ns-map