tools-deps

mwolf 2024-06-02T17:16:00.549389Z

what's the typical method for resolving symbols read from deps.edn? suppose I had the following in deps.edn -- evil-inc/revenge is an API which takes an option map (containing :plot-fn and :plot-args fields) as an argument:

{:aliases {:hax {:exec-fn evil-inc/revenge,
                 :exec-args {:plot-fn evil-inc/take-over-world,
                             :plot-args {:scheme "ai-bot-swarm"}}}}}
... and in evil_inc.clj:
(defn revenge [{:keys [plot-fn plot-args]}]
  ;; `plot-fn' is a *symbol* here -- 'evil-inc/take-over-world -- not the actual `take-over-world' function
  (let [{:keys [scheme]} plot-args]
    (plot-fn scheme)))
given the command line clj -X:hax the clojure cli code correctly resolves :exec-fn to the revenge fn in the evil-inc namespace, but :exec-args contains {:plot-fn 'evil-inc/take-over-world} -- the symbol rather than the function -- and the call (plot-fn scheme) breaks. is there a better method for resolving symbols read from a deps file than splattering (resolve x) calls everywhere a fn is used? (actually, I'd probably go with (defn maybe-resolve [x] (if (symbol? x) (resolve x) x)) ... but that still seems too inelegant)

Alex Miller (Clojure team) 2024-06-03T12:26:21.392329Z

This would be general reader functionality

aisamu 2024-06-02T17:36:09.185499Z

Perhaps worth noting: :ns-default might throw a wrench on a simple resolve call

seancorfield 2024-06-02T18:10:24.679179Z

:ns-default isn't going to affect how the :exec-args are handled, only how the CLI itself resolves the function name (symbol) on the command-line.

seancorfield 2024-06-02T18:15:41.459859Z

Inside your own code @mbarillier yes, you'll need resolve to turn a symbol into a Var (and therefore a function, if it is defn'd). You probably want requiring-resolve to allow for it to be in a different namespace that has not yet been loaded. The :exec-args are just EDN data, so it's entirely up to the program how to process that data, so it should have full knowledge of the data. It's typically for -X-invoked functions to be an API that maps data (EDN) to Clojure, and part of that is requiring namespaces and resolving functions. If :plot-fn is intended to be treated as a function, then it's always going to come into your "exec API" as a symbol and you're always going to need to call requiring-resolve on it -- and then in general, your "exec API" would call into some internal function(s) passing in the fully-processed "exec args":

(defn revenge [args]
  (impl/revenge (update args :plot-fn requiring-resolve)))
(for example)

Alex Miller (Clojure team) 2024-06-02T18:46:16.302039Z

Agree with all that, but an aside - this is often a thing people run into and we’ve been thinking about making var quote rehydrate on read as one approach

👍 2
👍🏻 1
namenu 2024-06-03T06:30:00.031689Z

Is that only planned for :exec-args? We have #var tagged-literals extensively in our edn files and read them with {:readers {'var requiring-resolve}} option. It's not a huge hassle, but it would be nice to have it built in.