有 Clojure 原则吗?
Clojure 有什么原则吗?
a.就像 Java 等 OO 语言的 SOLID 面向对象设计原则 一样吗?
b.或者其他更具启发性的,例如“告诉而不是询问”、“倾向于组合与继承”、“与接口对话”?
是否有任何设计模式(针对灵活代码)?
函数式编程基础(如面向对象封装)的对应部分是什么?
知道这些资源吗?
Are there any Principles for Clojure ?
a. Like the S.O.L.I.D. Object-Oriented Design Principles for OO languages like Java ?
b. or others more heuristic, like "Tell don't ask", "Favor Composition vs Inheritance", "Talk to Interfaces" ?
Are there any design patterns (for flexible code) ?
What is the counter part of the basic of functional-programming like encapsulation for object-oriented ?
Know of any resources for these ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于你的第一个问题:不。 †
Clojure 可以帮助您正确、快速、愉快地完成工作。之后的一切都是肉汁。
而且还有很多肉汁。我不知道 Clojure 方式,即使有一种,但这里有一些我在用 Clojure 编写时被告知和发现的指导原则:
首先,让一些东西发挥作用。 然后您可以根据需要进行检查、测试和优化。
time
宏出现在核心语言中是有原因的。 正确性优先于快速性,要可爱。摘要。 如果你重复自己的话,那么你可能做得不对。组合、柯里化和组合函数。
将副作用与逻辑分开。例如,如果您想格式化并保存字符串,请在一个函数中对其进行格式化,然后使用另一个函数来保存它,无论您需要什么。
3a.不要对此太疯狂。有时,拥有一些匿名函数比一堆乱七八糟的单行 defn 更好。
测试。 Rich 给你 REPL 是有原因的;使用那个 REPL 吧。测试
不要让你的命名空间变得混乱。我们在 Clojure 领域很干净。限定您的
使用
或:仅
您需要的内容。让你的代码可读。了解核心库。不仅仅是
clojure.core
,还有clojure.java.io
、clojure.string
、clojure.set
以及所有内容之间。如果您认为 Clojure 应该有一个函数来执行 X 操作,那么它可能确实如此。您可以使用apropos
(来自,是的,另一个核心库:clojure.repl
)。记录您的代码。文档字符串是一件美丽的事情。如果您有啰嗦的倾向,那么文档环就是您放松的地方。但是,也要知道好的代码通常“记录自己”。如果代码是不言自明的,则无需迂腐。
这是一种函数式语言。 如果可以,请使用函数。协议、宏和记录都很棒:但是当您可以摆脱它们时,请使用函数。您可以组合、组合、映射、减少、迭代(列表不断,不断,不断……)函数。这真的很好。
最重要的是,如果有道理的话就打破上述规则。但要准备好重新思考和重构。如果您的代码足够模块化,那么重构代码应该是重新组织和重新组合的问题。
其他一些提示:阅读其他人的代码。如果您开始阅读代码,并且擅长阅读代码,那么您将更擅长编写自己的代码,并且您也可能会学到新东西:几乎所有事情都有不止一种方法。
最后,阅读 Clojure 库编码标准,了解生产 Clojure 代码。
† 至少现在还没有。
To your first question: no. †
Clojure is here to help you get things done correctly, quickly, and enjoyably. Everything after that is gravy.
And there's a lot of gravy. I don't presume to know the Clojure way, even if there is one, but here are some guidelines I've been told and have discovered while writing in Clojure:
First, get something working. Then you can examine, test, and optimize if necessary. There's a reason that the
time
macro is in the core language. Correctness before quickness, to be cute.Abstract. If you are repeating yourself, you're probably not doing it right. Compose, curry and combine functions.
Separate side-effects from your logic. e.g. if you want to format and save a string, format it in one function, then use another function to save it, however you need to.
3a. Don't go too crazy with this. Sometimes it's better to have a a few anonymous functions than a bunch of one-line
defn
s littering your code.Test. Rich gave you a REPL for a reason; use the hell out of that REPL.
Don't clutter your namespace. We're clean in Clojure-land. Qualify your
use
s or use:only
what you need. Make your code readable.Know the core library. Not just
clojure.core
, butclojure.java.io
,clojure.string
,clojure.set
and everything in between. If you think Clojure should have a function to do X, it probably does. You can useapropos
(from, yes, another core library:clojure.repl
).Document your code. Docstrings are a beautiful thing. If you have a tendency to be verbose, the doctsring is the place to let loose. But, know too that good code often "documents itself". If the code is self-explanatory, there's no need to be pedantic.
This is a functional language. When you can, use a function. Protocols, macros and records are all great: but when you can get away with it, use a function. You can compose, combine, map, reduce, iterate (the list goes on, and on, and on…) functions. That's really nice.
Above all, break the above rules if it makes sense. But be prepared to rethink and refactor. If you've kept your code modular enough, refactoring your code should be a matter of reorganization and recombination.
Some other tips: read other people's code. If you begin to read code, and become good at reading code, you'll become better at writing your own, and you're likely to learn new things, too: there's more than one way to do just about everything.
Finally, read though the Clojure Library Coding Standards to get an idea of what's expected in production Clojure code.
† At least, not yet.
很难回答的问题。
Clojure 非常灵活。
所以它们是最佳实践,但它们并不像 java 那样重要。
我在这里写了一些从最普遍的家庭到最特殊的家庭的建议的例子。
一般而言,对于编程有以下建议:
编写大量测试,编写正确且漂亮的内容,在需要时进行分析和优化
对于函数式编程有一些建议:
编写小函数、编写纯函数、组合小函数、通过函数分解代码、尽可能尝试使用组合器...
对于 LISP 有一些建议:
使用宏来分解重复的模式,自下而上地构建你的程序。 (请参阅 Paul Graham 的“on LISP”以获得比我更好的解释)
还有一些专门针对 Clojure 的建议:
请仔细分析状态和身份( http://clojure.org/state ,以获得非常好的解释),尽可能使用 seq 及其函数,为函数编写文档字符串
更多建议的一个很好的来源是 Clojure 库编码标准
http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
但所有这些建议都只是建议,不想遵循这些建议的人也可以使用 Clojure,因为作为 Lisp,它非常灵活。
就设计模式而言,函数式程序员很少考虑这些术语,因为它们大多数是为面向对象语言设计的,不适用于函数式语言。
Peter Norvig 有关于设计模式和 LISP/Dylan 的有趣幻灯片:
http://norvig.com/design-patterns/
希望有所帮助。
Hard question.
Clojure is very flexible.
So they are best practices, but they aren't nearly as important as for java.
I write here a few examples of advices from the most general to the most particular families.
There are advices for programming in general:
write a lot of tests, write something correct and nice, profile and optimize when needed
There are advices for functional programming:
write small functions, write pure functions, compose the small functions, factor your code through functions, try to use combinators when possible...
There are advices for LISP:
use macro to factor out repetitive patterns, build your program bottom-up. (See Paul Graham's 'on LISP' for a better explanation than mine)
There are also some advices specifically for Clojure:
follow the careful analysis of state and identity ( http://clojure.org/state , for a very good explanation), try to use seqs and their functions when possible, write doc strings for functions
A good source for more advices are the Clojure Library Coding Standard
http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
But all these advices are just advices, and Clojure can be used by someone that do not want to follow these advices, because, as a Lisp, it is very flexible.
As far as design pattern are concerned, functional programmer rarely think in these terms, as most of them has been designed for OO languages and do not apply in a functional language.
Peter Norvig has interesting slides on Design Pattern and LISP/Dylan:
http://norvig.com/design-patterns/
Hope that helps.
1a)我不知道有类似的事情,但是每本关于 FP 的书都会做类似的事情。
1b)
“偏好组合与继承” -->已经被处理了,因为你从 FP 开始
“与抽象对话”开始 -->更一般的
“能偷懒的时候”
“避免状态”
“使用纯函数!!!”< /p>
列表项
....
2.) 您可以使用一些相同的设计模式,它们只是更容易实现。其中一些意义不大,但通常是这样。 FP 的人不会小题大做。
(这是关于 GoF 模式,我只知道它们)
例如观察者模式。在 Clojure 中,您可以使用 add-watcher 函数来废弃观察者模式。
3.)您可以在名称空间中使用封装(查看 defn-),或者您可以将您的函数隐藏在其他函数中。 《Clojure 的乐趣》中有一些例子。您可以将其推至任意远的位置。
1a) I don't know of something like that but every book about FP will do something like that.
1b)
"Favor Composition vs Inheritance" --> is already taken care of because you started with FP
"talk to abstractions" --> more general
"be lazy when you can"
"avoid state"
"Use PURE FUNCTIONS!!!"
List item
....
2.) You can use some of the some same design patterns they are just much easier to implement. Some of them make less sense but normally. FP folks don't make a big deal out of it.
(This is about GoF patterns I only know them)
Look at the observer-pattern for example. In Clojure you can use add-watcher function witch make the observer-pattern obsolete.
3.)You can use encapsulation in name spaces look at defn- or you can hide your function in other functions. In the Joy of Clojure are some examples. You can push it as far as you want.
不要重复自己 (DRY) 原则非常适用于 clojure。该语言非常灵活,并且确实促进了组合抽象,从而可以真正将锅炉位置代码量减少到非常接近于零。
删除重复代码的方法的一些示例是:
(lazy-seq (cons (do-something data) (call-myself (rest data)))
,请检查是否map
或 < 如果一个函数需要格式化一些数据,将其包装在 XML 中,然后通过网络发送,那么 code>iterate 将(def send-formated-xml (comp send xml format))
这样您就可以稍后将格式函数映射到某些数据上等。The Don't Repeat Yourself (DRY) principal applies very well to clojure. The language is very flexible and really promotes composing abstractions in ways that can really reduce the amount of boiler place code very close to zero.
some examples of ways to remove duplicated code are:
(lazy-seq (cons (do-something data) (call-myself (rest data)))
, check to see ifmap
oriterate
will do what you want.(def send-formated-xml (comp send xml format))
this way you can map the format function onto some data later etc.此视频介绍了 SOLID 原则,以及如何在 Clojure 中应用它们。
它展示了这些原则在函数世界中和在 OOP 中一样适用,因为我们仍然需要解决相同的根本问题。总的来说,它让我认为函数式编程更适合 SOLID 设计。
This video presents the SOLID principles, and how to apply them in Clojure.
It shows how these principles hold in the Functional world as much as in OOP, because we still need to solve the same underlying problems. Overall, it made me think Functional Programming is better suited for SOLID design.
博客中有一篇文章提到“在 clojure 中思考”此处,它提供了一些指向《The Joy Of Clojure》一书以及其他一些书籍的链接(甚至链接到一些视频)
现在,我得到了《Clojure 的乐趣》一书,读了一点,它承诺教我“Clojure 之道”。希望它能告诉我我在寻找什么,一些原则......
这本书正在努力,但你可以从曼宁购买“早期访问版”此处并使用代码“s140”获得 40%。请参阅此处的信息
there is a post in a blog mentioning "thinking in clojure" here and it gives some pointers to the book The Joy Of Clojure, and to some other books (and even links to some videos)
now, i got the book The Joy Of Clojure, read a bit of it, and it promises to teach me "The Way Of Clojure". hope it turns out telling me what i'm looking for, some principles...
this book is work it progress but you can buy an "early access edition" from manning here and get 40% of with code "s140". see info here