Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm new to object-oriented programming, and one concept that has been taking me a while to grasp is immutability. I think the light bulb went off last night but I want to verify:

When I come across statements that an immutable object cannot be changed, I'm puzzled because I can, for instance, do the following:

NSString *myName = @"Bob";
myName = @"Mike";

There, I just changed myName, of immutable type NSString. My problem is that the word, "object" can refer to the physical object in memory, or the abstraction, "myName." The former definition applies to the concept of immutability.

As for the variable, a more clear (to me) definition of immutability is that the value of an immutable object can only be changed by also changing its location in memory, i.e. its reference (also known as its pointer).

Is this correct, or am I still lost in the woods?

share|improve this question
13  
Your your type is not an NSString, it is a "pointer to and NSString", which is not immutable. I know nothing of objective C, but I'm guessing in your example that @"Mike" is creating a new instance of NSString and assigning it to the pointer, myName. So you haven't changed the object that myName was pointing to, just what it was pointing to. –  fwgx Jun 29 '11 at 12:44
2  
@fwgx Put it as an answer and you'll get my upvote. –  Gulshan Jun 29 '11 at 13:02
    
Thank you everyone for all the replies, they are very helpful. I now uderstand that the immutable object is the value in memory, not the variable which points to it. –  Michael Mangold Jun 29 '11 at 15:57
    
@Gulshan Done, see below.... –  fwgx Jun 29 '11 at 19:56
    
To understand immutability, I recommend learning a programming language that clearly separates binding (i.e. giving names to objects) with mutability (i.e. allowing a name to be reassigned to a different object). ML (in any guise: SML, Ocaml, F#) is a good example. –  Gilles Jun 30 '11 at 23:23

7 Answers 7

up vote 4 down vote accepted

It sounds like you're heading in the right direction, but haven't quite got it yet. This is wrong:

There, I just changed myName, of immutable type NSString. My problem is that the word, "object" can refer to the physical object in memory, or the abstraction, "myName."

In your code snippet, myName is not of immutable type NSString, it is of mutable type NSString* (pointer to NSString). It sounds like the key thing you're missing is to understand that a pointer is just another value, and it has a completely separate life from the thing it points to (or things, if you change it part way through its lifetime).

You say:

... the value of an immutable object can only be changed by also changing its location in memory, i.e. its reference (also known as its pointer).

This is wrong. An object doesn't own the pointers that point to it, nor is an object's memory location controlled or otherwise affected by any pointers to it.

So, the two NSString objects in your example (@"Bob" and @"Mike") are completely separate from the myName variable. They are also completely separate from each other. When you change myName to point to @"Mike" instead of pointing to @"Bob", you are not changing the NSString objects.


For completeness, I will note that garbage collectors make this more complex in that changes to pointers may affect the objects they point(ed) to. However, this is an implementation detail which should not affect the observable behaviour of the code.

share|improve this answer

You are lost at words. Immutability means: As long as you don't change the variable, it will always "contain" the same value, not matter what you do with other variables.

Counterexample in C (a bit simplified, assuming an architecture that allows that):

 char *a = "Hello World";
 char *b = a;
 b[0] = 'Y';

Now a no longer "contains" (i.e. points at) the string "Hello World", but it's "Yello World" instead.

In languages where strings are immutable, like Java and (EDIT: safe) C#, you cannot do that. No way. This means that every part of the program can safely keep a reference to the string and rely that its contents never change; otherwise, they would have to create a copy just to be on the safe side.

But the variable still is mutable. You can let it point to another object. It's just that the object itself won't change behind your back.

share|improve this answer
1  
You technically can modify string contents in C#, you just have to use unsafe code. –  Aaronaught Jun 29 '11 at 16:57
1  
Aaronaught: Thanks for the info, you are right; for everyone who needs to know how: msdn.microsoft.com/en-us/library/ms228599.aspx –  user281377 Jun 29 '11 at 18:35

You are confusing variables with objects. Variables can be used to store references to objects, but they are NOT objects. It is objects that are immutable, not variables, so you can change the variable from one object to another, but you cannot change the attributes of the object if its immutable.

Think of the object as a loud, drunken neighbour. If he is reasonable (mutable), you might be able to knock on his door and convert him to a lifestyle where he doesn't make as much noise. But if he is immutable, your only change is to hope that someone else moves in!

share|improve this answer
3  
I've had some neighbors that I would have loved to mute. –  Dave Nay Jun 29 '11 at 13:01
    
I don't think you need your example in the second paragraph as your explanation is good enough. IMO the example could just confuse. However +1 for a succinct answer to the chap's question. –  Paul McCabe Jun 29 '11 at 16:02
    
@DaveNay: I apologize for the stealth pun. Wasn't intended at all. –  Kilian Foth Jun 30 '11 at 12:12

A variable is not an object. A variable is a name, that refers to an object (or more generally a value).

For example "the goalkeeper" is a name we use to refer to the object (person) responsible to defend the goal. But if I substitute that person by another (because the former is injured or whatnot), the new person is now referred to as the "goalkeeper".

The assignment statement is what makes variables mutable (some languages, such as Haskell don't have it and in fact use immutable variables). It allows you to redefine the meaning of a name and thereby reassign the value.

Now objects themselves can be immutable. A few thousand years ago one could have thought of diamonds as being immutable. No matter what you did with a diamond, you could not modify it. Whether you called it waggawooga (loosely translates to "our tribe's biggest shiny stone") or ceased to call it that way (because you found a bigger one), the diamond stayed the same. In contrast the piece of wood you used to carve in funny pictures with your waggawooga did not stay the same. It proved mutable. Even if it had the same name all the time.

Both variables and values can be immutable (independently). In this case, it's the objects which are immutable. Once you construct an NSString, you can not modify it. You can call it names and pass it around, but it'll stay the same. In contrast to that, NSMutableString can be changed after creation, for example by calling the setString method.

share|improve this answer
    
Love the waggawooga comparison! –  Michael K Jun 29 '11 at 13:55
    
Just so as to not confuse the original poster more than necessary: though your point that a variable is not an object is good, a variable is not actually defined as "a name that refers to a value". A variable is possibly named, and refers to a storage location that contains a value. In many programming languages variables need not be named, and in many languages the same variable can have more than one name. –  Eric Lippert Jun 29 '11 at 17:04

I think you feel lost, because you're mixing two concepts: object itself and variable name bound to that object.

Immutable objects cannot be changed. Period. However, variable name (symbol) bound to an immutable object, can modified to be bound to another immutable object.

In other words, what you did in these two lines was:

  1. create immutable string object with value "Bob"
  2. bind symbol myName to that object
  3. create immutable string object with value "Mike"
  4. bind symbol myName to that object
share|improve this answer

Your your type is not an NSString, it is a "pointer to an NSString", which is not immutable. I know nothing of objective C, but I'm guessing in your example that @"Mike" is creating a new instance of NSString and assigning it to the pointer myName. So you haven't changed the object that myName was pointing to, just what it was pointing to.

share|improve this answer

Here's an example of a mutable object: an array of char in C:

char str[10];

I can change the contents of str to my heart's content (so long as it's no more than 10 characters). For it to be recognized as a string by the C string library functions, there has to be a trailing 0, so it can hold strings up to 9 characters in length:

strcpy(str, "hello"); // str now contains the string "hello\0"
strcpy(str, "world"); // str now contains the string "world\0"

str[0] = 'W';         // str now contains "World\0"

und so weiter.

Contrast this with a string object in Java:

String foo = "Hello";

The string instance (the chunk of memory that contains the characters 'H', 'e', 'l', 'l', and 'o') cannot be modified; I cannot alter any of the contents of that string. When you write something like

foo = foo + " World";

you're not appending " World" to the end of the "Hello" instance; you are creating a new instance, copying "Hello World" to it, and updating foo to refer to that new string instance.

foo does not itself contain the string instance; it only refers to that instance (similar to a pointer in C or Obj-C), hence why types like String are called reference types.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.