Reference Commentary

General:. Note: When experimenting with references, use the $V ... $v facility to display rather than %**. This is because Glee will automatically dereference references before operating on them. %** is an operator whereas the $V ... $v  is just a signal to the scanner and not an operator.
Glee
references are a powerful programming tool. They allow access to objects from more than one place in a program simultaneously. They also allow access to the same object by different names (but I think that is poor programming style.)
     Example: An object could be a string naming a company. Every place that company name is needed, the programmer could use a reference to this string object. One reason for doing this is maintainablilty. If the company changes its name, you just change the base string object. All references are immediately affected. Further, if you change the name through a reference, the base object and all other references are affected.
     Because references are so powerful, you must exercise a certain degree of caution in using them. Know what you are doing. Always consider whether it is best to use a copy of an object or a reference to it.
     To best understand references, you should know how they are implemented. In Glee, when you name an object by assigning a value to a name (e.g. 10=>i), you create what is called an association. An association is a pair of objects. The first element of the pair is a string object. This string names the other element. The other element is the data object. Namespaces are formed by collecting in a sequence, pointers to associations. This all happens implicitly with the assignment operator (=>).
     References are pointers to associations. They are formed by the (@) operator (e.g. 10=>i; i@ =>ri). In the example, "i" is an association in the local namespace sequence. "ri" is also an association, but it associates the symbol "ri" with a pointer to the association named "i".
     Glee can distinguish reference objects from other associations. In so doing, it can automatically dereference them. This allows programs to deal with references in exactly the same fashion as their base association referents. Glee always dereferences objects before using them in operations. References are also always singletons, not vectors. If you want a vector of references you need to contain them in a sequence.
     Glee allows the creation of anonymous references. These are references to unnamed objects (e.g. 10@). They have meaning only in the context in which they are used. The best example is the result of the niladic referencing operator (@). Just as (i@ =>ri) creates a reference to the object "i" named "ri"; (@ =>rns) creates a reference to the local namespace and stores it as "rns". Through this reference, objects in the namespace can be addressed by fields (e.g "@.i" or "rns.i" yields the same result as just plain "i").





A simple example: This is the simplest of examples. An object "i" containing the number 10 is created. Next, a reference to that object, "ri" is created. A new value, 30 is assigned to "ri". And as we expect, the value of "i" is changed as well. What has really happened is the following: An association is created in the local namespace. Its name is "i" and its data object is a pointer to a number object containing 10. Then a reference "ri" is created using the reference operator (@) in the expression (i@ =>ri). This creates an association in the local namespace named "ri". Its data object is a reference. A reference is a pointer-to a pointer-to an association. When Glee assigns to a reference, it dereferences the pointers and makes the assignment to the untimate target object.




Simple reference usage: I assign numbers to "i" and "j". At the same time I create references to them as "ri" and "rj" respectively. I then use "ri" and "rj" in an expression (ri*rj) just as I would use "i" and "j". Looking at "ri" I see it is a reference to "i" (i.e. i@). To see "i", I reveal "ri" (i.e. ri ^@ $;) and see its contents (10).
     Next, I assign the string 'abc' to "ri". Glee recognizes "ri" as a reference to "i" and changes the data object in that association. Now I see "ri" still references "i" but now contains 'abc' as does "i".
     Remember, you can use references just as if they were their referants. However, to display them, you need to disclose them explicitly.





References to References: Glee does not allow you to assign a reference into a reference. Rather, it replaces the reference with the new reference. This example illustrates Glee's behavior when you try to assign a reference into an existing reference.
     "i" is created and a reference to it is assigned to "r". "j" is then created and a reference to it is assigned to "r". But at this point "r" already exists as a reference. Glee sees the reference being assigned into a reference and does a replacement rather than the assignement into the object referenced.




Anonymous References and Indirect Assignment: I illustrate here how references can be made to objects without names. In this example I create two references ("name" and "desc") to unnamed string objects. I then form a sequence containing these references with (name desc => rec;). Next, I assign values to "name" and "desc" and show how those assignments are reflected in "rec". Next, I make a new assignment to "desc" and show "rec" again reflecting the assignment to the reference. Finally I illustrate assignment into an element of the "rec" variable with ('WithGLEE' => (rec[1]<); rec$;) and show its effect on "desc". Note: Once an item of a sequence takes on a reference object, it forever remains a reference object. This is the nature of reference objects. They don't become values ... they refer to them. If you assign a reference to a reference object, it replaces it. If you assign a non-reference object to a reference object, it assigns into the referant. In both cases, the object is a reference.




Dereferencing references: As noted earlier, references are implicitly dereferenced when used in an operation. However, if you just display them, the display shows them to be a reference. It does not reveal their contents. The monadic dereference operator (^@) returns a copy of the referent. If the argument is not a reference, the argument is just passed through. In this example I create a number object "i" and reference to it, (i@ => ri). I then illustrate the various displays in turn.

Note: I currently have no way of determining if an object is a reference. My normal .field style of returning object information can't be used. This is because, with references, fields are indexes into the referants. I expect this will soon become an issue. If it does, I will likely use a double reference (@@) to return the type of any object or (*@) for "exists as a reference". Doing this raises new issues I'd rather not address until I have an obvious need.




Is Reference ( ?@ ): Queries for object being a reference.




:




: