# Some small keypath extensions: identity and tuple components

**URL:** <https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729>\
**Category:** Pitches\
**Created:** [June 15, 2018, 9:55pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729 "2018-06-15T21:55:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [June 15, 2018, 9:55pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/1 "2018-06-15T21:55:54Z")

</div>

There two small gaps in key paths that'd be nice to fill in:

- There's no way to form an identity key path today, short of writing a property definition. The identity keypath is useful to be able to pass to APIs that take a key path to describe what part of a value to manipulate in order to say "all of it", among other things. We have the magic `.self` member in every type, and we could conceivably spell the identity key path that way, as `\.self`. The identity keypath would be a `WritableKeyPath<T, T>`, and appending an identity key path would be an identity operation, so that `(\.self).appending(x) == x` and `x.appending(\.self) == x`.
- Tuple elements should be allowed in key paths, either labeled or indexed, and form `WritableKeyPath<(..., T, ...), T>` values.

Of course, there are infinite other features that could be considered, but I'd like to focus on these two because they're small incremental features that fit easily into the current model. The identity key path also would need a small amount of runtime support to get the correct appending behavior that would be good to get into the runtime before it stabilizes. How does this sound?

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [June 16, 2018, 10:11pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/2 "2018-06-16T22:11:43Z")

</div>

+1 on both concepts, and the second one seems like obvious goodness. For the first one, I hope we can find a more clear way of expressing this. I get what you're going for with .self, but that is an ObjC thing, not a Swift thing.

---

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [June 17, 2018, 12:27pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/3 "2018-06-17T12:27:24Z")

</div>

`\.self` sounds clear enough to me: it's very similar to the `self` property available on types and both can be chained:

```swift
\.self.self.self.self == \.self
self.self.self.self == self

```

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [June 17, 2018, 4:40pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/4 "2018-06-17T16:40:03Z")

</div>

But keypaths apply to instances, right? Objective-C has a self member for instances, but Swift does not.

---

<div class="post-metadata">

**Author:** ![beccadax](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/beccadax/32/34217_2.png) [@beccadax](https://forums.swift.org/u/beccadax)\
**Post date:** [June 17, 2018, 5:04pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/5 "2018-06-17T17:04:38Z")

</div>

`print(1.self)` works fine. Maybe that’s a keyword rather than a real property, but that’s real enough for me.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [June 17, 2018, 5:37pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/6 "2018-06-17T17:37:45Z")

</div>

Currently, it's allowed to declare

```
var `self`: T

```

Aside from the question wether that is a good idea or not, I'd prefer a solution that simply can't interfere with real properties.  
Forbidding "self" as a member name would be one way around that issue, the other would be a string that can never be the name of a property.  
`\.` is probably the most obvious one (and if Swift would use slashes instead of points for path separation, Unix guys would feel home right away ;-)

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [June 18, 2018, 5:37pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/7 "2018-06-18T17:37:53Z")

</div>

The quoted identifier ``self`` is different from the keyword `self`, though. I agree that `\.self` is not the ideal syntax, especially because with an explicit root type it looks like `\T.self`, which is only one character away from a type value reference `T.self`. Ideally, if we ever get around to revisiting [SE-90](https://github.com/apple/swift-evolution/blob/master/proposals/0090-remove-dot-self.md), we would be able to kill the `.self` member entirely. `\.` is cute but maybe a little mysterious. What about a static member of `AnyKeyPath`?

```swift
extension AnyKeyPath {
  static func identity<T>() -> WritableKeyPath<T, T>
}

```

This would let you write `.identity()` in context where a `KeyPath` or any subclass thereof is expected.

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [June 18, 2018, 8:12pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/8 "2018-06-18T20:12:17Z")

</div>

In a current discussion about single element tuples there was mention of this thread, and a suggestion to use `\.0` as the identity keypath element, [here](https://forums.swift.org/t/roadmap-for-and-state-of-single-element-tuple-types/13711/17).  
This would effectively be coercing `T` to an unlabeled single element tuple `(T)` getting it's first element, and coercing back to `T`, except unlabeled single element tuples don't exist.  
And even labeled single element tuples only exist in some parts of the compiler.

---

<div class="post-metadata">

**Author:** ![jberry](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jberry/32/6360_2.png) [@jberry](https://forums.swift.org/u/jberry)\
**Post date:** [June 19, 2018, 3:22pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/9 "2018-06-19T15:22:50Z")

</div>

> [@Joe\_Groff](#):
>
> `\.` is cute but maybe a little mysterious

Personally, I think `\.` is short, sweet, and, erhm, to the point! More to the point, perhaps, it seems easy to come up with: it's the first thing I'd think of for how to spell the identity keypath, and I could remember it rather than having to google for how to spell it otherwise. When you first suggested this concept my first thought was "hmm, too bad it can't be spelled `\.` because that would be so obvious."

---

<div class="post-metadata">

**Author:** ![zoul](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/zoul/32/9559_2.png) [@zoul](https://forums.swift.org/u/zoul)\
**Post date:** [June 19, 2018, 3:28pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/10 "2018-06-19T15:28:20Z")

</div>

FWIW, `\.` was the first thing I have tried some time ago when I wanted the identity path and was wondering if that’s supported.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [June 19, 2018, 3:30pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/11 "2018-06-19T15:30:57Z")

</div>

> [@Joe\_Groff](#):
>
> `\.` is cute but maybe a little mysterious.

Agree, but it's worth considering. It is somewhat reminiscent of using `.` to refer to the current working directory. That analogy might be enough to help people remember what it means.

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [June 19, 2018, 11:59pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/12 "2018-06-19T23:59:54Z")

</div>

One theoretical downside to `\.`, besides the cryptic nature, is it makes more partially-written code valid. Probably not a big deal in practice though, especially since keypaths are a somewhat niche feature at the moment.

---

<div class="post-metadata">

**Author:** ![nonsensery](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nonsensery/32/4317_2.png) [@nonsensery](https://forums.swift.org/u/nonsensery)\
**Post date:** [June 21, 2018, 6:23pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/13 "2018-06-21T18:23:02Z")

</div>

I also like "`.`" for the identity key path.

Since appending the identity key path is an identity operation, it seems this would be valid syntax:

```swift
let keyPath = \Person.....address......city......

```

It might be worth considering how the compiler treats expressions like that.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [June 21, 2018, 8:06pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/14 "2018-06-21T20:06:20Z")

</div>

Can we add support for static members into the bucket of small extensions?

```swift
struct MyType {
  static var staticMember = "swift"
}

\MyType.Type.staticMember

```

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [June 21, 2018, 8:17pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/15 "2018-06-21T20:17:28Z")

</div>

That would require some more infrastructure to support. I would prefer to focus on these two, as I noted in the original post.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [June 21, 2018, 8:19pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/16 "2018-06-21T20:19:30Z")

</div>

No objection, but I‘d wish to see it in Swift 5 though. 🙂

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [June 22, 2018, 3:51pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/17 "2018-06-22T15:51:35Z")

</div>

FWIW, I ran into a use case yesterday where the identity key path is exactly what I need. I can work around not having it, but it would be much better if I didn't have to. 🙂

---

<div class="post-metadata">

**Author:** ![plorenzi](https://avatars.discourse-cdn.com/v4/letter/p/bc8723/32.png) [@plorenzi](https://forums.swift.org/u/plorenzi)\
**Post date:** [June 23, 2018, 10:40am UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/18 "2018-06-23T10:40:05Z")

</div>

About small improvements to key paths, it would be nice to know if a key path is a property (like \Value.field) or a sub-property (like \Value.field.subField). And to be able to decompose a key path if it is a sub-property.

I needed that once, when I handled lazy-loading with key paths. To lazily load the sub-property of a value, you have to lazily load the property then the sub-property. So you need the decomposition of the key path.

---

<div class="post-metadata">

**Author:** ![bob](https://avatars.discourse-cdn.com/v4/letter/b/ea666f/32.png) [@bob](https://forums.swift.org/u/bob)\
**Post date:** [June 23, 2018, 8:35pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/19 "2018-06-23T20:35:10Z")

</div>

I prefer a bare `\` for the identity KeyPath. My rationale:

- It feels like root, akin to the `/` directory
- Unlike `\.`, it obeys the rule that, textually, you append one KeyPath to another by adding a dot and the attribute name, e.g., the `name` of `\.father` is `\.father`_`.name`_. Accordingly, if you iteratively stripped away attributes in that KeyPath, you'd be left with `\.father.name` → `\.father` → `\` .

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [June 25, 2018, 5:14pm UTC](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729/20 "2018-06-25T17:14:26Z")

</div>

Key path decomposition would be another thing that's straightforward to add to the current implementation, but I'd appreciate if we could discuss it as a separate topic.

[Next page](https://forums.swift.org/t/some-small-keypath-extensions-identity-and-tuple-components/13729.md?page=2)
