A defensive copy is when you are copying one mutable state to a completely different mutable state that so happens to be the same type. For example, you want to take, say, an "OK Button" widget and you want to also have this widget on another page. They are separate buttons, and modeled as mutable state objects. Given that the model strongly hints one button is not like another, you should duplicate the button, not use the exact same object in two completely different places.
or, to stay within the examples we've created here, if you need to do some emulation of sales on a POS system, you are effectively modelling a new POS machine. Hence, copy the mutable finance rule object. If you modelled it that way. This particular case isn't hard to model as an immutable structure, but that's certainly not always the case. Games and windowing systems come to mind. (Shallow) cloning a window object just because it moved a pixel to the right isn't going to lead to nice design. Why would you "implore" me to look at JodaTime when I've already suggested it before, *and* said that the date/time API that java ships with today is horribly broken. Immutability, or lack thereof, is only the tiniest of reasons for this. I'm just taking issue with your notes on immutability which strongly suggest that everything, everywhere, should always be immutable. I suggest you try to set up all your systems that way. Not practical. On May 10, 11:53 am, Kevin Wright <[email protected]> wrote: > On 10 May 2010 09:57, Reinier Zwitserloot <[email protected]> wrote: > > > I think you're oversimplifying, Kevin. > > > Yes, sure, you need to make defensive copies here and there if things > > are immutable. And, sure, dates be as immutable as strings and > > numbers. > > I do so love that term, "defensive copy". It raises the question of what, > exactly, are you defending against - if not inappropriate mutability? > > > But take your VAT example. If I have an object that represents, say, > > the current state of the finance rules for a point-of-sale system, VAT > > might as well be mutable. It has no concept of time other than 'valid > > right now'. > > Yes, the vat field in the context object *could* be mutable, though the vat > object it references certainly shouldn't be. > But this still has the potential to expose the problem I outlined with > dates. If two users grab the same instance of context and one then updates > it to reflect the conditions of 2 years ago (perhaps for running a report), > then conflicts can occur, and very likely will. > > A cleaner solution is to make the context immutable, then you can be certain > that a context won't be silently updated on your behalf by passing it to a > function call. Languages with good FP support can make it trivial to obtain > a new context based on an existing one, if you need that. In Scala 2.8 for > example: > > val context = ...get context from somewhere... > val newContext = context.copy(vat = 0.15) //takes one immutable object, > return another one > doSomethingWith(newContext) > > In this case, anyone who's been using the original context object won't be > getting any nasty surprises. > > There is a strong argument to make everything immutable as much as possible, > keeping mutability restricted to just a high-level part of your application > where it's easier to reason about. There's also an argument for using it > selectively in situations where it can confer a significant advantage in > speed or memory footprint, but even then there are techniques to encapsulate > such uses of mutability and reduce the associated risks. Hopefully ongoing > research into compiler optimisations and data structures will reduce the > need for such cases in the future. > > On the other hand, in a database entry, 'timestamp' is undoubtedly > > > part of a sale. And THEN the correct model for VAT (and almost > > everything else) HAS become immutable: At a certain point in time, the > > VAT was X, and the VAT on Jan 7th 1989 in Country Y will always be X > > no matter where or when we are, hence, immutable. > > Sure, this is a clear-cut example of the sixth normal form > (http://en.wikipedia.org/wiki/Sixth_normal_form) > though I wasn't really thinking to drag databases into the discussion. > This also moves beyond just immutability and into the realm of so-called > "persistent" data structures. > > In a programmatic representation, the essential complexity of vat is that > it's a function mapping a date to a value, so in java: > > public BigDecimal vat(Date dt) { ...do something here, maybe a db lookup... > > } > > or in scala: > > val vat : (Date) => Decimal = ... logic goes here ... > > I actually find it much clearer to think of vat as a function in this > manner, though the (current) lack of support for closures and method handles > in Java does make it harder to write code designed around this kind of > approach. > > The date API also isn't broken strictly for immutability reasons. > > > That's because timestamps ought to be stored as (immutable) longs, and > > the date/time APIs used only to calculate new ones; effectively > > Calendar is a builder. It's API certainly looks like a (badly written) > > builder. > > As for the statement "timestamps out to be stored as...", this is surely > just an implementation detail? > By convention, we commonly store dates as the number of seconds elapsed > since the unix epoch, but this is just one possibility and is certainly not > valid if we want to measure e.g. the occurrence of decay events in a highly > unstable radioisotope. > > In addition, a date can be more than just a timestamp. In many cases, the > timezone it relates to is also useful information. Without this it's not > even possible to translate from a timestamp back to a date unless you also > specify the timezone whose date you're interested in. > > From a physics perspective, it makes no sense to talk about absolute times > at all, and the only "truth" lies in the observed duration between events. > Even then, the duration you measure will be dependant on your relative > motion. > > From an OO purist perspective, a date *ought* to be stored as an opaque > object, with it's dateness determined only on the basis of the operations > available to that object. > > Seriously, Date/Calendar is a joke, and I strongly implore you to look at > the JodaTime API. > > On May 9, 2:30 pm, Kevin Wright <[email protected]> wrote: > > > > > > Why immutability matters. > > > > Imagine you have a financial system, it includes VAT calculations at some > > > point, using VAT at 17.5% > > > vat = 0.175 > > > then, at a later point in time, the government changes the VAT rate to > > 15%, > > > possibly in response to some sort of "banking crisis": > > > 0.175 = 0.15 > > > > The value 0.175 is made to equal 0.15 > > > > Patently ridiculous, of course. Numbers are immutable, 17.5 will always > > be > > > 17.5 and never 15. What changes is the reference! If you think in pure > > > object-oriented terms then some variable 'vat' can start off pointing to > > the > > > 17.5 object and later be changed to point to the 15.0 object. > > > > So how about dates? Does it make any more sense to state that: > > > may 5 = september 22 > > > > Again no, but the Java data API allows exactly this to occur. > > > It's especially fun when it happens across threads... > > > > So a slightly fictional example here, but close enough to the real world > > > that I think it makes the point. > > > > - You have an array of date objects, call it "datesInSeptember". This > > array > > > is used to populate a selection dialog on a form or webpage somewhere. > > > > - A user selects "September 22nd" from these dates to use as a project > > > deadline. > > > > - Later on, another user attempts to use the 22nd from the same array for > > a > > > totally different purpose > > > > - Later still, the first project deadline changes, so the date object is > > now > > > updated to, say, 1st November. > > > (remember, this is still the exact same object still held in the > > > "daysInSeptember", and used by the second user) > > > > - ... > > > > *this* is why immutability is so important. It's not about stating that > > a > > > value once chosen can never be changed, it's about changing that variable > > by > > > having it refer to a new object and not mutating the original reference > > in > > > place, especially when that value may be used elsewhere. > > > > and for this reason, the Java date API is badly broken. We fortunately > > have > > > JodaTime which *does* make all date values immutable, so there is a > > solution > > > for this particular problem. In general, it's good advice to make > > > everything immutable that possibly can be, and change is achieved by > > taking > > > a copy of objects and making the update as the copy is taken. This issue > > > goes far beyond dates and is critical for being able to reason > > effectively > > > about concurrent systems. > > > > On 9 May 2010 01:30, Peter Becker <[email protected]> wrote: > > > > > On 09/05/10 09:21, Wildam Martin wrote: > > > > > [...] > > > > >> I shudder at the > > > >>> thought of mutability in some of this, the API effectively states > > that > > > >>> you > > > >>> can change May 5th to become September 22nd; > > > > >> Who cares? - Really: This is something, a professor at university may > > > >> mutable > > > > >> have a philosophic problem with - in the real world nobody had a > > > >> problem with that before the functional and immutable hype. > > > > > Oh yes. I have seen bugs based on using mutable (and mutating) objects > > were > > > > clients made assumptions about immutability, or even worse: not making > > the > > > > assumptions themselves but using data structures that do. The classic > > > > example: put a mutable object into a hash structure and change > > properties > > > > that affect the hash code. > > > > > Any object that mutates its identity is a bug waiting to happen. Lack > > of > > > > immutability is real problem in the real world. It makes reasoning > > about > > > > code much, much harder and allows for bugs that are hard to see. > > > > > And BTW: Yes, it can make sense: Let's have a deadline on May 5th that > > > >> is moving to September 22nd. Why shouldn't it be valid to change that > > > >> date? - Not every date is a birthday. > > > > > There is a difference between a date as a property and a date as an > > > > instance. You might again claim that is "philosophical" or "academic" > > (in > > > > the negative senses of those words), but I will again claim that it is > > of > > > > relevance for writing easy to understand and safe code. If you change > > the > > > > date of a milestone, you assign a new date to the milestone, you do not > > > > change the nature of the old date. The latter would affect everything > > else > > > > that uses the same date. > > > > > [...] > > > > > - They continue to be willing to add proven new techniques and > > patterns to > > > >>> the platform and C# language. Such as dynamic lang support, FP > > > >>> constructs > > > >>> via LINQ, sensible property handlers, delegates (method handles), > > > >>> closures, > > > >>> etc. Java prevaricates over all of these. > > > > >> Guess what: I didn't miss any of that stuff in the last 15 years of > > > >> development - so a) it can't be something real essential. And apart > > > >> from that I currently don't see a particular situation currently where > > > >> I > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
