Live data from Hacker News

Clojure: A Lisp that wants to spread

simongray.github.io

81–90 of 306 posts

Re: Clojure: A Lisp that wants to spread

#81
post #66

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…

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.

Re: Clojure: A Lisp that wants to spread

#82

Earlier 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.

Why?

Re: Clojure: A Lisp that wants to spread

#83
post #2

Thats 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…

For me, scripts and command line application startup time is mostly a solved problem. You can just use ClojureScript, Babashka or Joker for scripting and CLI apps that don't need to perform too much CPU bound work. And for CPU intensive CLI apps, you can now use Graal's SubstrateVM to have a native build which starts instantly.

Re: Clojure: A Lisp that wants to spread

#84
post #27

I 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…

Hum, that's one of my favorite things. Some JDK APIs/libs are quite well designed, and when they are, Clojure doesn't bother re-inventing the wheel, which is a great thing in my opinion.

Re: Clojure: A Lisp that wants to spread

#85
post #66

Earlier 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.

That used to be different. There were Scheme programs running in both Scheme and Common Lisp or moving between them. For example the Yale Haskell compiler was originally developed in a Scheme dialect called T and then moved to Lisp (here Common Lisp) by embedding a shallow compatibility layer in Lisp. Another example is Common Music, a music composition system, which ran for a while both in Scheme and CL. Scheme itself was originally a hosted program on top of Maclisp. A few more Scheme implementations were written and/or embedded in Lisp - for example the Scheme variants for Naughty Dog's Crash Bandicoot and Jak and Daxter Playstation games were written in Common Lisp. The Scheme written by Peter Norvig was used in a content management system, embedded in CL.

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

#86
I 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 programmers almost write immutably by default. The only (common) exception being hash tables, but you just don’t use them if you need more control.

Re: Clojure: A Lisp that wants to spread

#88

I 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…

> sometimes it is necessary in high performance multi—threaded/multi-processor environments to use side effects judiciously

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

#89
post #4

While we are at it - how do you refactor a mid-sized/large Clojure project?

So, my first answer is that you shouldn't have too, and if you do, you might not be writing proper Clojure code.

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

#90
post #66

Earlier 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.

[deleted]
Post reply on HN