This week we're going to talk about the design of data.
And what we're going to see is that the design of data really turns out to be a
point of leverage in designing programs. Because when we design data.
We make decisions about all the functions that later operate on that data.
But before we get to that, this video covers cond expressions which are a new
kind of expression in Racket that's going to let us program conditional behavior
where there's more than just two cases. I have the constarter.racket file open
from the lecture page. Lets just look at this file quickly.
It starts by defining three constants, called I1, I2, and I3.
And they're all three rectangles, and let's see.
One is 10 wide and 20 high. And the, I 2 is 20 by 20.
And I 3 is 20 by 10. So these are three rectangles of
different shapes. And now here's a function design.
And the function consumes an image and produces a string, and let's see.
It produces the shape of the event one of tall square or wide.
And these three examples slash check expects really help me understand this
function. If I ask for the aspect ratio I want, I
get tall. Whereas for I2 I get squared and for I3 I
get wide. In reading through the rest of this,
there's a stub and a template that are commented out.
And now when we look at the definition of the function, what does it say?
It says well if the height of the image is greater than the width of the image
then produced tall, that's this, this whole if there.
And that's its question, and that's its true answer.
On the other hand, let's see, its false answer is another if that asks if the
image height and width are equal, produced square otherwise produce wide.
So, this function design works and if I run it I'll get what I want.
But there is something I'm not entirely happy about here.
If you think about this function, there are really three cases, right?
There's the tall case, the square case, and the wide case.
And those three cases really feel like they're parallel to me, they feel like
they're corresponding cases. Whereas, when we implement them here with
if. We end up having one case tall, which has
two other cases square and wide, kind of inside of it.
And that doesn't feel quite right, doesn't feel quite right to have one case
with 2 inside of it as oppose to 3 parallel cases.
So what we're going to learn. In this video is a new mechanism called
cond. That's what called a multi armed
conditional and that's something we can use when we want to make an expression
that has different behavior depending on the answered predicates but there's more
than two different options. So here we go lets do it to this one.
Let me first show you a new trick. If I do sharp sign semicolon, that's
going to comment out the entire, all of that stuff.
It basically comments out from balance parenthesis to balance parenthesis.
It's easier than putting a semi-colon before each line.
Now let's redo this function. I'll say define, aspect-ratio, image.
And what I have is three cases so whatever it is I'm going to write cond,
and then there's three cases. And each case has a question and an
answer. And there's three of them.
So I'll just, copy that, like that. Okay, and I spelled the name of it wrong.
Now, notice something here, which is that I'm using square brackets instead of
round parentheses. Around the question and answer pair,
that's just a convention to make the question and answer pairs stand out
better, particularly when they get larger.
Square brackets and round parenthesis are really treated at the same by racket,
square brackets balance each other and round parenthesis balance each other you
could use round parenthesis here, but square bracket just makes it look a
little bit better. Now what's the question for the first
case. Well the question for the first case is
actually right here. I'll takethat, and I'll replace that
question with it. And if that question is true then what's
the answer? Well the answer Is right here, tall.
And what's the question for the second case?
Well, the question for the second case is right here.
And the answer for the second case is right there.
And then what's the question for the third case?
Well the third case is the last case. It's the in all other cases case.
And so there's a special question that we can put there called else which means, if
it wasn't the first one or the second one just do this and the answer for the last
case is wide. Let me first run this to make sure I
haven't made any mistakes. [UNKNOWN] It's working.
And so the way I want to read this is it says, gee there's multiple conditions, if
image height is greater than image width then produce this result, evaluate this
expression and produce that result. If image height is equal to image width,
evaluate this expression and produce that result.
Otherwise, or else evaluate that expression and produce that result.
And that's kind of nice. What that gets me is multiple questions,
kind of all at the same level of nesting, all at the same level of importance in
some sense. So cond is a good thing to use.
For multiple case expressions, when there's more than two cases.
You can use if, you can use if and nest them the way we have up here.
But, it tends to read more easily if you use cond when there's more than two
cases. [INAUDIBLE] Now, we'll do the usual thing
and look at the rules for forming a cond expression.
It's just open paren cond. And then one or more question answer
pairs, where each question answer pair is open bracket, a question expression, and
then an answer expression, and a closed bracket.
And all of the question expressions have to produce a boolean, except the last
question expression which is allowed to be the special word else, Which is
going to mean if you get to this question answer pair definitely produce this
answer. Look at the rules for evaluating cond.
What I want to do is work with a slightly simpler example.
So I want to do is make a new tab and here's my simpler example.
And I'll do the usual thing about putting the evaluation rules for cond off to the
right here. Now let's get going.
We start evaluating and we see open parameter cons and this is a conned
expression. We have to use the rules of con .There
are question answer pairs so there's no error.
And let's see the first question right here, E is not a value.
Its an expression. So we need to evaluate it.
Well lets see evaluating it its open paren greater than.
Its a call to our primitive. So we would use our call to a primitive
role. Both operators are already values so we
can apply the primitive directly So this greater than one, two, is going to
produce false. So what we're going to do is replace the
entire cond, with a cond in which the ker, first question is false.
Now we start evaluating it. Open print cond, its a cond.
Lets see the first question is false so that takes us to the if the first
question is false rule and what that rule wants us to do is drop the first question
answer pair. So what we get now is a new cond in which
this first First question answer pair is going to be deleted entirely.
When do you command E now to get myself more room here.
Okay, lets see open end cond, there are question answer pairs.
The first question is not a value, it's an expression.
So I need to evaluate the first question and replace the question with its value.
Well, we know how to do that now. That just gives me false again.
Open paren cond, there are question answer pairs.
The first question is false. So again, it's the drop the first
question rule. We basically drop the first question.
Open [INAUDIBLE] conditon, there are questions.
The first question is not a value it's an expression, I evaluate it.
Okay, we're getting there, we're getting very close now.
That is now true, open paren, cond, the first question is true, now I replace the
entire cond with the first answer expression.
Okay, let's see what I have now. Oh, I have a value, I'm done evaluating.
The key intuition is the way the evaluation of con works is, it evaluates
the first question. If it's false, it drops that question
answer pair and starts over. If the first question is true, then it
replaces the entire con. With the first answer.
You can see here an interesting pattern, right, which is the rule for call, the
rule for function call, the rule for if, they all work the same way.
They in some sense try to do their thing and then get out of the way.
Right here in this last step with cond, once we got to the answer, the cond was
gone. And that's the same thing that happened
with function call. Once the body of the function is replaced
in the function call itself is gone. Any style of evaluation rules work that
way the idea is to take care of the sophitacted construct and then get it out
of the program. Okay, here's another example for you to
do stepping. It's a little bit more complicated.
I apologize for all these stepping examples but we know that they really
help people in terms of mastering how the language works.
And that really starts to help as the program gets more complicated.
So here is another example of that as an exercise, but it will be interactive so
that you kind of work through it as you go.