[MUSIC]. In this segment, I want to introduce the cond construct into racket. it's useful in place of nested if/then/else expressions. It's better style. And it's not very hard to learn. I just put it off to get us started with the bigger ideas in Racket. But you do want to use this. Whenever you have a bunch of nested ifs where your else branch, your false branch is another if. And then the else branch of that is another if. Cond is definitely better style. You can think of cond as just syntactic sugar for nested if/then/else expressions. Or if you prefer to think of if/then/else as syntactic sugar for a cond with just 2 branches, that's fine too. So here's how cond works. It's just a special form, COND. So of course, it has a parenthesis at the beginning, and at the end. We then have, in parentheses, n pairs of expressions, right? So I have a bracket, because that's the convention. Semantically, it doesn't matter. Just, syntactically, it's better styled at the bracket. matter. You can use round parentheses if you want. Then, 1 expression. Then another expression and that branch, another one, another one. The way this works is all these first ones are tests and all the second ones are what to do if that test is true. So if the first one is true Then do the second one. Else, if this is true, do this one. Else, if this one. And you stop, and your result is the first branch, where the thing on the left was true, and then you evaluate the thing on the right, and that's your answer. Now, as a matter of style, it's very important that your last branch typically be just true, which we write in Racket, #t. This is your default case. This is saying, in any other case, I want to evaluate this last expression, and that's my. My answer. If you do not do this and your last test expression also evaluates the false then cond will return some strange void object which is a bad idea in Racket, it will not produce an error here but probably it's going to return some result that someone else doesn't want to use. And you'll end up confusing yourself. So always make your last branch have as it's test a true, okay. So let's go over here to DrRacket, here is the sum functions that I wrote in the previous segment. So this first, this First one works on a list of numbers that could have nested within them other lists of numbers and so on, as deep as you want. And it's an error tab, anything in there that's not a list or a number. And then the second version that if there's some non-list or non-number nested somewhere on the list, we just skip over it. [UNKNOWN] And we can rewrite each of these just using cond, and so I'm going to do that just in a different file here there we go. And, this will not be very difficult so I'll call these sum 3 and sum 4 to continue what we were doing in the previous section and I can have a cond which of course can have any number of branches I want and the first branch will be that if the input X's is the No list, the empty list, the results should be 0. Otherwise if the 1st element is a number, so number of car of x's, then add the car of x's to the recursive sum of the cdr of x's. That will end that branch. Notice you can type round parentheses and if they match square brackets, Dr. Racket will turn it into a square bracket for us. And in any other case for this version, so for #t, I'll go ahead and assume that the first element of xs is itself a list. So I know how to sum a list. I call sum3, and then I need to sum3 the cdr of xs. Codes that, and this should all be correct if we compare it to our other version, I'm going to flip that over here, you'll see that we have the same three cases. If it's null 0, the first number first thing to list as a number, do this addition. Otherwise do this addition but you'll probably agree with me that it's easier to read laid out as this [UNKNOWN] we can see that three tests null, number and true quite easily and then what to do in each case by the expression that follows that test, k, so that's sum three now let me quickly do sum four. It's the same idea. I'll have a con and if the list is empty then return 0, if the first thing in the list is a number then, sorry, number car of xs. And in fact it's exactly the same as before, car of xs, sum4 For now cdr of x's, alright? Otherwise I have another test in this version where I ask, well is x's a list? Because if it is, then I want to do what I used to do just by the default assumption but this time I check that it was the list. So you can see the difference between the 2 versions quite easily and in any other case. Skip the car of xs and just cdr of xs and if you look back this is exactly like some 2 just laid out nicely with the cond construct. So that's our example. Now what I want to do is go back to the slides and talk about one other issue, okay. as before o sorry here's where I want to to go, okay. So for both if and cond. I just didn't tell you this for if and now I'm telling you for both. The test expression, that first expression does not have to be true or false, #t or #f. It turns out, it can be anything. It's never an error and it's fine. So what is the semantic? The schemantics in Racket is that anything other than false, counts as true. So, the only way to take the false brancgh is if you have #f. But, to take the true branch you so not need #t. You just need anything that is not #f. This is very common in dyanamically type languages, some dynamicaaly type languagees make other things false. Things like the empty list or the empty string, or things like this. That's not true in Racket. In Racket there's exactly one thing that's false, and that's #f. Everything else counts as true. Now this makes no sense in a statically typed language. In a statically typed language We would insist that a conditional expression take something of type Buhl[UNKNOWN] for it's first argument. Since everything has exactly one type, there is no point in allowing anything to be in that first position. But a language like Racket, you can You can do this. Now, a lot of people consider this bad style. A lot of people consider this convenient and okay. And some people are kind of in between and say it depends on the situation. I'm not a huge fan of this construct, but since it reinforces the idea That Racket supports dynamic typing, I though I would show it to you. So let's do couple quick examples here. so first of all let me just click run and do something at the repel here. So what if I said if 34 then 14, l's 15. Well since 34 is not false it must be true and I get 14. Okay? So it's just that simple and I could say if empty list. 14 else 15, and I would get 14, and so on. But if I saw hash false, then I get 15. So now, let me just paste in a quick example of where this is useful, and I want to take the time to type it all out. and you don't need this, okay? You could, you know, get by in, in Racket without this feature. Woop. There we go. So what this function does is it cou, it takes in a list, just a list no nested list or anything, and counts how many falses are in it. Okay? So let me just run this. So we can see it in action. And so if I count falses of the list 34, true, and hi, I should get 0. But if I add in here a couple falses, maybe one at the beginning, one there, and how about a couple at the end. Then I get 4. That's all it does, it counts how many false's there are. Use cond, which we introduced here, and we say that if the list is empty then there are 0 false's in it. If the car of x's is not false, well here is one way to do that. Right? If car of x's is anything other than false Then this test will be true. And so we'll recursively count the falses in the cdr. And in any other case, the only case that's left, it that the first thing in the list was false. And then we would add 1 to count falses of cdr of xes, okay? So that is an example of using this feature that everything that is not #f is true. The only thing that is false is #f. But the main idea in this segment was using cond for better style, and now we can use it in all of our homework problems in Racket programming, rather than nested if/then/else.