We can't leave the topic of object oriented programming without digging in a little deeper on type checking. So, we've talked about and emphasized throughout Java, the idea of static or compiled time type checking. All variables must have declared types and the system checks for type errors at compile time. You can even run your program unless the system knows that operations that your specifiers are compatible with the types of the variables that are involved. The alternative is called dynamic or runtime type checking which is what they do in Python. Java also does some runtime type checking, but let's talk about this contrast. The ideas that the values not the variables have defined types in the system, therefore it can check just when it's time to reform an operation, just in time that it's got the right types. So, these are two dramatically different approaches to looking for type errors. The question would be, which is best? Of course, you can never multiply a string by a double value, that's an error. The question is should you find out at compile time or runtime? I'm going to have to say that there's ongoing religious wars about this. Some people say static typing is just not worth the trouble, is too much of a pain to have to type the values and then specify the values of all your variables and check that. On the other hand, maybe the compiled code that we get out is much more efficient if we know that the types are okay. Maybe the code is more reliable if it's carefully type-checked. Maybe, but on the other hand, maybe there's lot of advanced features like generic types that we want to write programs that work on many different types of data and maybe it's too hard to use with static typing. There's many, many, many, many other questions that come up and people still really argue vociferously on both sides. I'll give you an example. So, one idea is that while type checking is one way to look for errors, but another thing that we can do, we have computers. We can test our programs by writing a program to produce a lot of inputs and check our programs against the inputs that we produce. We automate program testing. Even in the '60s, Dijkstra who's a character that we've seen before, said this about program testing, "It can be a very effective way to show the presence of bugs, but it's hopelessly inadequate for showing their absence." Dijkstra was a pioneer in the idea of trying to ensure, through mathematical reasoning, that programs would be correct. Static typing can really play an important role in that. By contrast, there's plenty of people out there nowadays and you can find them all over the Web. Here's a typical example, "Since static type checking can't cover all possibilities, you will need automated testing. Once you have automated testing, static type checking is redundant." When I saw that quote, I showed it to my colleague, Dave Walker, who's a world expert in this field and here's the response that he wrote, "Dear random Python blogger. Why don't you think of static type checking as a complementary form of completely automated testing to augment your other testing techniques? I actually don't know if any other testing infrastructure that is as automated, fast, and responsive as a type checker, but I'd be happy to learn. By the way, type checking is a special kind of testing that scales perfectly to software of arbitrary size because it checks that the composition of two modules is okay based only on their interfaces, without re-examining their implementations. Conventional testing doesn't scale the same way. Also, did you know that type checking is capable of guaranteeing the absence of certain classes of bugs? That is particularly important if you want your system to be secure. Python can't do that." The ideas that programming a way we've taught it with modular programming that are put together to make larger programs with static type checking really enables this kind of approach where we use the power of computer, the computer to help us reason about what our programs are supposed to do, specify as much as we can, what we think they're supposed to do, and with the idea of composing modules to get proofs about bigger and bigger programs is an extremely powerful one in modern systems. I didn't give the random Python blogger a chance to respond to Dave. My personal opinion is that there are way, way, way, way too many possibilities for inputs for automated testing to be effective at all, so I'm with Dave. I'll just finish off with an old story from early programming languages. So, at the beginning with machine languages, there was not much support for types and that was one of the actually innovations of C and Charles Simonyi who was a programmer in the 1970s at Xerox PARC, had the idea of making a program easier to understand by encoding the type in the variable name itself. We don't even do that in modern languages. There were some old languages that did that. The Fortran language, if a variable was i, j, or k was an integer. Otherwise, it was a floating point value. Charles say "Well, I have to write programs that deal with strings and other types of data. I'm going to put the type in the first few characters of the variable name." Now, again we had tiny computers in there were limits and so you could only have an eight-character limits. So, you had to leave out the vowels and then truncate. So, a typical variable name in Charles's code would be arru8Fbn, and so that's an array of eight-bit integers that are unsigned. The variable name is short for Fibonacci and Charles who was much more important to know the type than to have a clue of what the variable name was. He and teams of programmers who worked with them wrote huge programs based on this system. When you think about it, and you look at a line of code knowing the type of the variable just reading the code that's evolved and that's a useful thing to have when debugging. You can just type check while you're reading the code and sure it's got this problem with short vowels and variable names, but Charles used that to great advantage. He actually built the first version of Microsoft Word using code like this. I tell this story just to teach the lesson that type checking really has always been important in large software system. That's not something that can be ignored or that will go away.