1 00:00:07,200 --> 00:00:07,680 Hello. 2 00:00:08,280 --> 00:00:16,140 In this video, we're going to talk about Question 30, what are immutable types and what's their purpose? 3 00:00:16,740 --> 00:00:24,660 Immutability of a type means that once an object of this type is created, none of its fields or properties 4 00:00:24,660 --> 00:00:25,860 can be updated. 5 00:00:26,340 --> 00:00:28,770 Let's see a simple, immutable type. 6 00:00:29,670 --> 00:00:36,840 The objects of this glass are immutable because the X and Y properties do not have stars. 7 00:00:37,230 --> 00:00:42,870 Once we create an object using the constructor, it will not be possible to modify it. 8 00:00:45,880 --> 00:00:53,050 As you can see, the concept of immutable thought is very simple it can extend to more complex types 9 00:00:53,050 --> 00:00:55,450 than point, for example, collections. 10 00:00:55,720 --> 00:01:01,960 Once we create an immutable collection, no element can be ordered, removed or altered. 11 00:01:02,440 --> 00:01:07,150 The question is why should we bother creating immutable types? 12 00:01:07,540 --> 00:01:12,760 First of all, immutable types let us create clear and simple gold. 13 00:01:13,270 --> 00:01:14,560 Let's consider this. 14 00:01:15,160 --> 00:01:18,190 What do you think will be printed from the fourth line? 15 00:01:18,640 --> 00:01:25,810 Well, it's impossible to say because we don't know what happens in some mimetic and some other method. 16 00:01:26,320 --> 00:01:30,970 Maybe they simply redid the values of the point, but maybe they alter it. 17 00:01:31,360 --> 00:01:38,110 We won't be sure what the code does and how it behaves until we follow the flow of the code very carefully 18 00:01:38,200 --> 00:01:42,550 checking what exactly every method does with the point object. 19 00:01:43,000 --> 00:01:46,330 If the point was immutable, we wouldn't need to worry. 20 00:01:46,720 --> 00:01:50,860 We would be sure that once it's created, its value remains the same. 21 00:01:51,160 --> 00:01:54,940 And we would know right away what would be printed to the council. 22 00:01:55,570 --> 00:02:01,150 Another thing that immutable types make simpler is writing pure functions. 23 00:02:01,510 --> 00:02:08,530 Pure functions are functions whose results only depend on the input parameters, and they do not have 24 00:02:08,550 --> 00:02:09,670 any side effects. 25 00:02:10,000 --> 00:02:16,330 They don't alter the state of the application and they don't modify the input parameters. 26 00:02:16,810 --> 00:02:23,710 We can call a pure function anytime we want with the same set of parameters, and it will always yield 27 00:02:23,800 --> 00:02:25,000 the same result. 28 00:02:25,360 --> 00:02:31,060 Because of that, we can cache the result, making the parameters the key of the cache. 29 00:02:31,510 --> 00:02:37,570 Pure functions are simple to understand, as we don't need to be aware of the context in which they 30 00:02:37,570 --> 00:02:38,350 are called. 31 00:02:38,740 --> 00:02:42,070 Testing is extremely simple as we only track. 32 00:02:42,250 --> 00:02:49,270 The result is as expected for testing purposes we don't need to set up and the context in which those 33 00:02:49,270 --> 00:02:53,890 functions work, as they only depend on the input parameters and not. 34 00:02:54,010 --> 00:03:00,880 For example, the state of the class they live in, using immutable types and creating pure functions 35 00:03:00,880 --> 00:03:02,410 work very well together. 36 00:03:02,650 --> 00:03:09,250 And actually, there are two tenets of functional programming, according to the IGN, that grows more 37 00:03:09,250 --> 00:03:16,090 and more popular for its clarity, as well as working great in multi-threaded applications, which actually 38 00:03:16,090 --> 00:03:18,010 leads us to the next point. 39 00:03:18,310 --> 00:03:24,790 When working with multi-threaded applications, we must always be very cautious when it comes to making 40 00:03:25,030 --> 00:03:32,710 assumptions about the state of an object because it can always be the case that another threat alters 41 00:03:32,800 --> 00:03:35,020 the state without our knowledge. 42 00:03:35,530 --> 00:03:38,950 Using immutable objects wipes this program out. 43 00:03:39,370 --> 00:03:45,670 If an object cannot be altered, there is no need to worry that some other threat altered it, right? 44 00:03:46,360 --> 00:03:53,290 This makes the creation of multi-threaded applications much simpler and less error prone, and you must 45 00:03:53,290 --> 00:03:59,950 know that the finding box in multi-threaded applications can be extremely hard as they often happen 46 00:03:59,950 --> 00:04:04,870 in our non deterministic manner that can be extremely hard to reproduce. 47 00:04:05,500 --> 00:04:12,250 Another benefit of using immutable types is that they make it easier to avoid invalid objects. 48 00:04:12,640 --> 00:04:17,170 To understand this, let's consider this class and its constructor. 49 00:04:18,860 --> 00:04:25,370 Someone clearly put up a lot of work to make sure that when an object of the person cross is created, 50 00:04:25,400 --> 00:04:28,390 it is valued its ideas correct. 51 00:04:28,500 --> 00:04:32,660 The name is not empty and they are of birth is reasonable. 52 00:04:33,140 --> 00:04:39,620 If objects of the person class could be mutated, it would mean that at any time of the application 53 00:04:39,620 --> 00:04:42,650 execution, they can be rendered invalid. 54 00:04:51,870 --> 00:04:58,350 If objects of the person class are mutable, we never know when someone changes some of its properties 55 00:04:58,480 --> 00:05:05,670 to something invalid, for example, like in this line, if the person's class objects can become invalid 56 00:05:05,670 --> 00:05:06,810 at any moment. 57 00:05:06,960 --> 00:05:11,700 That would mean that our code would quickly become filled with lines like this. 58 00:05:14,610 --> 00:05:21,600 This is not only a code duplication because we already define the districts in the persons class constructor, 59 00:05:21,900 --> 00:05:28,950 but it also creates a lot of notes in the code, making it harder to understand, maintain and dust. 60 00:05:29,160 --> 00:05:35,970 Because whatever we want to test code that uses this type will have to write tests for both valid and 61 00:05:35,970 --> 00:05:37,590 invalid person objects. 62 00:05:38,010 --> 00:05:42,150 The easier testing is another benefit of immutable objects. 63 00:05:42,390 --> 00:05:49,290 But before we move on to respond, let's consider another aspect of making objects invalid, which is 64 00:05:49,290 --> 00:05:50,670 identity mutation. 65 00:05:51,120 --> 00:05:55,320 Imagine we want to use the person class object as a key in. 66 00:05:55,320 --> 00:06:01,590 Additionally, we want to use the person's ID as the hash code that the dictionary will use. 67 00:06:03,270 --> 00:06:10,260 This looks simple, but what if the idea is mutable, we can actually lose this object in the dictionary? 68 00:06:10,560 --> 00:06:12,170 Let's see this in practice. 69 00:06:27,220 --> 00:06:28,600 Let's see what happened here. 70 00:06:29,110 --> 00:06:37,240 First, we used the person object as the key in the dictionary using its ideas hush code, then the 71 00:06:37,240 --> 00:06:38,170 idea changed. 72 00:06:38,560 --> 00:06:44,650 Because of that, this line throws an exception because in the dictionary there is no key, with the 73 00:06:44,650 --> 00:06:48,100 hash code coming from the new ID string. 74 00:06:48,640 --> 00:06:51,550 The only key release is the one build move. 75 00:06:51,550 --> 00:06:52,420 The old idea. 76 00:06:53,140 --> 00:06:59,590 As a rule of thumb, if an object is meant to be a key in the dictionary, it should be immutable or 77 00:06:59,590 --> 00:07:04,540 at least those fields and properties that are used in the good hash called method. 78 00:07:05,330 --> 00:07:09,700 The last benefit of immutable types that they wanted to mention is easier. 79 00:07:09,700 --> 00:07:17,500 Testing immutable objects make it easier to understand, and they also give us a guarantee that once 80 00:07:17,500 --> 00:07:22,120 a valid object had been created, it will remain valid forever. 81 00:07:22,540 --> 00:07:28,690 This makes testing much simpler because we have fewer puffs of code to test us. 82 00:07:28,750 --> 00:07:32,080 Handling of invalid objects is simply not needed. 83 00:07:32,830 --> 00:07:39,220 As mentioned before, using immutable objects make it easier to create pure functions, and they are 84 00:07:39,250 --> 00:07:41,020 extremely simple to test. 85 00:07:41,800 --> 00:07:42,490 All right. 86 00:07:42,910 --> 00:07:50,140 Seems like immutable objects can be really beneficial, but following this, nothing of a tenuous rule 87 00:07:50,140 --> 00:07:51,310 can be demanding. 88 00:07:51,640 --> 00:07:54,910 After all, we sometimes need to change something. 89 00:07:55,450 --> 00:07:59,620 Let's consider the daytime type, which is immutable in c sharp. 90 00:08:09,510 --> 00:08:14,730 Adding seven days to January the 1st won't make it a different date. 91 00:08:15,120 --> 00:08:16,980 It will produce a no doubt. 92 00:08:17,430 --> 00:08:19,140 It makes perfect sense. 93 00:08:19,530 --> 00:08:22,920 After all, a date never changes tenders and worry. 94 00:08:22,920 --> 00:08:28,500 The first 2022 will always be January the 1st 2022. 95 00:08:29,070 --> 00:08:36,000 Such apparent modification of immutable objects is called a non-destructive mutation. 96 00:08:36,420 --> 00:08:42,540 It is an operation of creating a new object based on another immutable object. 97 00:08:43,050 --> 00:08:49,980 The immutable object won't be modified, and the result of these non-destructive mutation will be a 98 00:08:49,980 --> 00:08:50,880 new object. 99 00:08:51,510 --> 00:08:56,730 We'll learn more about it in the next lecture when we'll talk about records. 100 00:08:57,450 --> 00:08:58,110 All right. 101 00:08:58,440 --> 00:09:04,620 We learned what immutable types are and what are the most important benefits of using them. 102 00:09:04,950 --> 00:09:11,880 But we must also be aware of the important disadvantage they have with the non-destructive mutation. 103 00:09:12,060 --> 00:09:17,760 Each update of an object actually creates a new object allocating new memory. 104 00:09:18,210 --> 00:09:21,800 The old object must be cleaned up by the garbage collector. 105 00:09:22,170 --> 00:09:28,200 It is usually not an issue of small types, but remember, even collections can be immutable. 106 00:09:28,620 --> 00:09:36,450 Imagine having a list of milyong elements and that adding a new item to this list means actually building 107 00:09:36,450 --> 00:09:39,870 a whole new collection of size million and one. 108 00:09:40,290 --> 00:09:45,570 It may sound scary, but don't be discouraged to use immutable types. 109 00:09:46,200 --> 00:09:52,170 First of all, there are implementations of collections that actually make this quite efficient. 110 00:09:52,650 --> 00:09:59,880 Second, not all applications suffer from the performance loss when using immutable types, and the 111 00:09:59,880 --> 00:10:02,970 benefits are often bigger than the costs. 112 00:10:03,510 --> 00:10:11,100 Garbage Collector is a smart tool, and most often you won't even notice the performance impact of introducing 113 00:10:11,100 --> 00:10:12,420 immutable types. 114 00:10:13,020 --> 00:10:17,100 Nevertheless, there are cases when performance is critical. 115 00:10:17,400 --> 00:10:24,600 For example, I wouldn't recommend making every type immutable when developing video games, as it would 116 00:10:24,600 --> 00:10:27,390 make the garbage collector kick off more often. 117 00:10:27,750 --> 00:10:34,500 And remember that when garbage collector works, all other trends are frozen until it finishes. 118 00:10:34,920 --> 00:10:40,830 In the case of games, it could lead to a performance decrease that would be noticed by the players. 119 00:10:41,730 --> 00:10:49,110 During the interview, you can hear questions like What are pure functions, pure functions or functions 120 00:10:49,290 --> 00:10:55,800 whose results only depend on the input parameters, and they don't have any side effects, like changing 121 00:10:55,800 --> 00:11:01,440 the state of the class they belong to or modifying the object passed as an input. 122 00:11:02,190 --> 00:11:05,730 What are the benefits of using immutable types? 123 00:11:06,270 --> 00:11:10,050 The code using immutable types is simple to understand. 124 00:11:10,410 --> 00:11:13,650 Immutable types make it easy to create new functions. 125 00:11:14,130 --> 00:11:20,340 They also make it easier to work with multi-threaded applications, as there is no risk that one thread 126 00:11:20,340 --> 00:11:21,840 will modify a value. 127 00:11:22,050 --> 00:11:29,100 That's the other thread is using immutable objects retain their identity and validity. 128 00:11:29,790 --> 00:11:32,820 Mutable objects make testing problematic. 129 00:11:33,240 --> 00:11:36,870 This thing, called using immutable types, is much simpler. 130 00:11:37,650 --> 00:11:40,110 What is the non-destructive mutation? 131 00:11:40,710 --> 00:11:48,330 The non-destructive mutation is an operation of creating a new object based on another immutable object. 132 00:11:48,840 --> 00:11:55,890 The immutable object won't be modified, but the result of this apparent modification will become a 133 00:11:55,890 --> 00:11:56,850 new object. 134 00:11:57,360 --> 00:12:02,610 The real life analogy could be adding seven days to a date of January, the first. 135 00:12:03,030 --> 00:12:09,450 It will not turn out the date of January the first, but it will produce a new date of January eight. 136 00:12:10,200 --> 00:12:12,330 All right, that's it in this lecture. 137 00:12:12,990 --> 00:12:17,670 Thanks for watching and see you in the next one when we'll talk about records.