Clojure中的代码顺序

我有一个简单而令人沮丧的问题在Clojure中,我有一个函数(让我们把它称为读函数),它能够计算出用户想从他的input中做什么,然后调用另一个函数(我们称之为动作函数)。 这个动作函数在完成后调用读取函数,以便用户可以执行另一个任务。

现在我的问题是,如果我把动作函数代码之前的读函数的代码,我得到一个读函数的错误,说它不知道什么动作函数是(因为它的代码是进一步下来),如果我做相反的事情,那么我明显得到一个类似的错误,说阅读function不能解决等。

有一个简单的方法来解决这个问题吗?

实际的代码:

(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)行中得到一个错误:无法parsingsymbol:readCmd在这个上下文中

如果我把这两个函数的代码以相反的顺序,我会得到一个错误:在这个上下文中无法parsing符号:ajout

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

 (declare readCmd) 

应该pipe用!

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

正如其他人已经回答,你需要(宣布readCmd)来解决你的眼前的问题。

然而,这个代码仍然存在问题,因为它实际上是使用相互recursion(readCmd – > ajout – > readCmd – > imprimer – > readCmd – > …)来实现迭代过程,这会消耗堆栈,您将得到上)堆栈溢出。 一个更好的方式来组织这个,将是使readCmd尾recursion,并使其调用操作。 当一个动作返回时,readCmd尾recursion地调用它自己。

此代码片段:

 ((println "Ajout 8o") (ajout botin)) 

可能不是你想要做的:它会调用println,并尝试使用结果作为一个函数。 用“do”代替:

 (do (println "Ajout 8o") (ajout botin)) 

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

你的代码另一个奇怪的事情是

 (def botin botin) 

这是关于什么?

在你的代码的顶部放:

 (declare readCmd) 

Clojure谷歌小组有一个关于这个的话题,提供了一些有趣的考虑,特别是关于如何使用declare可以使生态系统中的某些工具绊倒:

线

当然,你可能会认为好的工具应该与语言的所有结构一起工作:)

国际海事组织,你习惯了自下而上的风格,只是反向阅读。 这是一个不同的故事,告诉你在哪里build立起来而不是分解它们。

当然,正如其他人所说,你可以转发声明

 (declare my-function)