AB39.3.1 Specification of partial parametrization proposal. C.H.Lindsey (University of Manchester) The following specification has been released by the IFIP Working Group 2.1 Standing subcommittee on ALGOL 68 Support, with the authorization of the Working Group. This proposal has been scrutinized to ensure that a) it is strictly upwards-compatible with ALGOL 68, b) it is consistent with the philosophy and orthogonal framework of that language, and c) it fills a clearly discernible gap in the expressive power of that language. In releasing this extension, the intention is to encourage implementers experimenting with features similar to those described below to use the formulation here given, so as to avoid proliferation of dialects. {{Although routines are values in ALGOL 68, and can therefore be yielded by other routines, the practical usefulness of this facility is limited by scope restrictions. Consider: PROC f = (REAL x) PROC (REAL) REAL: (REAL y) REAL: x + y; PROC (REAL) REAL g := f (3); x := g (4) This attempts to assign to g the routine "add 3". It does not work because the body of the routine is still fundamentally the routine-text (REAL y) REAL : x + y which expects to find the value x (i.e. 3) on the stack in the form of an actual-parameter of f, and by this time f is finished with and its stack level has disappeared. The problem arises whenever a routine-text uses identifiers declared globally to itself and the limitation is expressed in the Report by making the scope of a routine dependent on its necessary environ (7.2.2.c). Here is an attempt at functional composition which fails to work for the same reason: PROC compose = (PROC (REAL) REAL f, g) PROC (REAL) REAL: (REAL x) REAL: f (g (x)); PROC (REAL) REAL sex = compose (sqrt, exp) Clearly, if the restriction is to be lifted, a routine value has to have associated with it copies of these global values. Unfortunately, their number is in general indeterminable at compile time, and so the implementation of such values must be similar to that of multiple values referred to by flexible names (2.1.3.4.f) requiring, in most implementations, the use of the heap. In this variant, all the intended global values appear to the routine-text as its own formal-parameters. At each call, some or all of these parameters are provided with actual values, resulting in a routine with that number of parameters fewer. Ultimately (possibly after several calls) a routine without parameters is obtained and, if the context so demands, deproceduring can now take place. Thus, all calls in the original language turn out to be parametrizations followed by immediate deproceduring, but their effect is the same. Here are some examples: 1) PROC f = (REAL x, y) x + y; PROC (REAL) REAL g := f (3, ); x := g (4) # or x := f (3, ) (4) # 2) PROC compose = (PROC (REAL) REAL f, g, REAL x) REAL; f (g (x)); PROC (REAL) REAL sex = compose (sqrt, exp, ) 3) OP ^ = (PROC (REAL) REAL a, INT b) PROC (REAL) REAL: ((PROC (REAL) REAL a, INT b, REAL p) REAL: ( REAL x := 1; TO b DO x *:= a(p) OD; x )) (a, b, ); REAL theta; print ((cos^2)(theta) + (sin^2)(theta)) }} {{A routine now includes an extra locale.}} 2.1.3.5. Routines a) A "routine" is a value composed of a routine-text {5.4.1.1.a,b}, an environ {2.1.1.1.c} and a locale {2.1.1.1.b}. {The locale corresponds to a 'DECSETY' reflecting the formal-parameters, if any, of the routine-text.} b) The mode of a routine is some 'PROCEDURE'. c) The scope of a routine is the newest of the scopes of its environ and of the values, if any, accessed {2.1.2.c} inside its locale. {{A routine-text yields the new style of routine.}} 5.4.1.2. Semantics The yield of a routine-text T, in an environ E, is the routine composed of (i) T, (ii) the environ necessary for {7.2.2.c} T in E, and (iii) a locale corresponding to 'DECS2' if T has a declarative-defining-new-DECS2-brief-pack, and to 'EMPTY' otherwise. {{Most of the remaining changes to the Report needed to incorporate this facility are in section 5.4.3 (calls).}} 5.4.3. Calls (with partial parametrization) {A call is used to provide actual-parameters to match some or all of the formal-parameters of a routine. It yields a routine with correspondingly fewer formal-parameters or with none at all, in which case the yield is usually subject to deproceduring (6.3). Examples: y := sin (x) ° PROC REAL ncossini = (p | ncos | nsin) (i) ° print ((set char number ( , 5), x)) .} 5.4.3.1 Syntax A) PARAMSETY :: PARAMETERS ; EMPTY. a) procedure yielding MOID NEST call{5D} : meek procedure with PARAMETERS1 yielding MOID NEST PRIMARY{5D}, actual NEST PARAMETERS1 leaving EMPTY{c,d,e} brief pack. b) procedure with PARAMETERS2 yielding MOID NEST call{5D} : meek procedure with PARAMETERS1 yielding MOID NEST PRIMARY{5D}, actual NEST PARAMETERS1 leaving PARAMETERS2{c,d,e,f} brief pack. c) actual NEST PARAMETER PARAMETERS leaving PARAMSETY1 PARAMSETY2{a,b,c} : actual NEST PARAMETER leaving PARAMSETY1{d,e}, and also{94f} token, actual NEST PARAMETERS leaving PARAMSETY2{c,d,e}. d) actual NEST MODE parameter leaving EMPTY{a,b,c} : strong MODE NEST unit{32d}. e) actual NEST PARAMETER leaving PARAMETER{a,b,c} : EMPTY. f)* actual MODE parameter : actual NEST MODE parameter leaving EMPTY{d}. g)* dummy parameter : actual NEST PARAMETER leaving PARAMETER{e}. {Examples: a) set char number (stand out, 5) b) set char number ( , 5) c) , 5 d) 5 } 5.4.3.2. Semantics a1) The yield W of a call C, in an environ E, is determined as follows: ° let R {a routine} and V1, ... , Vn be the {collateral} yields of the PRIMARY of C, in E, and of the constituent actual- and dummy-parameters of C, in an environ E1 established {locally, see 3.2.2.b} around E, where the yield of a dummy-parameter is "absent"; ° W is {the routine which is} the yield of the "parametrization" {a2} of R with V1, ... , Vn; ° except where C is the constituent call of a deprocedured-to-MOID-call {6.3.1.a}, it is required that W be not newer in scope than E {thus, PROC (CHAR, STRING) BOOL cs = char in string ( , LOC INT, ) is undefined but q := char in string ("A", LOC INT, s) is not}. a2) The yield W of the "parametrization" of a routine R0 with values V1, ... , Vn is determined as follows: ° let T0, E0 and L0 be, respectively, the routine-text, the environ and the locale of R0, and let L0 correspond {2.1.1.1.b} to some 'DECS0'; ° let L1 be a new locale corresponding to 'DECS0', and let the value, if any, accessed by any 'DEC0' inside L0 be accessed also by that 'DEC0' inside L1; ° let 'DECS1' be a sequence composed of all those 'DEC0's enveloped by 'DECS0' which have not {yet} been made to access values inside L1, taken in their order within 'DECS0'; For i = 1, ... , n, If Vi is not absent,{see a1}, then the i-th 'DEC1' enveloped by 'DECS1' is made to access Vi inside L1; {otherwise, the i-th 'DEC1' still does not access anything;} ° W is the routine composed of T0, E0 and L1. {A routine may be parametrized in several stages. Upon each occasion the yields of the new actual-parameters are made to be accessed inside its locale and the scope of the routine becomes the newest of its original scope and the scopes of those yields.} b) The yield W of the "calling" of a routine R0 in an environ E1 {see 5.4.2.2 and 6.3.2} is determined as follows: ° let T0, E0 and L0 be, respectively, the routine-text, the environ and the locale of R0; ° let E2 be a {newly established} environ, newer in scope than E1, composed of E0 and L0 {E2 is local}; ° W is the yield, in E2, of the unit of T0. {Consider the following serial-clause: PROC samelson = (INT n, PROC (INT) REAL f) REAL : BEGIN LONG REAL s := LONG 0; FOR i TO n DO s +:= LENG f(i) ^ 2 OD; SHORTEN long sqrt (s) END; y := samelson (m, (INT j) REAL: x1[j]). In that context, the last deprocedured-to-real-call has the same effect as the deprocedured-to-real-routine-text in: y := REAL : ( INT n = m, PROC (INT) REAL f = (INT j) REAL : x1[j]; BEGIN LONG REAL s := LONG 0; FOR i TO n DO s +:= LENG f(i) ^ 2 OD; SHORTEN long sqrt (s) END ). The transmission of the actual-parameters is thus similar to the elaboration of identity-declarations {4.4.2.a}; see also establishment {3.2.2.b} and ascription {4.8.2.a}.} {{Minor changes are required at other places in the Report.}} {{The third bullet of 5.4.2.2 (semantics of formulas) is replaced by}} ° let R1 be {the routine which is} the yield of the parametrization {5.4.3.2.a2} of R with V1, ... , Vn; ° W is the yield of the calling {5.4.3.2.b} of R1 in E1; {{5.4.4.2.Case B, 10.3.4.1.2.c and 10.3.4.9.2 must be modified to show that the routines there created are composed, additionally, from a vacant locale {2.1.1.1.b}.}}