XEROX
BUSINESS SYSTEMS
System Development Department
August 7, 1978
To:Mesa Language Working Group

From:Dick Sweet

Subject:
Mesa Language Working Group minutes

File:
[iris]<sweet>lwg>lwg7aug78.bravo
The Language Working Group met on 4 August 1978.
Discussion was begun on three memos by Ed on Inline Procedures, Default Field Initialization, and Allocation, Variants & Sequences.
Default fields were postponed to a later meeting, but it was discussed that a reasonable fall-back position would be to allow constants plus whatever came for free with Inlines.
The major topic of discussion was storage allocation [1].
It was observed that the MAKE statement buys nothing more than a simple assignment (of possibly an empty constructor) except in the case of immutable variant records (since their tag supposedly can’t be set in an assignment). It was felt that perhaps a different assignment syntax should be used as a temporary measure (←← and := were suggested, no final decision was made).
It was noted that the proposals in [1] were primarily suited for use of absolute pointers, i.e., not for relative pointers or fingers. The compiler has few absolute pointers, having primarily relative ones. Juniper has mainly fingers. If Star is going to be written with some sort of fancy pointers, it is important to at least plan for some means of dealing with them. The examples below are for relative pointers, a finger example is similar. Consider the following declarations:
SEIndex: TYPE = Base RELATIVE POINTER [...] TO SERecord;
sei: SEIndex;
seb: Base;
AllocSE: PROCEDURE RETURNS [SEIndex];
The statement
seiALLOCATE USING AllocSE: SERecord ← [...];
doesn’t work, since the compiler has no way of getting to the actual address of the SERecord in order to do the initialization. There is a related problem with discriminating relative pointers.
ISEIndex: TYPE = Base RELATIVE POINTER [...] TO id SERecord;
proc: PROCEDURE [ISEIndex];
WITH rec: seb[sei] SELECT FROM
id => proc[ LOOPHOLE[sei, ISEIndex]];
. . .
ENDCASE;
If proc required an absolute pointer, the LOOPHOLE would be unnecessary, since @rec would be known to be of the correct type.
The following design seems to address both problems, and also have other nice properties. For each pointer type, allow the programmer to specify the dereferencing mechanism. For example,
SEIndex: TYPE = POINTER [...] TO SERecord DEREF seb[SELF];
would be the declaraion of SEIndex in a particular module. All references, explicit or implicit, to sei↑ would imply relocation by the base seb. The "@" operator could be extended so that @(sei↑) would be sei, no matter what the interpretation of ↑. Some care needs to be taken in the DEREF clause about the meaning of ↑, perhaps using some other character for the old sense of the symbol.
This proposal requires a redeclaration of the type in each module (to bind in the global variable seb). How does this interact with definitions modules, etc.? Allow the declaration of dummy variables within definitions modules, e.g.
In the definitions module:
base: DUMMY Base;
GenSEIndex: TYPE = POINTER [0..37777B] TO SERecord;
DSEIndex: TYPE = GenSEIndex DEREF base[SELF];
In the program module:
seb: Base;
SEIndex: TYPE = GenSEIndex DEREF seb[SELF];
The procedures in the interface would have parameters declared to be of type DSEIndex. There is some problem with pointers imbeded within records. The type matching algorithm for pointers would be extended to match the DEREF expressions, considering free variables of equivalent types to be equivalent.
In this new scheme of things, the statement
seiALLOCATE USING AllocSE: SERecord ← [...];
now works, meaning
t: SEIndexAllocSE[];
t↑ ← SERecord[...];-- in the new sense of ↑
seit;
There is some problem here, in that AllocSE presumably returns a DSEIndex, which must be somehow mapped into a SEIndex, presumably by some target type mechanism from the left hand side of the assignment.
One might want to allow allocation procedures that take parameters in addition to the implicitly supplied size. For example, the compiler might (does) have a single allocator that is passed an enumerated type saying which zone to allocate from. The compiler could accept a parameter list and tack on the size at the end (if desired). Thus the statement might be written:
seiALLOCATE USING Alloc[SEBlock]: SERecord ← [...];
The problem of the type of the return record of Alloc is even more difficult in this case.
There is an alternative syntax for the above design that has the advantage/disadvantage of looking more like parameterized types:
GenSEIndex: TYPE [base: Base] =
POINTER
[0..37777B] TO SERecord DEREF base[SELF];
. . .
SEIndex: TYPE = GenSEIndex[seb];
On the surface, it looks like the former syntax is easier to implement in the current compiler.
One nice side effect of this proposal is that it allows the programmer to change from absolute pointers to based pointers to fingers, etc. (and back) while changing only the declarations at the top of the program.
The next meeting was scheduled for Wed, 9 August, at 9:30 AM.
Bibliography
[1]Satterthwaite, Allocation, Variants, and Sequences. August 1978.