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.

What is Clojure good at?

49 pointsby bobobjornover 14 years ago

11 comments

jrockwayover 14 years ago
Clojure is fine, but just to play devil's advocate:<p><i>First of all, the repl is a killer. This is not something that is unique to clojure, but that doesnt make it less good. Beeing able to try out new api’s and fumble forward is great.</i><p>You can do this with Java and every other language. There's even a C++ REPL floating around out there. The real difference between Clojure (and CL, and Haskell) is that there is a REPL culture -- library designers use a REPL, so using one to play with their library feels natural. Trying using a C++ or Java REPL and you'll find that... it's not so nice.<p><i>Second, there is no compile time. It is not that the compile time is short, it doesnt [sic] exist.</i><p>Not correct. Fast compile time is always nice, and it's great that you don't notice. But this statement is simply not technically correct.<p><i>Third, functions without state and side effects are alot [sic] easier to test then [sic] java code. Yes you can still create hard to test code, but it is harder.</i><p>But of course, nothing in Java forces you to use state and side effects. It's a culture problem, again; but if you use Java libraries from within Clojure, you are going to run into those same culture problems.<p><i>Fourth, you can abstract away more code.</i><p>This is true. Java is missing something like Perl's "roles" that allow you to have code in interfaces. Imagine an "Equal" interface that defines equals and not equals. In Perl, you can provide a default implementation for not equals in terms of equals in Equals. In Java, well, I hope you like cut-n-paste or messy delegation. (I have never seen a Java programmer do this, but here's the pattern. Create a NotEquals class that has one parameter, a class that does the Equals interface. Implement not equals by delegating to equals in the object that was passed in. Now you have a class that can do equals and not equals; so create an instance and delegate YourClass.not_equals to NotEquals.not_equals. Now you can get not_equals without cut-n-paste. This is too hard for most people to figure out, it seems.)<p>With a higher-level syntax, you can add Roles later, or automate the delegation, so you can pick which design to use based on which one makes the most sense, instead of which one means you have less boilerplate to cut-n-paste. And that's the joy of high-level languages; you can write good code without wearing out your fingers.
评论 #1803669 未加载
评论 #1803367 未加载
评论 #1804549 未加载
mr_lucover 14 years ago
I sympathize with the author!<p>I had the same experience a couple of nights ago -- a corporate-programmer-turned-manager friend (highly competent, Formally Trained in Dimensional Modelling and Analysis using the Microsoft stack, etc) was asking me, with some confusion, why I'd use a scripting language or any other 'out there' language.<p>My first answers were, really, only good for someone who already knows what the language features being described are. CL has macros, Ruby is dynamic and the practice of using blocks ... what are those features, and what do they buy you?<p>I could tell that my explanations were being parsed -- he's a very smart guy -- but the parse tree was just being cached, with timeouts that would expire long before compilation could take place.<p>So, I changed tactics -- like the author of this article.<p>"I like these languages because, look! I can type THIS instead of THIS!"<p>I kick myself now for not showing him some lisp, but I was working on a ruby+sinatra app on my server in emacs in screen, so I brought up a repl and showed him how few lines of code it took to make a class, and iterate through a list, etc.<p>What stuck was showing the actual code handling signups in the (sinatra, so, from-scratch) web app -- "look, 2 functions, 6 lines apiece, with error handling and everything."<p>My friend has to manage programmers now, so he knows that (despite the existence of libraries and frameworks and so forth) if you ask for someone to make you an interface that does X, it's rare that you can get a 5-minute turnaround. The productivity arguments carried the day(1).<p>"Look, I get to type less code than you, by far, every day!(2)" &#60; -- is a quick way to get past whatever mental blocks the person has to considering your language of choice.<p>And it sure ought to be easy to demonstrate if they're coming from C# or Java, or what are you wasting your time on? ;)<p>-----<p>(1) Unfortunately, he spent the rest of the night trying to pitch me on a startup project of his own that he wanted help "implementing," because the "lion's share" of the work, the data model, was done. But I digress.<p>(2) But with Ruby, it's easier to add "and look how easy it is to read!" regardless of the background of your listener. Languages like Lisp, that involve a "scary" new lack of syntax, well ... still, side-by-side demonstrations like the one in the article are a good way to pique a practical curiosity.
ohyesover 14 years ago
'I of course started rambling about how nice it is for concurrent applications, that you can make a map statement run in multiple threads by simply changing “map” to “pmap”.'[sic apparent typos]<p>While this is sort of true, that is not true concurrency, it is parallelism. It seems that a lot of production Clojure code will end up relying on Java code at a low level. (That was at least my experience in getting things performant).<p>When you do this, it seems to me that you lose some of the safe parallelism guarantees. Immutable data structures with 'pmap' are great, as long as you didn't use a mutable Java array somewhere... (This is reasonable, you have enough rope to hang yourself). The takeaway is not 'instant concurrency', it simply isn't true. The takeaway 'great built in support for certain types of concurrency' would be better.<p>I think the 'fourth' point, Lisp is great at syntax abstraction, has always been true, and is a great point to make in favor of any lisp. If you know what you are doing, it is possible to write some extremely pretty, declarative code. (But again, there's no accounting for taste, and you have enough rope to hang yourself).<p>Lisp: enough rope to hang yourself, or write awesome code. Or (more likely) do both.
swannodetteover 14 years ago
I would honestly answer "It's good at removing complexity from your programs". People adopted OO because it eliminated certain forms of incidental complexity from their applications. People adopted GCed languages because it eliminated a particular serious form of incidental complexity for many applications.<p>Clojure is good at taking the elements of OO that are sound and ruthlessly removing the ones that introduce complexity. Especially those problems which cause incidental complexity to explode under concurrency.
grogersover 14 years ago
The two examples he gives could be done easily in any programming language that supports higher order functions (ie. functions which take a function as an input argument). To a lesser extent he requires lambdas in the with-memcached example, but it isn't 100% necessary (could have just written the some-heavy-code part in a named function).<p>None of this is very novel or unique to clojure. Clojure (and other lisps) do have some nice syntax sugar to make writing this type of code easily, which is nice.
tsothaover 14 years ago
<i>First of all, the repl is a killer. This is not something that is unique to clojure, but that doesnt make it less good. Beeing able to try out new api’s and fumble forward is great.</i><p>Spell checker, man!<p>I don't understand all the REPL love. To me it's great for goofing around with something you don't understand (like clojure itself, when I started). But where is the option to save the REPL state? When I'm actually working on a project it's back to the old edit-compile-run cycle, because otherwise I lose my work. Granted, the compile is pretty quick, but that's true when I'm writing java code in eclipse.
评论 #1803971 未加载
评论 #1803677 未加载
llilesover 14 years ago
I spent the weekend writing a scraper in Clojure using the HtmlUnit Java library. As much as possible I aimed for purely functional, side effect free code, but as with most Java libraries, using the HtmlUnit API forced me to write functions dealing with mutable, stateful Java objects.<p>I would have preferred to write everything in a purely functional style because I agree that it makes testing and reasoning about your code so much easier. But looking back, the ability to dip into Java (and use the great HtmlUnit library) was a big win in terms of accomplishing the task at hand.
seancronover 14 years ago
The main problem I had when I was learning Clojure was definitely finding good, up-to-date documentation about it. There were many times when I'd try an example that I had found online, only to find out that something had changed in Clojure 1.2 since the article was written, or that it wasn't documented well.<p>For example: Using command line arguments is not clearly documented. The best resource that I found was this Stack Overflow answer <a href="http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface" rel="nofollow">http://stackoverflow.com/questions/1341154/building-a-clojur...</a><p>Another problem that I've had with Clojure, is that because programs can be written so concisely, it's very easy to get lost reading other people's code when you're first starting out. Things like the "-&#62;&#62;" macro and the "#" shorthand confused me when I was trying to learn Clojure because symbols aren't very descriptive, and they're very hard to search for.
sorenbsover 14 years ago
The point about functional languages changing your coding style really is true. After playing around with lift in a university course i went ahead and implemented the exact same cache access pattern you have described in a .net application (using lambda in c#):<p>var data = Caching.GetOrAdd(cacheKey, () =&#62; doWorkAndReturnData);
newobjover 14 years ago
(time (my-function))<p>is a pretty horrible example because i can instrument my java code with a single annotation, which is far less brittle.
评论 #1804853 未加载
评论 #1805269 未加载
Tichyover 14 years ago
Just skimming the headlines - it sounds as if Clojure is good at Java. That's it? I hate Java...<p>Still interested in Clojure, though.
评论 #1803194 未加载