Clojure is by far the best programming language I've ever used. Rich Hickey's Sermons On The Mount changed the game of programming once and for all. With Clojure you could finally have your Lisp cake and eat it. Witness the sheer chutzpah of the guy when he basically told Ruby devs they were doing it wrong at Rails Conf in 2012 (<a href="https://www.youtube.com/watch?v=rI8tNMsozo0" rel="nofollow">https://www.youtube.com/watch?v=rI8tNMsozo0</a>).
Can anyone give a pro/cons analysis of a ML variant versus of a Lisp variant. Let's say F# versus Clojure?<p>One of the general arguments in Lisp vs the world is that lisp is more concise. F# is really concise. It has datastructures as intrinsic part of the language syntax (just like Clojure, i.e in F# [|,,,|] is an array and in Clojure [...] is a vector, so more or less the same thing). Furthermore, the type inferences concierges the developer through the regular bureaucracy involved with strong type systems so effortlessly that you seldom notice it ... unless your code does not compile, in which case it's wrong somewhere and you need to fix it (which you needed to do anyway).<p>Ok, so for the sake of the argument, let's say the syntax is equally light for F# and Clojure, and their support for immutability is in the same ballpark. And let's remove the argument "a type system is an encumbrance" because that will only lead to situation specific debates - one side will say that massive refactorings are a pita without types, and the other side responds that in Clojure you can use data schemas and should have unit tests anyway. And those discussions never lead anywhere conclusive.<p>So, besides the above mentioned topics, is there anything general one can say of the distinctive advantages of these two languages in specific situations, including how their two different ecosystems and runtimes affect the calculus?<p>I suppose it's extremely rare to have experts who have participated in any large scale industrial developments with both of the languages, but if there are, it would be really nice to hear their opinion. And the things I listed as "outside of the discussion" might actually be critical, who knows...
The response to "but is it slow" is pretty disappointingly bad.<p>> No. Clojure is not slow. Oh, look, it’s not C. It’s not assembler. If nanoseconds are your concern than you probably don’t want Clojure in your innermost loops. You also probably don’t want Java, or C#. But 99.9% of the software we write nowadays has no need of nanosecond performance. I’ve built a real time, GUI based, animated space war game using Clojure. I could keep the frame rates up in the high 20s even with hundreds of objects on the screen. Clojure is not slow.<p>If you're going to respond to this question at least provide <i>some</i> comparison maybe.<p>But otherwise that anecdote of "I could keep the frame rates up in the high 20s even with hundreds of objects on the screen." absolutely screams <i>extremely slow</i>. High 20s FPS with hundreds of objects is incredibly bad on the surface of things. Maybe it's closures fault, maybe it isn't and is instead the fault of whatever was doing the drawing. But it's not a good look either way if that's the only data point that can be provided.<p>Similarly the IDE/dynamic type question seems to have missed the main downside of dynamic languages - lack of good IDE & other tooling support. How well are things auto-completed for me? How well does the IDE warn I've made a type error <i>before</i> I've gone through a long compile & test iteration loop? How well do linters or other things work, or is there some aspect of LISP that means this is just not an issue like it is in other languages?
> 1. Economy of expression<p>Funny, this list is the same one I use as to why I'm so annoyed with Clojure right now.<p>I inherited a mission-critical Clojure ML library my team uses for it's primary business goals. It was written 4 years ago by a research scientist- who quit 3 years ago. We know what it's supposed to do. We know that it seems to do the job well. We just can't understand the code well enough to be certain of what it's doing or how it's doing it. If this thing breaks or stops working, we're screwed.<p>The problem is that the author, like most of us, found great joy in writing very few characters to express very big ideas. Clojure let him do that to an extreme degree. And I'm sure if you were sitting beside the author, with him explaining these dense expressions, you would be enlightened at the elegance and beauty of this language.<p>Sadly, I was not.<p>I'm sure Clojure is a lovely language. But it lets you write a Voynich manuscript that compiles.
A little bit off-topic, but I'm really confused that, why people on HN like Clojure and hate JavaScript? I didn't have any analytical data but it's very obvious already to anyone who read HN often. Are they possibly be the same crowd or just independent groups of people?<p>For me, Clojure and JavaScript (at least for modern React community) are similar when it comes to usage: Dynamic typing with Hash-map centric modeling, use functions to compose thing but mostly without monadic patterns. The methodology in the Clojure community has an official name: "It's just data". This methodology works, and have it's own pros and cons. The obvious pro is people can write generic functions without poking hundreds of nominal types, interfaces and type classes.<p>The only big difference I see is macro, but Clojure community also doesn't recommend writing macros unless you have to. There are also protocols and types, but they're not encouraged to poke around, it's still map-first recommended across the community.<p>There are very few language communities follow the "It's just data patterns". From Java to Python to ML, people mostly modeling things with fixed-property model, instead of just untyped maps, unless they have to.<p>For Lisps, I don't see map-centric approach is that stressed. Scheme might be still list-centric, Common Lisp is more diversed when it comes to approaches.<p>Why people hate JavaScript so much? And why people speak highly of Clojure? It's just about inconsistent details, or about the whole design itself? Is there any important point I missed?
Has anyone done both elm and clojure script for Web work? Which did you prefer, which had the best tooling etc?<p>I need to learn Web, as mucj as I don't want to, and love clojure and fp. Also figwheel looks awesome, but how hard is it to setup.<p>I also think maybe to really get the best out of clojure script you also need to learn react??<p>I'm not sure this is the case with elm.<p>Any other non js alternatives?
Can someone explain me why they always (OK let's say almost always) use math formulas to show what you can do with a programming language ?<p>I'm a desktop application programmer, not a mathematician. I don't need to print the first 25 squares of integers or Fibonacci whatever. In fact I think the hardest math I did at work was using modulo to get even and odd numbers ...<p>Show me how you parse a csv file, how do you connect to webservices or retrieve data from a database, show me how to do a simple GUI, show me something useful for the common dev.<p>I'll judge your ultimate programming language on these menial tasks that comprise 99.9% of my programming time.
Clojure is one of the better dynamic languages.<p>The rub however is that GHC can check the consistency of my software faster than I or my colleagues will ever be able to, and programmer time is expensive.<p>So that's why <i>not</i> Clojure.
This is all nice and exciting until you start to
1) Debug code, the high density of clojure code means that this is really painful.
2) Read code you wrote a while back. The high density of clojure code means that this is really painful.
I played around with Closure for a while to learn its cost/benefits. It is basically the love child of Lisp, Haskell and Java. So it introduces nothing new to the world. However it is certainly an interesting mix that some developers like. And Rich Hickey is an entertaining speaker/presenter/seller of Clojure. Even if you don't care about Closure, watch his talks on YouTube.
My team owns a Clojure app, amongst a lot of other apps - my understanding is the current DRI (who inherited this app once the original one left for another org) doesn't like working in it though, and that has been the experience of other developers who have been recruited to the project over the past two years. Most developers I work with on a day to day basis don't have any interest in learning Clojure, and would rather work with Scala, the JVM language most heavily used within my org.<p>One of my teammates also has production ClojureScript experience, and called it the worst of both worlds (Clojure and JavaScript). The primary problem is it doesn't try to abstract away the DOM, the most typically problematic part of working with JS.<p>Just my own encounter with it so far - I haven't had the experience of writing production Clojure myself, but from what I've seen with the syntax, I'm still happily primarily writing JS so far when I'm not writing Python/Scala/etc.
Here is my "Why Clojure?" blog post: <a href="https://medium.com/@ertu.ctn/why-clojure-seriously-why-9f5e6f24dc29" rel="nofollow">https://medium.com/@ertu.ctn/why-clojure-seriously-why-9f5e6...</a>
been jumping into clojure lately myself. after years of js fatigue I've been dying for a functional pairing to elixir on the backend. clojure is growing on me with its nice hot code reloading and macros. (babel is basicly an overgrown macro)
> <i>I saw the CARs and CDRs and CADDADDRs and thought it was all just academic baloney; interesting but not truly useful.</i><p><i>car</i> and <i>cdr</i> are accessors for the fields of a basic data-structure; nothing academic about that. The very origin of the names is rooted in <i>systems</i> work, not academics.<p><i>(caddr x)</i> provides a shorthand for (car (cdr (cdr x))), which is a pragmatic thing.<p>You know, like #(* % %) instead of (lambda (x) (* x x)).
The most annoying phrase was "less code, less time, less...". Uncle Bob thought us to be explicit, help the reader understand the code and be verbose with the variables etc.
Now he loves a Syntax that says #(25 % %)... Aaaalright, try to get a new company member understand a big code base with this massive oneliners.
I doubt that this is the right language for enterprise projects.
"<i>Economy of Expression. [..] It requires fewer lines. It require fewer characters. It require fewer hours. It requires fewer mental gymnastics. So, here, for your entertainment, is the program that prints the first 25 squares of integers.</i>"<p><pre><code> (println (take 25 (map #(* % %) (range))))
</code></pre>
And in APL[1], iota 25 is the first 25 integers, and feeding the same list into both sides of multiply squares the list, then turning it from a row to a column is tabling it. "Table the multiply-commute of the first 25 integers":<p><pre><code> ⍪×⍨⍳25
</code></pre>
It's fewer lines, fewer characters, fewer hours, less syntax, less grammar, fewer symbols, fewer functions, less nesting, fewer mental gymnastics. Yet .. worse? Because those things you say both lead you towards codegolf, and implicitly have "fewer mental gymnastics" mean "I'm familiar with it already".<p>[1] <a href="https://tryapl.org/?a=%u236A%D7%u2368%u237325&run" rel="nofollow">https://tryapl.org/?a=%u236A%D7%u2368%u237325&run</a>
>> Robert C. Martin: <i>Smalltalk was also an image based language. Very few programmers have ever wrapped their minds around what that really meant. So, unfortunately, the language languished compared to all the text-file based languages.</i> <<<p>Where is the evidence?<p>Back in the 1990's IBM taught many of their consultants Smalltalk, and researched what made learning Smalltalk difficult —<p><i>Smalltalk, although recognized as a good platform for rapid prototyping and software reuse, is widely regarded as difficult to learn. Unlike learning a procedural language like Pascal or C, learning Smalltalk is dominated by browsing and code comprehension. Learners of Smalltalk typically experience a long, slow start-up phase in which they become familiar with the class hierarchy and object-oriented computational model but do little meaningful work (our colleague Dave Smith calls this "climbing the Smalltalk mountain").</i><p>Programmers having to wrap their minds around the class hierarchy and OO was seen to be the problem.
I've been programming in Lisps on and off since the mid 80's, and I like Clojure the language, but in recent times as mostly as .Net programmer, I find the JVM and the surrounding Clojure tooling rather baroque. I find tutorials often cover Clojure/Lisp basics, but assume that you're coming from the Java world, so I had some difficulty getting what I consider basic workflows working as expected. If homoiconicity/macros/eval isn't an issue, I'm happy with F#/C# for the most part, but wouldn't mind having Clojure in the toolchest as well, but I'm not sure of the state and maintenance of Clojure.net.
> Now let’s compare that to the equivalent Java program:<p><pre><code> public class SquaresOfIntegers {
public static void main(String[] args) {
for (int i=0; i<25; i++)
System.out.println(i*i);
}
}
</code></pre>
> This is considerably more wordy, even if you don’t count the enclosing class.<p>First of all, Java is famously verbose. Nobody is impressed when a language is more concise than Java.<p>But even ignoring that, the comparison isn't representative. The enclosing class and 'main' function aren't needed for every additional fragment of code, so it probably shouldn't be counted here.
I might be damaged from years of Java, but my main imagined issue with Clojure is the lack of a component system. Call it OCaml functors or OOP classes, but instantiating a component with replaceable components as input is what I personally need for large scale programming. To make things more concrete, let's say you are writing an integration to another system using HTTP. On the surface you'll have functions like `fetch-album-information` and they will internally use a HTTP client. How do you handle TLS configuration, HTTP connection pooling, etc. and make the function testable and lifecycle-managed to allow clean shutdown? The easy answer is to parameterise the function with another function that takes care of all of that. But that function will need to come from somewhere and I imagine threading these kind of functions explicitly through your entire program will make it less than palatable. The alternative of using globals that can be replaced in testing carry all the usual problems that global variables have but seems to be what many settle with judging from Clojure code on GitHub. It seems like others are feeling this pain and have invented band-aid solutions like <a href="https://github.com/stuartsierra/component" rel="nofollow">https://github.com/stuartsierra/component</a> but this is something I think needs a first-class solution to encourage this kind of programming.
It just breaks my heart to see Uncle Bob seduced by a Java-family language right when C++ is getting increasingly fun. He suffered through the bad old days when C++ was only fast and powerful, and is now missing out on the good new days.<p>I guess he's happy. At least he isn't touting Haskell. Bon Voyage, Bob!<p>But somebody needs to break it to him that Lisp is not a functional language. Or, if it is, so is C++.