# \[Pitch\] Reflection

**URL:** <https://forums.swift.org/t/pitch-reflection/61438>\
**Category:** Pitches\
**Tags:** reflection\
**Created:** [November 14, 2022, 11:01pm UTC](https://forums.swift.org/t/pitch-reflection/61438 "2022-11-14T23:01:52Z")\
**Posts on this page:** 1\
**Showing post:** 39

<div class="post-metadata">

**Author:** ![Alejandro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro/32/46197_2.png) [@Alejandro](https://forums.swift.org/u/Alejandro)\
**Post date:** [December 2, 2022, 7:00am UTC](https://forums.swift.org/t/pitch-reflection/61438/39 "2022-12-02T07:00:23Z")

</div>

> [@Slava\_Pestov](#):
>
> I only have a minor aesthetic comment. I think "partial type" is a non-standard term for this, can we call it a "type constructor" or "generic type" or something instead?

I agree partial type is maybe not the best name for this thing. I think type constructor would be a good name if that's the only thing this did (which is pretty much the only thing it does _right now_). I imagine in the future if we wanted to inspect "generic requirements of a generic type", then this would probably happen on partial types and wouldn't make sense with the name type constructor. Generic type is an interesting name because it fits nicely with the use case above, but it gets a little weird because the type doesn't necessarily need to be generic to have a "GenericType" (e.g. Int has a "GenericType"). That being said, I'm all ears for a better name 🙂

> [@Philippe\_Hausler](#):
>
> Is there space for consideration for reflection into key paths? For example recently I have found the need to split up a key path into its constituent components and iterate down them. I think there are probably a few nifty tools we could use in that range of thing. Or is that out of scope of this?

Keypath introspection is definitely a much requested featured and I imagine we'll eventually want to be able to do that (either directly on keypaths, or some new facility in this Reflection module). I've held off on designing anything that space so far and only focused on what's being proposed.

> [@AlexanderM](#):
>
> Could we do a comparison of design choices, names, etc. and see if there's anything we can learn from their first-mover positions?
> 
> - 600 ⭐ [Zewo/Reflection](https://github.com/Zewo/Reflection) (Now deprecated, but was popular nonetheless)
> - 234 ⭐ [Azoy/Echo](https://github.com/Azoy/Echo)
> - ... any others?

The second library on that list happens to be one I made a couple of years ago 🙂 That library is intended to be a low level interface to the Swift runtime which allows for higher level APIs like the ones being proposed. The first library has some similarities (`Property` vs `Field`), but it looks like it was mostly used to get/set properties via string name (which one can do here by comparing `Field.name` and using `Field.keyPath`) and construct instances of types at runtime (using unsafe bits that doesn't always work).

> [@benrimmington](#):
>
> `Reflection.Type` can be initialized from either a metatype or an instance, but will the latter ignore a `CustomReflectable` conformance? Should the initializers be failable, in case the `-disable-reflection-metadata` option has been used?

`-disable-reflection-metadata` removes the reflective capabilities of `Field` and `Case`, so every other API available on `Type` and `PartialType` would still work because it uses information required by the runtime (not strippable).

> [@benrimmington](#):
>
> Like the `MemoryLayout.offset(of:)` method, should the `Field.offset` property fail by returning `nil` rather than zero? Should the other `MemoryLayout` APIs (size, stride, alignment) be added to `Reflection.Type`?

Yeah, `Field.offset` should probably return nil in that case. We can for sure add all of the `MemoryLayout` APIs and more onto `Reflection.Type`, but it does feel redundant because you can get the same info from 2 separate facilities.

> [@benrimmington](#):
>
> Would `[AnyHashable: Any]` or `[Never: Never]` be more appropriate than `[Int: Int]` in the `PartialType` examples? Should the textual representation also include placeholders (e.g. `"Dictionary<_, _>"`)? Instead of the `name` properties, could there be `description` and `debugDescription` properties, for unqualified and qualified names?

Yeah, those placeholder types are probably better to use than `[Int: Int]`. Thanks! Having the placeholder in the textual representation is also a nice improvement here. I made the textual representation a separate API under `name` because I was unsure how common it is to access a type's `description`, but if people think that's a better place to put this, then by all means 🙂 I imagine `description` would look like `Type<_, _>` and `debugDescription` could look like `Module.Outer<_>.Type<_, _>`?

> [@benrimmington](#):
>
> To avoid confusion between metatypes and metadata, I suggest renaming:
> 
> - `Type` to `Metadata`
> - `Type.swiftType` to `Metadata.type`
> - `Field.type` to `Field.metadata`
> - `Case.payloadType` to `Case.metadata`
> 
> The `@usableFromInline` internal APIs should probably be removed from the detailed design, but the `index` and `tag` might be useful as public APIs. The `@frozen` and `@inlinable` attributes could also be removed for readability.

I included all of the `@usableFromInline`, `@inlinable`, and `@frozen` as part of the detailed design because I wanted evolution to clearly see what we're committing to as ABI. As you can see, `Type` stores a value of type `Metadata` which is why I didn't name it as such (that API will be proposed at a later date).

---

_[View the full topic](https://forums.swift.org/t/pitch-reflection/61438)._
