Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Depends on your style of programming CL. Clojure is immutable by default with a heavy emphasis on concurrency and strong ties to the JVM as its host environment. The differences you’ll find mostly lie in those areas.


sort by: page size:

Clojure has a very different workflow and way of thinking to CL, both technically and culturally.

I like both, but they take very different approaches to a lot of things (the most obvious of which is mutability).


Right, and what makes me like clojure is the default of immutability. Even if I don't use their concurrency primitives heavily, the default to immutability makes writing concurrent code less scary.

Clojure performs well because of the JVM. Other than the immutable data structures that it includes, which are written in Java, it isn't optimized particularly heavily for dealing with immutable data.

Which is less of a concern considering Clojure's focus on immutability.

Note that CL's data structures are mutable, whereas Clojure's are persistent.

Think about what immutability means. It means that there's no assignment statement. If there's no assignment statement, there can't be any side effects. If there are no side effects, you can't race conditions or concurrent update problems. You can't have resource leaks. You can't have order dependencies.

Does Clojure guarantee all these things? Not entirely; because Clojure allows you to invoke the java stack, which is decidedly not immutable; and because clojure provides mechanisms for changing state; albeit with significant discipline imposed.

The end result is that clojure is _much_ safer to use in complex and multi-threaded systems, and is likely much, _much_ safer in extreme multi-core applications.


I would rather use Clojure's fantastic immutable data structures than CL's rather odd ones (like hashmap, in particular).

But immutability makes it conceptually a hell of lot cleaner, and feasible to do even if you're investing orders of magnitude less in your GC than went into the JVM.

Which is important if Clojure gets ported to bare metal runtimes, as the parent was suggesting.


Clojure has more to do with immutability as a default and concurrency than simply being on the JVM. So perhaps:

Clojure: lisp promotes mutability too much.


They're not trying to be the same thing.

- Clojure has a unique take on state management backed up by unique value semantics. This has created an emergent data-oriented paradigm.

- It heavily favours functional programming and all of the built-in data structures are persistent.

- It is designed to be used and reused across different host environments (CLJC), not just the JVM.

- It bases its collections on a common, flexible abstraction (seq) and has introduced very useful data literals for maps, sets, vectors, regexes, etc.

- It eliminated a bunch of anachronisms like superfluous parens everywhere and car/cdr, while introducing useful syntax for destructuring.

- It's a Lisp-1 like Scheme.


To be fair to Clojure, it has a much more nuanced approach to state management than simple encouraging immutability. It pushes that you should be immutable whenever possible, but if you must use state then you should use it in a controlled and understandable way either by atomic operations, transactional memory, or agent. Further, it provides implementations of all of these things.

So Clojure explicitly allows for state transition and provides controlled and standardized ways of handling it. One of the selling points of Clojure is that it speaks to practicality in implementation by providing alternatives, or in the extreme case, complete escape hatches to low level tools that avoid even it's state control mechanisms. It simply encourages first immutability, and second state control in a well defined way.


Pretty strange that you put Clojure in the "anything goes" category when it has been the clear leader when it comes to immutability. Lots of those languages you put in the other categories don't even have persistent data structures in their standard library.

Honest question: is immutability complicated in Clojure because it's hard, or because it's running in a virtual machine with no meaningful support for it?

The Erlang VM has immutability deeply baked in, and it just works(™).


Immutability is optional in Clojure, though it is the default. Also I'm confused what you mean with size and speed mattering, ClojureScript does better then most by going through the Google Closure compiler for minification and dead code elimination.

Clojure is a different beast, not better or worse, just different.

CL doesn't have opinions, it's a toolbox.


One of the most striking difference between Clojure and Haskell:

In Haskell Immutability is an Abstraction, not Implementation. Clojure data structures and INTEGER & FLOAT object wrappers are expensive. Haskell build toolchain produces much-optimized code which preserves the functionality at high level and reasonable performant mutating code at a low level.


If we're mentioning Clojure:

1) Clojure is secretly a compiled language. A lot of routine errors in Clojure dev are compiler errors.

2) Clojure aims for super-native performance. Immutability in practice gives weird benefits. The obvious example is copying a large object but making a small change. As a native operation in C that is very expensive. In Clojure, the cost is roughly equivalent to the cost of making the small change, because the structure of the big object can be safely reused (everything is immutable, why not?). It enables completely different styles of coding, it is a very practical benefit of Clojure.


Clojure's power is not in its ability to be fast.

Immutability has a price and it's a price we're consciously paying. JVM also has a performance cost, but it's well worth paying due to the wins of running on a virtual machine.

For most boiler-plate tasks, especially where I/O is involved, Clojure is fast enough (eg. handling HTTP requests or talking to a database).

The true power of Clojure, in my opinion, is in how it allows you to think about problems; that machines produce side effects by interpreting a data structure, that the program is one transformation of the input data structure to the target data structure for the desired side effect. You don't think in terms of imaginary objects 'doing' things, you think about the input data structure and how the output data structure should look like, such that if fed to a library function, the desired side effect will occur (eg. the text will be printed or the robot arm will rise).

This mode of thinking about problems is closer to how machines actually work on a higher level and amusingly, 'close to the metal' C++, offers abstractions which take the writer into a fairy tale of class hierarchies, methods that 'do' things to other things, inserting, deleting, mutating everything all over the place. Because that's efficient and fast (and dangerous). But it's also focused a lot on telling the machine 'how' to run; while coincidentally making it do 'what' you want it to do. As a wizard who can put that orchestra with swords and knifes in motion without too much blood spilling on the floors, you can't but feel proud to have achieved it.

Data in -> data out. That's Clojure's way of thinking.

It's a lot simpler way of looking at the problem and maybe makes the `->` feel a bit insignificant and maybe not that important in most cases, as long as it produces the correct output.

The biggest performance hit will be choosing the wrong data structure for solving the problem in a functional way. If that's done correctly, Clojure does offer some tools for squeezing a bit more out of performance critical pieces of code (the articles covers some). Those should be a couple of functions in all your code base; for the boilerplate and domain logic or code involving non realtime I/O, it doesn't matter that much.

If performance is a big concern and you end up writing imperative code in Clojure, I think you'll be better off writing the bits in Java or choose a different language, which is better designed for that purpose.


I don't think the syntax is the main consideration with Clojure.

It's an opinionated language: dynamic, with immutable data structures, hosted on the JVM. I like it quite a bit, personally, and it's been adopted in places where it makes sense.

But many-to-most projects are better off picking another runtime, and the syntax has little to do with why.

next

Legal | privacy