<p>In a language, some types are actually type variables. I am aware of three kinds of type variables:</p>
<ol>
<li>Generic Parameter Types: In the declaration of <code>Foo&lt;T&gt;</code>, the <code>T</code> is a type that is a variable.</li>
<li>Associated Types: In languages like Scala, Swift, and Rust, a trait/protocol can have an associated type <code>trait Foo { type T; }</code>. Again, in the declaration of <code>Foo</code>, the <code>T</code> is a type that is a variable.</li>
<li>Self Types: In Swift and Rust, the type <code>Self</code> is a type variable.</li>
</ol>
<p><em>What is an umbrella term for all types that are not type variables?</em></p>
<p>OR</p>
<p><em>What is an umbrella term for reference and value types that are not type variables?</em></p>
<p>(I need a short way to refer to these in my compiler and language spec.)</p>
<p><strong>EDIT:</strong></p>
<p>It appears many people misunderstood my question in a way I hadn't anticipated. I was trying to keep the explanation of type variables short because it wasn't the core of the question. It is just background information. However, that led to the confusion.</p>
<p>When I said &quot;in the declaration of,&quot; I meant in the scope of the declaration of that thing. Let me try to clarify.</p>
<ol>
<li>Generic Parameter Types:</li>
</ol>
<pre><code>public abstract class Foo&lt;T&gt;
{
    // Here T is a type, but not a specific one. It is a type variable.
    public abstract fn test() -&gt; T; 
}
</code></pre>
<ol start="2">
<li>Associated Types</li>
</ol>
<pre><code>public trait Foo
{
    public abstract type T;
    // Here T is a type, but not a specific one. It is a type variable.
    public abstract fn test() -&gt; T;
}
</code></pre>
<ol start="3">
<li>Self Types</li>
</ol>
<pre><code>public abstract class Foo
{
    // Here Self is a type, but not a specific one. It is a type variable.
    public abstract fn test() -&gt; Self; 
}
</code></pre>
<p>My language is an OO language in the style of Swift, C#, Java, or Scala and has all three of Generic Parameter Types, Associated Types, and Self Types. It also has abstract classes.</p>
<p>An example of how I want to use this term:</p>
<p>In the compiler, I have a class hierarchy that represents types. Simplifying some, there is a class <code>Type</code> with a tree of subclasses including ones like <code>OptionalType</code> (i.e. <code>x?</code>), <code>NeverType</code> (i.e. the bottom type), <code>SimpleType</code> (i.e. primitive types), <code>ValueType</code> (i.e. like the types declared with <code>struct</code> in C#), <code>ReferenceType</code>, and <code>GenericParameterType</code>. There is a part of the heriarchy where the &quot;type variables&quot; split off. They have a lot in common and have a base class <code>TypeVariableType</code> . They can have constraints on the type but they have no actual properties. The other types, the non-type-variables also have a lot in common. I want a superclass for them. I need to name that superclass.</p>
<p>One answer brought up the term &quot;ground type&quot;. That isn't what I am describing here. If <code>test()</code> above returned <code>List&lt;T&gt;</code>, that would be a non-type-variable type in my schema. That is because <code>List&lt;&gt;</code> is a reference type.</p>
<p>I am expecting this term to also be helpful in the language spec.</p>

<types><static-typing><terminology>
What is the term for types that are not type variables?
CC BY-SA 4.0
2024-10-06T10:01:18.480Z
I’m not fully convinced the premise makes sense. This is a little bit like asking “what’s a word for integers that aren’t variables?” But an integer is never a variable. A variable can be a sort of “placeholder” for an integer though, just like a type variable can be a placeholder for a type.
David Young
CC BY-SA 4.0
2024-10-06T12:04:47.713Z
*Defined* types, maybe? An example of why this concept is useful to you would help.
Naïm Favier
CC BY-SA 4.0
2024-10-07T03:00:57.220Z
@DavidYoung: The confusion might be a result of "type variable", which makes *mathematical* sense but not *programming* sense. We think of variables in programs as being storage locations for values of a stated type, but "type variables" are not storage locations. In the C# spec we avoided "type variable" (though it got into the MSDN documentation, grrr) in favour of "type parameter" for the declaration and "type argument" for the construction.
Eric Lippert
CC BY-SA 4.0
2024-10-07T18:03:18.867Z
What is the reasoning behind things like `TypeVariableType`? Continuing my analogy, that would almost be like having a special `IntVariable` type/property that would apply to expressions like `x` but not to `x + 1` or `7` or `f(y)` (where `f` gives back an integer). That would seem to be kind of complicated and it's not clear to me what the benefit would be. Can you elaborate on the benefits you want from it? Maybe my analogy is misleading in someway?
David Young
CC BY-SA 4.0
2024-10-07T20:47:26.350Z
@JeffWalkerCodeRanger I would just go with `NonTypeVariableType`. Alternatively, "constructed type" (note that even [nullary types are considered zero-argument type constructors](https://en.wikipedia.org/wiki/Type_constructor), and tuples and functions are also type constructors).
tarzh
CC BY-SA 4.0
2024-10-08T16:53:09.073Z
What exactly do you mean by *`GenericParameterType`*? Is that a type that is parameter for a generic, i.e. a type variable (`T` in `def List<T> = Nil | Cons<T, List<T>>`), or is it a type that has generic parameters, i.e. a type constructor (`List` itself)? Also it's unclear how "*`List<>` is a reference type*" - do you mean `List` itself, or any instantiation (`List<int>` , `List<String>` and so on) are reference types?
Bergi
CC BY-SA 4.0
2024-10-17T18:10:07.433Z
"Here T is a type, but not a specific one. It is a type variable." - the designation "is" is used in two different ways here. This is like saying, for `int foo`, "Here, foo is an int, but not a specific one. It is an int variable." The problem is, one part of the sentence is less literal than the other - conceptually, the symbol "foo" is not itself an integer, we're just saying it's a *name* that's restricted in what it can represent (only integers). So, "T" is not literally a type, and thus not a special kind of type; maybe you can just make the distinction between types and type variables.
Filip Milovanović
<blockquote>
<p>In a language, some types are actually type variables.</p>
</blockquote>
<p>Which language? I would simply say that a type is a type, and a type variable is a variable that refers to a type, not a kind of type itself.</p>
<p>Usually, one talks about generic <em>functions</em>, whose types may involve one or more type variables. Your examples using <code>List</code> would be better described as a <em>parameterized</em> type, with <code>List&lt;Int&gt;</code>, <code>List&lt;Char&gt;</code>, <code>List&lt;T&gt;</code>, etc, being examples of the type being &quot;indexed&quot; with either concrete types or type variables.</p>
<p>An associated type isn't really a kind of type, but a kind of type-valued attribute.</p>
<p><code>Self</code> is not a type at all, just a kind of &quot;reference&quot; to some other type. In the case of your <code>Foo.fn</code> example, <code>fn</code>'s return value is whatever type is used to invoke it, either <code>Foo</code> or a subclass of <code>Foo</code>.</p>

CC BY-SA 4.0
2024-10-07T20:02:29.750Z
2024-10-07T20:02:29.750Z
chepner
CC BY-SA 4.0
2024-10-08T00:09:20.967Z
For example, the [Java Language Specification](https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.3) says *"There are four kinds of reference types: class types (§8.1), interface types (§9.1), **type variables** (§4.4), and array types (§10.1)."* (emphasis added) If they weren't types, then every other part of the spec would have to say "a type or a type variable". And would `List<T>` be a type, or not? It's not a type variable, certainly, but if `T` isn't a type why should `List<T>` be one?
kaya3
CC BY-SA 4.0
2024-10-08T11:44:49.330Z
`List<T>` is polymorphic, since `List` is applied to a type variable rather than a concrete type. I'd say this is an idiosyncrasy of Java (as type variables were bolted on long after the core type system was defined).
chepner
CC BY-SA 4.0
2024-10-08T14:45:46.747Z
Generics in C#, TypeScript and plenty of other languages work the same way. Java may have added them after initial release vs. them being a feature in other languages from the start, but Java's semantics for them are fairly ordinary.
kaya3
CC BY-SA 4.0
2024-10-08T14:50:10.630Z
I’m not sure this distinction is useful. Many languages do not strictly separate variables and their values, so that, say, `name` in a function would be seen both as a variable (when looking at the function itself) and a value (when looking at execution of the function) depending on context. Unless variables themselves are actually first class objects then for most purposes describing variables as separate from values does not seem to add anything (outside of the language implementation, of course). Effectively, a type variable can usually be used like a type.
MisterMiyagi
CC BY-SA 4.0
2024-10-11T18:47:50.137Z
Saying that `name` *is* a value is just shorthand for saying that it's the name of a variable that that contains the value. That doesn't make `name` a separate "kind" of value (though it could make it a kind of expression).
chepner
CC BY-SA 4.0
2024-10-11T19:25:30.890Z
@chepner Well, in the end are there actually values (/types) in the language itself? Or just expressions evaluating to values (/types) - even if trivially so? Most people would call `10` (`int`) an integer (type) instead of a literal expression evaluating to an integer (type). The distinction seems more based on analogy than actual semantics.
MisterMiyagi
<p>I'd just call them paravariables. Why do you need anything more complicated?</p>
<p>I suppose if you need to name that set as a syntactic element, which is completely reasonable, you could just call them nonvariables, because they are the complement of the set of variables.</p>
<p>I'm sure there's a reason for this concern, but it's one of many things I don't understand.</p>

CC BY-SA 4.0
2024-10-07T01:15:03.780Z
2024-10-07T01:15:03.780Z
Miss Understands
CC BY-SA 4.0
2024-10-07T15:11:03.847Z
In what way is "paravariables" not complicated? The [para- prefix has a lot of meanings](https://en.m.wiktionary.org/wiki/para-) out of which maybe one or two *could* fit the intended meaning.
MisterMiyagi
CC BY-SA 4.0
2024-10-08T14:26:56.637Z
I have no idea what that is supposed to mean.
MisterMiyagi
<p>A <strong>concrete</strong> type may fit your description. It’s any type that’s not “abstract”, where the types of abstraction possible depend on the type system. For example:</p>
<ul>
<li><p>It’s not a type variable, if type constructors can be parameterised by such variables.</p>
</li>
<li><p>It’s not a universally quantified type, if there’s first-class polymorphism.</p>
</li>
<li><p>It’s not a reducible expression, if there’s any type-level computation or dependent typing.</p>
<p>This is also called a <strong>normal</strong> form, if you want to avoid the term “concrete” in a context where you might already be using it for something else, such as subtyping.</p>
</li>
</ul>
<p>A type can still be concrete in this sense even if it’s not ground or named. For example, say <code>(x, y)</code> is the type of a tuple of <code>x</code> and <code>y</code>, which are unsolved metavariables that stand for some concrete types, say <code>T1</code> and <code>T2</code>. This is in weak head normal form, but not ground as long as <code>x</code> or <code>y</code> are unknown, yet we know it will be solved to a concrete type <code>(T1, T2)</code>, which is concrete even though it doesn’t necessarily have a distinct name like <code>Pair_T1_T2</code>.</p>

CC BY-SA 4.0
2024-10-06T21:19:07.387Z
2024-10-08T18:16:49.033Z
2024-10-08T18:16:49.033Z
Jon Purdy
CC BY-SA 4.0
2024-10-06T23:17:45.280Z
Though a parameterized type like `List<X>` (with X a type variable) is not a type variable itself, but I wouldn't call it a concrete type.
Paŭlo Ebermann
CC BY-SA 4.0
2024-10-07T12:28:12.337Z
I agree that "concrete" is a fairly good word for this, but it's worth noting that in Java `abstract class Foo {}` declares a type which is not a type variable, and which we would normally not call "concrete" in the sense that "abstract" and "concrete" are normally antonyms.
kaya3
CC BY-SA 4.0
2024-10-07T17:07:57.980Z
My language has abstract classes, so "concrete" would be confusing. Also, I would consider a trait type to be abstract, but the term I am looking for would include it.
Jeff Walker Code Ranger
<p>I can tell you what we did in the C# spec, and it is a cautionary tale; see if you can do better than we did.</p>
<ul>
<li>Generic types that have type arguments supplied are &quot;constructed&quot; types and also &quot;bound&quot; types.</li>
<li>Generic types whose type arguments are not specified <em>at all</em> are &quot;unbound&quot;.  (This is rare; it only really happens in the context of the <code>typeof</code> operator and maybe a few other corners.)</li>
<li>A non-generic type is both &quot;bound&quot; and &quot;unbound&quot;, grrr.  (That makes certain other sections of the spec easier to write.)</li>
<li>All types are exactly one of &quot;open&quot; and &quot;closed&quot;.</li>
<li>Type parameters are open types.</li>
<li>Arrays of open type are open types.</li>
<li>Constructed types with at least one open type argument are open.</li>
<li>Types that are not open are closed.</li>
</ul>
<p>There was no jargon defined for &quot;type that is not a type parameter&quot; because we didn't need it when writing the spec. We did need &quot;type that has no usage of a type parameter&quot;, and that's &quot;closed&quot;.</p>

CC BY-SA 4.0
2024-10-07T02:37:29.983Z
2024-10-07T02:37:29.983Z
Eric Lippert
CC BY-SA 4.0
2024-10-07T17:11:53.033Z
Thanks. Yes, I was aware of those terms and have used a few. I do tend to forget what some of them mean. There are so many variations that it is hard to come up with terms. I think I am needing this term where C# spec didn't because I have generic type parameters, associated types, and self types, where C# only had generic type parameters.
Jeff Walker Code Ranger
CC BY-SA 4.0
2024-10-07T18:46:02.923Z
@JeffWalkerCodeRanger Yeah, I always have to double-check to make sure I'm using the right jargon. They're not obvious choices.
Eric Lippert
<p>You're actually asking about at least three different concepts, for which the concepts of “being” or “containing” a variable are different.</p>
<p>In a <strong>type definition</strong> (examples 1 and 2), what you're defining (<code>Foo</code>) is never a variable. Any <em>parameter</em> of the type is denoted by a variable. The number of parameters of a type definition is typically called its <em>arity</em> (“<a href="https://en.wikipedia.org/wiki/Arity" rel="nofollow noreferrer">arity</a>” is the number of parameters something has, whether it's a type, a function, etc.) This terminology is used, for example, <a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.inamedtypesymbol.arity" rel="nofollow noreferrer">in .NET</a>, <a href="https://smlfamily.github.io/sml97-defn.pdf" rel="nofollow noreferrer">ML (§4.1)</a>. So a type definition with no parameters can be said to <strong>have arity 0</strong>, also called a <strong>nullary type</strong>. More generally, the “shape” of the parameters of a type is sometimes called a <em><a href="https://en.wikipedia.org/wiki/Kind_(type_theory)" rel="nofollow noreferrer">kind</a></em> (which can be more complex than an integer if the language has, for example, higher-order kinds or named parameters for types). A type with no parameters is a type whose kind is the “base” kind. This terminology is used <a href="https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-640004.1.1" rel="nofollow noreferrer">in Haskell</a>, where the kind of nullary types is written <span class="math-container">$*$</span>.</p>
<p>In a <strong>type expression</strong> (example 3), I can't think of a word that means that a type expression <em>is</em> not a variable, for example including <code>int * T</code> and <code>list(T)</code> while excluding <code>T</code>. A type expression that does not have any free variable is a <strong><a href="https://en.wikipedia.org/wiki/Ground_expression" rel="nofollow noreferrer">ground</a> type</strong>, following the general terminology used in term rewriting. For example, <code>int * bool</code> and <code>list(int)</code> are ground types, whereas <code>int * T</code> and <code>list(T)</code> are not. Note that in some languages, a type expression can include bound variables; <span class="math-container">$\forall \alpha, (\mathtt{list}(\alpha) \to \mathtt{int})$</span> is a ground type while <span class="math-container">$\mathtt{list}(\alpha) \to \mathtt{int}$</span> is not. A type expression with no variables appearing anywhere would have to be a <strong>quantifier-free ground type</strong>.</p>
<p>In your revised question, it looks like you're interested in the top-level aspect of the type: the node at the root of the parse tree of the type expressed in its canonical form. For example <code>*</code> (or <code>Tuple</code> or whatever your language calls it) for something like <code>int * T</code>, <code>list</code> for <code>list(int)</code>, <code>int</code> for <code>int</code>, <code>T</code> for a type variable, <code>forall</code> for a quantifier <span class="math-container">$(\forall \alpha, \ldots)$</span>, etc. The node at the root is usually called the <strong>head</strong>. If the head isn't a variable, it's probably a <strong>constructor</strong>. <code>int</code> is a nullary constructor, <code>list</code> and <code>Optional</code> are unary constructors, <code>Tuple</code> is a constructor of variable arity, etc. Each <code>struct</code> is a constructor (<code>struct</code> itself isn't a constructor, it's a way to define new constructors). <code>NeverType</code> may or may not be a constructor, depending on how you model it (a type constructor with subtype declarations, or a separate form of types that can unify with anything).</p>

CC BY-SA 4.0
2024-10-06T16:42:47.000Z
2024-10-08T09:46:26.027Z
2024-10-08T09:46:26.027Z
Gilles 'SO- stop being evil'
CC BY-SA 4.0
2024-10-06T17:03:22.003Z
Another term for a type with no free variables, common in type theory, is a **closed type**.
Naïm Favier
CC BY-SA 4.0
2024-10-07T17:06:57.247Z
I've clarified my question. In all cases, I was trying to talk about type expressions. However, I was not asking for what you have called a ground type. I would include examples like `int * T` and `list(T)` (with different syntax).
Jeff Walker Code Ranger
CC BY-SA 4.0
2024-10-08T09:47:11.450Z
@JeffWalkerCodeRanger I'm not sure I understand your edit, but my best guess is that you're interested in the head of the type expression, in which case the class you're looking for is **constructors**.
Gilles 'SO- stop being evil'
# What is the term for types that are not type variables?
Posted by: username_0 on 2024-10-06
In a language, some types are actually type variables. I am aware of three kinds of type variables:

Generic Parameter Types: In the declaration of Foo, the T is a type that is a variable.
Associated Types: In languages like Scala, Swift, and Rust, a trait/protocol can have an associated type trait Foo { type T; }. Again, in the declaration of Foo, the T is a type that is a variable.
Self Types: In Swift and Rust, the type Self is a type variable.

What is an umbrella term for all types that are not type variables?
OR
What is an umbrella term for reference and value types that are not type variables?
(I need a short way to refer to these in my compiler and language spec.)
EDIT:
It appears many people misunderstood my question in a way I hadn't anticipated. I was trying to keep the explanation of type variables short because it wasn't the core of the question. It is just background information. However, that led to the confusion.
When I said "in the declaration of," I meant in the scope of the declaration of that thing. Let me try to clarify.

Generic Parameter Types:

public abstract class Foo
{
    // Here T is a type, but not a specific one. It is a type variable.
    public abstract fn test() -> T; 
}


Associated Types

public trait Foo
{
    public abstract type T;
    // Here T is a type, but not a specific one. It is a type variable.
    public abstract fn test() -> T;
}


Self Types

public abstract class Foo
{
    // Here Self is a type, but not a specific one. It is a type variable.
    public abstract fn test() -> Self; 
}

My language is an OO language in the style of Swift, C#, Java, or Scala and has all three of Generic Parameter Types, Associated Types, and Self Types. It also has abstract classes.
An example of how I want to use this term:
In the compiler, I have a class hierarchy that represents types. Simplifying some, there is a class Type with a tree of subclasses including ones like OptionalType (i.e. x?), NeverType (i.e. the bottom type), SimpleType (i.e. primitive types), ValueType (i.e. like the types declared with struct in C#), ReferenceType, and GenericParameterType. There is a part of the heriarchy where the "type variables" split off. They have a lot in common and have a base class TypeVariableType . They can have constraints on the type but they have no actual properties. The other types, the non-type-variables also have a lot in common. I want a superclass for them. I need to name that superclass.
One answer brought up the term "ground type". That isn't what I am describing here. If test() above returned List, that would be a non-type-variable type in my schema. That is because List<> is a reference type.
I am expecting this term to also be helpful in the language spec.
**Tags:** types static-typing terminology
> **Comments:**
> **username_1**: I’m not fully convinced the premise makes sense. This is a little bit like asking “what’s a word for integers that aren’t variables?” But an integer is never a variable. A variable can be a sort of “placeholder” for an integer though, just like a type variable can be a placeholder for a type.  
> **username_2**: *Defined* types, maybe? An example of why this concept is useful to you would help.  
> **username_3**: @DavidYoung: The confusion might be a result of "type variable", which makes *mathematical* sense but not *programming* sense. We think of variables in programs as being storage locations for values of a stated type, but "type variables" are not storage locations. In the C# spec we avoided "type variable" (though it got into the MSDN documentation, grrr) in favour of "type parameter" for the declaration and "type argument" for the construction.  
> **username_1**: What is the reasoning behind things like `TypeVariableType`? Continuing my analogy, that would almost be like having a special `IntVariable` type/property that would apply to expressions like `x` but not to `x + 1` or `7` or `f(y)` (where `f` gives back an integer). That would seem to be kind of complicated and it's not clear to me what the benefit would be. Can you elaborate on the benefits you want from it? Maybe my analogy is misleading in someway?  
> **username_4**: @JeffWalkerCodeRanger I would just go with `NonTypeVariableType`. Alternatively, "constructed type" (note that even [nullary types are considered zero-argument type constructors](https://en.wikipedia.org/wiki/Type_constructor), and tuples and functions are also type constructors).  
> **username_5**: What exactly do you mean by *`GenericParameterType`*? Is that a type that is parameter for a generic, i.e. a type variable (`T` in `def List<T> = Nil | Cons<T, List<T>>`), or is it a type that has generic parameters, i.e. a type constructor (`List` itself)? Also it's unclear how "*`List<>` is a reference type*" - do you mean `List` itself, or any instantiation (`List<int>` , `List<String>` and so on) are reference types?  
> **username_6**: "Here T is a type, but not a specific one. It is a type variable." - the designation "is" is used in two different ways here. This is like saying, for `int foo`, "Here, foo is an int, but not a specific one. It is an int variable." The problem is, one part of the sentence is less literal than the other - conceptually, the symbol "foo" is not itself an integer, we're just saying it's a *name* that's restricted in what it can represent (only integers). So, "T" is not literally a type, and thus not a special kind of type; maybe you can just make the distinction between types and type variables.  
---
## 5 answers
### Answer by username_11 on 2024-10-06. Score: 14
A **concrete** type may fit your description. It’s any type that’s not “abstract”, where the types of abstraction possible depend on the type system. For example:

* It’s not a type variable, if type constructors can be parameterised by such variables.
* It’s not a universally quantified type, if there’s first-class polymorphism.
* It’s not a reducible expression, if there’s any type-level computation or dependent typing.

  This is also called a **normal** form, if you want to avoid the term “concrete” in a context where you might already be using it for something else, such as subtyping.

A type can still be concrete in this sense even if it’s not ground or named. For example, say `(x, y)` is the type of a tuple of `x` and `y`, which are unsolved metavariables that stand for some concrete types, say `T1` and `T2`. This is in weak head normal form, but not ground as long as `x` or `y` are unknown, yet we know it will be solved to a concrete type `(T1, T2)`, which is concrete even though it doesn’t necessarily have a distinct name like `Pair_T1_T2`.
> **Comments:**
> **username_12** (2024-10-06): Though a parameterized type like `List<X>` (with X a type variable) is not a type variable itself, but I wouldn't call it a concrete type.  
> **username_8** (2024-10-07): I agree that "concrete" is a fairly good word for this, but it's worth noting that in Java `abstract class Foo {}` declares a type which is not a type variable, and which we would normally not call "concrete" in the sense that "abstract" and "concrete" are normally antonyms.  
> **username_0** (2024-10-07): My language has abstract classes, so "concrete" would be confusing. Also, I would consider a trait type to be abstract, but the term I am looking for would include it.  
---
### Answer by username_3 on 2024-10-07. Score: 11
I can tell you what we did in the C# spec, and it is a cautionary tale; see if you can do better than we did.

* Generic types that have type arguments supplied are "constructed" types and also "bound" types.
* Generic types whose type arguments are not specified *at all* are "unbound". (This is rare; it only really happens in the context of the `typeof` operator and maybe a few other corners.)
* A non-generic type is both "bound" and "unbound", grrr. (That makes certain other sections of the spec easier to write.)
* All types are exactly one of "open" and "closed".
* Type parameters are open types.
* Arrays of open type are open types.
* Constructed types with at least one open type argument are open.
* Types that are not open are closed.

There was no jargon defined for "type that is not a type parameter" because we didn't need it when writing the spec. We did need "type that has no usage of a type parameter", and that's "closed".
> **Comments:**
> **username_0** (2024-10-07): Thanks. Yes, I was aware of those terms and have used a few. I do tend to forget what some of them mean. There are so many variations that it is hard to come up with terms. I think I am needing this term where C# spec didn't because I have generic type parameters, associated types, and self types, where C# only had generic type parameters.  
> **username_3** (2024-10-07): @JeffWalkerCodeRanger Yeah, I always have to double-check to make sure I'm using the right jargon. They're not obvious choices.  
---
### Answer by username_13 on 2024-10-06. Score: 9
You're actually asking about at least three different concepts, for which the concepts of “being” or “containing” a variable are different.

In a **type definition** (examples 1 and 2), what you're defining (`Foo`) is never a variable. Any *parameter* of the type is denoted by a variable. The number of parameters of a type definition is typically called its *arity* (“[arity](https://en.wikipedia.org/wiki/Arity)” is the number of parameters something has, whether it's a type, a function, etc.) This terminology is used, for example, [in .NET](https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.inamedtypesymbol.arity), [ML (§4.1)](https://smlfamily.github.io/sml97-defn.pdf). So a type definition with no parameters can be said to **have arity 0**, also called a **nullary type**. More generally, the “shape” of the parameters of a type is sometimes called a *[kind](https://en.wikipedia.org/wiki/Kind_(type_theory))* (which can be more complex than an integer if the language has, for example, higher-order kinds or named parameters for types). A type with no parameters is a type whose kind is the “base” kind. This terminology is used [in Haskell](https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-640004.1.1), where the kind of nullary types is written $\*$.

In a **type expression** (example 3), I can't think of a word that means that a type expression *is* not a variable, for example including `int * T` and `list(T)` while excluding `T`. A type expression that does not have any free variable is a **[ground](https://en.wikipedia.org/wiki/Ground_expression) type**, following the general terminology used in term rewriting. For example, `int * bool` and `list(int)` are ground types, whereas `int * T` and `list(T)` are not. Note that in some languages, a type expression can include bound variables; $\forall \alpha, (\mathtt{list}(\alpha) \to \mathtt{int})$ is a ground type while $\mathtt{list}(\alpha) \to \mathtt{int}$ is not. A type expression with no variables appearing anywhere would have to be a **quantifier-free ground type**.

In your revised question, it looks like you're interested in the top-level aspect of the type: the node at the root of the parse tree of the type expressed in its canonical form. For example `*` (or `Tuple` or whatever your language calls it) for something like `int * T`, `list` for `list(int)`, `int` for `int`, `T` for a type variable, `forall` for a quantifier $(\forall \alpha, \ldots)$, etc. The node at the root is usually called the **head**. If the head isn't a variable, it's probably a **constructor**. `int` is a nullary constructor, `list` and `Optional` are unary constructors, `Tuple` is a constructor of variable arity, etc. Each `struct` is a constructor (`struct` itself isn't a constructor, it's a way to define new constructors). `NeverType` may or may not be a constructor, depending on how you model it (a type constructor with subtype declarations, or a separate form of types that can unify with anything).
> **Comments:**
> **username_2** (2024-10-06): Another term for a type with no free variables, common in type theory, is a **closed type**.  
> **username_0** (2024-10-07): I've clarified my question. In all cases, I was trying to talk about type expressions. However, I was not asking for what you have called a ground type. I would include examples like `int * T` and `list(T)` (with different syntax).  
> **username_13** (2024-10-08): @JeffWalkerCodeRanger I'm not sure I understand your edit, but my best guess is that you're interested in the head of the type expression, in which case the class you're looking for is **constructors**.  
---
### Answer by username_7 on 2024-10-07. Score: 0
> In a language, some types are actually type variables.

Which language? I would simply say that a type is a type, and a type variable is a variable that refers to a type, not a kind of type itself.

Usually, one talks about generic *functions*, whose types may involve one or more type variables. Your examples using `List` would be better described as a *parameterized* type, with `List`, `List`, `List`, etc, being examples of the type being "indexed" with either concrete types or type variables.

An associated type isn't really a kind of type, but a kind of type-valued attribute.

`Self` is not a type at all, just a kind of "reference" to some other type. In the case of your `Foo.fn` example, `fn`'s return value is whatever type is used to invoke it, either `Foo` or a subclass of `Foo`.
> **Comments:**
> **username_8** (2024-10-08): For example, the [Java Language Specification](https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.3) says *"There are four kinds of reference types: class types (§8.1), interface types (§9.1), **type variables** (§4.4), and array types (§10.1)."* (emphasis added) If they weren't types, then every other part of the spec would have to say "a type or a type variable". And would `List<T>` be a type, or not? It's not a type variable, certainly, but if `T` isn't a type why should `List<T>` be one?  
> **username_7** (2024-10-08): `List<T>` is polymorphic, since `List` is applied to a type variable rather than a concrete type. I'd say this is an idiosyncrasy of Java (as type variables were bolted on long after the core type system was defined).  
> **username_8** (2024-10-08): Generics in C#, TypeScript and plenty of other languages work the same way. Java may have added them after initial release vs. them being a feature in other languages from the start, but Java's semantics for them are fairly ordinary.  
> **username_9** (2024-10-08): I’m not sure this distinction is useful. Many languages do not strictly separate variables and their values, so that, say, `name` in a function would be seen both as a variable (when looking at the function itself) and a value (when looking at execution of the function) depending on context. Unless variables themselves are actually first class objects then for most purposes describing variables as separate from values does not seem to add anything (outside of the language implementation, of course). Effectively, a type variable can usually be used like a type.  
> **username_7** (2024-10-11): Saying that `name` *is* a value is just shorthand for saying that it's the name of a variable that that contains the value. That doesn't make `name` a separate "kind" of value (though it could make it a kind of expression).  
> **username_9** (2024-10-11): @chepner Well, in the end are there actually values (/types) in the language itself? Or just expressions evaluating to values (/types) - even if trivially so? Most people would call `10` (`int`) an integer (type) instead of a literal expression evaluating to an integer (type). The distinction seems more based on analogy than actual semantics.  
---
### Answer by username_10 on 2024-10-07. Score: -3
I'd just call them paravariables. Why do you need anything more complicated?

I suppose if you need to name that set as a syntactic element, which is completely reasonable, you could just call them nonvariables, because they are the complement of the set of variables.

I'm sure there's a reason for this concern, but it's one of many things I don't understand.
> **Comments:**
> **username_9** (2024-10-07): In what way is "paravariables" not complicated? The [para- prefix has a lot of meanings](https://en.m.wiktionary.org/wiki/para-) out of which maybe one or two *could* fit the intended meaning.  
> **username_9** (2024-10-08): I have no idea what that is supposed to mean.  
---
