将函数放在Clojure映射中是不是一个坏主意,就像在JavaScript中一样?

dan*_*dan 10 functional-programming clojure

我是Clojure的新手并找到了我的海腿.我想知道从功能编程的角度来看,将函数放在Clojure映射中,然后将这些映射像准对象一样传递,就像在JavaScript中经常做的那样,是否认为它是好的还是坏的.解释也将不胜感激.

Joh*_*den 8

如果它使您的代码更短或更容易理解,或测试或调试,请执行此操作.

或者如果你愿意的话.相信你的判断.


Stu*_*rra 7

Clojure的多种方法本质上是函数的映射,所以不,这根本不是一个坏主意.


Gor*_*vic 6

由于以下几个原因,这会很糟糕:

  1. 没有必要 - 在JavaScript中,我们这样做是为了将简单的地图用作类似Java的对象.在Clojure中,如果您真的想这样做,可以通过Java互操作使用实际的Java对象.
  2. 无论是将函数放在映射中还是使用真正的Java对象,您都在为函数式编程设计的语言环境中进行面向对象编程.随之而来的首要问题是您的代码不适合.它在Clojure中看起来很奇怪,笨拙甚至可能太复杂.在这一点上,我并不是说OOP一定是坏的,只是最好用为它设计的语言编写OOP.
  3. 反对这种编码风格的最重要的一点是,类似OOP的程序将不可避免地依赖于具有某种状态的对象,以及它们改变该状态的成员函数(有点像方法).如果您正在使用状态,那么您的功能并不纯粹,您无法使用所有功能优点,如简单的并行化.

长话短说,如果你使用Clojure做OOP,你只会生气.你可以用很多其他语言轻松地做OOP,比如说Groovy.如果你确实想使用Clojure,那么就可以使用它.

到目前为止,我写道不要这样做,为什么不这样做.现在您可能会问我:那么,我应该如何在Clojure中编写函数?

编写将您的数据结构(即地图,列表,对象......等)作为参数的函数.所以,而不是:

 foo.bar();
Run Code Online (Sandbox Code Playgroud)

您可以这样定义:

 (defn bar [foo]
   ;stuff
   ) 
Run Code Online (Sandbox Code Playgroud)

并称之为:

  (bar foo)
Run Code Online (Sandbox Code Playgroud)

现在,对于纯函数bar,foo在函数求值之后对象没有改变,如果你决定并行化你的代码,你就不必担心对象的共享状态,如果你以OOP的方式做事,你会有这种状态.

此外,它可能看起来像一个小差异,但请注意,bar函数定义是一个完全独立于数据结构的实体foo.此外,foo仅包含数据,而不包含行为 - 所有行为都在函数中.这种分离在编码时为您提供了更大的自由度.