Chapter 12. Locatives

There is in MDL a facility for obtaining and working directly with objects which roughly correspond to "pointers" in assembly language or "lvals" in BCPL or PAL. In MDL, these are generically known as locatives (from "location") and are of several TYPEs, as mentioned below. Locatives exist to provide efficient means for altering structures: direct replacement as opposed to re-copying.

Locatives always refer to elements in structures. It is not possible to obtain a locative to something (for example, an ATOM) which is not part of any structured. It is possible to obtain a locative to any element in any structured object in MDL -- even to associations (chapter 13) and to the values of ATOMs, structurings which are normally "hidden".

In the following, the object occupying the structured position to which you have obtained a locative will be referred to as the object pointed to by the locative.

12.1. Obtaining Locatives

12.1.1. LLOC

<LLOC atom env>

returns a locative (TYPE LOCD, "locative to iDentifier") to the LVAL of atom in env. If atom is not bound in env, an error occurs. env is optional, with the current ENVIRONMENT used by default. The locative returned by LLOC is independent of future re-bindings of atom. That is, IN (see below) of that locative will return the same thing even if atom is re-bound to something else; SETLOC (see below) will affect only that particular binding of atom.

Since bindings are kept on a stack (tra la), any attempt to use a locative to an LVAL which has become unbound will fetch up an error. (It breaks just like a TUPLE....) LEGAL? can, once again, be used to see if a LOCD is valid. Caution: <SET A <LLOC A>> creates a self-reference and can make PRINT very unhappy.

12.1.2. GLOC

<GLOC atom pred>

returns a locative (TYPE LOCD) to the GVAL of atom. If atom has no GVAL slot, an error occurs, unless pred (optional) is given and not FALSE, in which case a slot is created (chapter 22). Caution: <SETG A <GLOC A>> creates a self-reference and can make PRINT very unhappy.

12.1.3. AT

<AT structured N:fix-or-offset>

returns a locative to the Nth element in structured. N is optional, 1 by default. The exact TYPE of the locative returned depends on the PRIMTYPE of structured: LOCL for LIST, LOCV for VECTOR, LOCU for UVECTOR, LOCS for STRING, LOCB for BYTES, LOCT for TEMPLATE, and LOCA for TUPLE. If N is greater than <LENGTH structured> or less than 1, or an OFFSET with a Pattern that doesn't match structured, an error occurs. The locative is unaffected by applications of REST, BACK, TOP, GROW, etc. to structured.

12.1.4. GETPL and GETL

<GETPL item:any indicator:any default:any>

returns a locative (TYPE LOCAS) to the association of item under indicator. (See chapter 13 for information about associations.) If no such association exists, GETPL returns EVAL of default. default is optional, #FALSE () by default.

GETPL corresponds to GETPROP amongst the association machinery. There also exists GETL, which corresponds to GET, returning either a LOCAS or a locative to the indicatorth element of a structured item. GETL is like AT if item is a structure and indicator is a FIX or OFFSET, and like GETPL if not.

12.2. LOCATIVE?

This SUBR is a predicate that tells whether or not is argument is a locative. It is cheaper than <MEMQ <PRIMTYPE arg> '![LOCD LOCL ...]>.

12.3. Using Locatives

The following two SUBRs provide the means for working with locatives. They are independent of the specific TYPE of the locative. The notation locative indicates anything which could be returned by LLOC, GLOC, AT, GETPL or GETL.

12.3.1. IN

<IN locative>

returns the object to which locative points. The only way you can get an error using IN is when locative points to an LVAL which has become unbound from an ATOM. This is the same as the problem in referencing TUPLEs as mentioned in section 9.2, and it can be avoided by first testing <LEGAL? locd>.

Example:

<SET A 1>$
1
<IN <LLOC A>>$
1

12.3.2. SETLOC

<SETLOC locative any>

returns any, after having made any the contents of that position in a structure pointed to by locative. The structure itself is not otherwise disturbed. An error occurs if locative is to a non-LEGAL? LVAL or if you try to put an object of the wrong TYPE into a PRIMTYPE UVECTOR, STRING, BYTES, or TEMPLATE.

Example:

<SET A (1 2 3)>$
(1 2 3)
<SETLOC <AT .A 2> HI>$
HI
.A$
(1 HI 3)

12.4. Note on Locatives

You may have noticed that locatives are, strictly speaking, unnecessary; you can do everything locatives allow by appropriate use of, for example, SET, LVAL, PUT, NTH, etc. What locatives provide is generality.

Basically, how you obtained a locative is irrelevant to SETLOC and IN; thus the same program can play with GVALs, LVALs, object in explicit structures, etc., without being bothered by what function it should use to do so. This is particularly true with respect to locatives to LVALs; the fact that they are independent of changes in binding can save a lot of fooling around with EVAL and ENVIRONMENTs.