Global References

## 10.8 Global References

Terms stored in non-logical variables and arrays are copies of the setval/2 arguments, and the terms obtained by getval/2 are thus not identical to the original terms, in particular, their variables are different. Sometimes it is necessary to be able to access the original term with its variables, i.e., to have global variables in the meaning of conventional programming languages. A typical example is global state that a set of predicates wants to share without having to pass an argument pair through all the predicate invocations.

ECLiPSe offers the possibility to store references to general terms and to access them even inside predicates that have no common variables with the predicate that has stored them. They are stored in so-called references. For example,

>     :- local reference(p).

or

>     :- local reference(p, 0).

creates a named reference p (with an initial value of 0) which can be used to store references to terms. The reference is accessed and modified via setref/2 and getref/23.

The following points are different for references:

- the accessed term is identical to the stored term (with its current substitutions):

  >     [eclipse 1]: local reference(r).
  >     yes.
  >     [eclipse 2]: Term = p(X), setref(r, Term), getref(r, Y), Y == Term.
  >     X = X
  >     Y = p(X)
  >     Term = p(X)
  >     yes.

  >     [eclipse 3]: local variable(v).
  >     yes.
  >     [eclipse 4]: Term = p(X), setval(v, Term), getval(v, Y), Y == Term.
  >     no (more) solution.

- the modifications are backtrackable, when the execution fails over the setref/2 call, the previous value of the global reference is restored

  >     [eclipse 5]: setref(r, 1), (setref(r, 2), getref(r, X) ; getref(r, Y)).
  >     X = 2
  >     Y = Y     More? (;)

  >     X = X
  >     Y = 1

- references (and the associated terms) are private to each engine. This implies that the referenced terms are not shared between engines, and each engine may have a different term associated to a particular reference name.
- there are no arrays of references, but the same effect can be achieved by storing a structure in a reference and using the structure’s arguments. The arguments can then be accessed and modified using arg/3 and setarg/3 respectively.

The use of references should be considered carefully. Their overuse can lead to programs which are difficult to understand and difficult to optimize. Typical applications use at most a single reference per module, for example to hold state that would otherwise have to be passed via additional arguments through many predicate invocations.

3
  For backward compatibility, setval/2 and getval/2 also work on references, but this use is deprecated: use setref/2 and getref/2 instead.