Не может принимать значение макроса (clojure) - PullRequest
11 голосов
/ 22 апреля 2011

В этом сегменте кода 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 прокомментирована выше.

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

Ответы [ 3 ]

8 голосов
/ 22 апреля 2011

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

(defn makeStructs ;line 27
 "..."
 [fName]
   (with-open ; note the extra paren
7 голосов
/ 22 апреля 2011
(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
  ) 
)

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

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

    (let [res (doall (map makeStruct (line-seq r))))] ...)

  3. Почему вы делаете (. r close) макрос with-open делает это для вас здесь: 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, и вы упростите свою жизнь.

1 голос
/ 08 мая 2012

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

В вашем конкретном случае, как уже отмечалось в других ответах, в вашем коде отсутствует символ '(' в 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))

Вы можете увидеть пропавший '(' прямо перед определением.

...