Heading:qjk40(635)Cedar 7T10 Changesy756qjk40\b18BPage Numbers: Yes  X: 527  Y: 10.5"qjk40Inter-Office Memorandumz18592l4445y762\f5bTo	Cedar Users	Date	December 18, 1981z18592l4445d2998e21(0,65535)(1,4445)(5,11684)(6,14146)\f7 2f0t2 1t0 11t6 1f7t0 4f0t7 1t0From	Ed Satterthwaite	Location	Palo Altoz18592l4445d2998y716e25\f7 4f0t2 1t0 16t6 1f7t0 8f0t7 1t0Subject	Cedar 7T10 Language and Compiler Changes	Organization	CSLz18592l4445d2998e25\f7 7f0t2 1t0 40t6 1f7t0 12f0t7 1t0XEROX       z18592l508y644e14(2116)\f2 5f0Filed on: [Indigo]<CedarDocs>Lang>Cedar7T10.Bravo	DRAFTe30(0,16264)(1,65535)(5,65535)(6,65535)\f7 49f1 1f9b5f1Bx2e12(2116)The document [Indigo]<CedarDocs>Lang>Cedar6T5.press describes the Cedar language.  This memo summarizes the significant changes to the language and compiler since that document was prepared.x2e6jk40(1799)Types in Cedarx2e18k80\b14BThis section sketches some current thinking about the Cedar type system and might help you to understand the motivation for some of the changes described below.  (See also Lampson, Cedar abstract machine [CedarAM.memo, February 1980].)x2e12jk40\181i22ITypes as Predicatesx2e24k80\iEvery type is characterized by some predicate; a value x has type T iff x satisfies the predicate for T.  In general, such predicates are defined in terms of a set of marks (tags, etc.) carried by each value; however, the Mesa type system is designed so that most mark manipulation can be done statically (by the compiler), and the usual representations of most values do not include explicit marks.x2e12jk40\55i1I10i1I5i1I29i1IA given expression has some fixed syntactic type that depends upon the form of the expression and the declared types of constituent identifiers.  The value denoted by an expression always satisfies the predicate characterizing its syntactic type, but such a value will often satisfy predicates characterizing other types as well.  In this sense, a Cedar value may have an arbitrary number of types. For example:x2e12jk40\34i14IIf Thing is a variant record type with a variant red, a reference to a Thing might simultaneously satisfy the predicates for REF ANY, REF Thing, and REF Thing[red] (formerly REF red Thing, see below).l3564x2e6jk40\3i5I41i3I19i5I49f7 7f0 2f7 3f0 1i5I6f7 3f0 1i5I1i3I12f7 3f0 1i3I1i5IAn opaque type and the corresponding concrete type are distinct, even within an exporter of the concrete type, but the predicates for the two types are identical.l3564x2e6jk40Roughly speaking, the primary job of the predicates associated with types is to provide correct answers to questions about low-level representational conventions so that, e.g., the Cedar garbage collector can operate correctly.x2e12jk40The form ISTYPE[x, T] returns the result of applying the predicate characterizing T to the value x.  In Cedar 7T10, ISTYPE has been redefined to work in a somewhat more general and uniform way, and the operations of NARROWing and (type-based) SELECTion have been defined in terms of ISTYPE.x2e12jk40\9f7 6f0 1i1I2i1I62i1I14i1I18f7 6f0 94f7 6f0 21f7 6f0 34f7 6f0Types as Clusters of Operationsx2e24k80\iIn addition to its predicate, a cluster of operations (sometimes called a group) can be associated with a type.  The main purposes of this grouping are to provide a number of packaging conveniences and to support so-called "object oriented" notation.  If x has (syntactic) type T, x.Op[args] means Op[x, args] where Op is found by looking in the cluster associated with T.  Two types may be characterized by the same predicate but have different associated clusters; in current Cedar, this is true of, e.g., an opaque type and the corresponding concrete type.x2e12jk40\32i7I35i5I176i1I22i1I2i1I1i2I1i4I8i2I1i1I2i4I8i2I52i1IEach of the type constructors in Cedar supplies a standard and implicitly defined cluster for each type that it constructs.  The only mechanism currently available for the explicit construction of such a cluster is the interface module, and previous versions of Cedar have limited support of this mechanism to opaque types.  If T is an opaque type declared by, e.g.,    T: TYPE;in some interface Defs, operations (procedures) declared in Defs become components of the cluster associated with T and may be invoked using object notation.  Cedar 7T10 extends this support to allow construction of similar clusters for record types.  If T is declared in Defs by    T: TYPE = RECORD [ ... ];the operations declared in Defs become part of the cluster associated with T.  In this case, however, they augment the operations already supplied for T by the RECORD type constructor.x2e12jk40\328i1I42i2I1f7 4f0 20i4I38i4I50i1I140i1I16i4I8i2I1f7 4f0 3f7 6f0 37i4I44i1I75i1I8f7 6f0Defining clusters in this way has some drawbacks.  The use of interfaces as the units of grouping somewhat overloads the existing notion of an interface; note that all operations declared in an interface become parts of the clusters of all types declared in that interface.  Also, requiring a type and the operations in its cluster to be defined in the same interface occasionally conflicts with other criterea for partitioning interfaces.  On the other hand, this method of defining clusters seems to cover the important cases well enough to be acceptable in practice.  In addition, there is a fairly well worked-out plan for supporting clusters in a comprehensive, uniform way and for using them to explain parts of the Cedar abstract machine.  We therefore recommend the following style guidelines for your Cedar programming:x2e12jk40Partition interfaces so that a single interface defines both a main type T (record or opaque) and all the operations to be provided in the cluster of T (or REF T).  Define multiple main types within an interface only if the sets of meaningful operation names for those types are disjoint.l3564x2e6jk40\73i1I76i1I5f7 3f0 1i1IUse object notation in clients of interfaces designed to support it; i.e., use x.Op[args] in preference to Defs.Op[x, args].l3564x2e6jk40\79i1I1i2I1i4I19i4I1i2I1i1I2i4I(For Humus veterans) Avoid interface designs that require clients to write x.Op[x, args], x.ops.Op[x, args] or the like.  Use an inline definition of Op within Defs to achieve such an effect.  l3564x2e6jk40\75i1I1i2I1i1I2i4I3i1I1i3I1i2I1i1I2i4I44i2I8i4ILANGUAGE CHANGESx2e24k80\bSyntax for Discriminated Typesx2e18k80\b30BIf V is a type expression designating some variant record type with variant a, V[a] is a type expression designating the discriminated type. Thus forms such asx2e12jk40\3i1I72i1I2i1I1i1IObject[red]      Object[red][short]      Object[red][long][80]l3564x2k40\i6I1i3I4i9I1i3I2i5I4i9I1i3I2i4I2i2I1iare equivalent to the old formsx2jk40red Object      short red Object      long red Object[80].l3564x2k40\i3I1i6I3i8I1i3I1i6I3i7I1i3I1i6I1i2IIn Cedar 7T10, both forms are acceptable, but you will eventually have to convert to the former as Cedar moves toward a unified syntax for expressions and type expressions.x2e6jk40Type Discriminationx2e18k80\b19BCedar 7T10 unifies the mechanisms for discriminating variant records with those for discriminating values with type REF ANY.  This unification affects the operators ISTYPE and NARROW as well as discriminating selection.x2e12jk40\116f7 7f0 42f7 6f0 5f7 6f0Type Testingx2e24k80\iThe primitive function ISTYPE tests whether a given value satisfies the predicate characterizing a specified type.  You will probably have little direct use for ISTYPE; its importance lies in its use to define other, more common operations as described below.  Let x be an expression with syntactic type S.  In Cedar 7T10, the value of ISTYPE[x, T] is determined as follows, where V is any variant record type:x2e12jk40\23f7 6f0 132f7 6f0 98i1I38i1I31f7 6f0 1i1I2i1I34i1I(1) It is TRUE (at compile time) ifl3564x2e12k40\10f7 4f0S and T are equivalent types; orl3917x2e6k40\i1I5i1IS is an opaque type and T is the corresponding concrete type; orl3917x2k40\i1I23i1IS is a concrete type exported as the opaque type T.l3917x2k40\i1I48i1IThe last two cases are recognized only within program modules that export the concrete type.l3917x2e6k40\f1(2) It is determined dynamically by a test of the value x, yielding TRUE or FALSE, ifl3564x2e12k40\56i1I11f7 4f0 4f7 5f0S is REF ANY and T is REF U for any U except ANY; orl3917x2e6k40\i1I4f7 7f0 5i1I4f7 3f0 1i1I9i1I8f7 3f0S is equivalent to V and T is equivalent to V[a]; orl3917x2k40\i1I18i1I5i1I18i1I1i1IS is equivalent to REF V and T is equivalent to REF V[a]; orl3917x2k40\i1I18f7 3f0 1i1I5i1I18f7 3f0 1i1I1i1IS is equivalent to (LONG) POINTER TO V and T is equivalent to (LONG) POINTER TO V[a];l3917x2k40\i1I18f7 17f0 1i1I5i1I19f7 16f0 1i1I1i1Iwhere V[a] is a particular variant of V, perhaps discriminated to several levels.  Note that the result is TRUE if the value of x is NIL.l3564x2e6k40\6i1I1i1I29i1I68f7 4f0 17i1I4f7 3f0(3) In all other cases, ISTYPE is unimplemented and is treated as a compile-time error.l3564x2e12k40\24f7 6f0Subsequent versions of Cedar will provide a more general definition and implementation of ISTYPE.  Note in particular that ISTYPE cannot currently be used to test a value for membership in a subrange.x2e12jk40\90f7 6f0 27f7 6f0Narrowingx2e24k80\iNARROW[x, T] allows a value x to be viewed as a value of type T and succeeds iff ISTYPE[x, T] is TRUE.  More precisely, NARROW[x, T] has (syntactic) type T, and its value is given byx2e12jk40\f7 6f0 1i1I2i1I17i1I33i1I18f7 6f0 1i1I2i1I5f7 4f0 19f7 6f0 1i1I2i1I23i1IIF ISTYPE[x, T] THEN x ELSE ERROR <Error>l3564x2e6k40\f7 9f0 1i1I2i1I2f7 4f0 1i1I1f7 10f0where <Error> isx2e6k40RTTypesBasic.NarrowRefFault[x, CODE[T]]	if ISTYPE[x, REF ANY]RTTypesBasic.NarrowFault[]		otherwise.l3564x2e6k40\i12I1i14I1i1I2f7 4f0 1i1I6f7 6f0 1i1I2f7 7f0 2i12I1i11IThe following situations correspond to the three cases enumerated in the definition of ISTYPE above:x2e12jk792\87f7 6f0(1) NARROW[x, T] is guaranteed (at compile time) to succeed.(2) NARROW[x, T] may succeed or fail at run time.(3) NARROW[x, T] is unimplemented.l3564x2e6k40\4f7 6f0 1i1I2i1I50f7 6f0 1i1I2i1I39f7 6f0 1i1I2i1ICase (2) arises only when the syntactic type of x is related to T in one of the ways described above for ISTYPE.  In Cedar 7T10, case (3) is treated as a compile-time type error.  Fine point: NARROW[x, T] is also considered a compile-time error if the only possible value of x yielding TRUE is NIL.  Use x = NIL instead.x2e6jk40\48i1I15i1I40f7 6f0 69f1 12f7 6f1 1i1I2i1I72i1I10f7 4f1 4f7 3f1 7i1I3f7 3f1In case (1), NARROW is an identity operation but can be useful to change the (syntactic) type of x without using a LOOPHOLE or requiring any code to be executed.  Example:x2e12jk40\13f7 6f0 78i1I17f7 8f0Defs: DEFINITIONS = {   T: TYPE;   R: TYPE = RECORD [g: REF T, ... ];   Pn: PROC [r: REF R];   ... }.l3564x2e6k40\i5I1f7 11f0 8i2I1f7 4f0 5i2I1f7 4f0 3f7 6f0 2i2I1f7 3f0 1i1I12i3I1f7 4f0 2i2I1f7 3f0 1i1IImpl: PROGRAM EXPORTS Defs = {   T: PUBLIC TYPE = RECORD [n: NAT, ...];   Pn: PUBLIC PROC [r: REF Defs.R] = {      r.g.n _ 0; 		-- invalid; r.g^ is opaque, with no field selection operations      NARROW[r.g, REF T].n _ 0;	-- valid (because Impl exports Defs)      ...};   }.l3564x2e6k40\i5I1f7 15f0 1i4I8i2I1f7 11f0 3f7 6f0 2i2I1f7 3f0 11i3I1f7 11f0 2i2I1f7 3f0 1i6I12i1I1i1I1i1I20i1I1i1I54f7 6f0 1i1I1i1I2f7 3f0 1i1I2i1I24i4I9i4IAs before, NARROW[x, T] may be written as NARROW[x] when the target type T is implied by context.x2e12jk40\11f7 6f0 1i1I2i1I20f7 6f0 1i1I23i1IDiscriminating Selectionx2e24k80\iThe syntactic form of WITH ... SELECT that is currently used for REF ANY discrimination has been extended to discriminate any value for which ISTYPE performs a dynamic test of that value (see case (2) in the discussion of ISTYPE).  The formx2e12jk40\22f7 15f0 28f7 7f0 70f7 6f0 74f7 6f0WITH v SELECT FROM   v1: T1 => s1;   v2: T2 => s2;   ...   vn: Tn => sn;   ENDCASE => se;l3564e6(635)\f7 4f0 1i1I1f7 11f0 4i3I1i2I4i2I5i3I1i2I4i2I5f7 4f0 3i3I1i2I4i2I5f7 7f0 4i2Iis, by definition, equivalent tox2e12jk40(1799)u: T = v;IF u # NIL AND ISTYPE[u, T1] THEN {v1: T1 _ NARROW[u]; s1}ELSE IF u # NIL AND ISTYPE[u, T2] THEN {v2: T2 _ NARROW[u]; s2}  ...ELSE IF u # NIL AND ISTYPE[u, Tn] THEN {vn: Tn _ NARROW[u]; sn}ELSE se;l3564e6(635)\i2I1i1I3i1I2f7 3f0i1I3f7 15f0i1I2i2I2f7 4f0 2i3I1i2I3f7 6f0 1i1I3i2I2f7 8f0i1I3f7 15f0i1I2i2I2f7 4f0 2i3I1i2I3f7 6f0 1i1I3i2I4f7 12f0i1I3f7 15f0i1I2i2I2f7 4f0 2i3I1i2I3f7 6f0 1i1I3i2I2f7 5f0i2Iwhere T is the (syntactic) type of v.  The tests against NIL are omitted if T does not have a NIL value.x2e6jk40(1799)\6i1I28i1I21f7 3f0 16i1I17f7 3f0Note that this form always copies the discriminated value.  Thusx2e12jk792r: REF V;l3564e6(635)\i2I1f7 3f0 1i1I. . .l3564e6\f7WITH r SELECT FROM   x: REF V[a] => { ... x ...};	-- x is a copy of r with type REF V[a]   ...   ENDCASE;l3564e6\f7 4f0 1i1I1f7 11f0 4i2I1f7 3f0 1i1I1i1I11i1I10i1I14i1I11f7 3f0 1i1I1i1I5f7 4f0 3f7 7f0WITH r^ SELECT FROM   x: V[a] => { ... x ...};	-- x is a copy of r^ with type V[a]   ...   ENDCASE;l3564e6\f7 4f0 1i1I2f7 11f0 4i1I2i1I1i1I11i1I10i1I14i1I14i1I5f7 4f0 3f7 7f0Contrast these with the old form of variant record discrimination, which does not copy the discriminated value and reevaluates the discriminating expression each time that it is used:x2e12jk40(1799)WITH x: r SELECT FROM   a => { ... x ... };	-- x is a synonym for r^ (but with syntactic type V[a])   ...   ENDCASE;l3564x2e6k40\f7 4f0 1i4I1f7 6f0 1f7 4f0 4i1I10i1I11i1I18i1I27i1I1i1I6f7 6f0 1f7 7f0The new forms are easier to make type-safe, and you should use them whenever possible.  Unfortunately, the old form is still required, at least outside the checked language, for dealing with computed variants and with pointers having non-standard dereferencing operations, such as the current relative pointers).x2e6jk40\88f1Interaction with Opaque Typesx2e24k80\iIf T is any exported type, REF T must have the "standard" implementation of type discrimination.  We impose this requirement in anticipation of making REF ANY discrimination work correctly with opaque types (it still doesn't in 7T10).  As a consequence, discriminated variant record types cannot be exported as the concrete values of opaque types.x2e12jk40\3i1I23f7 3f0 1i1I119f7 7f0Object Notationx2e18k80\b15BThe form  x.Op[args]  is interpreted as  Defs.Op[x, args]  if the type of x is (REF | POINTER TO)* T for some opaque type T declared in an interface, the principal instance of which is Defs.  In other words, all the operations defined in Defs become part of the cluster of the type T.x2e12jk40\10i1I1i2I1i4I22i4I1i2I1i1I2i4I18i1I5f7 3f0 3f7 10f0 3i1I22i1I62i4I49i4I40i2IThis convention applies within the corresponding DEFINITIONS module (for writing inlines, etc.) as well as within importers of such modules.  This is only a notational extension; the bindings of implicitly imported values are determined as before.x2e12jk40\49f7 11f0The clustering mechanism has also been extended in Cedar so that all operations declared in an interface become components of the clusters of any record types defined in that interface.  With this extension, Op can be inline in more interesting ways.  In addition, you may now be able to use object notation more extensively to invoke operations in existing interfaces, many of which are written in terms of (concrete) record types.x2e12jk40\208i2INote that every operation declared in an interface module becomes part of the cluster of every (record or opaque) type declared in that interface.  Although the type of a particular operation normally will make it a useful component of only one cluster, its name appears in every other cluster and potentially hides or precludes a more appropriate definition of that name for that cluster.  You therefore should define more than one main type per interface only if the sets of meaningful operation names for those types are disjoint.x2e12jk40Other points to note when using this convention with record types include the following:e12j(635)In determining the binding of Op, the field identifiers declared in T take precedence over the identifiers declared in the interface Defs.l3564e12j\30i2I36i1I64i4IA value x with a record type T having a single component can be coerced to a value with the type of that component.  In the form x.id, the lookup of id considers first the field identifier of the single component, then identifiers declared in the interface defining T, and finally any interpretation given to id by applying the coercion.  You abuse this feature at your own risk (but see the discussion of clusters above).  Example:l3564e12j\8i1I20i1I99i1I1i2I16i2I115i1I42i2IDefs1: DEFINITIONS = {    ...   T1: TYPE = RECORD [f1: REF Defs2.T2];   ...   OpN: PROC [self: T1, ...];   ...}.Defs2: DEFINITIONS = {   ...   T2: TYPE = RECORD [ ... ];   ...   OpM: PROC [self: REF T2, ...];   OpN: PROC [self: REF T2, ...];   ...} r1: Defs1.T1; r2: REF Defs2.T2; ... r1.OpN[...]  means Defs1.OpN[r1, ...]		-- from the cluster defined by Defs1 ... r1.OpM[...]  means Defs2.OpM[r1.f1, ...]		-- from the cluster defined by Defs2 (after coercion) ... r2.OpN[...]  means Defs2.OpN[r2, ...] ... r1.f1.OpN[...] means Defs2.OpN[r1.f1, ...]	-- dubious stylel3564e12\i6I1f7 11f0 16i3I1f7 4f0 3f7 6f0 2i3I1f7 3f0 1i5I1i2I13i3I2f7 4f0 2i5I1i2I18i6I1f7 11f0 15i3I1f7 4f0 3f7 6f0 20i4I1f7 4f0 2i5I1f7 3f0 1i2I11i4I1f7 4f0 2i5I1f7 3f0 1i2I18i3I1i5I1i2I3i3I1f7 3f0 1i5I1i2I8i2I1i3I13i5I1i3I1i2I39i5I6i2I1i3I13i5I1i3I1i2I1i2I39i5I23i2I1i3I13i5I1i3I1i2I12i2I1i2I1i3I12i5I1i3I1i2I1i2IPredeclared Typesx2e18k80(1799)\b17BTo support the currently recommended Cedar standards, the types BOOL, INT and CHAR are predeclared, with the following definitions:e12j(635)\64i4I2i3I5i4I BOOL: TYPE = BOOLEAN; CHAR: TYPE = CHARACTER; INT: TYPE = LONG INTEGER;l3564e12\1i5I1f7 4f0 3i7I3i5I1f7 4f0 3i9I3i4I1f7 4f0 3f7 4f0 1i7IAlso, the definition of the predeclared type CONDITION has been changed.  The default value for the timeout interval now is effectively infinite; i.e., a WAIT on a condition variable with default initialization will never time out.  (The previous default provided a timeout after 100 ticks.)  Use a runtime procedure such as Process.SetTimeout to change the default setting.e12j\45i9I100f7 4f0 167i7I1i10IRope Literalsx2e18k80(1799)\b13BThe Cedar language now provides rope literals.  Such a literal is denoted by a quoted string, e.g., "This is a rope literal".  Its value is a reference to a rope object in the standard (counted) zone provided by the Cedar system.x2e12jk40The target type established by the context in which a quoted string literal appears determines the interpretation of that literal.  There are three cases:x2e12jk40If the target type is Rope.ROPE, Rope.Ref or Rope.Text, the quoted string denotes a rope literal and has type Rope.Ref.l3564x2e6jk40\22i4I1i4I2i4I1i3I4i4I1i4I56i4I1i3IIf the target type is any other REF type, the literal has type REF TEXT.l3564x2e6k40\32f7 3f0 28f7 8f0Otherwise, the literal has type STRING.l3564x2e6k40\32f7 6f0In the first case, the test is actually for equivalence between the target type and either REF Rope.RopeRep or REF Rope.TextRep.  The matching is performed on the names of the interface (Rope) and referent type (RopeRep or TextRep), not on the structure of the referent type.  Since this is a loophole in the type checking, use nonstandard versions of the Rope interface very cautiously.x2e12jk40\f1 91f7 3f1 1i4I1i7I4f7 3f1 1i4I1i7I60i4I21i7I4i7I126i4IEscape Convention for Literalsx2e18k80\b30BCedar provides an escape convention to allow denotations of nonprinting characters in character and string literals (cf. the escape convention for the language C).  The escape character is \, and the following codes are recognized:e12j(635)  Code		                  Interpretationl3564x2e6k40(1799)\2u4U20u14U\n, \N, \r, \R		Ascii.CR\t, \T			Ascii.TAB\b, \B			Ascii.BS\f,  \F			Ascii.FF\l, \L			Ascii.LF		-- note that \n = LF in C\ddd			dddC		-- where d is an octal digit, ddd < 377B\\			\\'			'\"			"l3564x2e6k40\15i6I1i2I9i6I1i3I9i6I1i2I10i6I1i2I9i6I1i2I29i3I2i4I12i1I20i3I1f3 1f0 10i1I6i1I6i1IAnything else following a \ is an error.e6(635)You can use the escape convention in character literals (e.g., '\n or '\032) or string literals (e.g., "abc\ndef").e12jAPPLY and RETURNx2e18k80(1799)\f7b5f0 5f7 6f0BCedar is based upon a model of interprocedural control transfer in which the construction of an argument record is clearly separated from the actual transfer of control.  In the usual forms for specifying call or return, however, these operations are syntactically indivisible.  There are now alternative syntactic forms that allow you to invoke transfer operations using already constructed argument records.e12j(635)This extension is not fully general.  The existing record must have a type compatible with the type required by the transfer operation, and the only types compatible with argument record types are other argument record types.  Such types are defined implicitly by the definitions of transfer types, and they are always anonymous.  Thus you cannot declare variables having such types, nor can you construct values with such types unless the target type is established by a transfer operation of some sort. e12j\f1The operator APPLY is used to apply a value with some transfer type to an argument record.  The syntactic form ise12j\13f7 5f0Call 		::=	...		|	APPLY [ Expression , Expression ] 		|	APPLY [ Expression , Expression ! CatchSeries ]l3564x2e6k40(1799)\f6b4f0B15f7 5f0 3f6b10f0B3f6b10f0B8f7 5f0 3f6b10f0B3f6b10f0B3f6b11f0BThe type of the first Expression must be some transfer type (i.e., a type built using PROC, SIGNAL, ERROR, PROCESS, PORT or PROGRAM), and the second Expression must have a record type as good as the argument type required for the transfer (see below).  The effect is to invoke the transfer operation appropriate to the type of the first Expression, i.e., to call a procedure, raise a signal, join a process, etc.  The scope of the optional catch phrase is just the transfer itself.e12j(635)\22f6b10f0B54f7 4f0 2f7 6f0 2f7 5f0 2f7 7f0 2f7 4f0 4f7 7f0 18f6b10f0B178f6b10f0BNote that the first Expression implies a target type for the second, which can be (but normally would not be) a constructor.  For example,e12j\20f6b10f0Bp[x, y]	can be written as	APPLY[p, [x, y]]q[x]	can be written as	APPLY[q, [x]]      	-- not APPLY[q, x]l3564x2e6k40(1799)\i1I1i1I2i1I20f7 5f0 1i1I3i1I2i1I3i1I1i1I20f7 5f0 1i1I3i1I16f7 5f0 1i1I2i1IThe corresponding forms for returning an existing record aree12j(635)ReturnStmt 	::=	...		|	RETURN Call 		|	RETURN ( Expression )l3564x2e6k40(1799)\f6b10f0B14f7 6f0 1f6b4f0B6f7 6f0 3f6b10f0BResumeStmt 	::=	...		|	RESUME Call 		|	RESUME ( Expression )l3564x2e6k40\f6b10f0B14f7 6f0 1f6b4f0B6f7 6f0 3f6b10f0BIn these forms, the required type is established by the context in which the statement appears.  The type of the Call or Expression must be a record type as good as the result type of the procedure body in which the ReturnStmt appears (or of the catch phrase in which the ResumeStmt appears).e12j(635)\113f6b4f0B4f6b10f0B85f6b10f0B46f6b10f0BAn argument record type T1 is as good as an argument record type T2 if both of the following conditions are satisfied:e12j\24i1f1o252I1f0o0 39i1f1o252I1f0o0T1 and T2 have the same number of fields, say n.l3564x2e6k40(1799)\i1f1o252I1f0o0 5i1f1o252I1f0o0 37i1IFor each i, 1 < i < n, the type of the i-th component of T1 is as good as the type of the i-th component of T2; in addition, if both these components are named, the names are identical (i.e., names of field selectors must match, but an anonymous component matches any named component). l3564x2e6jk40\9i1I4f3 1f0 1i1I1f3 1f0 1i1I18i1I17i1f1o252I1f0o0 31i1I17i1f1o252I1f0o0Note that this rule is more liberal than the rule for explicitly declared record types.e6j(635)In the terminology of the Mesa 5 manual, T1 is as good as T2 iff T1 conforms freely to T2; e.g., [0..10) is as good as [0..100).  In the new view of types, we would say that T1 is as good as T2 iff the predicate for T1 implies the predicate for T2.e6j\f1 41i1o252I1o0 15i1o252I1o0 5i1o252I1o0 20i1o252I1o0 85i1o252I1o0 15i1o252I1o0 23i1o252I1o0 27i1o252I1o0In Cedar 7T10, the constructs described above do not work for empty argument records; i.e., you cannot nest applications of procedures taking/returning nothing.e6j\f1Examples:e12\i9IP1: PROC [x, y: INT] RETURNS [m, n: INT] = {...};l3564x2e6k40(1799)\i3I1f7 4f0 2i1I2i2I1i3I2f7 7f0 2i1I2i2I1i3IP2: PROC [m, n: INT] RETURNS [u, v: INT] = {...};l3564x2e6k40\i3I1f7 4f0 2i1I2i2I1i3I2f7 7f0 2i1I2i2I1i3IP3: PROC [a, b: INT] RETURNS [u, v: INT] = {  RETURN APPLY[P2, P1[a, b]]};l3564x2e6k40\i3I1f7 4f0 2i1I2i2I1i3I2f7 7f0 2i1I2i2I1i3I8f7 6f0 1f7 5f0 1i2I2i2I1i1I2i1Ii, j: INT;. . .[i, j] _ APPLY[P2, IF i < j THEN P1[i, j] ELSE [j, i]];[i, j] _ APPLY[P3, [0, 0] ! s => {GOTO L}];    	-- [i, j] _ P3[0, 0 ! s => {GOTO L}]l3564x2e6k40\i1I2i2I1f7 3f0 9i1I2i1I4f7 5f0 5f7 2f0 1i1I3i1I1f7 4f0 1i2I1i1I2i1I2f7 4f0 2i1I2i1I5i1I2i1I4f7 5f0 1i2I11i1I5f7 4f0 1i1I12i1I2i1I4i2I8i1I5f7 4f0 1i1ICOMPILER CHANGESx2e30k80\bVersion Stampsx2e18k80\b14BIn its intermodule type checking, Cedar uses so-called version stamps to identify independently compiled modules.  The version stamps computed by the Cedar 7T10 compiler are functions of the identity of that compiler and of its inputs.  You can now recompile the same source file, with the same included modules, the same compiler and the same switch settings to get an object file with the same version stamp.x2e12jk40This stamp, which is essentially a 48 bit hash, is computed recursively as follows.  Assume that any existing derived object (including the compiler itself) has a version stamp.  The stamp for a new derived object is a hash ofx2e12jk40the creation time of the source filethe version stamp of each bcd mentioned in the DIRECTORY clausethe version stamp of the compilerthe compiler switches (with those controlling only compile-time feedback masked off)l3564e12(635)\84f7 9f0There is also a 7T10 binder that computes version stamps for its output in the same way.e12Notee12\i4IIn the past, the version stamp has been a concatenation of a machine identifier and the creation time of the derived object.  Many existing utility programs therefore print the version stamp formatted as a machine and network number, a date and a time.  These programs give strange-looking output but, in all cases known to us, perform correctly.x2e6jk40(1799)Tioga Source Filesx2e18k80\b18BThe compiler and binder ignore text in Tioga trailers.  Any occurrence of a pair of NUL characters (characters with value 0C) in a source file marks the logical end of that source file.e12j(635)File Lockingx2e18k80(1799)\b12BThe Cedar 7T10 compiler is designed to be run under control of the system modeller.  It also exports an interface allowing it to be run from Tajo or from the temporary Cedar executive.  When it is run in this mode, the (rather minimal) facilities in PreCascade for obtaining exclusive access to a file are bypassed.  Use caution.e12j(635)Compiler Switchesx2e18k80(1799)\b17BThe Cedar compiler is no longer able to generate object code for an Alto (or D-machine emulating an Alto).  The switches /a and /l are ignored.x2e12jk40\121f8 2f0 5f8 2f0There is a Cedar switch /c; if it is set (the default), the code for FORK assumes the availability of the Cedar runtime.  If you plan to run your program directly under Pilot, compile with /-c.  If you are in doubt about how your processes will interact with the Cedar runtime, consult a wizard.x2e12jk40\24f8 2f0 43f7 4f0 116f8 3f0