>> Rustan Leino: It is my great pleasure today to introduce Tony Hoare. I think you all know Tony from his work, but let me just mention a couple of more recent things. One of which is that he just came from receiving the prestigious John [inaudible] award for his contributions to software design, and he just told me also that he is going to receive a SIGPLAN lifetime achievement award in January as well. So without any further ado let me give it to Tony. [applause]. >> Tony Hoare: One more chair, I just vacated [laughter]. >>: And it's warm. >> Tony Hoare: Anybody like to sit in my seat? [laughter]. Well, thank you very much for this invitation. I arrived in Redmond yesterday and I have very much enjoyed my visit so far. I hope you will continue that tradition. Thank you. The Algebra of Concurrent Programming, I have become interested in concurrent programming in its wider aspects in recent years with the advent of the multicore computer. I previously worked in concurrent programming on the model of disjoint communicating processors, so in both cases the development of my thinking has been triggered by the opportunities offered by the hardware. But my real ambition now is to try to unify the ideas that are relevant for reasoning about concurrency in both, all of its forms, at least as many as I can think of. And to present the results of the speculations in the form of algebra that appeals to human ability and human experience and maybe even interest in the use of algebraic manipulations to reason about mathematics, arithmetic and now about programs as well. Of course, the ideas that I will present I have stolen barefacedly from a number of other people, many of them interns at Microsoft in Cambridge. Algebra uses variables to stand for something and if I were a pure mathematician, I wouldn't worry what they stood for at all, but as an applied mathematician, and I expect most of you belong to that category, it is helpful to know at least one of the things that the variables of your algebra are standing for, and I am going to tell you that my intention is that they should stand for computer programs, computer program designs and computer program specifications. I am deliberately not going to say which of those I am talking about at a given time, because I want to concentrate on the similarities rather than their differences. All three describe what happens inside and around a computer that executes a given program. And of the three kinds of descriptions the program itself is the most precise in the sense that if the program doesn't say exactly what is going to happen, at least it delimits entirely the limited freedom that the implementer has in implementing the program in different ways. So the program can be nondeterministic, but nevertheless it is the most precise description you get of what the computer is going to do when it executes the program. Specification, one would like that to be the most abstract, describing only those parts of the behavior of the program that are of interest to its user and providing perhaps some means by which the user can predict and even control what that program is going to do. Designs are somewhere in between. They are more specific than the specification but perhaps less specific than the eventual program is going to be, the program that implements the design. Here are some examples of program specifications or designs. I formulated them all as statements about the execution of the program. So the concept of a postcondition is probably something you are fairly familiar with. A postcondition describes all programs with actually meet that postcondition, or should we say the execution of all programs that meet that postcondition. And so it is an assertion, a statement, a description of all executions that end with the given array sorted, for example. Quite often we reason with conditional correctness, and that can be a description which is conditional on the ending of the execution, if the execution ends it ends with A sorted. But it doesn't say that the execution will necessarily and. Perhaps the execution will be infinite. Precondition is very similar. It describes all executions which start with the precondition true. So, for example, execution starts with X even, and a program must become too something like X becomes X +1 describes all executions in which the final value of X is one greater than the initial value. Here are some examples which are slightly more wide ranging and they deal with aspects of correctness of a program which go beyond what can be expressed simply by assertions or assertional reasoning. The safety condition, which I know Microsoft has been very interested in, is the statement, description of all programs which have no buffer overflows. Termination for an algorithm, one wants the algorithm to terminate and therefore the specification would say the execution is finite; it always ends. On the other hand, for an operating system you want the opposite specification, that there is no infinite amount of internal activity in your program which could prevent it from giving you a response to an external stimulus, no livelock in other words. Fairness, I have tended to rather down play this issue of fairness in specifications, but, in general, there is no reason why we shouldn't regard fair executions as one of the things that we want and that we want to describe by means of a specification. A fairness criteria like no response, so any response is always given eventually to each request. And finally even probability, you can describe executions in which the ratio of a’s to b’s tends to 1 with time. Over a long period of time you would expect an equal number of a’s and b's. Those are just examples, but the idea that one should use the same conceptual framework for programs and specifications and assertions and designs is such, I have found such another one to, not so much to me, but to most audiences that I have spoken to, that I would like to justify it briefly. The point is really just to save effort and also to unify, in general, the concepts and reduce the number of concepts that we need to understand a particular branch of science. So as a result of this kind of unification, we can apply the same laws, same algebraic laws, same reasoning methods, the same theorems to programs, to designs and to specifications. We don't need three different branches of our subject to deal with those three important phenomena. Now the thing is that the same laws are going to be reusable for many kinds of correctness, associative correctness, fairness, probability have usually been dealt with by separate branches of our subject with their own axioms and their own reasoning methods. If we succeed in this unification, we will be able to apply the same laws to reasoning about every, well, many forms of correctness. And that is important too if we are building tools, because we would like to be able to use the same tools for many different purposes, not a special-purpose tool for dealing with fairness; well, that is the ideal. Clearly, when one comes to actually build these tools, you find that in order to make them reasonably efficient, you need to specialize them to particular kinds of problems, to particular kinds of applications and that is very fair. But the important thing is that whatever specialization you do, you do as part of a framework in which all of the tools can play together. So there is a common grounding of ideas, of concepts that can be built into the interfaces between the tools and make sure that there is no mismatch as a project moves from one phase to another, or as your programs or subprograms are used in a different contexts. It is understood how to link those together. It does not require a vast engineering enterprise to try to somehow adapt interfaces after they have been cast in concrete. I did not want to be--can somebody get me a bottle of water or something? I failed to provide myself with that. Thank you Russ. I don't want to be religious about this, but basically my strategy is to unify things first and then if necessary to make distinctions after I know enough about the subject to realize that the distinctions are going to be desirable or important or necessary. And so the distinctions are made within a common framework, within a common family framework. Thank you very much. I am always forgetting. Ah, great [laughter]. And when the need for them is apparent we will be able to motivate why the distinction is made, very often by showing what additional laws we can get by making the distinction. The basic laws which I am going to develop are based on the concept of refinement, refinement between our objects of discourse and I can explain refinement as more or less that everything, every aspect of the execution described by the left-hand side of this refinement symbol is also described by the right-hand side q, and it applies equally in all combinations of cases that I have described. If we prove that a specification implies a specification p--if p implies q as specifications, this certainly means that any implementation of p implies in the implementation, sorry, also satisfies the specification q. If the program p satisfies q that is a normal definition of correctness. If program p is more determinate then program q that also, the executions which it can evoke are a subset of those which are described by q and that means that the program is more deterministic. Now this refinement relation is used in an idealistic development process for programs which starts with a specification and gradually refines the specification to produce perhaps a series of designs, and eventually the process ends in a successfully delivered program, which because the whole design process has been supported by the mathematical basis of the algebra, it is known by construction to be correct at the time when it is first submitted to the computer. I have been an academic most of my life and as an academic I felt free to pursue ideals which I should have known were impossible although I am afraid I didn't. Coming to work for industry I now realize that they are impossible, but nonetheless very important because research science is driven by idealism. It is not driven by the profit motive, and therefore we must cultivate the ideals of scientists in the hopes that they produce lovely ideas which can then be exploited commercially or in other ways. Now since joining Microsoft I realized that program analysis which starts with a program and tries to work out aspects of its behavior is in practice going to be, at least in the short term, much more important than the idealism of correctness by construction. And that is just the reverse process using the same operator for refinement, same comparative operator, to start with the program and somehow postulate what design that program is conforming to and maybe even aspects of the specifications of that program. So that justifies why we use an ordering to, as the basic algebraic operator. Unfortunately again, the mathematicians always use a lot of different words. Almost any pair of words involving a comparative like bigger or better or greater or weaker or upper or lower or more or less or included, all of these words are used to mean, to note a relationship between what stands on the left-hand side of the refinement relation and on the right-hand side. I shall probably follow the same practice. Let's start with the, some of the basic algebraic laws that refinement is a partial order, which you probably know means that it is transitive, antisymmetric and reflexive. Why do we do this? How do we know that these laws are actually true? That is the wrong question. In algebra you don't know what you are talking about even. So the question about whether it might be true or not would be irrelevant. It is always true of something, well, yes, I think so. But we do know what you're talking about and therefore you can ask is it true, these algebraic properties of the ordering of the relation actually true; that's the wrong question too. Do we want them to be true? That is the right question, because algebra is about postulating laws; it is not about proving them, and therefore you need to be motivated to want the law to be true rather than actually believe it to be true. Yes? >>: [inaudible] definition of the [inaudible] since p and even prime and p equals two clearly imply each other. They are not the same statement in English or [inaudible]. >> Tony Hoare: Yes, but they are describing the same thing, and I am always going to concentrate on the thing that I am describing rather than just a description of it. That is being an applied mathematician, of course. Thank you. So we want them to be true. If the refined relation was not a partial order we couldn't use it for the stepwise development for analysis as I described in the last program. We've got to make sure of the link between the program and the specification at the two ends of the chain, and establish that link by just checking that each smaller link is actually valid. Antisymmetric means that two things which can be refined from each other actually describe the same thing. That's in order to bring in an element of abstraction into our reasoning, and reflexive I think is a matter of convenience, unless anybody can think of a good reason why it has to be reflexive, one could have worked with an irreflexive order; it doesn't matter much. I find the reflexive one more convenient. So now let's start talking about the programs, programming languages and descriptions and specifications. One of the fundamental operators of a programming language is sequential composition denoted by semicolon and that is what I intend to mean by semicolon when I write it between two program descriptions. Informally and when I construct a model of the algebra, I am going to ensure, state that each execution described by p;q consists of two parts, can be split into two parts. The first part of which consists of all events from x, all events from an execution of p and the second part consists of an execution of q. Those events are distinct from each other and subject to an ordering constraint that reflects the fact that p in some sense comes before q. But I am not going to tell you exactly what that ordering constraint is. I'm going to suggest some possible meanings for it. For example, the strong meaning could say all events x from p must precede all events from q. In other words p must finish before q starts and a lot of people think that is what semicolon means in a programming language. But people who actually write compilers for computers such as this know that isn't what it means. It actually means something a little weaker than that. It says no event from q, the second operand, can precede any event from p, but they could occur at the same time. The events at the beginning of q could occur at the same time as events from the end of p provided of course that they don't affect the same variables in the memory. There are, there is another distinction that you can draw whether the sequential composition is interoperable or not, whether it is possible for other threads to interfere between the execution of p and the execution of q or whether the interrupts are as it were inhibited during the transition between p and q. All I want to say is that our algebraic laws are going to apply equally to each of those four cases, so I don't have to tell you which because all I am interested in is the abstraction that the algebraic law makes from the details of the way in which sequential composition is implemented. Ah [inaudible] [laughter]. Come to something more familiar? I am actually going to define in 1969, I didn't know any better. And I postulated this as a primitive of the reasoning about programs and a lot of people have followed that example, but now I am going to define it algebraically as just a statement that p composed sequentially with q refines r. One could read that as saying that starting in the final state of the execution of p, q will end in the final state of some execution of r. You see, p and r will be mostly assertions, in fact post conditions, because we are talking about the end of execution, but there is no reason in the algebra why they shouldn't be post conditions. Any specification, any program will do. So we can describe the initial state of q by just writing a program p that will bring a machine into that initial state. There is complete flexibility; expressive power of the whole programming language can be used to actually specify preconditions, post-conditions and other aspects of specifications. Here is a little example. We have the usual example X becomes X +1 and in the brackets on the left we have an execution that ends with X +1 equal less than n and the r on the right says that X is equal less than n. Ah, some more laws. Semicolon is monotonic with respect to refinement. The definition of monotonicity is given in the next two lines, one saying that the semicolon is monotonic in its first argument and the other one in saying that it is monotonic in its second argument, except I should have scrubbed out these matches there. Yes, yes. Algebra is nice and simple and the only errors you have are the obvious ones. Well, this is a property that is shared with if p and q are numbers and semicolon was plus then monotonicity holds for normal arithmetic conditions. It is a familiar property. The rule of consequence was one of the very first rules that I put forward for the calculus of Hoare triples, and I have quoted that. It says if you strengthen the precondition or weaken the post condition, the triple is still true, and I thought that was very--that actually follows from the first law. Now would anybody like to count the number of symbols in that first law and the number of symbols here? The free variables, the number of free variables has gone up and the number of symbols has gone up. And if you look back at the definition of the Hoare triple, you will see that there are actually more symbols in the thing that was defined rather than the mathematical meaning that I am giving it here. It is very unusual in mathematics to see a, to define something which actually takes more symbols than the expression that you are defining it in terms of. We normally think of definitions as being abbreviations, don't we? But in this case I seem to have managed to not realize that, and I get my comeuppance with every theorem that I write is nearly twice as long as the algebraic law on which it is based. Now that seems to me to have been something of a mistake. Certainly a result of ignorance; it was not what I intended. So let's go on and postulate another law that the semicolon is associative. It doesn't matter in which order you take the operands. There is a similar law which expresses how you prove the correctness of a semicolon using Hoare triples. And this law follows from half of that law. If you replace that equality by a refinement, you find that the law will prove this theorem and vice versa. You can derive the theorem from the law. So the Hoare triple rule for sequential composition is not only nearly twice as long as the law from which it is derived, is only half as powerful. Yes? >>: [inaudible] previous slide, I did not understand the first question. >> Tony Hoare: Yes, it was a misprint. >>: Ah! >> Tony Hoare: I tried to rub it out. My finger wouldn't [laughter]. The program that does nothing, skip is what it is called, and the important algebraic property of it is that it is a unit of semicolon and from this law I can prove that the standard triple definition of the skip operation. It does nothing, so anything that was true before remains true afterwards. In this case the law is only one quarter as powerful as the theorem. You can prove one inequation in one direction only from the theorem. Well, that was easy. Can we do the same thing for concurrent composition, where we have two threads operating in simultaneously, perhaps even on the same computer, perhaps even sharing the same store, perhaps communicating with each other or whatever. And here the intended meaning is that all events of an execution of each of the threads is included in the execution when you run them concurrently. Everything that happens is either attributed to the execution of a command inside p or through an execution of a command inside q; there is nothing more, nothing less. But this time there is no constraint. They can occur, the events of p and the events of q can occur, they can occur one after the other, or they can occur simultaneously or they can occur concurrently so that they run during the same interval of time. Just as in the case of sequential composition, there is more than one possible meaning one could give to this operator. For example, does it mean concurrency on separate computers that don't share store or which do share store? Does it mean that the order implemented by interleaving so that the every event occurs either before or after an event of the other thread. I am not going to say which of those it is, because the laws will apply to both of them. Both of them are associative, commutative and monotonic. Now the way to, which has been suggested for reasoning about concurrency, is a widely known and new technique for reasoning about concurrencies given by separation logic. And the most important property of separation logic is one that I have written here, but if you have proved a given triple then you can run something else concurrently with the precondition and the postcondition. Remember these are precondition, postcondition are themselves descriptions of the program execution, so we can describe s running concurrently with r or with p and this implication is the basis for the simplicity of reasoning about correctness in separation logic. If you translate, you can actually translate this triple formulation back into the original algebra, you will get a statement which is I call left locality which is a sort of distribution law showing how concurrency distributes into a sequential composition. It relates the two operators. It's a property of the relationship between sequential and concurrent composition, which is very similar to the distribution laws which relate addition and multiplication in conventional numerical algebra. But you actually distribute this s to only one of the operands rather than the other. It is equally true, you could have distributed it to the second operand rather than the first, but that requires an additional axiom right locality. Now the second law which separation logic allows is sort of compositionality or modularity law which tells you that if you want to prove the correctness of a sequential composition, then you should prove the correctness of the two operands of the sequential composition and that enables you to conclude that the composition itself is correct. And in this case again, the law implies the theorem, but in this case the theorem also implies the law. If you want your semicolon to be modular, sorry, if you want your reasoning about concurrency to be modular, then you have to believe that law. It is not optional. And that is quite interesting, but is it true? Is that law true? Is that the right question? Well, we want it to be true, don't we, because we want to reason modularly? And if I were a pure algebraist, merely wanting the law to be true would be enough. But not for an applied scientist, we really do need to find at least something of which that law is true. Well this is an active topic of research of which I will shortly give you an example. Meanwhile, let me just write out the exchange law in a slightly different form, in a twodimensional form, in which the p and the p dashed are distributed in this way. If you read this matrix horizontally, it reads p concurrent with q all composed sequentially with p dashed concurrent with q dashed. And if we go to the next slide we are reading it by rows, rather than by columns, that p composed with p dashed is here parallel. This one with q composed with q dashed. So this law is really a sort of asserting the two dimensionality of what concurrency gives us. The, it is as though we are manipulating events, controlling events not just occurring in a single dimension of time as we do in sequential programming, but also in the dimension of space and so things that are separated by the parallel occur as it were in a different place from those which are separated by, from its two operands. And the exchange law says you can transpose that matrix, but the two axes are to a certain extent orthogonal to each other. This is a rather hand waving description, I'm afraid, but it is difficult to see, understand the real inwardness of that exchange law. So let me get on to the final question which is, is it true, or rather as we put it in the research, is there anything of which it is true? Well what is it true of? And I am going to and my talk with a claim that it is true of concurrency or rather of interleaving of regular languages. So my p, q and r are descriptions of the execution of a finite state machine that is limited machine for executing programs. p refines q means that the language, that the behavior of the machine is defined in the terms of strings, and the refinement means that every string which could possibly be an execution of p is also an execution of q or in other words their languages are included. The semicolon is the standard semicolon of regular expressions. It is a lifted concatenation of strings and parallel q is the interleaving of strings, perfectly good operator on regular languages because it preserves finaltude. The empty string is the unit of semicolon and the individual characters of the alphabet of the machine are of the generators of the algebra, but I won't be dealing with those. So now I have got to show that the left locality law is true, because I needed that to prove the framing law of separation logic. So look at the left-hand side. You can see that s interleaves just with p and all of q comes afterwards. I've drawn a picture here. Here is all of q coming afterwards and here is s interleaving with p. In this case p came first and then two possibly different symbols from s. On the right-hand side there has been a little bit more interleaving, because the s and the q have changed places. So there is more interleavings is on the right-hand side than there are on the left-hand side, and that is why it works. Another way of stating this, supposing we were told please find us an interleaving, this one here between s and p semicolon q. One of the ways of finding such an interleaving is to decide first of all to have all of q at the end, and then to interleave s with p. So refinement expresses the fact that one of the ways of implementing this specification is to take this as it is designed. And here is the exchange law. It is a little bit more complicated. And again I can give you the informal explanation that the, if you want to interleave two long strings, long sequential strings, then one of the things that you can do is you can split the first string and split the second string, and then interleave the first elements of the two operands and follow that by interleaving the second element. So it is an interleaving in which the two semicolons occurring on the right-hand side have been synchronized. And to synchronize those two semicolons, it follows that the left of that semicolon is an interleaving of the two left operands of the semicolon on the right-hand side and similarly on the right-hand side. Now it was quite a shock to me to discover that regular interleaving actually satisfies the same laws as separation logic, because the whole purpose of separation logic is to avoid interleaving. Interleavings are race conditions and those are the things that we want to avoid, and yet to reason about interleavings we use exactly the same reasoning principles, the same algebraic laws as we do for truly separate threads. So I haven't gone through all of the details, but the conclusion is that regular expressions satisfy all of our laws for refinement, sequential composition, skip and interleaving, and actually for many of the other operators that I won't have time to introduce later. Well, I hope if you don't believe any of the details of what I have been talking about, you will go away with the impression that I am extremely impressed by the power of algebra. The algebraic laws turned out to be much more simple than what I was originally familiar with, the Hoare triples. They are reusable. I can use the same laws and the same theorems based on them for many different operators and for many different languages, and many different operators within the same language. They are unifying in the sense that I've just described and indeed in another sense, because Hoare triples aren't the only way of describing the semantics of a programming language. There are operational semantics. There are two versions of Hoare triples. One is for total correctness and the other for partial correctness, and they are different, and they have different algebraic definitions, and there are at least two different kinds of operational semantics which are due to plot [inaudible] and used by Milner which actually describe how to execute a program. And those presentations of the semantics are of course more useful for actually implementing the language than the adaptive presentation which is given for logic and in order for practical programming language really, well, it must have an operational semantics. It must be operational. It must be able to execute the program or there isn't any point in it. And it is nice also to be able to prove that the programs are correct even if you never actually do it. So what we need is a combination of deductive proof methods for establishing the properties of programs, and inductive methods of actually executing the programs which we hope we now believe to be correct. All these forms of semantics can be derived from the algebra that I have shown you and the algebra of other operators which I haven't had time to show you, and vice versa. If you take the conjunction of all of the forms of semantics and prove the thing backwards, you can prove all of the laws of the algebra from four different versions of programming language semantics. But the algebra is much simpler and much shorter than four different complete semantic presentations of semantics of a language. So algebra is abstract; I think you have seen that. And I hope I have managed to convey some part of my admiration for the elegance of some of the algebraic formulations. Thank you very much. [applause]. 59: 56, one hour exactly. [laughter]. >>: [inaudible] preference on the [inaudible] another structure [inaudible] do you need some form of induction [inaudible]? >> Tony Hoare: Wonderful, isn't it [laughter]? I don't like induction very much [laughter]. Induction depends on--I think perhaps I can make two observations from what you said. The first one is that I am very glad that you raised this point because it shows that if you are interested in taking things further, Patrick will be able to enlighten you [laughter]. You have described the content of my second lecture [laughter]. The second thing is that one of the nice things about algebra is its incrementality. That I can tell you a great deal, but not everything, but a great deal about semicolon and interleaving and refinement and I don't have to mention whether it is a lattice ordering or not. And simply by adding a new axiom or a new operator to my algebra together with an associated axiom or definition, I can extend my language without changing anything that has gone before. And this is really, I think, an essential criteria for progress in science, that it builds on what has gone before rather than overthrowing it. Well, sometimes it needs overthrowing, but building is the normal thing to do for scientists and the ability to build on not just the foundations but the theorems, the first and second floors can be standard and then you can add new things without invalidating anything that has gone before. If you use too much induction, particularly induction on the syntax, you can't do this because an induction depends on limiting the range of operators or numbers or objects that you are dealing with so that you can deal with them by cases. So I think there is a very important point about algebra here, and I can say some very rude things about the other forms of semantics. I'll bet you've seen at least 4000 different languages defined using operational deductive semantics. Every one of them, as far as I know, I may be wrong, quotes every law that it uses, every rule that it proposes and re-proves every theorem that it needs, and that is why maybe our subject is not progressing as fast as it should. Algebra is marvelous. >>: I have a question. When you see the laws and how they simplify this, what lessons or conclusions to draw about [inaudible] programming languages to get the same [inaudible] for the same reason power? >> Tony Hoare: What I found in recent years--when I was an academic I used to say well you shouldn't be using programming languages that go beyond what I know how to prove. And since joining Microsoft I have realized that this is an untenable position [laughter]. But as a result I have learned an enormous amount, all of this stuff about concurrency rises out of the fact that it is needed, and so by studying what actually is and I mean what is in the languages that people actually use, I manage, I think, to extend the range of the research into the principles of programming. So I think there is a lot in current practice and current languages from which quite theoretical, interesting theoretical areas of research can be derived. If I believed that there would be a lot of new programming languages invented in this world, and then used by people other than their inventors, then I would suggest that one uses the algebra as a tool for discussing the programming language design. And since I don't believe that many new programming languages will be designed, I will apply the same principles to programs, to APIs, to protocols, to any other human interface which the programmer wishes to offer or sell to his colleagues. Try to formulate, try to discuss the way that you discuss your design of an API in terms of its algebraic properties. It just gives you a medium for considering alternatives, and when you have chosen the alternatives you might be very kind to explain to your potential users what they are. Certainly if you're going to build tools that are going to analyze the programs which used your constructions, then you are going to need some theory on which to base those tools. And the tools could be quite important at getting your designs accepted and used reliably by people who, if they don't understand what your interface does, at least could in principle understanding by reading the laws. >>: I have a question on the [inaudible] because I was thinking to [inaudible] mathematical moves or [inaudible] theory [inaudible] then you have a lot of chapters and if I assume that you are saying [inaudible] actual [inaudible] so these other, and another one, and another one and in the end you have a branching structure with no links between and I wondered if maybe you are afraid that that would happen to you also. >> Tony Hoare: No, I would welcome it. When you do have to make a distinction, you have to make a distinction, you say I'm afraid this doesn't mix; the details don't mix with some other branch of the subject. Unification is not cramming everything into the same basket; it is welcoming the branching structure of the subject and basing the structure on, as it were, the inner logic of the mathematics involved and explaining it and making it completely clear what the implications of making a decision to go down one branch or the other are going to be. So the pattern of a mathematical textbook that you have very eloquently described and very faithfully described is one that I would love to see reproduced when talking about the principles of programming. >>: Can you model procedure calls in your algebra or is that [inaudible]? >> Tony Hoare: Ideally it is sort of all of mathematics involves procedure calls. You just define something and then you use it. So one would prefer to avoid having to model the implementations of parameter passing mechanisms, if that is what you want. >>: I wondered if you could somehow model abstractly as an operator, you know a calls b, can semicolon do that? >> Tony Hoare: No. There is clearly a declaration not only of procedures but of variables that need to be included in the language. And I think specifications, interfaces too. One of the nice things that I discovered recently was a way of implementing the requires and ensures of boogie as an operator of the language; it delivers an explicit error message as it were if the program doesn't meet its specification, but which enables the person who calls the procedure to assume that it satisfies the specification and allows the implementer to use the body of the procedure to actually implement it. So just a little operator with algebraic properties based on [inaudible] greatest level bands, in this case. >>: The operator that you show us do you have negation and [laughter] and discussion, we discussed the fundamental distinction perhaps between programming specifications and logical specifications. You have negation and logic in your programs. >> Tony Hoare: Yes. That is a very good point. Specification is really essential to have very simple concepts like and, or and not. But in programs there is a very good reason for not allowing not; it is incomputable. There is a very good reason for not having nondeterminism, because it makes testing impossible. So we get sequential languages which are deterministic and certainly we don't have not. And in fact there are other, so it turns out that the programs are really a subset of specifications and it is very interesting to determine the algebraic properties of that subset, because as a subset it has more interesting algebraic properties than general specifications. So in some ways it is a good thing that programs are a special case. But it certainly means that, well, it actually means that the process of program design from specification actually has some significance. I mean you've got a specification that is as clear as you can make it using concepts like and, or and not. And then you've got to somehow massage that specification into form that does not use and, or or not. But only operators like semicolon and concurrency and so on, and that's what programming is all about in principle. Thank you. >>: What do you make of programming languages based on constructive logic [inaudible] type theories in which the language specifications and programs are indeed conflicted and things like not exist at both of the levels of specifications and the level of programming? >> Tony Hoare: I wasn't aware that not existed at level of programs but… >>: Not being just a function that takes a proof of the proposition that you want to prove and [inaudible] false. >> Tony Hoare: Yes. I mean it essentially collapses the program into false. >>: That's right. >> Tony Hoare: Yes. Well, I have a great admiration for them, clearly. They tend to restrict the programming language in ways that at least for Microsoft is unrealistic because it is a pure functional programming language and nearly every program written by Microsoft is nondeterministic. It is not even a function. Quite apart from the fact that the very essence of what Microsoft deals with, and indeed a lot of other software, involves time and space, trading off between time and space is what programmers these days have to do, and function programs are marvelous because you don't have to do it. As a result, we can't use functional programs for everything. >>: [inaudible] pure and functional [inaudible] to accommodate [inaudible]? >> Tony Hoare: I think that is another--it is a very funny thing about functional programming. People get quite enthusiastic about it, but when you come down to it they all put procedural features into their implementations, just the way that Fortran did. I mean Fortran loves functions; it included functions way back in 1956, thank you [laughter]. You remember that long time [laughter]. It was before my time [laughter]. It is just that they describe these things in different ways. An enthusiastic Fortran programmer can say yes, you got functions, and you should use them whenever you can. And the functional programmer puts the procedural facilities into his language and says, yes, it's got procedural facilities, but you should avoid them whenever you can [laughter]. And I agree with both of those [laughter]. >> Rustan Leino: All right. Thank you. >> Tony Hoare: Thank you very much. [applause].