>> Rustan Leino: It is my great pleasure today... know Tony from his work, but let me just mention...

advertisement
>> 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].
Download