Невозможно принять значение макроса (clojure)

В этом сегменте кода clojure:

(defn makeStructs ;line 27
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   with-open[r (reader (file fName))]
   (let [r 
      res (doall (map makeStruct (line-seq r)))
      ]    
  (. r close)
     res
  ) 
)

Я получаю эту ошибку компилятора:

Exception in thread "main" java.lang.Exception: Can't take value of a macro: #'clojure.core/with-open (clojureHW.clj:27)

Прочитана строка 27.

Любая идея, в чем проблема?

Ответ 1

Вам нужно называть макрос,

(defn makeStructs ;line 27
 "..."
 [fName]
   (with-open ; note the extra paren

Ответ 2

(defn makeStructs ;line 27
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   with-open[r (reader (file fName))]
   (let [r 
      res (doall (map makeStruct (line-seq r)))
      ]    
  (. r close)
     res
  ) 
)

Это не работает, потому что

  • У вас нет парнеров вокруг вашего with-open. Это будет обычный символ, который он не назвал.
  • У вас снова есть нечетное количество форм в вашем let. У вас есть r, res aund (doall...). Вы уже сделали правильную привязку для "r" в open-open. Все, что вам нужно, это

    (пусть [res (doall (map makeStruct (строка-seq r)))]....)

  • Почему вы делаете (. r close) с открытым макросом, который вы видите здесь: http://clojuredocs.org/clojure_core/clojure.core/with-open

Итак, вы получаете:

(defn makeStructs 
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   (with-open [r (reader (file fName))]
     (let [res (doall (map makeStruct (line-seq r)))]
        res)))

но поскольку у вас есть только одна вещь, пусть вам это действительно не нужно:

(defn makeStructs 
 "open fName as a file and turns each line into a struct. Returns a Vector of structs"
 [fName]
   (with-open [r (reader (file fName))]
     (doall (map makeStruct (line-seq r)))))

Lisp языки действительно просты, большинство программистов просто хотят сделать это тяжело для себя, потому что они привыкли это делать. Много вопросов у вас есть, потому что вы привыкли к вещам, работающим как X, но теперь они работают как Y. Старайтесь не предполагать, что все работает как X, и вы сделаете свою жизнь проще.

Ответ 3

Чтобы добавить в сумку инструмента для отладки, когда вы видите эту ошибку, я предлагаю вам искать функцию, определяемую или вызываемую без открытой скобки '('.

В вашем конкретном случае, как уже отмечали другие ответы, в вашем коде отсутствует '(' at with-open.

(defn makeStructs ;line 27
 "open fName as a file and turns each line into a struct. 
  Returns a Vector of structs"
 [fName]
-->   with-open[r (reader (file fName))]

Вы не вызывали с-open, но принимали его значение.

Моя ошибка выглядела следующим образом:

--> defn ret-col-match
    "Returns true false match on sequence position w/ cmp-val."

    [row cmp-val col-idx]
    (if (= (nth row col-idx nil) cmp-val)
        true
        false))

Вы можете увидеть отсутствующий '(' прямо перед defn.