250

If immutable objects¹ are good, simple and offer benefits in concurrent programming why do programmers keep creating mutable objects²?

I have four years of experience in Java programming and as I see it, the first thing people do after creating a class is generate getters and setters in the IDE (thus making it mutable). Is there a lack of awareness or can we get away with using mutable objects in most scenarios?


¹ Immutable object is an object whose state cannot be modified after it is created.
² Mutable object is an object which can be modified after it is created.

DarkWanderer
  • 101
  • 3
Vinoth Kumar C M
  • 15,455
  • 23
  • 57
  • 86
  • 42
    I think that, apart from legitimate reasons (as mentioned by Péter below), "lazy developer" is a more common reason than "stupid" developer". And before "stupid developer" there's also "uninformed developer". – Joachim Sauer Jun 06 '12 at 07:58
  • 201
    For every evangelical programmer/blogger there are 1000 avid blog readers that immediately re-invent themselves and adopt the latest techniques. For every one of those there are 10,000 programmers out there with their nose to the grind stone getting a days work done and getting product out the door. Those guys are using tried and trusted techniques that have worked for them for years. They wait until new techniques are widely adopted and show actual benefits before taking them up. Don't call them stupid, and they're anything but lazy, call them "busy" instead. – Binary Worrier Jun 06 '12 at 12:21
  • 22
    @BinaryWorrier: immutable objects are hardly a "new thing". They might not have been used heavily for domain objects, but Java and C# had them from the very beginning. Also: "lazy" is not always a bad word, some kinds of "lazy" are an absolute advantage for a developer. – Joachim Sauer Jun 06 '12 at 13:51
  • 11
    @Joachim: I think it's fairly obvious that "lazy" was used in it's pejorative sense above :) Also, Immutable Objects (like Lambda Calculus, and OOP back in the day - yes I am that old) don't need to be new to suddenly become _flavour of the month_. I'm not arguing that they're a bad thing (they're not), or that they don't have their place (they obviously do), just go easy on folks because they haven't heard the latest Good Word and been converted as fervently oneself (not blaming you for the "lazy" comment, I know you tried to mitigate it). – Binary Worrier Jun 06 '12 at 14:41
  • 4
    By the way, it's not "getters" and "setters" that make an object mutable or not. Public member variables can be modified without getters and setters--and that makes an object mutable. – Onorio Catenacci Jun 06 '12 at 17:53
  • 2
    Don't call them lazy. I am lazy. I make my classes immutable (usually), because it increases my chance of getting it right first time, and I can't be bothered with debugging. Yes busy is the word, very busy. – ctrl-alt-delor Jun 06 '12 at 18:13
  • 1
    BTW - even if we ignore the whole mutability vs immutability issue, public getters and setters are a well known source of pain in OO design, since they tend to break encapsulation and invariants. – hugomg Jun 06 '12 at 18:28
  • 1
    one reason: convenience – dietbuddha Jun 06 '12 at 19:31
  • 116
    -1, immutable objects arent 'good'. Just more or less appropriate for specific situations. Anyone telling you one technique or another is objectively 'good' or 'bad' over another for all situations is selling you religion. – GrandmasterB Jun 06 '12 at 20:43
  • 10
    Why are immutable objects good? – user16764 Jun 07 '12 at 03:40
  • 3
    Why do people keep using the Java language at all, if it is on one hand ridiculously uncompromising about "good style" of pure OO but does very little to even encourage style decisions that would _really_ be useful, such as not using mutable state? – leftaroundabout Jun 07 '12 at 09:10
  • 2
    @GrandmasterB read "if" as "given that" and you don't need to be offended by the opening of the question ;-) –  Jun 08 '12 at 14:34
  • In iOS objective-C, array = [array arraywithobject:] performance sucks... So immutable for performance. – Paul Aug 17 '12 at 15:10
  • 7
    @leftaroundabout I use Java because it works. It's not the latest fashion, but it works. – Paul Aug 17 '12 at 15:13
  • 4
    What's the point in objects if everything is immutable? Use proper functional languages instead. – SK-logic Sep 20 '12 at 09:13
  • 3
    Immutable vs mutable is failure to recognize the real problem IMO which is an excess of objects mutating other objects. – Erik Reppen Nov 05 '13 at 04:06
  • 5
    Of course if you design your objects to just be data-classes then I guess immutable is a "good-thing". However, good OO designs generally don't design their classes to just be data-classes. Thus, I really wonder about the types of designs coming out of people that make extensive use of immutable objects. – Dunk Nov 05 '13 at 15:09
  • 1
    Just a bit related to Immutability. But getters and setters is a direct violation of Encapsulation which is the main principle of OOP. This takes the responsibility of the state of the data away from the Object/Class which pretty much defeats the purpose of OOP. – andho Jan 29 '15 at 04:54
  • 1
    Mutable objects aren't bad. The problem is that they are often abused and handled irresponsibly. It does irk me a little when I run across a method that returns a value and edits the mutable parameters with zero documentation. (what happened to the single responsibility principle). – Isaiah van der Elst Sep 26 '15 at 00:00
  • @GrandmasterB - Could you please give some examples for situations where immutable are more appropriate ? – BornToCode Jan 10 '16 at 14:50
  • 1
    Immutable is best for 5% of stuff, mutable is best for 5% of stuff, and the other 90% of the time these objects aren't being used it ways where it matters either way. Therefore since mutable is default it takes that 90%. So 95% is mutable...which is about what most programmers do. Most people don't treat trends as religions...we just use them where they're useful. – Jimbo Jonny Apr 02 '16 at 19:57
  • 1
    @andho - ...that's 100% incorrect. Getters and setters are actually, literally, what makes encapsulation in OOP by abstracting away the internal changes to the external accessors/mutators (i.e. getters/setters). Read up on OOP: http://codebetter.com/raymondlewallen/2005/07/19/4-major-principles-of-object-oriented-programming/ – Jimbo Jonny Apr 02 '16 at 20:03
  • @JimboJonny if implemented correctly yes. But in context of a Java Bean, any other object is able to manipulate the data the class is responsible for and allows invalidating the invariants of the object. This style is okay for Anemic Domains, but then they are just data structures. All setters are mutators but not all mutators are setters. If you implement mutators as command methods, the classes will become more descriptive and more appropriate to the essence of OOP. The problem is most of the time, the classes not having any behaviour/logic except setting and getting values. – andho Apr 07 '16 at 04:18

23 Answers23

326

Both mutable and immutable objects have their own uses, pros and cons.

Immutable objects do indeed make life simpler in many cases. They are especially applicable for value types, where objects don't have an identity so they can be easily replaced. And they can make concurrent programming way safer and cleaner (most of the notoriously hard to find concurrency bugs are ultimately caused by mutable state shared between threads). However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious. And for objects with a distinct identity, changing an existing objects is much more simple and intuitive than creating a new, modified copy of it.

Think about a game character. In games, speed is top priority, so representing your game characters with mutable objects will most likely make your game run significantly faster than an alternative implementation where a new copy of the game character is spawned for every little change.

Moreover, our perception of the real world is inevitably based on mutable objects. When you fill up your car with fuel at the gas station, you perceive it as the same object all along (i.e. its identity is maintained while its state is changing) - not as if the old car with an empty tank got replaced with consecutive new car instances having their tank gradually more and more full. So whenever we are modeling some real-world domain in a program, it is usually more straightforward and easier to implement the domain model using mutable objects to represent real-world entities.

Apart from all these legitimate reasons, alas, the most probable cause why people keep creating mutable objects is inertia of mind, a.k.a. resistance to change. Note that most developers of today have been trained well before immutability (and the containing paradigm, functional programming) became "trendy" in their sphere of influence, and don't keep their knowledge up to date about new tools and methods of our trade - in fact, many of us humans positively resist new ideas and processes. "I have been programming like this for nn years and I don't care about the latest stupid fads!"

Péter Török
  • 46,427
  • 16
  • 160
  • 185
  • 27
    That's right. Especially in GUI programming, mutable object are very handy. – Florian Salihovic Jun 06 '12 at 07:56
  • 23
    It's not just resistance, I'm sure lots of devs would love to try out the latest and greatest, but how often do new projects spin up in the average dev's environment where they can apply these new practices? Not everone can or will write a hobby project just to try out immutable state. – Steven Evers Jun 06 '12 at 14:18
  • 29
    Two small caveats to this: (1) Take the moving game character. The `Point` class in .NET for instance is immutable but creating new points as the result of changes is easy and thus affordable. Animating an immutable character can be made very cheap by decoupling the “moving parts” (but yes, *some* aspect is then mutable). (2) “large and/or complex objects” can very well be immutable. Strings are often large, and usually benefit from immutability. I once rewrote a complex graph class to be immutable, making the code simpler and more efficient. In such cases, having a mutable builder is the key. – Konrad Rudolph Jun 06 '12 at 14:23
  • 2
    @SnOrfus, good point, I should add that resistance may come from the organization as well. Luckily, we can always look for a better workplace :-) – Péter Török Jun 06 '12 at 14:41
  • 4
    @KonradRudolph, good points, thanks. I did not mean to rule out using immutability in complex objects, but implementing such a class correctly and efficiently is far from being a trivial task, and the extra effort required may not be always justified. – Péter Török Jun 06 '12 at 14:47
  • 6
    You make a good point about state vs identity. This is why Rich Hickey (author of Clojure) broke the two apart in Clojure. One could argue, that the car you have with 1/2 tank of gas is not the same car as the one with 1/4 tank of gas. They have the same identity, but they are not the same, every "tick" of our reality's time creates a clone of every object in our world, our brains then simply stitch these together with a common identity. Clojure has refs, atoms, agents, etc. to represent time. And maps, vectors and lists for actual time. – Timothy Baldridge Jun 06 '12 at 18:56
  • 1
    Even more than simply moving a character around, imagine a particle effect system. Imagine the cost in time and memory to instantiate hundreds, possibly thousands of new particle objects 60 times per second. Mutable particles, with mutable world positions have a tremendous performance advantage. – scriptocalypse Jun 06 '12 at 20:09
  • 1
    As of speed - the compiler could optimize it out so the immutable object are mutable behind scene and/or reason about the code enabling further optimalisation. Of course it does not mean it do. @scriptocalypse: One could argue that if you mutate all of the state that make no difference performance-wise. If the 'objects' are large arrays then computation usually IS non-destructive(code writes into different region of memory the it reads from) - for example on GPUs. Which makes the particle systems probably a bad example. – Maciej Piechotka Jun 08 '12 at 04:54
  • 1
    @TimothyBaldridge, fair enough, "you can't step twice into the same stream", stated [Heraclitus](http://en.wikipedia.org/wiki/Heraclitus) more than 2K years ago :-) – Péter Török Jun 08 '12 at 07:42
  • @KonradRudolph: The `Point` structure in .net exposes its fields and thus allows them to be mutated by anything which has access to *the storage location holding the `Point` which contains them*. Note that the fields of all non-trivial structs stored in mutable storage locations are mutable (even if only by doing an all-field-copy assignment), and the fields of all structs stored in immutable storage locations are immutable. – supercat Jul 06 '12 at 20:27
  • @supercat Ouch, my mistake. Still, I think that it *could* have been just as well been made immutable. – Konrad Rudolph Jul 07 '12 at 08:41
  • 1
    "Note that most developers of today have been trained well before immutability (and the containing paradigm, functional programming) became "trendy" in their sphere of influence": I find this a bit strange though: FP languages have been around for more than 40 years and are quite common in Computer Science curricula. My main education was with procedural and object-oriented programming languages but I had to learn about Lisp, lambda calculus, etc, so now the switch to FP is not that hard. So I do not totally understand this inertia and this difficulty to think in a different paradigm. – Giorgio Aug 23 '12 at 08:22
  • 1
    @Giorgio, when did you study CS? I graduated in 1994 and our curricula contained none of FP nor lambda calculus, although it was math / theory heavy. Fair enough, my country was not and is not at the cutting edge regarding IT and CS, so it may be that FP was more well known in the academia of other parts of the world even back then. – Péter Török Aug 23 '12 at 20:01
  • @Péter Török: I graduated in 1993 in Italy. We had one course on computability, covering lambda calculus, and one general course on programming languages, covering the principles of procedural, object-oriented, functional, and logic programming languages. I did one project in Prolog and also played a bit with Lisp at that time. We also learnt about denotational semantics, which is also based on composing functions and often uses the lambda notation. – Giorgio Aug 23 '12 at 21:54
  • 2
    @FlorianSalihovic, ever heard of functional reactive programming? – SK-logic Sep 20 '12 at 09:17
  • +1 for *where objects don't have an identity*. Making up efficient reference-able identity was mostly impossible to me. I still want a trick to solve it. – Eonil Aug 28 '13 at 12:52
  • Well, if you consider gas in fuel tank is apart, you don't need to recreate the car and you can still keep most things immutable. – hurturk Mar 07 '14 at 18:30
  • 1
    "However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious." Generally true in most languages, but Clojure (and the genius of Rich Hickey) specifically seems to alleviate this concern by implementing persistent data structures. – Evan Zamir Dec 02 '14 at 20:20
  • @KonradRudolph It would be cool if languages allowed you to speak of 'values' and 'objects', and the compiler/interpreter would work out when it is appropriate (taking into account correctness and efficiency) to copy the data vs referencing it. – weberc2 Jan 30 '15 at 18:03
  • Immutability is now being embraced in "GUI", especially in the Web. See Redux, ImmutableJS, Rx, and the like. – srph Dec 13 '15 at 08:52
130

I think you've all missed the most obvious answer. Most developers create mutable objects because mutability is the default in imperative languages. Most of us have better things to do with our time than to constantly modify code away from the defaults--more correct or not. And immutability is not a panacea any more than any other approach. It makes some things easier but makes others much more difficult as some answers have already pointed out.

Onorio Catenacci
  • 2,937
  • 3
  • 26
  • 37
  • 9
    In most modern IDEs I know, it takes practically the same amount of effort to generate only getters, as to generate both getters and setters. Although it is true that adding `final`, `const` etc. takes a bit of extra effort... unless you set up a code template :-) – Péter Török Jun 07 '12 at 07:19
  • 10
    @PéterTörök it's not just the additional effort--it's the fact that your fellow coders will want to hang you in effigy because they find your coding style so alien to their experience. That also discourages this sort of thing. – Onorio Catenacci Jun 07 '12 at 12:37
  • 5
    That might be overcome with more communication and education, e.g. it is advisable to talk or give a presentation to one's teammates about a new coding style before actually introducing it into an existing codebase. It is true that a good project has a common coding style which is not just an amalgam of the coding styles favoured by every (past and present) project member. So introducing or changing coding idioms should be a team decision. – Péter Török Jun 07 '12 at 13:08
  • 3
    @PéterTörök In an imperative language mutable objects are the default behavior. If you want only immutable objects, it is best to switch to a functional language. – emory Jun 08 '12 at 01:15
  • @PéterTörök - it's also not just about the initial code that your tools can help you with. What about when you make changes? When you add a new field to your immutable type, do you remember to update equality and hashcode functions as well? – Pete Jun 10 '14 at 07:29
  • I think this is the most correct answer. Say you were developing in F# for example, you would create immutable types pr. default. I doubt that most developers would start adding 'mutable' keywords to their F# types, even if they came straight from an imperative programming style – Pete Jun 10 '14 at 07:33
  • Getters and setters are not the whole story; there are other aspects of a language that can support or discourage programming with immutable objects. Clojure, for example, by default provides functions such as `swap!` and `update-in`. I am by no means an knowledgable Clojure programmer, but I believe it can make a difference. – Martijn Jun 02 '15 at 07:53
  • 3
    @PéterTörök It's a little naive to assume that incorporating immutability into a program involves nothing more than dropping all setters. You still need a way for the state of the program to change incrementally, and for this you need builders, or popsicle immutability, or mutable proxies, all of which take about 1 billion times the effort just dropping the setters took. – Asad Saeeduddin Aug 01 '15 at 06:44
49
  1. There is a place for mutability. Domain driven design principles provide a solid understanding of what should be mutable and what should be immutable. If you think about it you will realize it is impractical to conceive of a system in which every change of state to an object requires the destruction and re-composition of it, and to every object that referenced it. With complex systems this could easily lead to completely wiping and rebuilding the entire system's object graph

  2. Most developers don't make anything where the performance requirements are significant enough that they need to focus on concurrency (or a lot of other issues that are universally considered good practice by the informed).

  3. There are some things you simply can't do with immutable objects, like have bidirectional relationships. Once you set an association value on one object, it's identity changes. So, you set the new value on the other object and it changes as well. The problem is the first object's reference is no longer valid, because a new instance has been created to represent the object with the reference. Continuing this would just result in infinite regressions. I did a little case study after reading your question, here's what it looks like. Do you have an alternative approach that allows such functionality while maintaining immutability?

        public class ImmutablePerson { 
    
         public ImmutablePerson(string name, ImmutableEventList eventsToAttend)
         {
              this.name = name;
              this.eventsToAttend = eventsToAttend;
         }
         private string name;
         private ImmutableEventList eventsToAttend;
    
         public string Name { get { return this.name; } }
    
         public ImmutablePerson RSVP(ImmutableEvent immutableEvent){
             // the person is RSVPing an event, thus mutating the state 
             // of the eventsToAttend.  so we need a new person with a reference
             // to the new Event
             ImmutableEvent newEvent = immutableEvent.OnRSVPReceived(this);
             ImmutableEventList newEvents = this.eventsToAttend.Add(newEvent));
             var newSelf = new ImmutablePerson(name, newEvents);
             return newSelf;
         }
        }
    
        public class ImmutableEvent { 
         public ImmutableEvent(DateTime when, ImmutablePersonList peopleAttending, ImmutablePersonList peopleNotAttending){
             this.when = when;     
             this.peopleAttending = peopleAttending;
             this.peopleNotAttending = peopleNotAttending;
         }
         private DateTime when; 
         private ImmutablePersonList peopleAttending;
         private ImmutablePersonList peopleNotAttending;
         public ImmutableEvent OnReschedule(DateTime when){
               return new ImmutableEvent(when,peopleAttending,peopleNotAttending);
         }
         //  notice that this will be an infinite loop, because everytime one counterpart
         //  of the bidirectional relationship is added, its containing object changes
         //  meaning it must re construct a different version of itself to 
         //  represent the mutated state, the other one must update its
         //  reference thereby obsoleting the reference of the first object to it, and 
         //  necessitating recursion
         public ImmutableEvent OnRSVPReceived(ImmutablePerson immutablePerson){
               if(this.peopleAttending.Contains(immutablePerson)) return this;
               ImmutablePersonList attending = this.peopleAttending.Add(immutablePerson);
               ImmutablePersonList notAttending = this.peopleNotAttending.Contains( immutablePerson ) 
                                    ? peopleNotAttending.Remove(immutablePerson)
                                    : peopleNotAttending;
               return new ImmutableEvent(when, attending, notAttending);
         }
        }
        public class ImmutablePersonList
        {
          private ImmutablePerson[] immutablePeople;
          public ImmutablePersonList(ImmutablePerson[] immutablePeople){
              this.immutablePeople = immutablePeople;
          }
          public ImmutablePersonList Add(ImmutablePerson newPerson){
              if(this.Contains(newPerson)) return this;
              ImmutablePerson[] newPeople = new ImmutablePerson[immutablePeople.Length];
              for(var i=0;i<immutablePeople.Length;i++)
                  newPeople[i] = this.immutablePeople[i];
              newPeople[immutablePeople.Length] = newPerson;
          }
          public ImmutablePersonList Remove(ImmutablePerson newPerson){
              if(immutablePeople.IndexOf(newPerson) != -1)
              ImmutablePerson[] newPeople = new ImmutablePerson[immutablePeople.Length-2];
              bool hasPassedRemoval = false;
              for(var i=0;i<immutablePeople.Length;i++)
              {
                 hasPassedRemoval = hasPassedRemoval || immutablePeople[i] == newPerson;
                 newPeople[i] = this.immutablePeople[hasPassedRemoval ? i + 1 : i];
              }
              return new ImmutablePersonList(newPeople);
          }
          public bool Contains(ImmutablePerson immutablePerson){ 
             return this.immutablePeople.IndexOf(immutablePerson) != -1;
          } 
        }
        public class ImmutableEventList
        {
          private ImmutableEvent[] immutableEvents;
          public ImmutableEventList(ImmutableEvent[] immutableEvents){
              this.immutableEvents = immutableEvents;
          }
          public ImmutableEventList Add(ImmutableEvent newEvent){
              if(this.Contains(newEvent)) return this;
              ImmutableEvent[] newEvents= new ImmutableEvent[immutableEvents.Length];
              for(var i=0;i<immutableEvents.Length;i++)
                  newEvents[i] = this.immutableEvents[i];
              newEvents[immutableEvents.Length] = newEvent;
          }
          public ImmutableEventList Remove(ImmutableEvent newEvent){
              if(immutableEvents.IndexOf(newEvent) != -1)
              ImmutableEvent[] newEvents = new ImmutableEvent[immutableEvents.Length-2];
              bool hasPassedRemoval = false;
              for(var i=0;i<immutablePeople.Length;i++)
              {
                 hasPassedRemoval = hasPassedRemoval || immutableEvents[i] == newEvent;
                 newEvents[i] = this.immutableEvents[hasPassedRemoval ? i + 1 : i];
              }
              return new ImmutableEventList(newPeople);
          }
          public bool Contains(ImmutableEvent immutableEvent){ 
             return this.immutableEvent.IndexOf(immutableEvent) != -1;
          } 
        }
    
smartcaveman
  • 1,522
  • 2
  • 11
  • 11
  • -1 It's not true _as a general rule_ that a single change to a well-designed immutable object, no matter how complex, usually requires "the destruction and re-composition of it" or that it risks "rebuilding the entire object graph". Where did you get that notion? – Andres F. Jun 07 '12 at 02:32
  • 1
    @AndresF., You're right. That is not the case. However, that's because no one actually builds complete systems out of immutable objects. If they did, then this would be a real concern. If you read my answer, you will see that I did not say it was a general rule. I said it was a potential implication of taking the preference for immutability to an absurd extent. The purpose of the code example is to demonstrate the kind of complications that would arise from a very basic application functionality that made EVERYTHING immutable. – smartcaveman Jun 07 '12 at 03:34
  • 2
    @AndresF., if you have a different take on how to maintain complex graphs with bidirectional relationships using only immutable objects, then I would love to hear it. (I assume we can agree that a collection/array is an object) – smartcaveman Jun 07 '12 at 03:36
  • @smartcaveman I was only addressing point 1, which is false. In general, making a change to a complex immutable object doesn't require rebuilding everything from scratch; you can reuse those immutable parts that haven't changed (this is one direct consequence of immutability: reuse). I do agree with you bidirectional relationships, as modeled by Java, seem to require some mutability. – Andres F. Jun 07 '12 at 03:54
  • 2
    @AndresF., (1) My first statement was not universal so it was not false. I actually provided a code example to explain how it was necessarily true in certain cases which happen to be very common in application development. (2) Bidirectional relationships require mutability, in general. I don't believe that Java is the culprit. As I said, I'd be happy to evaluate any **constructive** alternatives you would suggest, but at this point you're comments sound a lot like "You're wrong because I said so". – smartcaveman Jun 07 '12 at 16:31
  • 14
    @smartcaveman About (2), I also disagree: in general, a "bidirectional relationship" is a mathematical concept orthogonal to mutability. As usually implemented in Java it does require mutability (I agreed with you on that point). However, I can think of an alternative implementation: a Relationship class between the two objects, with a constructor `Relationship(a, b)`; at the point of creating the relationship, both entities `a` & `b` already exist, and the relationship itself is also immutable. I'm not saying this approach is practical in Java; just that it's possible. – Andres F. Jun 07 '12 at 17:21
  • 4
    @AndresF., So, based on what you're saying, If `R` is the `Relationship(a,b)` and both `a` and `b` are immutable, neither `a` nor `b` would hold a reference to `R`. For this to work, the reference would have to be stored somewhere else (like a static class). Am I understanding your intention correctly? – smartcaveman Jun 07 '12 at 18:38
  • Someplace else, yes, but I wouldn't choose a static class (for reasons you probably know). This is cumbersome and non-idiomatic in Java, sure -- but it's _possible_, which was my point. – Andres F. Jun 07 '12 at 19:00
  • 1
    @AndresF., I get you're point, but we're moving away from OOP. I do understand concurrency issues, but if we are sticking with the "all must be immutable" constraint then I think a static class is still the only option. Otherwise, **how would you locate the reference when you need it?** `a` doesn't have it, `b` doesn't have it, and if the owner of `R` is not static, then any reference to the owner of `R` would be lost whenever another relationship of the same type is created, because an immutable collection will return a new instance after it's `Add` operation mutates its content – smartcaveman Jun 07 '12 at 19:09
  • 1
    Actually, #3 isn't exactly right either; I had a problem in a Scala datastructure, and in that language it can be solved with lazy vals. – cthulhu Jun 10 '12 at 00:55
  • 1
    I think one could have bidirectional relationships with immutable data, if one defines immutability to mean that no execution path could cause an object to be *dereferenced* outside the execution context of its constructor until after its constructor is complete, and allows constructor parameters of immutable types to specify that the passed-in object will not be put anywhere that would be accessible without a reference to the object being constructed. If object #1 passes a reference to itself as such a parameter to the constructor of object #2, but constructor #2 is forbidden... – supercat Aug 24 '12 at 14:51
  • ...from doing anything with that parameter beyond storing it within its fields or passing it as a similarly-constrained parameter to the constructor of another immutable object with which it would do nothing but store a reference in its fields, then no direct or indirect rooted reference to object #1 would ever exist outside the execution context of object #1's constructor. Such constraints would allow one to create many types of bidirectionally-referenced data structures in programs that could be statically determined to behave as though all the objects were immutable. – supercat Aug 24 '12 at 14:56
  • To my mind, the key point of immutability is that every aspect of an object's state must attain its final value before the first time that aspect is observed. There should be no problem with an object exposing references to itself to code which can be statically verified not to examine its state, nor expose the reference to anything that would examine its state. I don't know if any languages or frameworks support such constrained parameters, but it would seem like a useful thing for a language which wishes to promote immutability. – supercat Aug 24 '12 at 15:00
  • 9
    It is possible to store a bidirectional relationship for immutable data as Chthulhu points out via laziness. Here is one way to do this: http://www.haskell.org/haskellwiki/Tying_the_Knot – Thomas Eding Aug 24 '12 at 23:36
  • 1
    So I know this question is super old but I am struggling with the issue of [inherent bidirectional relationships in my domain model](http://stackoverflow.com/questions/24677719/refactoring-domain-model-with-mutability-and-cyclical-dependencies-to-work-for-s) and how to avoid them. I was hoping I could get some advice from you guys? – Matt Foxx Duncan Jul 11 '14 at 15:22
36

I've been reading "purely functional data structures", and it's made me realize that there are quite a few data structures that are much easier to implement using mutable objects.

To implement a binary search tree, you have to return a new tree every time: Your new tree will have had to make a copy of each node that has been modified (the un-modified branches are shared). For your insert function this isn't too bad, but for me, things got fairly inefficient quickly when I started to work on delete and re-balance.

The other thing to realize is that you can go years writing object oriented code, and never really realize how terrible shared mutable state can be, if your code isn't run in a way that will expose concurrency problems.

Paul Sanwald
  • 1,459
  • 13
  • 11
29

From my point of view, that's a lack of awareness. If you look at other known JVM languages (Scala, Clojure), mutable objects are seen rarely in the code and that's why people start using them in scenarios where single threading is not enough.

I'm currently learning Clojure and have a little experience in Scala (4 years + in Java as well) and your coding style changes because of the awareness of state.

Gary
  • 24,420
  • 9
  • 63
  • 108
  • Perhaps "known" rather than "popular" would be a better choice of word. – Den Jun 06 '12 at 08:32
  • Yes, that's right. – Florian Salihovic Jun 06 '12 at 08:33
  • 5
    +1: I agree: after learning some Scala and Haskell, I tend to use final in Java and const in C++ everywhere. I also use immutable objects if possible and, while mutable objects are still needed very often, it is amazing how often you can use immutable ones. – Giorgio Aug 17 '12 at 16:19
  • 5
    I read this comment of mine after two and a half years, and my opinion has changed in favour of immutability. In my current project (which is in Python) we are using mutable objects very very seldom. Even our persistent data is immutable: we create new records as the result of some operations and delete old records when they are not needed any more, but we never update any record on disk. Needless to say, this has made our concurrent, multiuser application much easier to implement and maintain up to now. – Giorgio Dec 09 '14 at 21:51
13

I think one major contributing factor has been ignored: Java Beans rely heavily on a specific style of mutating objects, and (especially considering the source) quite a few people seem to take that as a (or even the) canonical example of how all Java should be written.

Jerry Coffin
  • 44,385
  • 5
  • 89
  • 162
  • 4
    +1, the getter/setter pattern is used way too often as some sort of default implementation after the first data analysis. – Jaap Jun 07 '12 at 12:12
  • This is probably a big point ... "because that is how everyone else is doing it" ... so it must be right. For a "Hello World" program it is probably easiest. Managing object state-changes via a slew of mutable properties... that is a little more tricky than the depths of "Hello World" understanding. 20 years later I am very much surprised that the pinnacle of 20th century programming is to write getX and setX methods (how tedious) over every attribute of an object with no structure whatsoever. It is only one step away from directly accessing public properties with 100% mutability. – Darrell Teague Mar 15 '13 at 20:53
12

Every enterprise Java system that I've worked on in my career uses either Hibernate or the Java Persistence API (JPA). Hibernate and JPA essentially dictate that your system uses mutable objects, because the whole premise of them is that they detect and save changes to your data objects. For many projects the ease of development that Hibernate brings is more compelling than the benefits of immutable objects.

Obviously mutable objects have been around for much longer than Hibernate, so Hibernate is probably not the original 'cause' of the popularity of mutable objects. Maybe the popularity of mutable objects allowed Hibernate to flourish.

But today if many junior programmers cut their teeth on enterprise systems using Hibernate or another ORM then presumably they'll pick up the habit of using mutable objects. Frameworks like Hibernate may be entrenching the popularity of mutable objects.

gutch
  • 520
  • 1
  • 4
  • 10
  • Excellent point. To be all things to all people, such frameworks have little choice but to drop to the lowest common denominator, use reflection based proxies and get/set their way to flexibility. Of course this creates systems with little to no state-transition rules or a common means by which to implement them unfortunately. I am not entirely sure after many projects now what is better for expediency, extensibility and correctness. I tend to think a hybrid. Dynamic ORM goodness but with some definitions for which fields are required and what state changes should be possible. – Darrell Teague Mar 15 '13 at 20:57
9

A major point not yet mentioned is that having the state of an object be mutable makes it possible to have the identity of the object which encapsulates that state be immutable.

Many programs are designed to model real-world things which are inherently mutable. Suppose that at 12:51am, some variable AllTrucks holds a reference to object #451, which is the root of a data structure which indicates what cargo is contained in all the trucks of a fleet at that moment (12:51am), and some variable BobsTruck can be used to get a reference to object #24601 points to an object which indicates what cargo is contained in Bob's truck at that moment (12:51am). At 12:52am, some trucks (including Bob's) are loaded and unloaded, and data structures are updated so that AllTrucks will now hold a reference to a data structure which indicates the cargo is in all the trucks as of 12:52am.

What should happen to BobsTruck?

If the 'cargo' property of each truck object is immutable, then object #24601 will forevermore represent the state that Bob's truck had at 12:51am. If BobsTruck holds a direct reference to object #24601, then unless the code which updates AllTrucks also happens to update BobsTruck, it will cease to represent the current state of Bob's truck. Note further that unless BobsTruck is stored in some form of mutable object, the only way that the code which updates AllTrucks could update it would be if the code was explicitly programmed to do so.

If one wants to be able to use BobsTruck to observe the state Bob's truck while still keeping all objects immutable, one could have BobsTruck be an immutable function which, given the value that AllTrucks has or had at any particular time, will yield the state of Bob's truck at that time. One could even have it hold a pair of immutable functions--one of which would be as above, and the other of which would accept a reference to a fleet state and a new truck state, and return a reference to a new fleet state which matched the old, except that Bob's truck would have the new state.

Unfortunately, having to use such a function every time one wants to access the state of Bob's truck could get rather annoying and cumbersome. An alternative approach would be to say that object #24601 will always and forevermore (as long as anyone holds a reference to it) represent the current state of Bob's truck. Code which will want to repeatedly access the current state of Bob's truck wouldn't have to run some time-consuming function every time--it could simply do a lookup function once to find out that object #24601 is Bob's truck, and then simply access that object any time it wants to see the present state of Bob's truck.

Note that the functional approach is not without advantages in a single-threaded environment, or in a multi-threaded environment where threads will mostly just be observing data rather than changing it. Any observer thread which copies the object reference contained in AllTrucks and then examines the truck states represented thereby will see the state of all the trucks as of the moment that it grabbed the reference. Any time an observer thread wants to see newer data, it can just re-grab the reference. On the other hand, having the entire state of the fleet represented by a single immutable object would preclude the possibility of two threads updating different trucks simultaneously, since each thread if left to its own devices would produce a new "fleet state" object which included the new state of its truck and the old states of every other. Correctness may be assured if each each thread uses CompareExchange to update AllTrucks only if it hasn't changed, and responds to a failed CompareExchange by regenerating its state object and retrying the operation, but if more than one thread attempts a simultaneous write operation, performance will generally be worse than if all writing were done on a single thread; the more threads attempt such simultaneous operations, the worse the performance will get.

If individual truck objects are mutable but have immutable identities, the multi-threaded scenario becomes cleaner. Only one thread may be allowed to operate at a time on any given truck, but threads operating on different trucks could do so without interference. While there are ways one could emulate such behavior even when using immutable objects (e.g. one could define the "AllTrucks" objects so that setting state of truck belonging to XXX to SSS would simply require generating an object that said "As of [Time], the state of the truck belonging to [XXX] is now [SSS]; the state of everything else is [Old value of AllTrucks]". Generating such an object would be fast enough that even in the presence of contention, a CompareExchange loop wouldn't take long. On the other hand, using such a data structure would substantially increase the amount of time required to find a particular person's truck. Using mutable objects with immutable identities avoids that problem.

supercat
  • 8,335
  • 22
  • 28
8

There's no right or wrong, it just depends what you prefer. There's a reason why some people prefer languages that favor one paradigm over another, and one data model over another. It just depends on your preference, and on what you want to achieve (and being able to easily use both approaches without alienating die-hard fans of one side or another is a holy grail some languages are seeking after).

I think the best and quickest way to answer your question is for you to head over Pros and Cons of Immutability vs Mutability.

haylem
  • 28,856
  • 10
  • 103
  • 119
7

Check this blog post: http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html. It summarizes why immutable objects are better than mutable. Here is a short list of arguments:

  • immutable objects are simpler to construct, test, and use
  • truly immutable objects are always thread-safe
  • they help to avoid temporal coupling
  • their usage is side-effect free (no defensive copies)
  • identity mutability problem is avoided
  • they always have failure atomicity
  • they are much easier to cache

People are using mutable objects, as far as I understand, because they are still mixing OOP with imperative procedural programming.

yegor256
  • 233
  • 3
  • 8
5

In Java immutable objects require a constructor that will take all the properties of the object (or the constructor creates them from other arguments or defaults). Those properties should be marked final.

There are four problems with this mostly having to do with data binding:

  1. Java Constructors reflection meta-data does not retain the argument names.
  2. Java Constructors (and methods) do not have named parameters (also called labels) thus it gets confusing with many parameters.
  3. When inheriting another immutable object proper order of constructors must be called. This can be rather tricky to the point of just giving up and leaving one of the fields non-final.
  4. Most binding technologies (like Spring MVC Data Binding, Hibernate, etc...) will only work with no-arg default constructors (this was because annotations did not always exist).

You can mitigate #1 and #2 using annotations like @ConstructorProperties and creating another mutable builder object (usually fluent) to create the immutable object.

Adam Gent
  • 109
  • 1
  • 5
5

Im surprised that no one has mentioned the performance optimization benefits. Depending on the language a compiler can make a bunch of optimizations when dealing with immutable data because it knows the data will never change. All sorts of stuff is skipped over, which gives you tremendous performance benefits.

Also immutable objects almost eliminate the entire class of state bugs.

Its not as big as it should be because its harder, doesn't apply to every language and most people were taught imperative coding.

Also i have found that most programmers are happy in their box and are often resistant to new ideas that they don't completely understand. In general people dont like change.

Also remember, that the state of most programmers is bad. Most programming that is done in the wild is terrible and its caused by a lack of understanding and politics.

Jay
  • 1
  • 1
  • 1
4

Why do people use any powerful feature? Why do people use meta-programming, laziness or dynamic typing? The answer is convenience. Mutable state is so easy. It's so easy to update in place and the threshold of project size where immutable state is more productive to work with than mutable state is quite high so the choice won't bite you back for a while.

dan_waterworth
  • 7,287
  • 2
  • 34
  • 45
4

Programming languages are designed for execution by computers. All important building blocks of computers - CPU's, RAM, cache, disks - are mutable. When they aren't (BIOS), they're really immutable and you can't create new immutable objects either.

Hence, any programming language built on top of immutable objects suffers from a representation gap in its implementation. And for early languages such as C, that was a big stumbling block.

MSalters
  • 8,692
  • 1
  • 20
  • 32
1

Without mutable objects you have no state. Admittedly, this is a good thing if you can manage it and if there is any chance an object might be referenced from more than one thread. But the program is going to be rather boring. A lot of software, particularly web servers, avoids taking responsibility for mutable objects by pushing mutability off on databases, operating systems, system libraries, etc. As a practical matter, this does free the programmer from mutability problems and makes web (and other) development affordable. But the mutability is still there.

In general, you have three types of classes: normal, non-thread-safe classes, that have to be carefully guarded and protected; immutable classes, which can be used freely; and mutable, thread-safe classes that can be used freely but which must be written with extreme care. The first type is the troublesome one, with the worst ones being those that are thought to be of the third type. Of course, the first type are the easy ones to write.

I usually end up with lots of normal, mutable classes that I have to watch very carefully. In a multi-thread situation, the synchronization necessary slows everything down even when I can avoid a deadly embrace. So I'm ususally making immutable copies of the mutable class and handing those off to whoever can use it. A new immutable copy is needed every time the orignal mutates, so I imagine at times I may have a hundred copies of the original out there. I'm utterly dependent on Garbage Collection.

In summary, non-thread-safe, mutable objects are fine if you are not using multiple threads. (But multithreading is inflitrating everywhere--be careful!) They can be used safely otherwise if you restrict them to local variables or rigorously synchronize them. If you can avoid them by using other people's proven code (DBs, system calls, etc.) do so. If you can use an immutable class, do so. And I think, in general, people are either unaware of multithreading problems or are (sensibly) terrified of them and using all kinds of tricks to avoid multithreading (or rather, pushing responsibility for it elsewhere).

As a P.S., I sense that Java getters and setters are getting out of hand. Check this out.

RalphChapin
  • 3,270
  • 1
  • 14
  • 16
1

Lots of people had good answers so I want to point out something you touched on that was very observant and extremely true and hasn't been mentioned elsewhere here.

Automatically creating setters and getters is a horrible, horrible idea, yet it's the first way procedural-minded people try to force OO into their mindset. Setters and getters, along with properties should only be created when you find you need them and not everyby default

In fact although you need getters pretty regularly, the only way setters or writable properties should ever exist in your code is through a builder pattern where they are locked down after the object has been completely instantiated.

Many classes are mutable after creation which is fine, it just shouldn't have it's properties directly manipulated--instead it should be asked to manipulate it's properties through method calls with actual business logic in them (Yes, a setter is pretty much the same thing as directly manipulating the property)

Now this doesn't really apply to "Scripting" style code/languages either but to code you create for someone else and expect others to read repeatedly over the years. I've had to start making that distinction lately because I enjoy messing with Groovy so much and there is a huge difference in targets.

Bill K
  • 2,699
  • 18
  • 18
1

Mutable objects are used when you have to set multiples values after instantiating the object.

You shouldn't have a constructor with, say, six parameters. Instead you modify the object with setter methods.

An example of this is a Report object, with setters for font, orientation etc.

For short: mutables are useful when you have a lot of state to set to an object and it would not be practical to have a very long constructor signature.

EDIT: Builder pattern can be used build the whole state of the object.

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
  • 3
    this is presented as if mutability and changes after instantiation is the only way to set multiple values. For the sake of completeness note that [Builder pattern](http://en.wikipedia.org/wiki/Builder_pattern "what's this?") offers equal or even more powerful capabilities and doesn't require one to sacrifice immutability. `new ReportBuilder().font("Arial").orientation("landscape").build()` – gnat Aug 17 '12 at 13:12
  • Obviously the ReportBuilder object method will have to either pass everything in the constructor or set the state with setters – Tulains Córdova Aug 17 '12 at 14:16
  • as long as API users are kept oblivious of multi-parameter constructor, who cares. Number of parameters doesn't matter if the only one who uses these is the original API designer. Six or sixty six, whatever - it's like _one hand clapping_ – gnat Aug 17 '12 at 14:28
  • 1
    "It would not be practical to have a very long constructor signature.": You can always group parameters into smaller objects and pass these objects as parameters to the constructor. – Giorgio Aug 17 '12 at 18:08
  • You don't even need a builder for this. Consider `new Report().withFont("Arial").withOrientation("landscape")`. Each `with` method returns a new Report, which is almost a clone of the old one -- except for the "changed" property, of course. Rather inefficient in Java, but that's how functional languages tend to view the world. They tend to work pretty well while still keeping most stuff immutable. – cHao Dec 27 '12 at 15:07
  • 1
    @cHao What if you want to set 10 or 15 attributes? Also it doesn't seem good that a method named `withFont` returns a `Report`. – Tulains Córdova Dec 27 '12 at 17:10
  • @user1598390: Efficiencywise, it doesn't seem good...but that's mainly because Java doesn't do FP very well. As for the interface, though, consider `String`. A string doesn't modify itself; every method that would "change" a string (like, say, `trim`) actually returns a new String corresponding to what you asked for. A `Report` could easily do the same thing, and it'd make perfect sense if the names were standardized -- like say, if `withXXX` returned an object exactly the same as `this` except for the XXX property changed. – cHao Dec 27 '12 at 17:40
  • 1
    As far as setting 10 or 15 attributes, the code to do so wouldn't be awkward if (1) Java knew how to elide the construction of all those intermediate objects, and if (2) again, names were standardized. It's not a problem with immutability; it's a problem with Java not knowing how to do it well. – cHao Dec 27 '12 at 17:44
  • 1
    @cHao Making a call chain for 20 attributes is ugly. Ugly code tends to be poor quality code. – Tulains Córdova Dec 27 '12 at 17:45
  • @user1598390: I'd argue that setting 20 properties on an object before you can even use it, is just as ugly. There should be sensible defaults. – cHao Dec 27 '12 at 17:45
1

I think using mutable objects stems from imperative thinking: you compute a result by changing the content of mutable variables step by step (computation by side effect).

If you think functionally, you want to have immutable state and represent subsequent states of a system by applying functions and creating new values from old ones.

The functional approach can be cleaner and more robust, but it can be very inefficient because of copying, so that you want to fall back to a shared data structure that you modify incrementally.

The trade-off that I find most reasonable is: Start with immutable objects and then switch to mutable ones if your implementation is not fast enough. From this point of view, using mutable objects systematically from the beginning can be considered some kind of premature optimization: you choose the more efficient (but also more difficult to understand and to debug) implementation from the beginning.

So, why do many programmers use mutable objects? IMHO for two reasons:

  1. Many programers have learnt how to program using an imperative (procedural or object-oriented) paradigm, therefore mutability is their basic approach to defining computation, i.e. they do not know when and how to use immutability because they are not familiar with it.
  2. Many programmers worry about performance too early whereas it is often more effective to first focus on writing a program that is functionally correct, and then try to find bottlenecks and optimize it.
Giorgio
  • 19,486
  • 16
  • 84
  • 135
  • 1
    The issue is not just speed. There are many types of useful constructs which simply cannot be implemented without using mutable types. Among other things, communication between two threads requires that, at absolute minimum, both must have a reference to a shared object which one can put data and the other can read it. Further, it is often semantically much clearer to say "Change properties P and Q of this object" than to say "Take this object, construct a new object which is just like it except for the value of P, and then a new object which is just like that except for Q". – supercat Aug 22 '12 at 22:55
  • Further, I would suggest that the use of immutable types is in many cases a kludge to get around many languages' relatively poor support for proper value semantics. Data types which are not being used to manage shared state should generally be either not be shared unless they are immutable, and should not be mutable if they are shared. In systems where all class references are promiscuous, however, it can be difficult to ensure that mutable class objects remain unshared. Value objects avoid that problem, since they are never shared with anything outside the current execution context. – supercat Aug 22 '12 at 23:06
  • 1
    I am not a FP expert but AFAIK (1) thread communication can be achieved by creating an immutable value in one thread and reading it in another (again, AFAIK, this is the Erlang approach) (2) AFAIK the notation for setting a property does not change much (e.g. in Haskell setProperty record value corresponds to Java record.setProperty(value)), only the semantics changes because the result of setting a property is a new immutable record. – Giorgio Aug 22 '12 at 23:07
  • 1
    "both must have a reference to a shared object which one can put data and the other can read it": more precisely, you can make an object immutable (all members const in C++ or final in Java) and set all the content in the constructor. Then this immutable object is handed-over from the producer thread to the consumer thread. – Giorgio Aug 22 '12 at 23:12
  • (1) Even if the state is encapsulated in an immutable object, there must be at minimum some sort of mutable "reference holder" to store it in, does there not? (2) Conceptually, that is be true provided there is no need for shared immutable state, and one wouldn't mind having programs run *many orders of magnitude* slower than they would otherwise need to. If one has a list of 10,000 items, one wants to have a list in which one property of item #7 is different, and one wouldn't want to keep a version of the list as it presently exists... – supercat Aug 22 '12 at 23:15
  • ...a simple implementation of the class would require making a new list by copying 9,999 items from the old list, along with most of the properties of item #7. One needn't profile to know that if one is doing that very often it's going to be a problem. It's possible to design an immutable-list type which can handle operations of that style reasonably efficiently, but getting good performance out of immutable types will require considerable complexity. Copying to a new mutable type instance, making all the changes, and then copying to a new immutable instance is apt to be much cleaner. – supercat Aug 22 '12 at 23:20
  • 1
    (2) I have already listed performance as a reason not to use immutable state. Regarding (1), of course the mechanism that implements the communication between threads needs some mutable state, but you can hide this from your programming model, see e.g. the actor model (http://en.wikipedia.org/wiki/Actor_model). So even if at a lower level you need mutability to implement the communication, you can have an upper abstraction level in which you communicate between threads sending immutable objects back and forth. – Giorgio Aug 22 '12 at 23:21
  • My examples weren't really good ones--perhaps I can explain better what I'm trying to say. If a program is supposed to keep track the state of something in the "real-world" whose attributes change, then either the association between "real thing" and "program object" can be immutable, or the attributes of the program object can be immutable, but not both. In many cases, having the association be immutable is more helpful than having the characteristics of the program object be immutable; immutability is good, but *something* has to be mutable--the question is what. – supercat Aug 23 '12 at 15:48
  • let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/4602/discussion-between-giorgio-and-supercat) – Giorgio Aug 23 '12 at 15:57
  • As I see it, mutable aspects of the system state should generally be represented by a rooted immutable references to a mutable layer which contains immutable things. For each mutable aspect of system state, there has to be at least one mutable layer someplace--ideally exactly one. An approach using immutable objects for everything will force the mutable layer to the very top. Having the mutable layer be lower down will in many cases make things easier, *if it means everything above it can then be immutable*. Confusion only arises when there are multiple mutable layers. – supercat Aug 23 '12 at 16:00
  • 1
    I am not sure I understand you fully, but even a pure functional language where every value is immutable, there is one mutable thing: the program state, i.e. the current program stack and variable bindings. But this is the execution environment. Anyway, I suggest that we discuss this in chat some time and then clean up the messages from this question. – Giorgio Aug 23 '12 at 16:04
1

I know you are asking about Java, but I use mutable vs immutable all the time in objective-c. There is a immutable array NSArray, and a mutable array NSMutableArray. These are two different classes written specifically in an optimized way to handle the exact use. If I need to create an array and never alter it's contents, I'd use NSArray, which is a smaller object and is much faster at what it does, compared to a mutable array.

So if you create a Person object that is immutable then you only need a constructor and getters, thus the object will be smaller and use less memory, which in turn will make your program actually faster. If you need to change the object after creation then a mutable Person object will be better so that it can change the values instead of creating a new object.

So: depending on what you plan on doing with the object, choosing mutable vs immutable can make a huge difference, when it comes to performance.

1

Additional to many other reasons given here, a problem is that mainstream languages do not support immutability well. At least, you are penalized for immutability in that you have to add additional keywords like const or final, and have to use illegible constructors with many, many arguments or code lengthy builder patterns.

That's much easier in languages made with immutability in mind. Consider this Scala snippet for defining a class Person, optionally with named arguments, and creating a copy with a changed attribute:

case class Person(id: String, firstName: String, lastName: String)

val joe = Person("123", "Joe", "Doe")
val spouse = Person(id = "124", firstName = "Mary", lastName = "Moe")
val joeMarried = joe.copy(lastName = "Doe-Moe")

So, if you want developers to adopt immutability, this is one of the reasons why you might consider switching to a more modern programming language.

Dr. Hans-Peter Störr
  • 1,393
  • 2
  • 10
  • 10
  • this doesn't seem to add anything substantial over points made and explained in prior 24 answers – gnat Dec 09 '14 at 08:13
  • @gnat Which of the previous answers makes the point that most mainstream languages do not decently support immutability? I think that point simply has not been made (I checked), but this is IMHO a quite important obstacle. – Dr. Hans-Peter Störr Dec 09 '14 at 20:10
  • [this one](http://programmers.stackexchange.com/a/165468/31260) for example goes in depth explaining this issue in Java. And at least 3 other answers indirectly relate to it – gnat Dec 09 '14 at 20:28
0

Immutable means you can't change the value, and mutable means you can change the value if you think in terms of primitives, and objects. Objects are different than primitives in Java in that they are built in types. Primitives are built in types like int, boolean, and void.

A lot of people people think that primitives and objects variables that have a final modifier infront of them are immutable, however, this isn't exactly true. So final almost doesn't mean immutable for variables. Check out this link for a code sample:

public abstract class FinalBase {

    private final int variable; // Unset

    /* if final really means immutable than
     * I shouldn't be able to set the variable
     * but I can.
     */
    public FinalBase(int variable) { 
        this.variable = variable;
    }

    public int getVariable() {
        return variable;
    }

    public abstract void method();
}

// This is not fully necessary for this example
// but helps you see how to set the final value 
// in a sub class.
public class FinalSubclass extends FinalBase {

    public FinalSubclass(int variable) {
        super(variable);
    }

    @Override
    public void method() {
        System.out.println( getVariable() );
    }

    @Override
    public int getVariable() {

        return super.getVariable();
    }

    public static void main(String[] args) {
        FinalSubclass subclass = new FinalSubclass(10);
        subclass.method();
    }
}
gnat
  • 21,442
  • 29
  • 112
  • 288
Jon
  • 9
  • 1
-1

I think a good reason would be to model "real-life" mutable "objects", like interface windows. I vaguely remember having read that the OOP was invented when somebody tried to write software to control some cargo port operation.

Alexey
  • 932
  • 7
  • 19
  • 1
    I cannot find yet where i've read this about the origins of OOP, but [according to Wikipedia](https://en.wikipedia.org/wiki/Orient_Overseas_Container_Line#Information_technology), some *Integrated Regional Information System* of a large container shipping company *OOCL* is written in Smalltalk. – Alexey Jan 01 '14 at 09:55
-2

Java, in many cases mandates mutable objects, eg when you want to count or return something in a visitor or runnable, you need final variables, even without multithreading.

Ralf H
  • 101
  • 1
  • 5
    `final` is actually about 1/4 of a step *towards* immutability. Not seeing why you mention it. – cHao Jun 07 '12 at 04:11
  • did you actually read my post? – Ralf H Dec 23 '12 at 18:16
  • Did you actually read the question? :) It had absolutely nothing to do with `final`. Bringing it up in this context conjures a really weird conflation of `final` with "mutable", when the very point of `final` is to *prevent* certain kinds of mutation. (BTW, not my downvote.) – cHao Dec 23 '12 at 19:45
  • I'm not saying you don't have a valid point in here somewhere. I'm saying you're not explaining it very well. I sorta semi see where you're probably going with it, but you need to go further. As is, it just looks confused. – cHao Dec 23 '12 at 19:59
  • OK, the original question was about why programmers use mutable objects despite their concurrency problems. I did not want to repeat everything that has been said above, only point out that in scenarios where a constant/final or whatever is required (like in java runnables) and we need to return a result from those runnables, we have to use a final reference to a mutable object. Not because we just don't get the idea how great immutability is. – Ralf H Dec 27 '12 at 14:08
  • 1
    There are actually very few cases where a mutable object is *required*. There are cases where the code would be clearer, or in some cases faster, by using mutable objects. But consider that the vast majority of design patterns are basically just a half-assed rendition of functional programming for languages that don't natively support it. Fun part of that is, FP only requires mutability in very select places (namely, where side effects must occur), and those places are generally tightly limited in number, size, and scope. – cHao Dec 27 '12 at 15:32