Clojure 如何实现关注点分离?
Clojure 如何实现关注点分离?由于代码是数据,因此函数可以作为参数传递并用作返回...
并且,由于有这样的原则“在 1 个数据结构上工作的 1000 个函数比在 100 个数据结构上工作的 100 个函数更好”(或类似的东西) 。
我的意思是,将所有内容打包成地图,给它一个关键字作为键,就这样?函数、标量、集合,一切……
关注点分离的思想是在 Java 中通过 Aspect(面向方面编程)和注释的方式实现的。这是我对这个概念的看法,可能有些局限性,所以不要认为这是理所当然的。
在 Clojure 中,避免其他程序员的 WTF 的正确方法(惯用方法)是什么?
How does Clojure approach Separation of Concerns ? Since code is data, functions can be passed as parameters and used as returns...
And, since there is that principle "Better 1000 functions that work on 1 data structure, than 100 functions on 100 data structures" (or something like that).
I mean, pack everything a map, give it a keyword as key, and that's it ? functions, scalars, collections, everything...
The idea of Separation of Concerns is implemented, in Java, by means of Aspects (aspect oriented programming) and annotations. This is my view of the concept and might be somewhat limited, so don't take it for granted.
What is the right way (idiomatic way) to go about in Clojure, to avoid the WTFs of fellow programmers _
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在函数式语言中,处理关注点分离的最佳方法是将任何编程问题转换为数据结构上的一组转换。例如,如果您编写一个 Web 应用程序,总体目标是获取请求并将其转换为响应,这可以被视为简单地将请求数据转换为响应数据。 (在一个重要的 Web 应用程序中,起始数据可能不仅包括请求,还包括会话和数据库信息)大多数编程任务都可以用这种方式来思考。
每个“关注点”都将是“管道”中的一个函数,有助于使转换成为可能。这样,每个功能都与其他步骤完全解耦。
请注意,这意味着您的数据在经历这些转换时,其结构需要丰富。本质上,我们希望将程序的所有“智能”放入数据中,而不是代码中。在复杂的函数式程序中,不同级别的数据可能足够复杂,以至于需要看起来像一种编程语言本身——这就是“特定于领域的语言”的思想发挥作用的地方。
Clojure 对操作复杂的异构数据结构具有出色的支持,这使得这比听起来更简单(即,如果做得正确的话,根本不麻烦)
此外,Clojure 对惰性数据结构的支持允许这些中间数据结构实际上(概念上) )的大小无限,这使得这种解耦在大多数情况下都是可能的。请参阅以下论文,了解为什么在这种情况下拥有无限数据结构如此有价值:http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf
这种“管道”方法可以处理 90% 的分离关注点的需求。对于剩下的 10%,您可以使用 Clojure 宏,从高层次来看,它可以被认为是面向方面编程的一个非常强大的工具。
这就是我相信您可以在 Clojure 中最好地解耦关注点的方式 - 请注意,“对象”或“方面”并不是这种方法中真正必要的概念。
In a functional language, the best way to handle separation of concerns is to convert any programming problem into a set of transformations on a data structure. For instance, if you write a web app, the overall goal is to take a request and transform it into a response, which can be thought of as simply transforming the request data into response data. (In a non-trivial web app, the starting data would probably include not only the request, but also session and database information) Most programming tasks can be thought of in this way.
Each "concern" would be a function in a "pipeline" that helps make the transform possible. In this way, each function is completely decoupled from the other steps.
Note that this means that your data, as it undergoes these transformations, needs to be rich in its structure. Essentially, we want to put all the "intelligence" of our program into the data, not in the code. In a complicated functional program, the data at the different levels may be complex enough that in needs to look like a programming language in its own right- This is where the idea of "domain-specific languages" comes into play.
Clojure has excellent support for manipulating complex heterogenous data structures, which makes this less cumbersome than it may sound (i.e. it's not cumbersome at all if done right)
In addition, Clojure's support for lazy data structures allows these intermediate data structures to actually be (conceptually) infinite in size, which makes this decoupling possible in most scenarios. See the following paper for info on why having infinite data structures is so valuable in this situation: http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf
This "pipeline" approach can handle 90% of your needs for separating concerns. For the remaining 10% you can use Clojure macros, which, at a high level, can be thought of as a very powerful tool for aspect-oriented programming.
That's how I believe you can best decouple concerns in Clojure- Note that "objects" or "aspects" are not really necessary concepts in this approach.