Clojure中的代码顺序

Clojure中的代码顺序,clojure,Clojure,在Clojure中我有一个简单但令人沮丧的问题,我有一个函数(我们称之为read函数),它从用户的输入中找出用户想要做什么,然后调用另一个函数(我们称之为action函数)。此操作函数在完成时调用read函数,以便用户可以执行其他任务 现在我的问题是,如果我把read函数的代码放在action函数的代码之前,我会在read函数中得到一个错误,说它不知道action函数是什么(因为它的代码在下面),如果我做相反的事情,我会得到一个类似的错误,很明显,说read函数不能被解析等等 有没有简单的方法来

在Clojure中我有一个简单但令人沮丧的问题,我有一个函数(我们称之为read函数),它从用户的输入中找出用户想要做什么,然后调用另一个函数(我们称之为action函数)。此操作函数在完成时调用read函数,以便用户可以执行其他任务

现在我的问题是,如果我把read函数的代码放在action函数的代码之前,我会在read函数中得到一个错误,说它不知道action函数是什么(因为它的代码在下面),如果我做相反的事情,我会得到一个类似的错误,很明显,说read函数不能被解析等等

有没有简单的方法来解决这个问题

实际代码:

(defn ajout [botin]
  (def botin botin)
  (readCmd botin)
)

(defn readCmd [botin]
  (println "Entrez une commande svp ")
  (def botin botin)
  (let [cmd (read-line)]
    (if (.equals cmd "a") ((println "Ajout 8o") (ajout botin))
      (if (.equals cmd "e") ((println "Elim 8o") (eliminer botin))
        (if (.equals cmd "i") ((println "Imprim 8o") (imprimer botin))
          ((println "Commande invalide, nous vous rapellons que les commandes possibles sont : ") (print-les-cmd) (readCmd))))))


)
像这样,我在ajout函数的(readCmd botin)行中得到一个错误,它说: 无法在此上下文中解析符号:readCmd

如果我将这两个函数的代码按相反的顺序放置,我将得到一个错误,即:
无法解析此上下文中的symbol:ajout在代码顶部放置:

(declare readCmd)

您可以在Clojure中使用前向声明,以便调用尚未定义的函数

(declare readCmd)
应该有用


在Clojure中,定义函数的顺序很重要,一个函数不能调用另一个尚未定义的函数(或任何其他函数)。这就是为什么我们有转发声明。

正如其他人已经回答的那样,您需要(declare readCmd)来解决眼前的问题

然而,这段代码仍然存在一些问题,因为它实际上使用相互递归(readCmd->ajout->readCmd->imprimer->readCmd->>…)实现了迭代过程,这将消耗堆栈,并且会导致堆栈溢出。更好的组织方法是使readCmd tail递归,并使其调用操作。当操作返回时,readCmd tail递归地调用自身

还有以下代码段:

((println "Ajout 8o") (ajout botin))
这可能不是您想要做的:它将调用println并尝试将结果用作函数。使用“do”代替:

你也可以考虑阅读案例或COND,他们将简化嵌套IFS。

关于代码的另一件奇怪的事情是

(def botin botin)

这是关于什么的?

Clojure google group上有一条关于这一点的线索,提供了一些有趣的注意事项,特别是关于declare的使用如何使生态系统中的一些工具出错:

当然,您可能会争辩说,好的工具应该适用于该语言的所有结构:)

在我看来,你有点习惯了自下而上的风格,只需反向阅读即可。这是一个有点不同的故事,你在讲你建立的东西,而不是分解它们

当然,正如其他人所说,您可以使用

(declare my-function)

你能不能发布一个简单的代码示例来说明什么是不起作用的。这有助于追踪问题。当然——代码开始——(defn add[book](函数书中的def book)(函数书中的readCmd book))(defn readCmd[book](println“Enter cmd”)(函数书中的def book)(let[cmd(read line)](if(.equals cmd“add”)((println“Adding”)(函数书中的add book))(println“不知道”)---代码结束---如果我这样写,我将无法解析symbol:readCmd在这个上下文中位于add函数中的read cmd调用行如果我将这两个函数按相反的顺序放置,我将得到一个类似的错误,但是对于read cmd函数中的add函数,我在看到注释后编辑了原始帖子:)Upvoted,因为我知道人们将来会用谷歌搜索这个!好问题!@ErrorUserName和Pascal/Modula-2/Oberon单通道编译器。加上一个变化……这是编写Clojure对我来说最糟糕的事情之一。我喜欢这种语言,但它似乎添加了不必要的bolilerplate。编译器可以隐式地这样做。嗯,必须这样做通常是一种非常难闻的代码味道,所以我对此很满意。这增加了问题的复杂性,不需要前向声明就可以用更简单的方式解决。Rich Hickey关于“clojure编译器为什么是单通的”:
(declare my-function)