Here is an example of a proof.
Given that the program must be of finite size , all types defined in the program should contain only a finite number of members and refer only to a finite number of other types. The same is true for any entry point into the program and for any objects defined prior to program initialization.
In the absence of continuous arrays (which are a product of a type with a natural number of runtimes and therefore unlimited in size), all types must be obtained through the composition of types, as indicated above; type inference (pointer-to-pointer-to- A ) is still limited by the size of the program. there are no objects except adjacent arrays to create a runtime value with a type.
This is a bit controversial; if, for example, comparisons are considered primitive, then you can approximate an array with a map whose keys are natural numbers. Of course, any map implementation must use self-referenced data structures (B-trees) or continuous arrays (hash tables).
Further, if the types are non-recursive , then any type chain ( A link B link C ...) should end and can be no longer than the number of types defined in the program. Thus, the total size of the data subject to the program is limited by the product of the sizes of each type, multiplied by the number of names defined in the program (at its entry point and static data).
This is done even if the functions are recursive (which strictly violates the prohibition on recursive types, since functions are types); the amount of data immediately visible at any point in the program is still limited by the product of the sizes of each type, multiplied by the number of names visible at this point.
An exception is storing the "container" in the stack of recursive function calls ; however, such a program will not be able to randomly move its data without unwinding the stack and re-reading the data, which is a bit of a disqualification.
Finally, if it is possible to create types dynamically , the above proof does not hold; we could, for example, create a Lisp-style list structure, where each cell has a separate type: cons<4>('h', cons<3>('e', cons<2>('l', cons<1>('l', cons<0>('o', nil))))) . This is not possible in most languages with a typical type, although this is possible in some dynamic languages, for example. Python