1 00:00:06,080 --> 00:00:09,500 This week we're going to talk about the design of data. 2 00:00:09,500 --> 00:00:12,380 And what we're going to see is that the design of data really turns out to be a 3 00:00:12,380 --> 00:00:17,940 point of leverage in designing programs. Because when we design data. 4 00:00:17,940 --> 00:00:23,160 We make decisions about all the functions that later operate on that data. 5 00:00:23,160 --> 00:00:27,255 But before we get to that, this video covers cond expressions which are a new 6 00:00:27,255 --> 00:00:31,675 kind of expression in Racket that's going to let us program conditional behavior 7 00:00:31,675 --> 00:00:39,729 where there's more than just two cases. I have the constarter.racket file open 8 00:00:39,729 --> 00:00:44,139 from the lecture page. Lets just look at this file quickly. 9 00:00:44,139 --> 00:00:47,020 It starts by defining three constants, called I1, I2, and I3. 10 00:00:47,020 --> 00:00:50,370 And they're all three rectangles, and let's see. 11 00:00:50,370 --> 00:00:57,009 One is 10 wide and 20 high. And the, I 2 is 20 by 20. 12 00:00:57,009 --> 00:01:00,638 And I 3 is 20 by 10. So these are three rectangles of 13 00:01:00,638 --> 00:01:03,460 different shapes. And now here's a function design. 14 00:01:03,460 --> 00:01:09,090 And the function consumes an image and produces a string, and let's see. 15 00:01:09,090 --> 00:01:12,310 It produces the shape of the event one of tall square or wide. 16 00:01:12,310 --> 00:01:16,790 And these three examples slash check expects really help me understand this 17 00:01:16,790 --> 00:01:20,550 function. If I ask for the aspect ratio I want, I 18 00:01:20,550 --> 00:01:24,394 get tall. Whereas for I2 I get squared and for I3 I 19 00:01:24,394 --> 00:01:27,570 get wide. In reading through the rest of this, 20 00:01:27,570 --> 00:01:31,110 there's a stub and a template that are commented out. 21 00:01:31,110 --> 00:01:34,580 And now when we look at the definition of the function, what does it say? 22 00:01:34,580 --> 00:01:39,726 It says well if the height of the image is greater than the width of the image 23 00:01:39,726 --> 00:01:45,600 then produced tall, that's this, this whole if there. 24 00:01:45,600 --> 00:01:49,940 And that's its question, and that's its true answer. 25 00:01:49,940 --> 00:01:53,722 On the other hand, let's see, its false answer is another if that asks if the 26 00:01:53,722 --> 00:01:59,270 image height and width are equal, produced square otherwise produce wide. 27 00:01:59,270 --> 00:02:05,070 So, this function design works and if I run it I'll get what I want. 28 00:02:05,070 --> 00:02:07,760 But there is something I'm not entirely happy about here. 29 00:02:07,760 --> 00:02:11,970 If you think about this function, there are really three cases, right? 30 00:02:11,970 --> 00:02:14,410 There's the tall case, the square case, and the wide case. 31 00:02:14,410 --> 00:02:18,442 And those three cases really feel like they're parallel to me, they feel like 32 00:02:18,442 --> 00:02:22,935 they're corresponding cases. Whereas, when we implement them here with 33 00:02:22,935 --> 00:02:26,398 if. We end up having one case tall, which has 34 00:02:26,398 --> 00:02:30,640 two other cases square and wide, kind of inside of it. 35 00:02:30,640 --> 00:02:36,121 And that doesn't feel quite right, doesn't feel quite right to have one case 36 00:02:36,121 --> 00:02:41,764 with 2 inside of it as oppose to 3 parallel cases. 37 00:02:41,764 --> 00:02:45,956 So what we're going to learn. In this video is a new mechanism called 38 00:02:45,956 --> 00:02:48,844 cond. That's what called a multi armed 39 00:02:48,844 --> 00:02:52,812 conditional and that's something we can use when we want to make an expression 40 00:02:52,812 --> 00:02:57,152 that has different behavior depending on the answered predicates but there's more 41 00:02:57,152 --> 00:03:04,665 than two different options. So here we go lets do it to this one. 42 00:03:04,665 --> 00:03:09,460 Let me first show you a new trick. If I do sharp sign semicolon, that's 43 00:03:09,460 --> 00:03:12,295 going to comment out the entire, all of that stuff. 44 00:03:12,295 --> 00:03:18,590 It basically comments out from balance parenthesis to balance parenthesis. 45 00:03:18,590 --> 00:03:22,445 It's easier than putting a semi-colon before each line. 46 00:03:22,445 --> 00:03:28,839 Now let's redo this function. I'll say define, aspect-ratio, image. 47 00:03:28,839 --> 00:03:33,595 And what I have is three cases so whatever it is I'm going to write cond, 48 00:03:33,595 --> 00:03:40,654 and then there's three cases. And each case has a question and an 49 00:03:40,654 --> 00:03:45,750 answer. And there's three of them. 50 00:03:45,750 --> 00:03:54,550 So I'll just, copy that, like that. Okay, and I spelled the name of it wrong. 51 00:03:54,550 --> 00:03:57,586 Now, notice something here, which is that I'm using square brackets instead of 52 00:03:57,586 --> 00:04:01,269 round parentheses. Around the question and answer pair, 53 00:04:01,269 --> 00:04:04,809 that's just a convention to make the question and answer pairs stand out 54 00:04:04,809 --> 00:04:08,420 better, particularly when they get larger. 55 00:04:08,420 --> 00:04:12,440 Square brackets and round parenthesis are really treated at the same by racket, 56 00:04:12,440 --> 00:04:16,520 square brackets balance each other and round parenthesis balance each other you 57 00:04:16,520 --> 00:04:20,180 could use round parenthesis here, but square bracket just makes it look a 58 00:04:20,180 --> 00:04:26,184 little bit better. Now what's the question for the first 59 00:04:26,184 --> 00:04:27,838 case. Well the question for the first case is 60 00:04:27,838 --> 00:04:31,723 actually right here. I'll takethat, and I'll replace that 61 00:04:31,723 --> 00:04:36,454 question with it. And if that question is true then what's 62 00:04:36,454 --> 00:04:41,035 the answer? Well the answer Is right here, tall. 63 00:04:41,035 --> 00:04:46,400 And what's the question for the second case? 64 00:04:46,400 --> 00:04:52,490 Well, the question for the second case is right here. 65 00:04:52,490 --> 00:04:59,291 And the answer for the second case is right there. 66 00:04:59,291 --> 00:05:03,780 And then what's the question for the third case? 67 00:05:03,780 --> 00:05:10,115 Well the third case is the last case. It's the in all other cases case. 68 00:05:10,115 --> 00:05:14,535 And so there's a special question that we can put there called else which means, if 69 00:05:14,535 --> 00:05:18,760 it wasn't the first one or the second one just do this and the answer for the last 70 00:05:18,760 --> 00:05:24,812 case is wide. Let me first run this to make sure I 71 00:05:24,812 --> 00:05:30,006 haven't made any mistakes. [UNKNOWN] It's working. 72 00:05:30,006 --> 00:05:35,814 And so the way I want to read this is it says, gee there's multiple conditions, if 73 00:05:35,814 --> 00:05:41,798 image height is greater than image width then produce this result, evaluate this 74 00:05:41,798 --> 00:05:49,247 expression and produce that result. If image height is equal to image width, 75 00:05:49,247 --> 00:05:52,570 evaluate this expression and produce that result. 76 00:05:52,570 --> 00:05:58,390 Otherwise, or else evaluate that expression and produce that result. 77 00:05:58,390 --> 00:06:01,534 And that's kind of nice. What that gets me is multiple questions, 78 00:06:01,534 --> 00:06:05,758 kind of all at the same level of nesting, all at the same level of importance in 79 00:06:05,758 --> 00:06:11,550 some sense. So cond is a good thing to use. 80 00:06:12,980 --> 00:06:17,940 For multiple case expressions, when there's more than two cases. 81 00:06:17,940 --> 00:06:21,780 You can use if, you can use if and nest them the way we have up here. 82 00:06:21,780 --> 00:06:25,196 But, it tends to read more easily if you use cond when there's more than two 83 00:06:25,196 --> 00:06:29,435 cases. [INAUDIBLE] Now, we'll do the usual thing 84 00:06:29,435 --> 00:06:32,051 and look at the rules for forming a cond expression. 85 00:06:32,051 --> 00:06:36,350 It's just open paren cond. And then one or more question answer 86 00:06:36,350 --> 00:06:41,390 pairs, where each question answer pair is open bracket, a question expression, and 87 00:06:41,390 --> 00:06:46,380 then an answer expression, and a closed bracket. 88 00:06:48,479 --> 00:06:52,054 And all of the question expressions have to produce a boolean, except the last 89 00:06:52,054 --> 00:06:55,464 question expression which is allowed to be the special word else, Which is 90 00:06:55,464 --> 00:06:58,874 going to mean if you get to this question answer pair definitely produce this 91 00:06:58,874 --> 00:07:04,804 answer. Look at the rules for evaluating cond. 92 00:07:04,804 --> 00:07:09,394 What I want to do is work with a slightly simpler example. 93 00:07:09,394 --> 00:07:13,740 So I want to do is make a new tab and here's my simpler example. 94 00:07:13,740 --> 00:07:17,492 And I'll do the usual thing about putting the evaluation rules for cond off to the 95 00:07:17,492 --> 00:07:21,990 right here. Now let's get going. 96 00:07:21,990 --> 00:07:24,484 We start evaluating and we see open parameter cons and this is a conned 97 00:07:24,484 --> 00:07:28,050 expression. We have to use the rules of con .There 98 00:07:28,050 --> 00:07:32,520 are question answer pairs so there's no error. 99 00:07:32,520 --> 00:07:38,170 And let's see the first question right here, E is not a value. 100 00:07:38,170 --> 00:07:41,308 Its an expression. So we need to evaluate it. 101 00:07:41,308 --> 00:07:45,862 Well lets see evaluating it its open paren greater than. 102 00:07:45,862 --> 00:07:50,458 Its a call to our primitive. So we would use our call to a primitive 103 00:07:50,458 --> 00:07:53,629 role. Both operators are already values so we 104 00:07:53,629 --> 00:07:57,409 can apply the primitive directly So this greater than one, two, is going to 105 00:07:57,409 --> 00:08:02,710 produce false. So what we're going to do is replace the 106 00:08:02,710 --> 00:08:10,429 entire cond, with a cond in which the ker, first question is false. 107 00:08:12,640 --> 00:08:16,570 Now we start evaluating it. Open print cond, its a cond. 108 00:08:16,570 --> 00:08:19,702 Lets see the first question is false so that takes us to the if the first 109 00:08:19,702 --> 00:08:23,320 question is false rule and what that rule wants us to do is drop the first question 110 00:08:23,320 --> 00:08:27,875 answer pair. So what we get now is a new cond in which 111 00:08:27,875 --> 00:08:33,170 this first First question answer pair is going to be deleted entirely. 112 00:08:33,170 --> 00:08:37,275 When do you command E now to get myself more room here. 113 00:08:37,275 --> 00:08:42,420 Okay, lets see open end cond, there are question answer pairs. 114 00:08:42,420 --> 00:08:47,050 The first question is not a value, it's an expression. 115 00:08:47,050 --> 00:08:52,430 So I need to evaluate the first question and replace the question with its value. 116 00:08:52,430 --> 00:08:57,311 Well, we know how to do that now. That just gives me false again. 117 00:08:57,311 --> 00:09:04,139 Open paren cond, there are question answer pairs. 118 00:09:04,139 --> 00:09:09,855 The first question is false. So again, it's the drop the first 119 00:09:09,855 --> 00:09:17,090 question rule. We basically drop the first question. 120 00:09:17,090 --> 00:09:23,360 Open [INAUDIBLE] conditon, there are questions. 121 00:09:23,360 --> 00:09:30,240 The first question is not a value it's an expression, I evaluate it. 122 00:09:30,240 --> 00:09:32,252 Okay, we're getting there, we're getting very close now. 123 00:09:32,252 --> 00:09:41,426 That is now true, open paren, cond, the first question is true, now I replace the 124 00:09:41,426 --> 00:09:49,950 entire cond with the first answer expression. 125 00:09:49,950 --> 00:09:52,585 Okay, let's see what I have now. Oh, I have a value, I'm done evaluating. 126 00:09:54,400 --> 00:09:57,760 The key intuition is the way the evaluation of con works is, it evaluates 127 00:09:57,760 --> 00:10:01,717 the first question. If it's false, it drops that question 128 00:10:01,717 --> 00:10:06,512 answer pair and starts over. If the first question is true, then it 129 00:10:06,512 --> 00:10:11,390 replaces the entire con. With the first answer. 130 00:10:11,390 --> 00:10:15,355 You can see here an interesting pattern, right, which is the rule for call, the 131 00:10:15,355 --> 00:10:20,552 rule for function call, the rule for if, they all work the same way. 132 00:10:20,552 --> 00:10:24,900 They in some sense try to do their thing and then get out of the way. 133 00:10:24,900 --> 00:10:29,373 Right here in this last step with cond, once we got to the answer, the cond was 134 00:10:29,373 --> 00:10:32,915 gone. And that's the same thing that happened 135 00:10:32,915 --> 00:10:35,904 with function call. Once the body of the function is replaced 136 00:10:35,904 --> 00:10:42,154 in the function call itself is gone. Any style of evaluation rules work that 137 00:10:42,154 --> 00:10:45,750 way the idea is to take care of the sophitacted construct and then get it out 138 00:10:45,750 --> 00:10:50,378 of the program. Okay, here's another example for you to 139 00:10:50,378 --> 00:10:53,660 do stepping. It's a little bit more complicated. 140 00:10:53,660 --> 00:10:56,720 I apologize for all these stepping examples but we know that they really 141 00:10:56,720 --> 00:11:00,320 help people in terms of mastering how the language works. 142 00:11:00,320 --> 00:11:04,350 And that really starts to help as the program gets more complicated. 143 00:11:04,350 --> 00:11:09,745 So here is another example of that as an exercise, but it will be interactive so 144 00:11:09,745 --> 00:11:14,703 that you kind of work through it as you go.