2.4 Representation of Refal Expressions

When we enter refgo or reftr command, we start a program which is an efficient interpreter of Refal. The fact that it is an interpreter means that the computer will basically imitate the steps of the Refal machine. It will maintain two storages: the program field and the view field; these will be representations of the program field and the view field of the abstract Refal machine.

At each step the computer will find the primary active sub-expression in the view field and apply one of the sentences in the program field to it. This will result in the replacement of the active sub-expression by another sub-expression. By calling the interpeter efficient we mean that it will use certain addresses in memory to jump directly to the needed points in memory without passing through intervening expressions, as the definition of the abstract Refal machine suggests. It must also avoid unnecessary copying of expressions. More specifically, the following requirements must be met:


  1. When a symbol has been located in the view field, it must be possible to immediately locate the preceding and the following symbols or brackets.
  2. When a structure or activation bracket has been located in the view field it must be possible to locate its pair in one jump, without scanning the enclosed expression.
  3. If the number of the entries of a variable in the right side is no more than the number of its entries in the left side, then the replacement of the variable entries in the right side by their values must be done without actually copying or scanning the values. In other words, it must be possible to transpose sub-expressions in the view field without examining or rewriting them.
  4. In the beginning of each step the primary active sub-expression in the view field (i.e., the next function call to evaluate) must be accessed in one jump, without scanning the view field, as is implied by the definition of the abstract Refal machine.
  5. The group of sentences defining a given function must be located in one jump, without looking through all contents of the program field.

The user of Refal need not know anything about the actual representation of expressions, aside from the fact that these five requirements are satisfied. The obvious way to satisfy them is to use doubly linked lists, with brackets keeping the reference to the pair bracket, in addition to forward and backward references. This is what we actually do in the Refal system. In order to jump to the next active sub-expression, we keep a stack of the addresses of active sub-expressions (stack of function calls). The Refal compiler, called as refc , translates the Refal program into an intermediate language RASL and creates a file which consists of subfields, each of which keeps one function definition. These subfields are accessed at run time through a hash table.

List elements representing Refal symbols include codes of the symbol's type. In this way the system distinguishes between characters, identifiers, macrodigits and real numbers. To convert one type into another (e.g., the digit string '321' into the macrodigit 321 or the identifier Sum into the string 'SUM' etc.) use the corresponding built-in functions described in Reference Section C.

If this brief description of the inside of the Refal system does not tell you much, do not worry: once again, you do not really need to know it if you only want to use the language.

Exercise 2.4 Define a function <Merge s.1 s.2> which creates a new identifier by concatenating the "bodies" (string representations) of the identifiers s.1 and s.2 .