问题 不能取宏的价值(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行在上面评论。

知道问题是什么吗?


1914
2018-04-22 00:43


起源

@Svante:我很抱歉,但我正在上课,希望我每周学一门语言,然后在里面写一个广泛的课程。我之前从未使用过Lisp,因此我很穷。教授没有上班时间,或者我会去那里。
每当我尝试新的东西时,我都无法学习基础知识而不会以类似于猎枪编程的方式重复应用基础知识。我经常误用学习基础或应用不正确的推断学习。当我这样做时,有时需要花费大量时间来解决问题,但我已经学会了基础知识。然后我通常尝试一些新的东西。 - dansalmo
在C你可以做到 #define X 4 并在随后的一行 bar = X; 最终得到代码 bar = 4; 但在Clojure你会做更多的事情 (defmacro X [] 4) 和其他地方 (let [bar (X)])。所以在最简单的情况下,在Clojure中有一些额外的工作,但在最困难的情况下......好吧,你根本无法用C预处理器做这些事情。 - Purplejacket


答案:


你需要实际调用宏,

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

8
2018-04-22 01:08



它是lisp的anwser,但它周围的parens :) - nickik


(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. 你周围没有parens with-open。这将是一个正常的符号,它不被称为。
  2. 您的let中的表单数量不一致。你有r,res aund(doall ...)。你已经在with-open中为'r'做了正确的绑定。所有你需要的是

    (让[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一样,你会让你的生活更轻松。


7
2018-04-22 11:28





要在看到此错误时添加到调试工具包中,我建议您查找正在定义或调用的函数,而不要使用左括号'('。

在您的特定情况下,正如其他答案已经注意到的那样,您的代码缺少'('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))]

你没有打开电话,而是接受它的价值。

我的错误如下:

--> 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之前。


1
2018-05-08 15:48