Now I'm going to finish the first version of the Cat program.
That's going to involve designing two functions.
So, in that way it's going to be quite familiar, we'll go through the HTDF
recipe twice. But we're going to be designing those
functions in the context of a partially complete, larger program.
That's something that gets to be more and more important as we go forward.
As the programs get bigger, we often have lots of incomplete function that we need
to finish before we're done. And the most important thing in this
video is going to be how to use the wish list mechanism, to keep track of that
work that remains to be done. We have a constants part of the file
which we know corresponds to the constants part of the analysis.
We have a data definitions part of the file that includes a world state type,
cat, which we know corresponds to the changing information part of the
analysis. We have a main function that calls
Bigbang with two options, on-tick and to-draw.
And now, if we've forgotten exactly what we have to do, I'll just search for three
exclamation marks, and very quickly, I see exactly what I have to do.
And if this program was larger, I could go here and say, Show Program Contour.
And I'd see off to the right, a picture of the whole program.
And you can barely see it there. But the places where the search has found
three exclamation marks are highlighted. So, if I had a very big program, I could
go over here, and quickly jump to those places like that.
I will hide that for now because we don't have that bigger program.
So, now what I have do, will this tells me, hey you are part way through an HTDF
problem. Here's the problem, you've got a function
that consumes a Cat and produces a Cat. This is an HTDF problem consuming Cat.
It consumes Cat, produces Cat, produces the next Cat by advancing it one pixel to
the right. If I'm a little bit unsure about what a
cat is, I can scroll up here to the data definitions and see oh, a cat is number.
And here's some good examples. And it's interpreted as the exposition of
the cat in screen coordinate. Okay, while signature purpose stub, the
next step is examples. Let's see, what's a good first example?
We'll say check-expect advance-cat of, I don't know, 3?
And we advance it by one pixel to the right, so that should produce 4.
And let's see, this function is consistently, it behaves consistently
independent of the number we gave it, so I really should only need one test.
I'll run the test to make sure that they're well formed.
The test is running, but failing, so it's well-formed.
This was the stub. I'll comment it out.
I'll say use template from Cat. I'll go up here and get the template.
I'll copy it. I'll just label this as being the stub.
And rename this to advance cat. And let's see.
I've gotta fill in the dots. I advance it one pixel to the right.
Oh, this is just plus C one. Or if you want there happens to be a
function called add one, we could use that, but I'll just say plus c 1.
Now, I'll run again my test passed. So, let's see, I've done that piece of
the wish list. I go back again looking for three
exclamation marks. Here's another function.
It consumes Cat and produces Image. And it's supposed to render the cat image
at an appropriate place on MTS. And now I say to myself, well what's the
cat image. I'll look up in the constants.
Oh yeah, there's a thing called CAT-IMG. And I'll say to myself well, what's the
appropriate place? I'll go look at the Cat data definition.
Cat is number; so Cat itself is a number, and I interpret that as the x position.
So, I've got the x position. And I remember now that the y position
doesn't change. So, I'll look in the constants for it
too. There it is, CTR-Y.
So, now I've got a pretty good idea about how this is going to work.
Signature purpose stub, the next thing is example, so check, expect, render of some
Cat, let's say 4. What's that supposed to produce?
So, render 4 does what? Well, there is this primitive called
place-image, and what we need to do is we ta, need to take the image of the cat
which is CAT-IMG. We need to put it at a certain x,y
location, which is 4 and CTR-Y. And the background that we're going to
put it on is MTS. Now I wrote that quickly because I
remember exactly how place-image works. If it takes you longer to write the
expected result for our rendered function, don't worry about that all.
You're figuring how the image functions work.
What you're going to use in order to produce the image you want.
Time spent here on this example translates into time saved when you do
the actual function. So let me run this.
And we have a failing test, which is what we'd expect.
One thing that's nice to do with these render functions is actually look at the
failing test. Lets see, we're getting an empty scene,
because the stub always produces the empty scene.
What's useful to do, and let me just make this bigger, is to look at the expected
result, and see if our test makes sense. And that seems about right, we've got a
cat there that's nose is a little bit off the edge.
Remember, Place Image places the center of cat image In other words, kind of a
center of this cat. At the specified position.
So, it's putting this center of the cat at 4 and CTR-Y.
The CTR-Y part is definitely right. And as I say, because the nose is a
little bit off and I can see the beginning of that eye, I think it is
about four. So that seems about right.
We'll know for sure, soon. Okay, let's see.
Let's finish up. This is the stub.
We're going to use the template from Cat. Let's go get that template.
[SOUND]. We'll rename this to render.
And, let's see. We need to render the cat image in an
appropriate place on MTS. Cat is itself the x coordinate, so
looking at the signature, the purpose and the example, what I can see is that this
is "place image cat image" C is itself the X coordinate.
CTR-Y and MTS. I'll run that.
Both my tests are passing, and now what I do, like to do is actually run the world
program. So going back to main.
I can call main, and the initial world-state is whatever cat I give it,
whatever x coordinate I give it. So, it probably makes sense to maybe call
it with zero to start. So, I run the program, and then I get
this interaction window down here, and I go main of zero, and there's my cat.
Walking across the screen. And now that I have a clear sense in my
mind of what's a good default way to start this program, what I'm going to do
is go back to the main function. And say start the world with main of 0.
Just as a way of telling people what's a good way to start it.
I actually could have put in that start the world with main zero at the
beginning, because as soon as we knew what the cat data definition was, we knew
that 0 would be a good default value. I just waited til the end here.
So there we go. We've got a complete running world
program. One of the things I hope you saw here is
that by working systematically at any moment in time our work was very focused.
Even though we did a lot, at every moment in time we were only doing one thing.
That's what working systematically did for us.
So, when we were working on the domain analysis, even then there were parts of
it. We worked on the constant information,
then we did the changing information, then we did the Bigbang options, and that
gave us the domain analysis. As we started building the program, first
we did the constants, then we did the data definition, for changing
information. Then we set up the main function and the
wish list for our big-bang option handlers.
And then we work that wish list one function at a time.
This is really important, as programs get big and remember, programs get big.
Cars have millions of lines of code in them.
The big benefit of having a systematic process is it lets you work on one thing
at a time, and know that it's all going to work out.
because in this case, when we were done, and we said, main of zero, bang, we got a
running row program. And also let me repeat a point I made
earlier about templates. Because we have a process, some parts of
the work we do don't really necessarily end up as specific sub-parts of the final
program. So, the domain analysis itself isn't in
the program. It's something we wrote on a piece of
paper. But it was part of the process that got
us there. That's just like the template.
The template kind of disappears into the final function definition, but the
template is part of the process that gets us there.
People who design, design methods, see that's a kind of meta design, that's one
of the things they work on, is how can there be elements of the design.
That get you there, even though they disappear in the final artifact.
We'll talk more about that as we go along.