我是Clojure的新手并找到了我的海腿。我想知道从功能编程的角度来看,将函数放在Clojure映射中,然后将这些映射像准对象一样传递,就像在JavaScript中经常做的那样,是否认为它是好的还是坏的。解释也将不胜感激。
答案 0 :(得分:8)
这样做,如果它使您的代码更短或更容易理解,或测试或调试。
或者如果你愿意的话。相信你的判断。
答案 1 :(得分:7)
Clojure的多种方法本质上是函数的映射,所以不,这根本不是一个坏主意。
答案 2 :(得分:6)
由于以下几个原因,这会很糟糕:
长话短说,如果你使用Clojure做OOP,你只会生气。你可以用很多其他语言轻松地做OOP,比如说Groovy。如果你确实想要使用Clojure,那么就可以使用它。
到目前为止,我写道不要这样做,为什么不这样做。现在您可能会问我:那么,我应该如何在Clojure中编写函数?
编写将数据结构(即地图,列表,对象......等)作为参数的函数。所以,而不是:
foo.bar();
您可以这样定义:
(defn bar [foo]
;stuff
)
并称之为:
(bar foo)
现在,对于纯函数bar
,foo
对象在函数求值后保持不变,如果您决定并行化代码,则不需要担心对象的共享状态如果你以OOP的方式做事,你会有的。
此外,它可能看起来很小,但请注意bar
函数定义是一个完全独立于数据结构foo
的实体。此外,foo
仅包含数据,而不包含行为 - 所有行为都在函数中。这种分离在编码时为您提供了更大的自由。
答案 3 :(得分:4)
它有效 - 从某种意义上说,如果你将函数视为语言中的第一类对象(正如所有函数式程序员所应该的那样),这是很自然的。)
然而 - 它需要真正关心,因为你基本上做的是用数据交错代码。这就像将数据模型与MVC中的表示代码混合在一起。是的,可能在某些情况下它是有意义的,但一般原则是避免它。
经过大约一年的Clojure,我慢慢收敛的风格是:
这解决了太阳下的大多数事情,我还想弄清楚的一件事是创建具有高度多态行为的对象的最佳方法。我能看到的主要选项是:
还没有找到哪条路.....但我有预感,功能可能会在未来潜入地图......
答案 4 :(得分:2)
如果你真的需要在Clojure中进行面向对象编程,有几种方法可以做到。
第一种方法是使用deftype
,defrecord
和defprotocol
系列宏。
第二种方法是使用多方法,结合地图或记录类型进行数据存储。
第三种方法是使用Steve Yegge概述的通用设计模式,或者在Chris Houser和Michael Fogus的书The Joy of Clojure中找到更多Clojure特定的介绍。
第三种方法与您在JavaScript中所期望的非常类似,第一种方法虽然没有被认为是传统意义上的OOP,但却是“现代”惯用语中最常见的方法。
答案 5 :(得分:1)
命名空间实际上是函数的映射。使用它们来组织你的功能要简单得多。但是,如果您遇到用例的命名空间限制,可以考虑将函数放在映射中。
像往常一样,当你走出人迹罕至的地方时,一定要认真思考为什么你不会走这条明显的路线。