<p>As per the comment about Swift having an <code>Any</code> type <a href="https://langdev.stackexchange.com/questions/2121/how-to-avoid-output-build-bloat-when-wanting-to-access-type-metadata-information">here</a> (and my related question in that post, on how to access type metadata at runtime without increasing the output build bloat), and because of the points made <a href="https://softwareengineering.stackexchange.com/questions/122205/what-is-the-supposed-productivity-gain-of-dynamic-typing/122212#122212">here</a>, I am thinking a statically typed language is best for long-term maintainability, even if it comes at the cost of not being able to do as quick of rapid prototyping as a dynamically typed language (like Ruby or JS).</p>
<p>But then languages like Swift just mentioned have the <code>Any</code> type, and <a href="https://doc.rust-lang.org/std/any/trait.Any.html" rel="noreferrer">Rust has <code>Any</code> too</a>, &quot;a trait to emulate dynamic typing&quot;. Why are these added to these languages? What problems do they solve? Are they <em>necessary</em> for statically typed languages? If you don't have an <code>Any</code> type, what problems will you face?</p>
<p>Basically I'm wondering, to solve my <a href="https://langdev.stackexchange.com/questions/2047/what-are-the-advantages-and-disadvantages-of-making-types-as-a-first-class-value/2120#2120">problem</a> of having 1.5 megabytes of type information in the output JavaScript build file (if I include dynamic typing / reflection capabilities in the custom lang), should I just cut that feature (runtime type checking and including the type metadata in the runtime build)? Or is it a necessity for certain key situations? It would seem it's a necessity sometimes, because Rust and Swift have the <code>Any</code> type, and to do that it seems you'd need to include the type info in the runtime build. I don't have a deep understanding of how the <code>Any</code> type really works in Rust or Swift (my main language is JS/TS), so I'm not sure why it was deemed necessary to include.</p>
<p>If you don't <strong>need</strong> an <code>Any</code> type, what problems will you face? Wondering at the same time if it would have been better for Rust and Swift to avoid this feature, or if not, what it's solving.</p>

<types><type-checker><runtime>
Do you need an "Any" type when implementing a statically typed programming language?
CC BY-SA 4.0
2023-07-06T20:26:21.730Z
Does C's `void*` (something that can refer to any object, but you have to separately keep track of what type it is, because the language doesn't) count as an "Any" type?
dan04
CC BY-SA 4.0
2023-07-06T20:28:00.113Z
I'm fairly sure Swift only has `Any` because it needed some way to represent Objective-C methods that take and return `id`. (Ironically, in modern Swift those no longer use `Any`, and instead `AnyObject`, which is different.)
Bbrk24
CC BY-SA 4.0
2023-07-06T20:39:36.743Z
You absolutely do not (many FP languages, such as Haskell and OCaml, don't). Even Java makes a distinction between objects and primitives.
user
CC BY-SA 4.0
2023-07-06T20:39:42.433Z
@mousetail [std::any](https://doc.rust-lang.org/std/any/index.html)?
phyrfox
CC BY-SA 4.0
2023-07-07T08:53:38.317Z
@Bbrk24, "AnyObject" and "Any" are very very similar, except that "AnyObject" must be an instance of a class, and not for example Integer. Since "id" in Objective-C is always an instance of a class, "AnyObject" would be more precise, but "Any" will just work. The main difference is that you cannot assign say Integer to an "AnyObject" variable.
gnasher729
CC BY-SA 4.0
2023-07-07T11:47:49.527Z
@gnasher729 They are completely different in layout. `Any` is five words, while `AnyObject` is just one.
Bbrk24
CC BY-SA 4.0
2023-07-07T19:23:07.473Z
Python has a type `object` that is the superclass of all types. [PEP 483](https://peps.python.org/pep-0483/#summary-of-gradual-typing) has a section describing how `Any` contrasts with `object` to allow for gradual typing.
chepner
<h1><code>Any</code> enables dynamic typing and type erasure in a statically-typed language.</h1>
<p>This turns out to be very useful, to the point where even <a href="https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Dynamic.html" rel="nofollow noreferrer">Haskell</a> and <a href="https://www.cs.hmc.edu/%7Eoneill/syb/syb-ml-oneill.pdf" rel="nofollow noreferrer">SML</a> (languages with strong type guarantees and no subtyping) have <code>Any</code> equivalents or people working on them. And as mentioned, Rust has <a href="https://doc.rust-lang.org/std/any/index.html" rel="nofollow noreferrer"><code>std::any</code></a> which relies on a compiler extension: the compiler gives runtime-accessible tags to every <code>'static</code> type for the sole purpose of supporting it.</p>
<ul>
<li><p><strong>Reflection AKA runtime metaprogramming</strong> is the main reason for dynamic types in statically-typed language. here are some meta-programming operations which are impossible at compile type, specifically ones which access metadata in private or dynamically-linked libraries. And even when the metaprogramming is possible at compile time, it's often easier to implement at runtime via reflection, because you can implement it in the language itself without creating a multi-phase compiler (a compiler which interprets its own code during compilation).</p>
<ul>
<li><p>Reflection is one of the big reasons <a href="https://en.wikipedia.org/wiki/Java_(programming_language)#Special_classes" rel="nofollow noreferrer">Java</a> is so popular (see <a href="https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful">reflection examples</a>; also one of the first sentences in the <a href="https://en.wikipedia.org/wiki/Java_(programming_language)#Special_classes" rel="nofollow noreferrer">wikipedia</a>, &quot;The Java runtime provides dynamic capabilities (such as reflection and runtime code modification) that are typically not available in traditional compiled languages&quot;). It's also one of the main benefits of dynamic languages like <a href="https://www.javascript.com/" rel="nofollow noreferrer">JavaScript</a>, <a href="https://www.python.org/" rel="nofollow noreferrer">Python</a>, and <a href="https://www.r-project.org/" rel="nofollow noreferrer">R</a> over static languages like <a href="https://en.wikipedia.org/wiki/C_(programming_language)" rel="nofollow noreferrer">C</a>/<a href="https://cplusplus.com/" rel="nofollow noreferrer">C++</a> and <a href="https://www.haskell.org/" rel="nofollow noreferrer">Haskell</a>.</p>
</li>
<li><p>A big example where reflection comes in handy is debugging. Sometimes even in static languages, you just want to <a href="https://hackage.haskell.org/package/base-4.18.0.0/docs/Debug-Trace.html" rel="nofollow noreferrer">print something</a>, particularly a datatype, but sometimes the datatype doesn't have <code>Debug</code>, <code>Show</code>, or any other <code>toString</code> equivalent. In this case reflection is your only option. This is the main reason for <a href="https://developer.apple.com/swift/" rel="nofollow noreferrer">Swift</a>'s <a href="https://developer.apple.com/documentation/swift/mirror" rel="nofollow noreferrer">Mirror</a>, a structure which, like Rust's <code>Any</code>, relies on a compiler extension.</p>
</li>
</ul>
</li>
<li><p>The <a href="https://en.wikipedia.org/wiki/Expression_problem" rel="nofollow noreferrer"><strong>expression problem</strong></a> is another reason why <code>Any</code> and downcasting, and specifically polymorphism, are popular. A version of the expression problem states that it's easy for a language to allow users to add <em>new methods to an existing type</em> (if the type is an ADT like an enum) or <em>new overloads to an existing method</em> (if the type is a non-sealed class), but it's tricky to cleanly allow both. <code>Any</code> provides a messy solution to allow both: you can <em>add new methods</em> to a non-sealed class which downcast <code>self</code> to <code>Any</code> and then try upcasting to every known subclass, and you can <em>add new overloads</em> to the class as usual, with the additional stipulation that you handle these new subclasses in your methods which downcast to <code>Any</code>.</p>
</li>
</ul>
<p>Ultimately, <a href="https://stackoverflow.com/questions/1251791/what-are-the-limits-of-type-checking-and-type-systems">not all programs can be conveniently represented with static types</a>. Notice I said &quot;conveniently&quot; because as <a href="https://stackoverflow.com/a/1251839">some of the answers</a> point out, you theoretically can encode any program in a statically-typed language, but only by inventing your own dynamic types e.g. by liberally using enums and failable functions. Furthermore, <a href="https://stackoverflow.com/a/3273068">as the first answer</a> points out, type-checking non-trivial properties requires formal proofs, which are extremely tedious). At these points (when you need enums and failable functions and/or formal proofs), it's much easier to simply upcast the type to &quot;Top&quot; and then downcast at runtime, asserting that the types are ok without a formal proof.</p>

CC BY-SA 4.0
2023-07-07T17:52:00.063Z
2023-11-08T23:14:31.860Z
2023-11-08T23:14:31.860Z
tarzh
<h1>Dependency Injection</h1>
<p>I wrote a dependency injection library in Swift. It makes use of <code>as!</code> and <code>Any</code>.</p>
<p>I'm not going to go into a detailed description of what DI is and when to use it, but the idea is that you can ask the DI container for an instance of <code>FooProtocol</code> (<code>IFoo</code> for the C# devs out there) and it gives you one. You don't need to worry about where it comes from, and it can easily be changed (e.g. for testing).</p>
<p>In order for this to be possible, the container needs to store, as a vast oversimplification, a bunch of type-instance pairs. However, you can't use <code>&lt;T&gt;Dictionary&lt;T.Type, T&gt;</code> for a number of reasons. Beyond the fact that that kind of generic container doesn't exist in the language, this doesn't facilitate lazy initialization or weak references.</p>
<p>Surely, I thought, this should be possible! Just start with a protocol:</p>
<pre class="lang-swift prettyprint-override"><code>protocol Registration {
  associatedtype T
  func resolve() -&gt; T
}
</code></pre>
<p>and then store an array, <code>[any Registration]</code>.</p>
<p>Let's try to implement the lookup function given this.</p>
<pre class="lang-swift prettyprint-override"><code>private var registrations: [any Registration]

func resolve&lt;T&gt;() -&gt; T {
  // I'm using .lastIndex rather than .firstIndex for reasons not important here
  let index = registrations.lastIndex(where: { $0.T == T })!
  return registrations[index].resolve()
}
</code></pre>
<p>Seems legit. Except, wait a second, how does that work? The answer is, it doesn't. Go ahead, <a href="https://swiftfiddle.com/zu3anphakbelreo2uhpenmthba" rel="noreferrer">try it yourself</a> if you don't believe me.</p>
<p>There are really two problems here:</p>
<ol>
<li>By using <code>lastIndex</code> + <code>subscript</code>, the type system has no way of verifying that <code>resolve()</code> returns the correct type. Indeed, the subscript returns an <code>any Registration</code>, so Swift marks <code>resolve()</code> as returning <code>Any</code>.
This is arguably a Swift-specific implementation problem, except that...</li>
<li>Determining whether <code>$0.T == T</code> <em>relies</em> on the exact kind of type information you want to eliminate!</li>
</ol>
<p><sup><sub>There are more reasons I chose to do it this way, such as being backwards-compatible with earlier versions than iOS 16.</sub></sup></p>
<p>I tried for weeks to eliminate <code>as!</code> and <code>Any</code> from that codebase, all to no avail. Some of it was restricted by limitations of Swift itself, but even if I managed to remove all explicit casts, there'd still have to be type comparisons somewhere.</p>

CC BY-SA 4.0
2023-07-06T21:20:37.170Z
2023-07-07T12:36:44.543Z
2023-07-07T12:36:44.543Z
Bbrk24
<p><a href="https://devblogs.microsoft.com/cppblog/stdany-how-when-and-why/" rel="noreferrer">Any</a> is mostly useful in the libraries that internally need to work with arbitrary data records, like some &quot;user data object&quot; on some library - managed data structure. It is the further evolution of the smart pointer:</p>
<ul>
<li>A smart pointer knows how to safely delete the object.</li>
<li><code>Any</code> also knows about the type of the object, and how to copy it.</li>
</ul>
<p>If you have knowledge about the type being stored, <code>Any</code> is not the proper tool. If all possible types that could be stored are known, a <code>Variant</code> is a better container for them, and for the single type value that may also be missing, an <code>Optional</code> may be offered.</p>

CC BY-SA 4.0
2023-07-07T16:42:59.077Z
2023-07-07T16:56:47.533Z
2023-07-07T16:56:47.533Z
Audrius Meškauskas
<p>The accepted answer already explains that you do not need it in your language. However, you'll need it in your compiler to get to a somewhat sane architecture. Otherwise, you wouldn't be able to process something like &quot;true ? new Object : 7&quot; in Java 1.4 or your compiler would have to quit on first error.
If you have it anyway in your compiler, you can expose it to the user.</p>
<p>However, in languages that are close to the hardware, i.e. the representation of int is something like 4 bytes that can reside in a register instead of having everything boxed on the heap, there is no way to <em>represent</em> any. Thus, such a language might have <code>any</code>, but it wouldn't allow you to use it everywhere.</p>

CC BY-SA 4.0
2023-07-08T09:06:54.290Z
2023-07-08T09:06:54.290Z
feldentm
CC BY-SA 4.0
2023-07-08T09:30:17.380Z
I don't see how that claim about the compiler follows at all. Compilers with great error checking have been written in C and Ada, which don't have an Any type.
prosfilaes
CC BY-SA 4.0
2023-07-08T09:32:21.770Z
The language used to implement the compiler is not relevant. I'm talking about a data structure or type representation for any in the processed language.
feldentm
CC BY-SA 4.0
2023-07-08T17:44:12.517Z
The argument from compiler design is completely fallacious.  A compiler can handle ill-typed expressions like that in many other ways — e.g. tagging them as a type error.  “Type them as ‘Any’, or quit immediately” is a massively false dichotomy.  And “If you have it anyway in your compiler, you can expose it to the user.” is just as dubious — compilers do many things (such as handling possibly ill-typed code) which you want to be outlawed in the object language, exactly so that the object language can provide type-safety guarantees.
Peter LeFanu Lumsdaine
CC BY-SA 4.0
2023-07-09T07:34:31.297Z
"Tag it as error" is the same thing as introducing an any type to a language that doesn't have one as you need to introduce some processable data to continue there. You could also call that type error or poison or whatever, but it will always be an any type. While I agree that "expose what you have" is dubious from design perspective, it is how things work from my experience.
feldentm
CC BY-SA 4.0
2023-07-10T19:59:06.537Z
An error type has no dynamic semantics; that is wildly different from an Any type.
prosfilaes
CC BY-SA 4.0
2023-07-12T06:55:40.423Z
The point, I'm trying to make here, is that the code required in the compiler to treat them is mostly the same in many cases.
feldentm
CC BY-SA 4.0
2023-07-24T11:49:42.517Z
Compiling an expression like `true ? new Object() : 7` in Java doesn't require a top type; it requires finding a least-upper-bound (in this case, of `Object` and `int`) and if that fails, it tries again with more type conversions allowed (including boxing conversions).
kaya3
<p><em>Any</em> is commonly known as a <a href="https://en.wikipedia.org/wiki/Top_type" rel="noreferrer">Top type</a>: a type that is a super-type of every type.</p>
<p>Some strongly typed languages have quite restricted notions of sub-typing, so the concept of top type makes no sense there.  For example, languages like SML and Idris allow sub-typing of type variables but not of defined types.</p>
<p>Sub-typing functional languages tend to have top types, but many others don't.</p>
<p>For example, Java.  It has a <code>java.lang.Object</code> type that is the super-type of all <em>reference types</em> like <code>java.lang.Integer</code> but is not the super-type of <em>value types</em> like <code>int</code>, and its <code>void</code> type is a special type that can only appear in return position.</p>
<p>Java does have an auto-boxing system; you can often use an <code>int</code> where a <code>java.lang.Integer</code> is expected and vice-versa, but there are subtleties.</p>
<p>But that doesn't mean you can treat <code>int</code> as if it were a sub-type of <code>java.lang.Object</code> via <code>java.lang.Integer</code>.  In that case, you would need to treat an array like <code>int[]</code> as a sub-type of <code>java.lang.Integer[]</code> which would cause problems because those two types are actually very different.</p>
<p>JVM languages like Scala and Kotlin do manage to have a top type, as you noted, but they do that by being very careful around how their array types map to JVM array types.</p>

CC BY-SA 4.0
2023-07-06T22:04:00.013Z
2023-07-06T22:04:00.013Z
Mike Samuel
CC BY-SA 4.0
2023-07-06T22:21:22.917Z
Not related to the actual question, but arrays in general are kinda scuffed in Java. You can treat a `String[]` as an `Object[]` at compile-time, but it'll blow up if you try to put in `Object`s into that casted `String[]` at runtime
user
CC BY-SA 4.0
2023-07-07T05:15:15.013Z
it's more that Java's entire type system is horrible. the whole int vs integer because they couldn't figure out how to represent objects without tons of pointers is a horrible mess
Oscar Smith
CC BY-SA 4.0
2023-07-07T08:57:24.823Z
In Swift, "Any" is a protocol, not a type. A variable declared as "Any" has a type, but you don't know which one, except you know it follows the "Any" protocol.
gnasher729
CC BY-SA 4.0
2023-07-07T20:15:11.513Z
@gnasher729 are Swift protocols existential?
Mike Samuel
CC BY-SA 4.0
2023-07-07T20:18:13.567Z
@user, yeah.  Java treated arrays as covariant even though they're mutable which is horribly unsound hence the need for *ArrayStoreException*s at runtime.  I think the way other JVM languages balance a top type with their own array types that map to JVM array types is by treating arrays as invariant.
Mike Samuel
CC BY-SA 4.0
2023-07-09T17:02:29.653Z
@MikeSamuel: IMHO, Java's mistake was failing to have an abstract "readable array" type with mutable and immutable subclasses (with the latter having a variety of constructors and factory methods that wouldn't expose a reference to the completed object until all members were populated).  A limited form of multiple inheritance should be supported here, since even though neither `ImmutableArray<Animal>` nor `ReadableArray<Cat>` is a subtype of the other, but both should be viewed as supertypes of `ReadableArray<Animal>`.
supercat
CC BY-SA 4.0
2023-07-11T15:42:18.190Z
@supercat, Yeah, I think *MutableCollection* as a subtype of *ImmutableCollection* makes sense per Liskov substitution but can seem confusing from the point of view of a programmer not immersed in types.

Guava's enduring contribution to the JVM ecosystem is showing that immutable collections are a thing people want and how they mesh with builder patterns.  Prior to that, there wasn't a lot of experience arguing for collection type hierarchies with a mutable/immutable split.
Mike Samuel
CC BY-SA 4.0
2023-07-11T15:50:11.883Z
@MikeSamuel: `MutableCollection` and `ImmutableCollection` are both subtypes of `ReadableCollection` but niether is a subtype of the other.  If at some time T  one has a reference to an `ImmutableCollection`, and wants a reference to something that encapsulates the state that the referenced object had at time T, a reference to an immutable collection would serve that purpose, no matter what other references exist to the object, but a reference to a MutableCollection would not.
supercat
CC BY-SA 4.0
2023-07-11T15:54:12.003Z
IMHO, the types of reference-type fields should support different kinds of references, indicating whether they hold a sharable reference that encapsulates the target's immutable state, an unshared reference that encapsulates the target's possibly-mutable state, a sharable reference that owns the target and encapsulates its identity, and a reference to a possibly-mutable object owned by some other entity.
supercat
CC BY-SA 4.0
2023-07-11T15:55:52.550Z
Creating an immutable copy of a mutable collection of unshared references that encapsulate state should create immutable copies of all of the objects identified therein, but an immutable copy of a mutable collection of references to objects that are owned by some other entity should simply copy the references as-is.
supercat
CC BY-SA 4.0
2023-07-11T16:20:31.163Z
@supercat, The problem of deep-immutability vs shallow-immutability seems somewhat orthogonal to me.  imo, a lot of that becomes simpler when type authors need to opt into their types having identity.  I shouldn't be able to do pointer comparisons if the type doesn't opt into identity and I'm not using some quasi-unsafe API meant to enable optimization of user-defined equality predicates.  But I digress.
Mike Samuel
CC BY-SA 4.0
2023-07-11T17:07:05.303Z
@MikeSamuel: If one distinguishes the purposes for which objects hold references, then in many situations the proper behavior of copy operations and equality comparisons will be obvious; in some cases, only deep copies would make sense, in others, only shallow copies would make sense, and in some neither would make sense.  If one knows the intended purpose of the reference the copy operation should be producing, and the purposes of the references held directly or indirectly by the object being copied, only one style of operation will usually make sense.
supercat
CC BY-SA 4.0
2023-07-11T17:16:45.890Z
@MikeSamuel: Value-copying an object reference should clone the reference if the object is immutable, or else produce a reference to a copy where any sub-objects references that encapsulate values are value copied, and those that are identify objects owned by outside entities should be reference-copied.  Objects which encapsulate shareable references that own mutable objects should only be value-copyable if they define explicit an expliclt method for such purpose.
supercat
CC BY-SA 4.0
2023-07-11T17:19:49.600Z
@MikeSamuel: From an LSP perspective, a collection of references of unknown kind would be a base type for a collection of references of known (value vs identity) kind, regardless of what the kind was, which would in turn be a base type for for a collection of each known type.
supercat
# Do you need an "Any" type when implementing a statically typed programming language?
Posted by: username_0 on 2023-07-06
As per the comment about Swift having an `Any` type [here](https://langdev.stackexchange.com/questions/2121/how-to-avoid-output-build-bloat-when-wanting-to-access-type-metadata-information) (and my related question in that post, on how to access type metadata at runtime without increasing the output build bloat), and because of the points made [here](https://softwareengineering.stackexchange.com/questions/122205/what-is-the-supposed-productivity-gain-of-dynamic-typing/122212#122212), I am thinking a statically typed language is best for long-term maintainability, even if it comes at the cost of not being able to do as quick of rapid prototyping as a dynamically typed language (like Ruby or JS).

But then languages like Swift just mentioned have the `Any` type, and [Rust has `Any` too](https://doc.rust-lang.org/std/any/trait.Any.html), "a trait to emulate dynamic typing". Why are these added to these languages? What problems do they solve? Are they *necessary* for statically typed languages? If you don't have an `Any` type, what problems will you face?

Basically I'm wondering, to solve my [problem](https://langdev.stackexchange.com/questions/2047/what-are-the-advantages-and-disadvantages-of-making-types-as-a-first-class-value/2120#2120) of having 1.5 megabytes of type information in the output JavaScript build file (if I include dynamic typing / reflection capabilities in the custom lang), should I just cut that feature (runtime type checking and including the type metadata in the runtime build)? Or is it a necessity for certain key situations? It would seem it's a necessity sometimes, because Rust and Swift have the `Any` type, and to do that it seems you'd need to include the type info in the runtime build. I don't have a deep understanding of how the `Any` type really works in Rust or Swift (my main language is JS/TS), so I'm not sure why it was deemed necessary to include.

If you don't **need** an `Any` type, what problems will you face? Wondering at the same time if it would have been better for Rust and Swift to avoid this feature, or if not, what it's solving.
**Tags:** types type-checker runtime
> **Comments:**
> **username_1**: Does C's `void*` (something that can refer to any object, but you have to separately keep track of what type it is, because the language doesn't) count as an "Any" type?  
> **username_2**: I'm fairly sure Swift only has `Any` because it needed some way to represent Objective-C methods that take and return `id`. (Ironically, in modern Swift those no longer use `Any`, and instead `AnyObject`, which is different.)  
> **username_3**: You absolutely do not (many FP languages, such as Haskell and OCaml, don't). Even Java makes a distinction between objects and primitives.  
> **username_4**: @mousetail [std::any](https://doc.rust-lang.org/std/any/index.html)?  
> **username_5**: @Bbrk24, "AnyObject" and "Any" are very very similar, except that "AnyObject" must be an instance of a class, and not for example Integer. Since "id" in Objective-C is always an instance of a class, "AnyObject" would be more precise, but "Any" will just work. The main difference is that you cannot assign say Integer to an "AnyObject" variable.  
> **username_2**: @gnasher729 They are completely different in layout. `Any` is five words, while `AnyObject` is just one.  
> **username_6**: Python has a type `object` that is the superclass of all types. [PEP 483](https://peps.python.org/pep-0483/#summary-of-gradual-typing) has a section describing how `Any` contrasts with `object` to allow for gradual typing.  
---
## 5 answers
### Answer by username_13 on 2023-07-06. Score: 20 | Accepted answer
*Any* is commonly known as a [Top type](https://en.wikipedia.org/wiki/Top_type): a type that is a super-type of every type.

Some strongly typed languages have quite restricted notions of sub-typing, so the concept of top type makes no sense there. For example, languages like SML and Idris allow sub-typing of type variables but not of defined types.

Sub-typing functional languages tend to have top types, but many others don't.

For example, Java. It has a `java.lang.Object` type that is the super-type of all *reference types* like `java.lang.Integer` but is not the super-type of *value types* like `int`, and its `void` type is a special type that can only appear in return position.

Java does have an auto-boxing system; you can often use an `int` where a `java.lang.Integer` is expected and vice-versa, but there are subtleties.

But that doesn't mean you can treat `int` as if it were a sub-type of `java.lang.Object` via `java.lang.Integer`. In that case, you would need to treat an array like `int[]` as a sub-type of `java.lang.Integer[]` which would cause problems because those two types are actually very different.

JVM languages like Scala and Kotlin do manage to have a top type, as you noted, but they do that by being very careful around how their array types map to JVM array types.
> **Comments:**
> **username_3** (2023-07-06): Not related to the actual question, but arrays in general are kinda scuffed in Java. You can treat a `String[]` as an `Object[]` at compile-time, but it'll blow up if you try to put in `Object`s into that casted `String[]` at runtime  
> **username_14** (2023-07-07): it's more that Java's entire type system is horrible. the whole int vs integer because they couldn't figure out how to represent objects without tons of pointers is a horrible mess  
> **username_5** (2023-07-07): In Swift, "Any" is a protocol, not a type. A variable declared as "Any" has a type, but you don't know which one, except you know it follows the "Any" protocol.  
> **username_13** (2023-07-07): @gnasher729 are Swift protocols existential?  
> **username_13** (2023-07-07): @user, yeah.  Java treated arrays as covariant even though they're mutable which is horribly unsound hence the need for *ArrayStoreException*s at runtime.  I think the way other JVM languages balance a top type with their own array types that map to JVM array types is by treating arrays as invariant.  
> **username_15** (2023-07-09): @MikeSamuel: IMHO, Java's mistake was failing to have an abstract "readable array" type with mutable and immutable subclasses (with the latter having a variety of constructors and factory methods that wouldn't expose a reference to the completed object until all members were populated).  A limited form of multiple inheritance should be supported here, since even though neither `ImmutableArray<Animal>` nor `ReadableArray<Cat>` is a subtype of the other, but both should be viewed as supertypes of `ReadableArray<Animal>`.  
> **username_13** (2023-07-11): @supercat, Yeah, I think *MutableCollection* as a subtype of *ImmutableCollection* makes sense per Liskov substitution but can seem confusing from the point of view of a programmer not immersed in types.

Guava's enduring contribution to the JVM ecosystem is showing that immutable collections are a thing people want and how they mesh with builder patterns.  Prior to that, there wasn't a lot of experience arguing for collection type hierarchies with a mutable/immutable split.  
> **username_15** (2023-07-11): @MikeSamuel: `MutableCollection` and `ImmutableCollection` are both subtypes of `ReadableCollection` but niether is a subtype of the other.  If at some time T  one has a reference to an `ImmutableCollection`, and wants a reference to something that encapsulates the state that the referenced object had at time T, a reference to an immutable collection would serve that purpose, no matter what other references exist to the object, but a reference to a MutableCollection would not.  
> **username_15** (2023-07-11): IMHO, the types of reference-type fields should support different kinds of references, indicating whether they hold a sharable reference that encapsulates the target's immutable state, an unshared reference that encapsulates the target's possibly-mutable state, a sharable reference that owns the target and encapsulates its identity, and a reference to a possibly-mutable object owned by some other entity.  
> **username_15** (2023-07-11): Creating an immutable copy of a mutable collection of unshared references that encapsulate state should create immutable copies of all of the objects identified therein, but an immutable copy of a mutable collection of references to objects that are owned by some other entity should simply copy the references as-is.  
> **username_13** (2023-07-11): @supercat, The problem of deep-immutability vs shallow-immutability seems somewhat orthogonal to me.  imo, a lot of that becomes simpler when type authors need to opt into their types having identity.  I shouldn't be able to do pointer comparisons if the type doesn't opt into identity and I'm not using some quasi-unsafe API meant to enable optimization of user-defined equality predicates.  But I digress.  
> **username_15** (2023-07-11): @MikeSamuel: If one distinguishes the purposes for which objects hold references, then in many situations the proper behavior of copy operations and equality comparisons will be obvious; in some cases, only deep copies would make sense, in others, only shallow copies would make sense, and in some neither would make sense.  If one knows the intended purpose of the reference the copy operation should be producing, and the purposes of the references held directly or indirectly by the object being copied, only one style of operation will usually make sense.  
> **username_15** (2023-07-11): @MikeSamuel: Value-copying an object reference should clone the reference if the object is immutable, or else produce a reference to a copy where any sub-objects references that encapsulate values are value copied, and those that are identify objects owned by outside entities should be reference-copied.  Objects which encapsulate shareable references that own mutable objects should only be value-copyable if they define explicit an expliclt method for such purpose.  
> **username_15** (2023-07-11): @MikeSamuel: From an LSP perspective, a collection of references of unknown kind would be a base type for a collection of references of known (value vs identity) kind, regardless of what the kind was, which would in turn be a base type for for a collection of each known type.  
---
### Answer by username_7 on 2023-07-07. Score: 13
# `Any` enables dynamic typing and type erasure in a statically-typed language.

This turns out to be very useful, to the point where even [Haskell](https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Dynamic.html) and [SML](https://www.cs.hmc.edu/%7Eoneill/syb/syb-ml-oneill.pdf) (languages with strong type guarantees and no subtyping) have `Any` equivalents or people working on them. And as mentioned, Rust has [`std::any`](https://doc.rust-lang.org/std/any/index.html) which relies on a compiler extension: the compiler gives runtime-accessible tags to every `'static` type for the sole purpose of supporting it.

* **Reflection AKA runtime metaprogramming** is the main reason for dynamic types in statically-typed language. here are some meta-programming operations which are impossible at compile type, specifically ones which access metadata in private or dynamically-linked libraries. And even when the metaprogramming is possible at compile time, it's often easier to implement at runtime via reflection, because you can implement it in the language itself without creating a multi-phase compiler (a compiler which interprets its own code during compilation).

  + Reflection is one of the big reasons [Java](https://en.wikipedia.org/wiki/Java_(programming_language)#Special_classes) is so popular (see [reflection examples](https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful); also one of the first sentences in the [wikipedia](https://en.wikipedia.org/wiki/Java_(programming_language)#Special_classes), "The Java runtime provides dynamic capabilities (such as reflection and runtime code modification) that are typically not available in traditional compiled languages"). It's also one of the main benefits of dynamic languages like [JavaScript](https://www.javascript.com/), [Python](https://www.python.org/), and [R](https://www.r-project.org/) over static languages like [C](https://en.wikipedia.org/wiki/C_(programming_language))/[C++](https://cplusplus.com/) and [Haskell](https://www.haskell.org/).
  + A big example where reflection comes in handy is debugging. Sometimes even in static languages, you just want to [print something](https://hackage.haskell.org/package/base-4.18.0.0/docs/Debug-Trace.html), particularly a datatype, but sometimes the datatype doesn't have `Debug`, `Show`, or any other `toString` equivalent. In this case reflection is your only option. This is the main reason for [Swift](https://developer.apple.com/swift/)'s [Mirror](https://developer.apple.com/documentation/swift/mirror), a structure which, like Rust's `Any`, relies on a compiler extension.
* The [**expression problem**](https://en.wikipedia.org/wiki/Expression_problem) is another reason why `Any` and downcasting, and specifically polymorphism, are popular. A version of the expression problem states that it's easy for a language to allow users to add *new methods to an existing type* (if the type is an ADT like an enum) or *new overloads to an existing method* (if the type is a non-sealed class), but it's tricky to cleanly allow both. `Any` provides a messy solution to allow both: you can *add new methods* to a non-sealed class which downcast `self` to `Any` and then try upcasting to every known subclass, and you can *add new overloads* to the class as usual, with the additional stipulation that you handle these new subclasses in your methods which downcast to `Any`.

Ultimately, [not all programs can be conveniently represented with static types](https://stackoverflow.com/questions/1251791/what-are-the-limits-of-type-checking-and-type-systems). Notice I said "conveniently" because as [some of the answers](https://stackoverflow.com/a/1251839) point out, you theoretically can encode any program in a statically-typed language, but only by inventing your own dynamic types e.g. by liberally using enums and failable functions. Furthermore, [as the first answer](https://stackoverflow.com/a/3273068) points out, type-checking non-trivial properties requires formal proofs, which are extremely tedious). At these points (when you need enums and failable functions and/or formal proofs), it's much easier to simply upcast the type to "Top" and then downcast at runtime, asserting that the types are ok without a formal proof.
---
### Answer by username_2 on 2023-07-06. Score: 9
Dependency Injection
I wrote a dependency injection library in Swift. It makes use of as! and Any.
I'm not going to go into a detailed description of what DI is and when to use it, but the idea is that you can ask the DI container for an instance of FooProtocol (IFoo for the C# devs out there) and it gives you one. You don't need to worry about where it comes from, and it can easily be changed (e.g. for testing).
In order for this to be possible, the container needs to store, as a vast oversimplification, a bunch of type-instance pairs. However, you can't use Dictionary for a number of reasons. Beyond the fact that that kind of generic container doesn't exist in the language, this doesn't facilitate lazy initialization or weak references.
Surely, I thought, this should be possible! Just start with a protocol:
protocol Registration {
  associatedtype T
  func resolve() -> T
}

and then store an array, [any Registration].
Let's try to implement the lookup function given this.
private var registrations: [any Registration]

func resolve() -> T {
  // I'm using .lastIndex rather than .firstIndex for reasons not important here
  let index = registrations.lastIndex(where: { $0.T == T })!
  return registrations[index].resolve()
}

Seems legit. Except, wait a second, how does that work? The answer is, it doesn't. Go ahead, try it yourself if you don't believe me.
There are really two problems here:

By using lastIndex + subscript, the type system has no way of verifying that resolve() returns the correct type. Indeed, the subscript returns an any Registration, so Swift marks resolve() as returning Any.
This is arguably a Swift-specific implementation problem, except that...
Determining whether $0.T == T relies on the exact kind of type information you want to eliminate!

There are more reasons I chose to do it this way, such as being backwards-compatible with earlier versions than iOS 16.
I tried for weeks to eliminate as! and Any from that codebase, all to no avail. Some of it was restricted by limitations of Swift itself, but even if I managed to remove all explicit casts, there'd still have to be type comparisons somewhere.
---
### Answer by username_8 on 2023-07-07. Score: 6
[Any](https://devblogs.microsoft.com/cppblog/stdany-how-when-and-why/) is mostly useful in the libraries that internally need to work with arbitrary data records, like some "user data object" on some library - managed data structure. It is the further evolution of the smart pointer:

* A smart pointer knows how to safely delete the object.
* `Any` also knows about the type of the object, and how to copy it.

If you have knowledge about the type being stored, `Any` is not the proper tool. If all possible types that could be stored are known, a `Variant` is a better container for them, and for the single type value that may also be missing, an `Optional` may be offered.
---
### Answer by username_9 on 2023-07-08. Score: 1
The accepted answer already explains that you do not need it in your language. However, you'll need it in your compiler to get to a somewhat sane architecture. Otherwise, you wouldn't be able to process something like "true ? new Object : 7" in Java 1.4 or your compiler would have to quit on first error.
If you have it anyway in your compiler, you can expose it to the user.

However, in languages that are close to the hardware, i.e. the representation of int is something like 4 bytes that can reside in a register instead of having everything boxed on the heap, there is no way to *represent* any. Thus, such a language might have `any`, but it wouldn't allow you to use it everywhere.
> **Comments:**
> **username_10** (2023-07-08): I don't see how that claim about the compiler follows at all. Compilers with great error checking have been written in C and Ada, which don't have an Any type.  
> **username_9** (2023-07-08): The language used to implement the compiler is not relevant. I'm talking about a data structure or type representation for any in the processed language.  
> **username_11** (2023-07-08): The argument from compiler design is completely fallacious.  A compiler can handle ill-typed expressions like that in many other ways — e.g. tagging them as a type error.  “Type them as ‘Any’, or quit immediately” is a massively false dichotomy.  And “If you have it anyway in your compiler, you can expose it to the user.” is just as dubious — compilers do many things (such as handling possibly ill-typed code) which you want to be outlawed in the object language, exactly so that the object language can provide type-safety guarantees.  
> **username_9** (2023-07-09): "Tag it as error" is the same thing as introducing an any type to a language that doesn't have one as you need to introduce some processable data to continue there. You could also call that type error or poison or whatever, but it will always be an any type. While I agree that "expose what you have" is dubious from design perspective, it is how things work from my experience.  
> **username_10** (2023-07-10): An error type has no dynamic semantics; that is wildly different from an Any type.  
> **username_9** (2023-07-12): The point, I'm trying to make here, is that the code required in the compiler to treat them is mostly the same in many cases.  
> **username_12** (2023-07-24): Compiling an expression like `true ? new Object() : 7` in Java doesn't require a top type; it requires finding a least-upper-bound (in this case, of `Object` and `int`) and if that fails, it tries again with more type conversions allowed (including boxing conversions).  
---
