Original JavaScript A symbol might be represented as a typed pointer that designates a sequence of the characters that form the symbol's printed representation. This sequence is constructed by the Lisp reader when the character string is initially encountered in input. Since we want two instances of a symbol to be recognized as the same symbol by eq? and we want eq? to be a simple test for equality of pointers, we must ensure that if the reader sees the same character string twice, it will use the same pointer (to the same sequence of characters) to represent both occurrences. To accomplish this, the reader maintains a table, traditionally called the obarray, of all the symbols it has ever encountered. When the reader encounters a character string and is about to construct a symbol, it checks the obarray to see if it has ever before seen the same character string. If it has not, it uses the characters to construct a new symbol (a typed pointer to a new character sequence) and enters this pointer in the obarray. If the reader has seen the string before, it returns the symbol pointer stored in the obarray. This process of replacing character strings by unique pointers is called interning symbols. A string might be represented as a typed pointer that designates a sequence of the characters that form the string's printed representation. The parser constructs such a sequence when it encounters a string literal, and the string-concatenation operator + and string-producing primitive functions such as stringify construct such a sequence. Since we want two instances of a string to be recognized as the same string by === and we want === to be a simple test for equality of pointers, we must ensure that if the system sees the same string twice, it will use the same pointer (to the same sequence of characters) to represent both occurrences. To accomplish this, the system maintains a table, called the string pool, of all the strings it has ever encountered. When the system is about to construct a string, it checks the string pool to see if it has ever before seen the same string. If it has not, it constructs a new string (a typed pointer to a new character sequence) and enters this pointer in the string pool. If the system has seen the string before, it returns the string pointer stored in the string pool. This process of replacing strings by unique pointers is called string interning.

[1] We could represent memory as lists of items. However, the access time would then not be independent of the index, since accessing the $n$th element of a list requires $n-1$ cdr tail operations.
[2] As mentioned in section 4.1.4 (footnote 2), JavaScript supports vectors as data structures and calls them arrays. We use the term vector in this book, as it is the more common terminology. The vector functions above are easily implemented using JavaScript's primitive array support.
[3] For completeness, we should specify a make-vector make_vector operation that constructs vectors. However, in the present application we will use vectors only to model fixed divisions of the computer memory.
[4] This is precisely the same tagged data idea we introduced in chapter 2 for dealing with generic operations. Here, however, the data types are included at the primitive machine level rather than constructed through the use of lists.
[5] This decision on the representation of numbers determines whether eq?, ===, which tests equality of pointers, can be used to test for equality of numbers. If the pointer contains the number itself, then equal numbers will have the same pointer. But if the pointer contains the index of a location where the number is stored, equal numbers will be guaranteed to have equal pointers only if we are careful never to store the same number in more than one location.
[6] This is just like writing a number as a sequence of digits, except that each digit is a number between 0 and the largest number that can be stored in a single pointer.
[7] There are other ways of finding free storage. For example, we could link together all the unused pairs into a free list. Our free locations are consecutive (and hence can be accessed by incrementing a pointer) because we are using a compacting garbage collector, as we will see in section 5.3.2.
[8] This is essentially the implementation of cons pair in terms of set-car! set_head and set-cdr!, set_tail, as described in section 3.3.1. The operation get-new-pair get_new_pair used in that implementation is realized here by the free pointer.
5.3.1   Memory as Vectors