In your example, [1 2 3 4 5] allocates and initializes a vector with the 5
elements 1 2 3 4 5.

The first (def my-vec ...) also allocates a Var, and makes it 'point' at
the vector [1 2 3 4 5].

When you do (assoc my-vec 2 "hello"), it looks up the current value pointed
at by my-vec, which is the immutable vector [1 2 3 4 5], and it creates a
new vector [1 2 "hello" 4 5].  That new vector is also immutable.  In the
common case, it does not copy the entire vector [1 2 3 4 5] and then modify
the element 3 to "hello" -- it uses a technique called 'path copying' to
leave most of the memory that has been allocated shared between the two
vectors [1 2 3 4 5] and [1 2 "hello" 4 5].

The second (def my-vec ...) does mutate the 'pointer' for my-vec so that it
no longer points at [1 2 3 4 5], but instead points at [1 2 "hello" 4 5].
This is true mutation, not of the vectors, but of the Var my-vec.  Such
mutation helps support redefinition of functions during interactive REPL
sessions, among other things.

Andy


On Thu, Jul 3, 2014 at 2:39 PM, Evan Zamir <zamir.e...@gmail.com> wrote:

> New to Clojure (find it fascinating so far, in large part due to watching
> approximately a billion Rich Hickey vids on YouTube). I had a similar
> question and figured I just resurrect this thread on it.
>
> My naive thought was that when you (re)def a variable, you aren't actually
> copying over the old memory location, but instead simply re-creating a
> pointer to a new value or place in memory. To take this example further,
> I'm wondering what goes on under the hood when I use replace like this:
>
> (def my-vec [1 2 3 4 5])
> => (var user/my-vec)
> (def my-vec (assoc my-vec 2 "hello"))
> => (var user/my-vec)
> my-vec
> => [1 2 "hello" 4 5]
>
> Is there a good explanation out there of what happens to the old my-vec
> and whether the new my-vec actually overwrites it, points to it, or points
> to a completely new location in memory?
>
> Another way to phrase this question: is this "real" mutability or just the
> appearance of mutability?
>
>
> On Tuesday, June 15, 2010 4:51:00 AM UTC-7, Joost wrote:
>>
>> On Jun 14, 10:09 pm, Jared <tri...@gmail.com> wrote:
>> > Also, I thought this language is functional but I'm able to do change
>> > declarations in the repl. For example:
>> > user=> (def x 1)
>> > #'user/x
>> > user=> x
>> > 1
>> > user=> (def x 2)
>> > #'user/x
>> > user=> x
>> > 2
>> > user=> (def x (+ 1 x))
>> > #'user/x
>> > user=> x
>> > 3
>> >
>> > Why does that happen? This seems to go against the ideas of functional
>> > programming. I can do the same things with functions too.
>>
>> It's true that def isn't a strictly functional construct.
>>
>> That's by design, since def is the construct that allows you to define
>> and set globally accessible vars, which includes all globally
>> accessible functions.
>>
>> If you couldn't re-def a var, you couldn't redefine functions while
>> coding (or modify/extent existing functions using macros etc). Clojure
>> (like most Lisps) is a dynamic language with strong support for
>> interactive development - and you need redefineable vars (or something
>> similar) for that. The alternative is to recompile/load the whole
>> program every time you change a function definition. And that sucks
>> too much.
>>
>> In idiomatic code, you only use (def) and its variants to set up
>> globally reachable data/functions across all threads and you don't,
>> for example, use def as a way to get "variable variables" - you will
>> get bitten if you try.
>>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to