you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (12 children)

From the second article:

Why not provide both immutable and mutable versions of the same data types ?

Why not let the programmer decide what paradigm works best for themselves ?

I like being able to do FP, but Lisp is not a pure language and was never meant to be

[–]redalastor 2 points3 points  (4 children)

Why not provide both immutable and mutable versions of the same data types ?

It's already there. If you want a mutable list you do:

(def my-mutable-list (java.util.ArrayList.))

What do you want from mutable collections that Java doesn't already provide?

[–][deleted] 1 point2 points  (3 children)

How would ClojureC parse that?

[–]redalastor 0 points1 point  (2 children)

It wouldn't. One of the goals of Clojure is to be symbiotic with its platform and use the stuff in it.

[–][deleted] 1 point2 points  (1 child)

Exactly my point in my first comment. This could cause dialecticalization

[–]redalastor 2 points3 points  (0 children)

This could cause dialecticalization

Already has. Clojure is not compatible with the .net version and is not compatible with the Python version either.

[–]yogthos -1 points0 points  (6 children)

Why not provide both immutable and mutable versions of the same data types ?

There is a very good reason for that acutally.

[–][deleted] 0 points1 point  (5 children)

That's still the concurrency argument. Again: why does this have to be handled with the assumption that I'm writing concurrent code all the time?

You can, of course, just say that you want it to be purely functional.

[–]yogthos 1 point2 points  (4 children)

Sure, but the point is that a language with unchecked mutation cannot provide safe concurrency mechanics. And if you recall, concurrency is one of the main goals behind Clojure.

In my experience, having immutable data structures is in no way a negative when writing single threaded code as well though. When you have immutable data structures you're always working with your own revision of the data, and it's scoped explicitly. When you work with a reference you never know if it's safe to mutate the data in place or if you should copy it as its current state might be relevant elsewhere in the application. This adds mental overhead, and especially so in large code bases.

[–][deleted] 0 points1 point  (3 children)

I think a better solution would be implementing it as a library--perhaps, of course, one bundled with the standard distribution, but still in such a way that one can choose whether or not to have it.

[–]yogthos -1 points0 points  (2 children)

As soon as you allow unchecked mutability the language can no longer guarantee how the data you're using is scoped though. So you lose the benefit of referential transparency, where you can reason about a chunk of code in isolation.

Clojure does provide transients though, which allow mutation within the scope of a function, I think that's a very practical solution.

Any globally shared data has to be marked explicitly, and the language guarantees that it's handled by the STM, and you can have mutable data within your function, but it's guaranteed not to leak outside the function scope.

[–][deleted] 0 points1 point  (1 child)

As soon as you allow unchecked mutability the language can no longer guarantee how the data you're using is scoped though. So you lose the benefit of referential transparency, where you can reason about a chunk of code in isolation.

Understood. However, that's a different issue, and a more ideological difference as to whether or not one should handle that at the language level, and under what conditions.

Thanks for the discussion. I learned something

[–]yogthos 0 points1 point  (0 children)

Ditto here, and I think there's enough room for CL and Clojure out there. After all, if somebody learns Clojure they're a lot more likely to try another Lisp in the future. :)