1 00:00:00,330 --> 00:00:03,470 Well let's take a look at another example of a generic function. 2 00:00:03,470 --> 00:00:06,210 This one is going to be a tiny bit more complicated but 3 00:00:06,210 --> 00:00:10,370 before we move on to the next topic, I want to quickly highlight the point I 4 00:00:10,370 --> 00:00:16,260 raised earlier in that we can make our function generic over more than one type. 5 00:00:16,260 --> 00:00:17,260 Let's define a function. 6 00:00:18,270 --> 00:00:20,780 We'll call it transform and 7 00:00:20,780 --> 00:00:24,460 this function is going to have two generic type parameters. 8 00:00:24,460 --> 00:00:29,090 So remember we start with an angle bracket in the first one will called T. 9 00:00:29,090 --> 00:00:31,790 To list more than one we add a comma. 10 00:00:31,790 --> 00:00:33,950 So it's a comma separated list of arguments. 11 00:00:33,950 --> 00:00:36,350 So T and then the second one we'll call U. 12 00:00:37,970 --> 00:00:40,560 Again, to specify multiple type parameters 13 00:00:40,560 --> 00:00:44,560 we separated them with commas inside of the angle brackets like so. 14 00:00:44,560 --> 00:00:48,310 We'll talk about how we name our type parameters in just a second, but 15 00:00:48,310 --> 00:00:50,170 in cases like this. 16 00:00:50,170 --> 00:00:53,760 Again, where there are no meaningful names beyond argument or 17 00:00:53,760 --> 00:00:58,360 value the convention is to use letters uppercase letters and 18 00:00:58,360 --> 00:01:03,270 typically we start at T for type and then go on from there. 19 00:01:03,270 --> 00:01:06,020 This function is going to take two arguments. 20 00:01:06,020 --> 00:01:11,890 The first will call arg is an argument of type T. 21 00:01:11,890 --> 00:01:15,010 For the second one this is going to be a bit more tricky. 22 00:01:15,010 --> 00:01:18,410 It's going to take another function as an argument. 23 00:01:18,410 --> 00:01:22,660 We'll call this function or we'll call this argument operation and for 24 00:01:22,660 --> 00:01:27,530 the type we'll accept a function that takes as an input 25 00:01:27,530 --> 00:01:32,500 an argument of type T, and returns an argument of type U. 26 00:01:32,500 --> 00:01:33,770 So how do we define that? 27 00:01:33,770 --> 00:01:37,400 It's pretty simple, the type of that function looks like this. 28 00:01:37,400 --> 00:01:38,980 So remember when we're writing a function, 29 00:01:38,980 --> 00:01:43,360 we include the arguments that a function accepts inside of parentheses. 30 00:01:43,360 --> 00:01:48,350 So this operation function is going to accept an argument of type T. 31 00:01:48,350 --> 00:01:51,500 Inside parentheses, we'll put T and 32 00:01:51,500 --> 00:01:55,980 then it's going to return an instance or a value of type U. 33 00:01:55,980 --> 00:01:59,530 So we'll put that return type arrow and then list at U. 34 00:01:59,530 --> 00:02:01,570 Then we'll close our argument list. 35 00:02:01,570 --> 00:02:06,580 Remember that both T and U are type parameters or placeholders, so 36 00:02:06,580 --> 00:02:08,630 right now they don't mean anything. 37 00:02:08,630 --> 00:02:13,340 Our function here simply states that it takes an argument of type T and then 38 00:02:13,340 --> 00:02:18,990 a second argument, which is a function in its own right that takes T and returns U. 39 00:02:18,990 --> 00:02:24,890 And then this entire transform function is going to return U as well. 40 00:02:24,890 --> 00:02:27,508 This sounds terribly over complicated, but 41 00:02:27,508 --> 00:02:32,250 all we're going to do is call this operation function. 42 00:02:32,250 --> 00:02:36,820 Now as you can see here operation takes an argument of type T and 43 00:02:36,820 --> 00:02:40,400 this argument arg happens to be of type T. 44 00:02:40,400 --> 00:02:42,830 So we'll call this function and pass through arg. 45 00:02:42,830 --> 00:02:48,790 That calling the operation function returns a value of type U and 46 00:02:48,790 --> 00:02:52,420 since that is also what we need to return from the transform function, 47 00:02:52,420 --> 00:02:55,260 we'll simply call or simply write out return U. 48 00:02:55,260 --> 00:02:56,760 And that's it. 49 00:02:56,760 --> 00:03:00,255 At this point we have no idea what T or U are, right? 50 00:03:00,255 --> 00:03:01,850 They're not defined but 51 00:03:01,850 --> 00:03:06,240 that's okay because we're just defining some rules about this function. 52 00:03:06,240 --> 00:03:10,430 Generic functions are more about defining rules than rather a specific 53 00:03:10,430 --> 00:03:12,010 implementation. 54 00:03:12,010 --> 00:03:16,830 So we have a function that we pass in to the operation argument. 55 00:03:16,830 --> 00:03:20,450 This function takes as its own argument something of type T. 56 00:03:20,450 --> 00:03:25,542 Our generic function says that this argument and both, so this argument 57 00:03:25,542 --> 00:03:30,476 right here in both the argument value, the arg value must be of type T. 58 00:03:30,476 --> 00:03:34,870 So before we all transform and do anything with it, let's define another function. 59 00:03:36,070 --> 00:03:38,770 So we'll call this function stringToInt. 60 00:03:38,770 --> 00:03:43,960 It takes as an argument an instance of a strings, 61 00:03:43,960 --> 00:03:48,700 so a value of type string, so we'll call this a of type string and 62 00:03:48,700 --> 00:03:52,730 then returns an int. 63 00:03:52,730 --> 00:03:57,070 The body of this functions going to be really simple. 64 00:03:57,070 --> 00:04:01,500 We'll try to convert the string eight to an integer and return it 65 00:04:01,500 --> 00:04:05,310 if it doesn't work for the sake of this example we'll just crash the program. 66 00:04:05,310 --> 00:04:11,110 So we'll say guard let value equal int a, 67 00:04:11,110 --> 00:04:18,080 else, Fatal error. 68 00:04:18,080 --> 00:04:22,170 So this is the initializer for the int type and it takes 69 00:04:22,170 --> 00:04:27,460 a value of type any if it can convert it to an int it returns an optional integer. 70 00:04:27,460 --> 00:04:30,770 So here we're trying to unwrap and assign it a value and 71 00:04:30,770 --> 00:04:33,700 if it doesn't returns nil in that case we're just going to crush. 72 00:04:34,750 --> 00:04:36,850 Now we have a value so we'll return value. 73 00:04:38,030 --> 00:04:43,690 We can now use this function in the transform function we defined earlier. 74 00:04:43,690 --> 00:04:48,470 Remember that the second parameter in transform operation 75 00:04:48,470 --> 00:04:53,780 takes a function as an argument of type T to u. 76 00:04:53,780 --> 00:04:58,270 If we pass in string to end as an argument to operation 77 00:04:58,270 --> 00:05:03,100 that makes T string and you Int. 78 00:05:03,100 --> 00:05:05,050 Since T has to be consistent, 79 00:05:05,050 --> 00:05:11,640 that means we then need to pass in the value of a string for the argument, arg. 80 00:05:11,640 --> 00:05:13,220 Okay, let's give that a try. 81 00:05:13,220 --> 00:05:17,620 So we'll call transform, and for arg we need to pass in a string, so 82 00:05:17,620 --> 00:05:22,810 we'll pass in a string that has one, the string one not the number. 83 00:05:22,810 --> 00:05:28,730 And then for the operation will pass in the string to int function. 84 00:05:28,730 --> 00:05:32,150 We're going to just pass the function you might not have seen this earlier but 85 00:05:32,150 --> 00:05:35,380 here we're just passing the function not actually calling it. 86 00:05:35,380 --> 00:05:39,870 Immediately in the results area you'll see that we get the value one back. 87 00:05:39,870 --> 00:05:46,450 Since T to you is now string to int and are transformed function returns you. 88 00:05:46,450 --> 00:05:49,240 This means it now returns an int value. 89 00:05:49,240 --> 00:05:54,100 So here we accepted as an argument a string value, and then our transform 90 00:05:54,100 --> 00:05:58,420 operation took a function that transformed it and returned the result. 91 00:05:58,420 --> 00:06:00,300 But this is a generic function, right? 92 00:06:00,300 --> 00:06:04,700 Which means that we should be able to use it with a different set of types, 93 00:06:04,700 --> 00:06:06,280 indeed, we can't. 94 00:06:06,280 --> 00:06:12,120 So, if we write another function that goes from int to string and then, 95 00:06:12,120 --> 00:06:17,350 so in the opposite direction and accepts an argument of type int and 96 00:06:17,350 --> 00:06:21,480 then, returns a string inside we can say return string. 97 00:06:23,370 --> 00:06:26,820 And now here we don't have to do the guard left and unwrap and 98 00:06:26,820 --> 00:06:30,559 all that because you can always convert to a string any integer. 99 00:06:30,559 --> 00:06:34,370 And just like before we can call the transform function and 100 00:06:34,370 --> 00:06:36,950 will pass in input to string over here. 101 00:06:38,070 --> 00:06:41,327 And again we're just passing the function not calling it or anything. 102 00:06:41,327 --> 00:06:46,287 Now when we pass it in this time, intToString accepts a value of Int and 103 00:06:46,287 --> 00:06:48,070 returns String. 104 00:06:48,070 --> 00:06:51,930 So T here is now Int and U is String. 105 00:06:51,930 --> 00:06:56,380 Which means that argument needs to be of type Int and 106 00:06:56,380 --> 00:06:58,950 we're going to get a string out of our function. 107 00:06:58,950 --> 00:07:03,160 So if I pass in 12 you'll see that we get the string 12 back. 108 00:07:03,160 --> 00:07:04,770 If I want to try and 109 00:07:04,770 --> 00:07:09,200 make this a string it's going to fail because now our types don't match up. 110 00:07:11,400 --> 00:07:14,390 So a bit complicated to maybe wrap your head around this function, 111 00:07:14,390 --> 00:07:16,620 but it shows you the power of generics. 112 00:07:16,620 --> 00:07:18,670 Let's take a break here. 113 00:07:18,670 --> 00:07:22,270 In the next few videos let's examine what else we can do with generic functions.