TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The Beauty of Clojure

217 pointsby erikcwover 9 years ago

26 comments

nnqover 9 years ago
I don&#x27;t get it why Clojure and other Lisp tutorials throw things like this in face of beginners:<p><pre><code> (reduce + (map (comp inc inc) (range 10))) </code></pre> instead of just using things like the &quot;-&gt;&quot; macro to make the damn thing just as in any other language:<p><pre><code> (-&gt; (range 10) (map #(+ % 2)) (sum)) </code></pre> ...it&#x27;s as if <i>they purposely try to scare people away from Lisp!</i> Some kind of smug superiority makes them wanna make sure no &quot;lesser mortals&quot; want to touch their beloved language. (The added benefit would be that later you can &quot;blow their minds&quot; but showing them how to <i>write &quot;-&gt;&quot; themselves</i> and instantly introduce them to the power of macros!)<p>This is almost close to showing a code snippet like this to someone trying to learn Haskell:<p><pre><code> fix$(&lt;$&gt;)&lt;$&gt;(:)&lt;*&gt;((&lt;$&gt;((:[{- thor&#x27;s mother -}])&lt;$&gt;))(=&lt;&lt;)&lt;$&gt;(*)&lt;$&gt;(*2))$1 </code></pre> (it only prints the powers of 2, but it was enough to scare some people into calling Haskell “the Taliban version of ML”... <a href="http:&#x2F;&#x2F;www.theregister.co.uk&#x2F;Print&#x2F;2012&#x2F;12&#x2F;21&#x2F;financial_software_disasters&#x2F;" rel="nofollow">http:&#x2F;&#x2F;www.theregister.co.uk&#x2F;Print&#x2F;2012&#x2F;12&#x2F;21&#x2F;financial_soft...</a>)<p>...really, people, stop scaring learners away!
评论 #10121617 未加载
评论 #10121645 未加载
评论 #10121810 未加载
评论 #10121987 未加载
评论 #10123262 未加载
评论 #10121647 未加载
评论 #10121633 未加载
评论 #10121496 未加载
评论 #10122591 未加载
评论 #10122439 未加载
numlockedover 9 years ago
This is very similar to my experience. There&#x27;s definitely some friction getting started; the odd using&#x2F;require macros for importing (which switched sometime in the last 2 years, which means a lot of out-of-date SO answers); the fact that most docs recommend using emacs which, if you aren&#x27;t already a user, is not going to be easy to deal with; the parens.<p>But it&#x27;s amazing. I do really miss types, but found that unit tests + Schema[0] serves my needs; they provide some type-ish enforcement, and do a terrific job documenting my code so that when I return to it months later, I have some idea of what&#x27;s in all these map structures.<p>Another unsung feature is that emacs + paredit + s-exprs + repl means the actual mechanics of writing Clojure is wildly better than any other dev environment. The ability to operate confidently and consistently on semantic units of code vs. text is really amazing and I immediately miss it when I switch back to JS or Python. I&#x27;m sure other Clojurists felt they had already experienced something like FB&#x27;s Prune when it was discussed here a few days ago.<p>Not to mention learning a Lisp really does increase your understanding of what&#x27;s possible. I&#x27;ve seen others recommend holding off on playing with macros until you&#x27;ve become quite familiar with the language, but I couldn&#x27;t disagree more. Play with them right away! I have perhaps ~200 hours of Clojure under my belt -- barely anything -- but I&#x27;ve hacked together a few useful macros. Though I barely understand how they work when revisiting them, it definitely increased my understanding of what&#x27;s possible, and what&#x27;s missing, in other languages.<p>So yeah...learn some Clojure. Just do it.<p>[0] <a href="https:&#x2F;&#x2F;github.com&#x2F;Prismatic&#x2F;schema" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;Prismatic&#x2F;schema</a>
评论 #10121537 未加载
评论 #10121461 未加载
评论 #10121304 未加载
评论 #10121555 未加载
评论 #10121303 未加载
_pmf_over 9 years ago
I&#x27;ve asked on StackOverflow, got shut down violenty, so I try to ask here: how do developers in large(-ish) projects deal with the lack of tool assisted refactoring? (Renaming a field in Java, I am 100% sure that every call site is found, changed or otherwise the codebase does not compile. The catch-all clause of dynamically typed language users seems to be that the test suite should catch everything, but looking at most projects, it&#x27;s outstanding to even see 40% test coverage.)
评论 #10121361 未加载
评论 #10121405 未加载
评论 #10121378 未加载
评论 #10121468 未加载
评论 #10122155 未加载
评论 #10121920 未加载
评论 #10121840 未加载
评论 #10123431 未加载
评论 #10121473 未加载
escherizeover 9 years ago
S-expressions have changed the way I think, and it&#x27;s really great. With paredit (or some other structural editor) and hiccup[1] I can make html so quickly out of pure functions that it&#x27;s truly a joy. Using Clojure&#x27;s datastructures, along with all the functions made to alter those datastructures gives such an immense feeling of power.<p>[1] <a href="http:&#x2F;&#x2F;hiccup.space" rel="nofollow">http:&#x2F;&#x2F;hiccup.space</a>
bad_userover 9 years ago
As disclaimer, I&#x27;ve been a Scala zealot for the last 3 years. On Clojure vs Scala, usually comparisons are kind of unfair I think. As somebody interested in FP, I tried Clojure first. And FP being all about immutable data-structures, pure functions operating on immutable data-structures and dealing with side-effects explicitly by means of abstractions such as the I&#x2F;O Monad, I expected to see that in Clojure, seeing how people describe it as being very FP.<p>And it was like a big WTF for me seeing how for example everything in Clojure is a Var that can be changed. And eventually I got it, I mean Clojure is a LISP and it&#x27;s meant to be compiled by a REPL and the unit of compilation is not a file and this is in LISP&#x27;s tradition and so on and so forth. But it&#x27;s still a WTF given its usual characterization. Even in Java classes are completely immutable (until you start manipulating bytecode of course) and you&#x27;ve got &quot;final&quot; declarations. You have no &quot;final&quot; in Clojure. And this is actually a pity because it (probably) means that those persistent data-structures can&#x27;t be implemented in Clojure, as &quot;final&quot; on top of the JVM comes with a pretty cool contract in the Java Memory Model that you need. And then instead of Scala&#x27;s implicit parameters, that are actually very explicit and type-checked by the compiler, in Clojure you have package-wide vars or refs that people manipulate as a poor man&#x27;s dependency injection mechanism. And state changes are usually done by mutating atoms. Well that&#x27;s cool, in Scala people also do that, but in Scala you also have a mature implementation of the I&#x2F;O monad and monad transformers if you want it, or various FRP libraries. And I&#x27;m sure that Clojure has plenty of libraries, but overall I feel that in Scala the ecosystem of design patterns <i>borrowed-from-Haskell</i> is more mature.<p>Scala provides mutable variants of its data-structures in the standard library. But that&#x27;s not extra rope to hang yourself, because in Clojure the use cases still exist and people end up using Java&#x27;s mutable data-structures instead. In Scala the blend of OOP and FP can sound overwhelming, but it&#x27;s actually the healthiest blend of FP + OOP to ever come up in a programming language. And in Clojure, just because you can&#x27;t declare a class, that doesn&#x27;t mean that OOP doesn&#x27;t exist. It does and the blend is not healthy. This is why &quot;reify&quot; and &quot;proxy&quot; exist and are used quite frequently. And things like clojure.lang.ISeq are a Java OOP interface and not a protocol. Basically Scala is trying to make the best of OOP, whereas Clojure considers it a necessary evil of the host platform that it can&#x27;t get rid of. Pick your poison.
评论 #10122151 未加载
评论 #10121640 未加载
评论 #10121538 未加载
评论 #10123069 未加载
dantiberianover 9 years ago
&gt; I can refactor a huge codebase in my IDE. Good luck trying that with Clojure.<p>Cursive Clojure, a plugin for IntelliJ has excellent refactoring support, especially considering how dynamic Clojure is. If you&#x27;ve come from a Java background, this gives you a lot of the refactoring and &#x27;Where Used&#x27; functionality that you might be used to.
评论 #10121596 未加载
sanatgersappaover 9 years ago
Great post.<p>Most discussions on lispy languages focus on the syntax. The unsaid assumption is that the only diff between a lisp and a non-lisp is the syntax. However, using lisp actually makes you think differently about programming. It is that which for me personally, is the selling point of a lisp. The syntax itself is merely expression, and is honestly simpler to grok than most other languages thanks to its consistency.
pronover 9 years ago
This post focuses on Clojure as a very pragmatic Lisp, but that, while great in itself, is not what makes Clojure so interesting. Clojure has proposed an interesting solution to the shared mutable state problem without trying to reduce it as much as possible like Erlang and without being pure functional -- and thus changing the whole concept of state and effects -- like Haskell (Clojure is imperative-functional). Clojure&#x27;s solution is that all shared mutable state be transactional (or atomic, which is a special case of transactional). AFAIK, this is the first language to do that (again, without going down the pure-functional path). An imperative language that doesn&#x27;t restrict global mutable state, but makes it transactional is a very interesting case study.
edgyswingsetover 9 years ago
I wonder why the author left the thread-first and thread-last macros as a footnote.<p>This:<p><pre><code> (reduce + (map (comp inc inc) (range 10))) </code></pre> And this:<p><pre><code> (-&gt;&gt; (range 10) (map (comp inc inc)) (reduce +)) </code></pre> Are totally different from a readability standpoint. Yeah, there&#x27;s some initial syntax to get used to, but in the long run I&#x27;ve noticed it to be the difference between immediately understanding what some code is doing and having my eyes glaze over.
bonobo3000over 9 years ago
For the OP - i&#x27;ve recently been programming in Scala, mostly spark jobs, nothing too complex, but damn its beautiful. I love how expressive the language is (certainly it can also be very complicated in large codebases, as you use more features, but I haven&#x27;t encountered that yet). Heck just the simple &#x27;scala&#x27; repl + JVM interop makes developing Java code so much easier. You seem to have tried Scala too - i&#x27;m wondering what you think of Clojure vs. Scala and what made you switch?
评论 #10121371 未加载
评论 #10121949 未加载
rjeliover 9 years ago
<p><pre><code> (reduce + (map (comp inc inc) (range 10))) </code></pre> is not analogous to (_ + 2). The more similar and idiomatic code is:<p><pre><code> (reduce + (map #(+ % 2) (range 10)))</code></pre>
jdeisenbergover 9 years ago
The first example could also be written as:<p><pre><code> (reduce + (map #(+ % 2) (range 10))) </code></pre> which looks more like the Scala example, or, perhaps more readable, in the long form:<p><pre><code> (reduce + (map (fn [x] (+ x 2)) (range 10)))</code></pre>
mseepgoodover 9 years ago
Why is reading from left to right counter-intuitive? Don&#x27;t we read f(x, y) from left to right as well? (f x y) has the same order, even the same amount of parentheses.
评论 #10123451 未加载
huahaiyover 9 years ago
For this code,<p>(reduce + (map (comp inc inc) (range 10)))<p>Clojure people would normally use thread macro, like so:<p>(-&gt;&gt; (range 10) (map #(+ % 2)) (reduce +))<p>This would be similar to the Scala version in term of order.
评论 #10121725 未加载
kazinatorover 9 years ago
&gt; <i>The use of s-expressions and their resulting prefix notation is in many respects the secret sauce of Clojure. However, it requires you to read right-to-left3 and inside-out. This is counterintuitive to most of us, and takes some getting over. It is a very real barrier to entry for Lisps.</i><p>Author still doesn&#x27;t get it. Lisp must, in fact, be read from the outside in, left to right --- in the same obvious direction in which it is evaluated. It is not very different from a nested f(x, y, ...) notation, except that the commas are gone, and the f ( exchange position to the ( f arrangement.<p>As a trivial example of why outside-in is wrong, is that if you follow that order, you might believe that (b c) is a function call in (defclass a () (b c)). The most important fact is that this is a class definition (in ANSI Common Lisp). The leftmost symbol in the outermost form, defclass, is the what McCarthy called the &quot;main connective&quot;. It determines the entire meaning of the interior of the form and all of its subforms, so it behooves us to visit that first. When we recognize that, we then know that (b c) are slots, and not operator b applied to argument c.<p>The right-to-left part is completely bizarre. Why, as a matter of course, would you read the arguments of a form before the main connective symbol? If that, you want, languages for you, there are: Forth, PostScript.
评论 #10123376 未加载
skimpycompilerover 9 years ago
As much as I like Clojure the lack of static typing always made refactoring a pain. The lack of it makes this a beauty I just can&#x27;t appreciate and see.
diegoover 9 years ago
(comp inc inc) is weird. You&#x27;d normally use #(+ 2 %) or (partial + 2) instead.
评论 #10128296 未加载
评论 #10122054 未加载
erichmondover 9 years ago
My couple of comments:<p>- Great write up, very approachable for who may be on the fence about toying clojure.<p>- Re: Enterprise, while our enterprise footprint isn&#x27;t ubiquitous yet, there are a couple of big name companies using clojure pretty heavily. Amazon, Walmart and Two Sigma amongst them. Also, because clojure sits on the JVM, we have a good interop story with legacy java codebases.<p>- Re: Refactoring, you should checkout intellij + cursive clojure, it&#x27;s made refactoring codebases much easier for myself.
评论 #10128276 未加载
评论 #10122204 未加载
pjmlpover 9 years ago
I would like to try to use Clojure for mobile development.<p>Together with ClojureCLR, RoboVM and reader conditionals it would be a good mix, without having to deal with FFI headaches.<p>But currently it is too slow on Android and I don&#x27;t know how well ClojureCLR, if at all, runs as Universal Windows App.
评论 #10121630 未加载
tragicover 9 years ago
&quot;FYI - there are better books to get started with [than the Joy of Clojure].&quot;<p>FMI: what are they? :-)
评论 #10121710 未加载
评论 #10128246 未加载
评论 #10122872 未加载
crimsonalucardover 9 years ago
Which is more beautiful, haskell or clojure? This is a subjective question, so I&#x27;m hoping to read subjective and highly opinionated answers.
评论 #10121653 未加载
评论 #10121565 未加载
评论 #10123552 未加载
infiniteseekerover 9 years ago
Is there a good online course for a beginning programmer who wants to learn Clojure? If not, a good book with exercises?
评论 #10128235 未加载
评论 #10122114 未加载
评论 #10122045 未加载
pixie_over 9 years ago
The line below looks a lot more readable than the closure version.<p>Enumerable.Range(1, 10).Select(i =&gt; i + 2).Sum()
评论 #10121497 未加载
评论 #10121507 未加载
评论 #10122291 未加载
zubairqover 9 years ago
Not, entirely true, there are some Clojure Frameworks like this one <a href="http:&#x2F;&#x2F;coils.cc&#x2F;coils&#x2F;a-framework.html" rel="nofollow">http:&#x2F;&#x2F;coils.cc&#x2F;coils&#x2F;a-framework.html</a>
craniumover 9 years ago
Perfect description of the average Enterprise codebase!
pkaover 9 years ago
Great! Now go for Haskell :)