NOTE: This transcription was contributed by Martin P.M. van der Burgt, who has devised a process for producing transcripts automatically. Although its markup is incomplete, we believe it serves a useful purpose by virtue of its searchability and its accessibility to text-reading software. It will be replaced by a fully marked-up version when time permits. —HR
Sequencing and the discriminated union.
The purpose of this note is to record an observation on a connection between the availability of sequencing primitives on the one hand and the need for the discriminated union on the other.
Our starting point is a rather abstract inner block that captures a structure of which I have encountered several examples. The variable z represents the global environment symbolically, the variable x is a local variable, and the predicates H(x) and K(x) , used in the annotations, are complementary, i.e. H(x) = non K(x) . The BHH , BHK , etc. represent boolean expressions such that (BHH(x,z) or BHK(x,z)) ⇒ H(x) , etc.
begin var x: Xtype; x:= some function(z); | ||
do BHH(x,z) → {H(x)} z:= ZHH(x,z); x:= XHH(x,z) {H(x)} | ||
▯ BHK(x,z) → {H(x)} z:= ZHK(x,z); x:= XHK(x,z) {K(x)} | ||
▯ BKH(x,z) → {K(x)} z:= ZKH(x,z); x:= XKH(x,z) {H(x)} | ||
▯ BKK(x,z) → {K(x)} z:= ZKK(x,z); x:= XKK(x,z) {K(x)} | ||
od | ||
end |
Suppose now that we have to code this inner block in the absence of the required Xtype , but in the presence of two types, Htype and Ktype , such that there is a natural one-to-one correspondence between the values in Htype and those x of Xtype satisfying H(x) , and, similarly, there is a natural one-to-one correspondence between the values in Ktype and those x of Xtype satisfying K(x) . The classical solution consists of replacing the above variable X by a triple, i.e. one boolean, one variable of Htype and one variable of Ktype . Reusing the same identifiers in analogous functions, we get:
begin var Hholds: boolean; var h: Htype; var k: Ktype; Hholds:= Q(z); | |||
if Hholds → h:= some function(z) ▯ non Hholds → k:= other function(z) fi; | |||
do Hholds cand BHH(h,z) → z:= ZHH(h,z); h:= XHH(h,z) | |||
▯ Hholds cand BHK(h,z) → z:= ZHK(h,z); k:= XHK(h,z); Hholds:= false | |||
▯ non Hholds cand BKH(k,z) → z:= ZKH(k,z); h:= XKH(k,z); Hholds:= true | |||
▯ non Hholds cand BKK(k,z) → z:= ZKK(k,z); k:= XKK(k,z) | |||
od | |||
end |
do Hholds → if BHH(h,z) → ... | ||||||
▯ BHK(h,z) → ... | ||||||
fi | ||||||
▯ non Hholds → if BKH(k,z) → ... | ||||||
▯ BKK(k,z) → ... | ||||||
fi | ||||||
od |
These complaints are largely overcome when we use —very much in the style suggested by Eric C.Hehner of the University of Toronto— what we might call “semi-recursion”. The main text for our program part then becomes
if Q(z) → processHtype(some function(z)) | ||
▯ non Q(z) - processKtype(other function(z)) | ||
fi |
processHtype(value h: Htype): | |||
begin do BHH(h,z) → z:= ZHH(h,z); h:= XHH(h,z) od; | |||
if BHK(h,z) → z:= ZHK(h,z); processKtype(XHK(h,z)) | |||
▯ non BHK(h,z) → skip | |||
fi | |||
end |
processHtype(value h: Htype): | |||
begin if BHH(h,z) → z:= ZHH(h,z); processHtype(XHH(h,z)) | |||
▯ BHK(h,z) → z:= ZHK(h,z); processKtype(XHK(h,z)) | |||
▯ non (BHH(h,z) or BHK(h,z)) → skip | |||
fi | |||
end | |||
This form of recursive refinement is at most “semi-recursion”, for what an ALGOL programmer would intuitively interpret as calls on recursive procedures are here all so-called “last calls”: for their implementation no stack is required and —because the term “continuation” has already a technical meaning in denotational semantics— we could call them “completions”. If the “completion” is a recognized syntactic concept, none of the four complaints against our second program applies to our semi-recursive programs!
* *
*
The above can be read as a plea for semi-recursion as a sequencing device. Its strength, however, remains to be ascertained. Semi-recursion provided a nice alternative for our second program, i.e. a second way of avoiding a discriminated union —a way of type formation about which I have mixed feelings— , but we should not forget that in this example we replaced only one variable ot such a type. The complete moral of this observation —if there is one— has still to be written; for the time being I must be content with having discovered a connection —between sequencing and types— of which I had been unaware before.
Plataanstraat 5 | prof.dr.Edsger W.Dijkstra |
5671 AL NUENEN | BURROUGHS Research Fellow |
The Netherlands |
Transcribed by Martin P.M. van der Burgt
Last revision 2015-02-02
.