5

I am wondering as to why Date structures & objects, like C#'s DateTime & Obj-C's NSDate have been made immutable.

Im looking for the reasoning behind this design and the benefits of making this information immutable, not just "because they can"

UPDATE: It seems as though there was a similar question with a fantastic answer to mine but specifically targeting Java, it can be found here: Why do we need immutable class?

That in combination with the answer to my question has been very informative

Community
  • 1
  • 1
CStreel
  • 2,642
  • 2
  • 19
  • 37
  • 1
    @IanMercer: Not a duplicate, immutable struct's can be due to a different reason. – Guvante Dec 12 '12 at 00:26
  • Since a `DateTime` represents a single value, it would make no sense in allowing it to be changed. Besides mutable structs are true evil. – Steven Dec 12 '12 at 00:50
  • Also a string represents a single value, but there is a class named NSMutableString.The time may change, like for example the date contained in a Clock class. – Ramy Al Zuhouri Dec 12 '12 at 00:56

4 Answers4

9

Immutability makes a lot of things easier. If you don't have to worry that something can change underneath you, then there is a lot of guard code you don't have to write. There's a lot of assumptions you don't have to make. There's a lot of possibilities for things to NOT go wrong.

It's common for strings, dates, and other kinds of common objects to be immutable in modern languages because it simplifies the compiler, the framework, and means the compiler is free to make assumptions when doing optimization.

The gist is that, for a small price (having to create a new object if you want to change the value) you get a lot of real performance, stability, and reliability.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • This is the only good answer. The other two specifically address the .NET DateTime objects and incorrectly explain why they are immuatable. – evanmcdonnal Dec 12 '12 at 00:27
  • +1. I did not want to make the same argument, though, because of NSString, which is immutable but has a mutable subclass, so the guarantee about no changes underneath you does not really seem to apply in all cases. – Thilo Dec 12 '12 at 00:28
  • @Thilo - technically, you can do a lot of things to work around immutability, but doing so is often dangerous and can cause unpredictable results. – Erik Funkenbusch Dec 12 '12 at 00:33
  • @evanmcdonnal: I misspoke by quoting an actual method, but `Properties` and mutable structs have well known and documented concerns. If you call something that mutates a returned struct, that mutation is lost unless you preserve it on the calling side. – Guvante Dec 12 '12 at 00:48
  • Having to create a new object if you want to change the value can be a negative. For example if you have a SortedList that you are performing several thousand updates on, this costs several thousand new DateTimes that garbage collection must eventually deal with. For this reason, I typically write a simple mutable class with comparators and integer fields for year, month, day, hours, minutes and seconds. I can then declare one instance, update the date and time fields and use it as a key. – Doug Kimzey Jan 04 '20 at 17:13
0

I'm not sure about Objective C, but in C# a date is backed by a simple numeric type. And since a number is immutable, so is the Date that is based on it.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Isn't that like saying since String is immutable, so are beans that are backed by Strings (for example for their "name" and "title" properties)? – Thilo Dec 12 '12 at 00:25
  • 2
    You could provide methods that update that number pretty easily. – Guvante Dec 12 '12 at 00:25
  • True you could do both of those. There are many better reasons to have data types immutable. I just thought this might've been one of the reasons behind .NET's choice to have Date immutable. – Frank van Puffelen Dec 12 '12 at 00:34
0

I am not sure about Objective-C, but DateTime's are immutable because making them mutable is actually really hard to do correctly.

This is because if you return them from a method (this includes properties) you get a copy, not the original. This could mean that the following code would not function as you would expect:

someObject.Timestamp.SetSeconds(10.0);

Where SetSeconds is void and mutates the underlying structure.

It would do nothing, since you would get a copy of the Timestamp object, add 10 seconds to it, and then do nothing with that copy.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • Isn't the way you use these methods a result of the class being immutable, not the other way around? – Thilo Dec 12 '12 at 00:29
  • @Thilo: Hah, I meant to make a faux method, accidentally changed it to a real one. Hypothetically if `AddSeconds` was void was my intention. – Guvante Dec 12 '12 at 00:46
0

The vast majority (99.99%) of structures written for use in .net (whether defined in the Framework or in user code) either represent a fixed collection of independent values, which can accept any combination of values that are legal for their types (e.g. a Point, which contains an X and a Y), or else represent a single abstract entity. Microsoft's structure usage guidelines in .net fail to distinguish between these different usage scenarios, assuming all structures fit the second pattern, with the unfortunate consequence that structures of the first type are often written in a fashion which is only really appropriate for those of the second. As it happens, though, the DateTime structure in .net certainly does not qualify as a collection of independent values, and thus the guidelines are entirely appropriate for it.

First of all, there's not really any good way that a DateTime could directly expose any fields. There's no clear set of independent values that a DateTime structure encapsulates, so it's unclear what the types of any fields should be. Further, many of the properties cannot sensibly be mutated because they're not independent; for example, if one has a DateTime which represents February 29, 2012, and one sets the year to 2011 and then sets the month to 3, what should the resulting date be? It only makes sense to mutate a DateTime using methods, and unfortunately both vb.net and C# will pretend to allow mutating methods to be called on a read-only structure instance, by silently replacing code like MyList[3].MutatingMethod(); with the horribly-broken var temp=MyList[3]; temp.MutatingMethod();. It should be fairly simple for Microsoft to fix this problem by defining an attribute such that invoking on a read-only instance a method tagged with the attribute should result in a compiler error rather than broken code, but unfortunately Microsoft's language people would rather declare that mutable structures are evil, than fix the language so they wouldn't be,

supercat
  • 77,689
  • 9
  • 166
  • 211