iGEL
iGEL

Reputation: 17392

Clojure: Recur anonymous function with different arity

Similar to Clojure recur with multi-arity I'd like recur with a different arity. But in my case, I define the function via a let, as I want to use another value from the let (file-list) without passing it:

(let [file-list (drive/list-files! google-drive-credentials google-drive-folder-id)
      download-file (fn
                      ([name]
                       (download-file ; <-- attempt to recur
                         name
                         (fn []
                           (throw
                             (ex-info
                               (str name " not found on Google Drive"))))))
                      ([name not-found-fn]
                       (if-let [file (->> file-list
                                          (filter #(= (:original-filename %)
                                                      name))
                                          first)]
                         (drive/download-file! google-drive-credentials file)
                         (not-found-fn))))]
  ;; #
  )

I get this error: Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: download-file in this context

Upvotes: 2

Views: 724

Answers (2)

Alan Thompson
Alan Thompson

Reputation: 29958

In order to make more readable exception error messages, I often append -fn to the inner function name, like so:

(let [download-file (fn download-file-fn [name] ...) ]
   <use download-file> ...)

Upvotes: -1

Lee
Lee

Reputation: 144136

You can give a local name to the fn:

(let [download-file (fn download-file
                      ([name] (download-file name (fn ...))))

you could also use letfn:

(letfn [(download-file
          ([name] (download-file name (fn ...)))
          ([name not-found-fn] ...)])

Upvotes: 4

Related Questions