当前位置: 首页 > 知识库问答 >
问题:

Clojure循环/重复模式,使用不好吗?

田翰林
2023-03-14

我正在学习Clojure,我正在使用4Clojure作为资源。我可以在网站上解决许多“简单”的问题,但是对我来说,以函数式编程的思维方式思考仍然不是自然而然的(我来自Java)。因此,我在大多数seq构建实现中使用循环/重复迭代模式,因为这是我习惯的思维方式。

然而,当我从更有经验的Clojure用户那里看到答案时,他们会以一种更实用的方式做事。例如,在一个关于实现范围函数的问题中,我的答案如下:

(fn [start limit]
  (loop [x start y limit output '()]
    (if (< x y)
      (recur (inc x) y (conj output x))
      (reverse output))))

当这起作用时,其他用户做了这样的事情:

(fn[xy](take(-yx)(iterate inc x))

我的函数更加冗长,我甚至不知道“迭代”函数的存在。但从效率的角度来看,我的答案更糟吗?循环/重复使用是否比其他方法更糟糕?我担心这类事情将来会在我身上发生很多,因为还有很多像iterate这样的函数我不知道。

共有3个答案

羊舌诚
2023-03-14

问题不应该是性能(这取决于!)但是关于交流:当使用循环/递归或普通递归或惰性序列或有时甚至减少时,你会让你的代码更难理解:因为读者必须先了解你如何执行迭代,然后才能理解你在计算什么。

蓬长恨
2023-03-14

为Clojure Cheetsheet网站添加书签,并始终打开浏览器选项卡。

学习所有函数,尤其是阅读它们链接到的示例(http://clojuredocs.org网站)。

网站http://clojure-doc.org也很有用(是的,两个名字几乎相同,但不完全相同)

公冶智刚
2023-03-14

第二个变量返回一个惰性序列,这可能确实更有效,尤其是在范围较大的情况下。

另一件事是,第二种解决方案更好地传达了这个想法。换句话说,它描述的是意图,而不是实现。与代码相比,理解它所需的时间更少,在代码中,你必须通读循环体并在头脑中建立控制流模型。

关于新函数的发现:是的,您可能事先不知道已经定义了一些函数。比如说,在Haskell中更容易,你可以通过类型签名搜索函数,但是通过一些经验,你将学会识别这样的函数编程模式。您将编写与第二个变体类似的代码,然后在标准库中查找类似于takeiterate的代码。

 类似资料:
  • 问题内容: 我想创建一个新的对象数组,将两个较小的数组放在一起。 它们不能为null,但大小可以为0。 我无法在这两种方式之间进行选择:它们是等效的还是效率更高的(例如system.arraycopy()复制整个块)? 要么 唯一的区别是代码的外观吗? 编辑: 感谢链接的问题,但他们似乎有一个未解决的讨论: 是否真的更快:byte [],Object [],char []?在所有其他情况下,都将执

  • 在我的程序中,我发现当为时,循环无法正确退出。它看起来像整数溢出,远远大于10,循环不会停止。请告诉我发生了什么,以及如何在大型项目中避免这个错误。 代码链接

  • 以上将给出以下随机输出: 任务很简单:确保每个promise只在另一个promise之后运行()。 由于某种原因,我找不到一个方法来做这件事。 我尝试了生成器函数(),尝试了返回promise的简单函数,但最终都归结为同一个问题:循环是同步的。 对于async,我只需使用。 你怎么解决?

  • 我正在制作一个基于文本的冒险游戏,我需要进行一些用户输入验证 我已经为这个特定实例设置了循环,但在输入正确的输入后,我似乎无法使循环中断。 代码: 我的输出是这样的: 你的选择是敲打还是猛击。别那么粗鲁。 大满贯 你猛地撞上沉重的橡木门,沉重的铁铰链砰的一声让位了。当你凝视城堡的第一个房间时,灰尘落在你的头上。大厅大约有五十英尺长。西墙有三扇门,东墙有两扇门。空气中弥漫着霉菌、湿气和铁的味道。曾经

  • 我需要使我的输出像预期的输出一样。我试图添加符号,但输出不像预期的输出 这是我的代码:

  • 本质上,我正在创建自己的字符串类,名为MyString。在这个类中有一个名为getline的函数,它的执行应该和字符串类的getline函数完全一样。 但是经过测试,当函数到达空字符或指定的分隔符时,它似乎不会退出循环,而是不断提示输入,并将该输入添加到已经存在的字符串(c-string)中。 我已经解决了我的上一个问题,但现在我的主服务器在我最后一次getline调用后关闭。