Earlier quoted context omitted.
The common talking points are * Clojure is based on seqs rather than cons cells. * Clojure renamed certain common functions, like car and cdr, so 30 year old Lisp example code no longer compiles. * Clojure doesn't have implicit tail call optimisation for recursion. * Clojure reveals its host platform when it has runtime errors.
Clojure did not just rename a few functions. It's basically zero source code compatible with Lisps. Not only old example code does not run, nothing runs. No applications, no libraries, no tools, ... It's not even easy to port. It's a rewrite and/or redesign. Obviously this is okay for people who don't care of the historical baggage (and want to avoid it) and who don't care about the functionality of Lisps, like inter…
Clojure: A Lisp that wants to spread
81–90 of 306 posts
Re: Clojure: A Lisp that wants to spread
#82Earlier quoted context omitted.
What got me started with Clojure was a coworker at megacorp. He's since moved on to a company that makes widespread use of Clojure in production. Startup time was a huge factor for me because I wanted to write command line tools with it. The leaky abstractions were the other painful part – Clojure itself wasn't so bad, but Clojurescript (which would sidestep the startup issue) always seemed to leave me in callback he…
Clojure seems like an odd choice for command line tools. I can see why a committed Clojure programmer would want to reuse their existing skills for a slightly mismatching domain. But Rust/Go (even C) would seem like a more obvious choice if you weren't setting off from Clojure as a starting point.
Re: Clojure: A Lisp that wants to spread
#83Thats last few sentences make no sense. The argument is that uptake is stunted by the JVM's slow startup time, making it unsuitable for commandline utils or desktop apps. However thats easily fixed which was never more hillariously stated than when Rich Hickey did it a decade ago. A blogpost went viral and it was a thunderous critique of Clojure, focused on this single point of slow start up. In the comment section w…
Uhm.. I want to give the benefit of the doubt, but frankly this seems deceptive, or at least out of date, unless I'm totally missing something. Why is there no magical --client / --script option for the Clojure ClI to make startup faster, if this is such an easy solution? Also, you show system time, but the time to load dependencies is in user time, which is slow by the nature of Clojure. Example: $ time java -client…
Re: Clojure: A Lisp that wants to spread
#84I tried Clojure but ended up hating it for reasons all stemming from its hosted implementation. Whenever I didn't know how to do something, I (and most other Clojure users) would go use some JDK class (or worse, an external Java library) instead of figuring out how to write the Lisp. For some reason this doesn't often happen with regular Lisp even though CFFI is available. There's a tendency to just reimplement it di…
Re: Clojure: A Lisp that wants to spread
#85Earlier quoted context omitted.
Clojure did not just rename a few functions. It's basically zero source code compatible with Lisps. Not only old example code does not run, nothing runs. No applications, no libraries, no tools, ... It's not even easy to port. It's a rewrite and/or redesign. Obviously this is okay for people who don't care of the historical baggage (and want to avoid it) and who don't care about the functionality of Lisps, like inter…
Nothing is sharable between Common Lisp and Scheme, either, but Scheme is generally considered a Lisp.
Nowadays I don't think of Scheme as a mainline Lisp -> it moved from a close Lisp dialect to its own language with its own standards, books, user groups, libraries, implementations, applications, ...
Re: Clojure: A Lisp that wants to spread
#86Re: Clojure: A Lisp that wants to spread
#87Re: Clojure: A Lisp that wants to spread
#88I don’t actually get the big deal about enforced immutability. Of course, you need to constrain yourself in certain circumstances to do things immutably, but it seems like something that should be contextual (immutably ...), rather than enforcing it. In fact, sometimes it is necessary in high performance multi—threaded/multi-processor environments to use side effects judiciously. Moreover, most serious lisp programme…
The short answer is: Clojure (and other languages/frameworks that emphasize immutability) is not intended for those use-cases.
The long answer is, Clojure added something called "transient data structures" as a trap-door for cases where you really absolutely need mutability for performance: https://clojure.org/reference/transients But they are really intended to be the exception, not the rule.
Enforced immutability is a conscious choice you make to trade some performance for increased robustness. Also, compared to "immutability by convention", enforced immutability allows certain optimizations to be made that greatly decrease the wasted memory and allocation/deallocation that would occur if you naively cloned everything.
Re: Clojure: A Lisp that wants to spread
#89While we are at it - how do you refactor a mid-sized/large Clojure project?
The most fundamental concept in Clojure, from the famous Rich Hickey talk Simple Made Easy (https://www.infoq.com/presentations/Simple-Made-Easy/) is that your code should strive to be decomplected.
That means that your program should be made of parts that when modified do not break anything else. This, in turn, means you don't really ever need to refactor anything major.
In practice, this has held true for most of my code bases.
Now, my second answer, because sometimes there are some small refactors that may still be needed, or you might deal with a Clojure code base that wasn't properly decomplected, you would do it the same way you do in any dynamic language.
The two things that are trickier to refactor in Clojure are removing/renaming keys on maps/records, and changes to a function signature. For the latter, just going through the call-sites often suffice. The former doesn't have that great solutions for now. Unit tests and specs can help catch breakage quickly. Trying out things in the REPL can as well. I tend to perform a text search of the key to find everywhere it is used, and refactor those places. That's normally what worked best for me.
It helps a lot if you write your Clojure code in a way that limits how deep you pass maps around. Prefer functions which take their input as separate parameters. Prefer using destructuring without the `:as` directive. Most importantly, design your logic within itself, and so keep your entities top level.
Re: Clojure: A Lisp that wants to spread
#90Earlier quoted context omitted.
Clojure did not just rename a few functions. It's basically zero source code compatible with Lisps. Not only old example code does not run, nothing runs. No applications, no libraries, no tools, ... It's not even easy to port. It's a rewrite and/or redesign. Obviously this is okay for people who don't care of the historical baggage (and want to avoid it) and who don't care about the functionality of Lisps, like inter…
Right. The reason Common Lisp is called “common” is that it has a standard that allows anyone to build a lisp from scratch that will run any common lisp code essentially completely unchanged (obviously you need to adjust a bit where you hit the OS, but even the file access methods are spec’ed). If you aren’t conformant you aren’t a Common Lisp - you could still be a lisp. Clojure is a lisp, just not a Common Lisp.