Search code examples
clojuredefn

clojure - defn/def in function body or let statements


user=> (defn make-list [] '(1 2 3))
#'user/make-list
user=> (defn get-list [] (map #(str "foo" % ) make-list))
#'user/get-list
user=> (get-list)
IllegalArgumentException Don't know how to create ISeq from: user$make-list  clojure.lang.RT.seqFrom (RT.java:505)
user=> (defn get-list [] (let [ml (make-list)] (map #(str "foo" % ) ml) ))
#'user/get-list
user=> (get-list)
("foo1" "foo2" "foo3")

Why can the value from defn not be accessed in the same way from the BODY of a function as it can from the LET clause?


Solution

  • defn declares a function so you need to invoke it in order to get its result:

    (defn make-list [] '(1 2 3))
    (defn get-list [] (map #(str "foo" % ) (make-list)))
    (get-list)
    
    ;; ("foo1" "foo2" "foo3")
    

    But since your makeList function doesn't do anything but return a list, you can use def instead as it simply declares a var:

    (def make-list '(1 2 3))
    (defn get-list [] (map #(str "foo" % ) make-list))
    (get-list)
    
    ;;("foo1" "foo2" "foo3")
    

    Lastly, use kebab-case instead of camelCase for function and var names in Clojure. That's the convention unless you're declaring Protocols or Types.