What is the single type in a dynamic typing language? Regarding static typing and dynamic typing, Practical Foundation of Programming Languages by Harper says:


  There have been many attempts by advocates of dynamic typing to
  distinguish dynamic from static languages. It is useful to consider
  the supposed distinctions from the present viewpoint.
  
  
  Dynamic languages associate types with  values, whereas static languages associate
  types to variables. Dynamic languages associate  classes, not types, to  values  by tagging them with identiﬁers such as num and
  fun. This form of classiﬁcation amounts to a use of recursive sum
  types within a statically typed language, and hence cannot be seen as
  a distinguishing feature of dynamic languages. Moreover, static
  languages assign types to expressions, not just variables. Because
  dynamic languages are just particular static languages (with a single
  type), the same can be said of dynamic languages.
  Dynamic languages check types at run-time, whereas static language check types at compile time. Dynamic languages are just as surely
  statically typed as static languages, albeit for a degenerate type
  system with only one type. As we have seen, dynamic languages do
  perform class checks at run-time, but so too do static languages that
  admit sum types. The difference is only the extent to which we must
  use classiﬁcation: always in a dynamic language, only as necessary in
  a static language.
  Dynamic languages support heterogeneous collections, whereas static languages sup-
  port homogeneous collections. The purpose of sum types is to support heterogeneity,
  so that any static language with sums admits heterogeneous data structures. A typical
  example is a list such as

 cons(num[1]; cons(fun(x.x); nil))

  
  (written in abstract syntax for emphasis). It is sometimes said that such a list is not
  representable in a static language, because of the disparate nature of its components.
  Whether in a static or a dynamic language, lists are type homogeneous, but can be class
  heterogeneous. All elements of the above list are of type dyn; the ﬁrst is of class num,
  and the second is of class fun.
  
  
  Thus, the seeming opposition between static and dynamic typing is an illusion. The
  question is not whether to have static typing, but rather how best to embrace it. Conﬁning
  one’s attention to a single recursive type seems pointlessly restrictive. Indeed, many so-
  called untyped languages have implicit concessions to there being more than one type.
  The classic example is the ubiquitous concept of “multi-argument functions,” which are
  a concession to the existence of products of the type of values (with pattern matching).
  It is then a short path to considering “multi-result functions,” and other ad hoc language
  features that amount to admitting a richer and richer static type discipline.


So "dynamic languages are just particular static languages (with a single type)". What is the single type in a dynamic  language?

For example, Python is said to use the reference model of variables, as opposed to the value model of variables. References are not explicit. 


Is it because of references that a list in Python can have elements of different "types", i.e. achieving heterogeneous collections in the quote?
Is the "single type"  in Python the type for all the references?  Is it the same for other dynamic  typing languages, i.e. is  the "single type"  in a dynamic typing language the type for all the references? Or is reference just an implementation option of the single type in a dynamic language, and there might be other implementation options?
Do references which refer to values of different "types" have the same type?


Thanks.
The &quot;single type&quot; for Python is called &quot;object&quot; and described in https://docs.python.org/3/reference/datamodel.html:

Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer”, code is also represented by objects.)
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory... An object’s type determines the operations that the object supports (e.g., “does it have a length?”) and also defines the possible values for objects of that type... The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable.

Of course, note that &quot;type&quot; and &quot;value&quot; are not used here in the same way as in Harper's book: Python's &quot;type&quot; is what Harper calls &quot;class&quot;.