# Anonymous Structs

**URL:** <https://forums.swift.org/t/anonymous-structs/31424>\
**Category:** Pitches\
**Created:** [December 6, 2019, 6:11pm UTC](https://forums.swift.org/t/anonymous-structs/31424 "2019-12-06T18:11:14Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 11, 2019, 9:56am UTC](https://forums.swift.org/t/anonymous-structs/31424/81 "2019-12-11T09:56:21Z")

</div>

> [@Karl](#):
>
> Equatable for closures is cool, but I'm not sure how useful it would be in practice given the `Self` type constraint and limitations that come with opaque types. As I understand it, each anonymous struct would be a different type, so you would only be able to test a closure with itself (essentially only checking its captures for equality).

To be able to compare different closures, you'll need to wrap each into a container similar to `AnyHashable`, or in the future `any Hashable`.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [December 11, 2019, 10:03am UTC](https://forums.swift.org/t/anonymous-structs/31424/82 "2019-12-11T10:03:44Z")

</div>

> [@Nickolas\_Pohilets](#):
>
> To be able to compare different closures, you'll need to wrap each into a container similar to `AnyHashable` , or in the future `any Hashable` .

But it would be useless anyway, because different anonymous closures wouldn't be equal even if they have the same data.

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 11, 2019, 10:11am UTC](https://forums.swift.org/t/anonymous-structs/31424/83 "2019-12-11T10:11:44Z")

</div>

Thats the intention. If you think of them as closures - they may capture the same data, but may execute different code on that data.

Structurally analysing closure bodies is too much, IMO. This penaltizes only copy-pasted code. If one needs the similar closures to compare as equal - it is always possible to extract a function.

---

<div class="post-metadata">

**Author:** ![TellowKrinkle](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tellowkrinkle/32/3370_2.png) [@TellowKrinkle](https://forums.swift.org/u/TellowKrinkle)\
**Post date:** [December 11, 2019, 11:05pm UTC](https://forums.swift.org/t/anonymous-structs/31424/84 "2019-12-11T23:05:40Z")

</div>

I think the optimization gets much harder once you store the closure and let it sit around for a while, since you have to know where the closure was made to do optimizations on it. Extra hard once you store it in a struct. I think the difference is similar to the difference between `View` and `some View`, which we just added to address the same problem in existentials (even if you can do the optimization when you send it through a function, we have trouble doing it when we store it in a struct)

---

<div class="post-metadata">

**Author:** ![ryansobol](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ryansobol/32/2983_2.png) [@ryansobol](https://forums.swift.org/u/ryansobol)\
**Post date:** [December 11, 2019, 11:16pm UTC](https://forums.swift.org/t/anonymous-structs/31424/85 "2019-12-11T23:16:50Z")

</div>

> [@anandabits](#):
>
> We shouldn't have to resort to a fully written out type all we need is a simple ad-hoc conformance.

Why?

Rhetorically speaking, the Motivation section of this proposal didn’t sufficiently or articulately answer this question, at least to me.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [December 12, 2019, 4:21pm UTC](https://forums.swift.org/t/anonymous-structs/31424/86 "2019-12-12T16:21:17Z")

</div>

Sure, I get the difference between an existential and a generic type. My question is why this needs new language syntax -- why does the compiler suddenly have this information necessary for unboxing if I write a `{{ ... }}` rather than `{ ... }`?

That's really the thing I still don't _entirely_ understand. From what @Joe_Groff said, my understanding is that he would essentially like to transform closure-taking functions in to generic ones (like the `ExistentialSpecializer` does), and give some closures (but not all of them?) individual representation in the type system, so the functions can be specialised.

And my issues are:

- Why not just make all closures "anonymous structs" internally? Why the new syntax?
- (new) How is this different from inlining?

So, it's my understanding that a function body is required for specialisation (i.e. same module or `@inlineable`). Even with this proposal, you would only _actually_ see unboxing if the closure-taking call's body was available and able to be specialised. So why not just make the inliner more aggressively inline closures?

---

<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:** [December 12, 2019, 4:38pm UTC](https://forums.swift.org/t/anonymous-structs/31424/87 "2019-12-12T16:38:00Z")

</div>

As I read it, no new syntax is being proposed, only the generalization of closure syntax into matching generic contexts. Indeed, closures are effectively anonymous types internally, and this could be a way of exposing the context type to the programming model.

> [@Karl](#):
>
> So, it's my understanding that a function body is required for specialisation (i.e. same module or `@inlineable` ). Even with this proposal, you would only _actually_ see unboxing if the closure-taking call's body was available and able to be specialised. So why not just make the inliner more aggressively inline closures?

Specialization and unboxing are separable concerns. Variables of generic type are still unboxed even if they aren't specialized. A closure context formed for a protocol conformance, similarly, would be storable in-line even if its body is not available for inlining, since its type information would be able to propagate.

---

<div class="post-metadata">

**Author:** ![Syre](https://avatars.discourse-cdn.com/v4/letter/s/cdc98d/32.png) [@Syre](https://forums.swift.org/u/Syre)\
**Post date:** [December 12, 2019, 8:46pm UTC](https://forums.swift.org/t/anonymous-structs/31424/88 "2019-12-12T20:46:24Z")

</div>

I think we should consider this syntax alternative (or some other alternative which still uses the struct keyword):

`let eq = struct _: Equatable { [x, var y = x + 1] }`

It makes it clear that this is a struct, not a closure.

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [December 12, 2019, 8:52pm UTC](https://forums.swift.org/t/anonymous-structs/31424/89 "2019-12-12T20:52:39Z")

</div>

I agree that this proposal would be better if _ **every** _ form of anonymous struct started with the keyword `struct`, regardless of how abbreviated the rest of the syntax might be.

OTOH, I'm not a fan of requiring the `:` there or the `_`. Instead, how about something like:

```swift
let eq = struct { [x, var y = x + 1] } : Equatable

```

with the understanding, of course, that the conformance could be omitted if it can be inferred.

---

<div class="post-metadata">

**Author:** ![Brad\_Hilton](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/brad_hilton/32/5169_2.png) [@Brad\_Hilton](https://forums.swift.org/u/Brad_Hilton)\
**Post date:** [December 12, 2019, 11:38pm UTC](https://forums.swift.org/t/anonymous-structs/31424/90 "2019-12-12T23:38:54Z")

</div>

I can definitely see the value here. Being able to provide inline types conforming to protocols would be great. My initial feeling is that the syntax is too close to closures. I'd prefer either using existing `struct` or `tuple` syntax to make it more clear. For example:

```swift
// `struct` syntax
let equatable: some Equatable = {
  let x = 0;
  let y = 4;
}
// `tuple` syntax
let equatable: some Equatable = (x: 0, y: 4)

```

Just using existing `struct` syntax out of the box would allow more flexibility:

```swift
let stringConvertible: CustomStringConvertible = {
  var description: String { "Hello, world" }
}

```

I'm not sure how I feel about using trailing closure syntax and automatically conforming to protocols with a single required method with closure syntax. It could make code difficult to reason about and potentially ambiguous.

---

<div class="post-metadata">

**Author:** ![Les\_Pruszynski](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/les_pruszynski/32/797_2.png) [@Les\_Pruszynski](https://forums.swift.org/u/Les_Pruszynski)\
**Post date:** [December 13, 2019, 5:17am UTC](https://forums.swift.org/t/anonymous-structs/31424/91 "2019-12-13T05:17:03Z")

</div>

> [@Brad\_Hilton](#):
>
> I'd prefer either using existing `struct` or `tuple` syntax to make it more clear.

Anonymous Structs stop being anonymous if you use any of those words.

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [December 13, 2019, 5:54am UTC](https://forums.swift.org/t/anonymous-structs/31424/92 "2019-12-13T05:54:42Z")

</div>

They are anonymous if they are unnamed. Keywords don't name them.

---

<div class="post-metadata">

**Author:** ![haikuty](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/haikuty/32/5652_2.png) [@haikuty](https://forums.swift.org/u/haikuty)\
**Post date:** [December 13, 2019, 9:41am UTC](https://forums.swift.org/t/anonymous-structs/31424/93 "2019-12-13T09:41:01Z")

</div>

> [@anandabits](#):
>
> Yes, it is captured by value in a stored property named `x`

This part kind of threw me since Swift closures capture by reference by default (unlike Objective C blocks). I just spent too much time chasing a bug because of the difference between ObjC and Swift in this regard. That made me think that having it be different between closures and anonymous structs in Swift would be potentially confusing.

---

<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:** [December 13, 2019, 1:52pm UTC](https://forums.swift.org/t/anonymous-structs/31424/94 "2019-12-13T13:52:49Z")

</div>

There were some interesting suggestions in this thread. Well an 'unnamed' struct might look like this.

```swift
struct {
  let x = 42
}

```

So why not use the `struct` or `class` keywords before the curly brackets?

```swift
let x = 0
let eq: any Equatable = struct { 
  [x] // capturing list
  let y = 42 // normal properties that can't capture from outer context 
}

```

It's simple, signals its intent right away and allows for anonymous struct private storage.

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 14, 2019, 12:38am UTC](https://forums.swift.org/t/anonymous-structs/31424/95 "2019-12-14T00:38:03Z")

</div>

This proposal covers two things:

- closures conforming to protocols
- anonymous structs

Which are combined into single proposal because closures conforming to protocols are implemented as anonymous structs.

But from this thread I see that trying to combine two into single syntax is causing a lot of confusion.

So, let's try to take a step back and separate them.

* * *

## Part 1. Closures conforming to protocols

That's a much simpler case, and I was able to work out a pretty complete proposal document - [swift-evolution/proposals/NNNN-closures-as-structs.md at master · nickolas-pohilets/swift-evolution · GitHub](https://github.com/nickolas-pohilets/swift-evolution/blob/master/proposals/NNNN-closures-as-structs.md).

## Part 2. Anonymous structs and classes

I'm trying to rework this to look more similar to Java's anonymous classes. Roughly like this:

```swift
protocol Foo {
    var x: Int { get }
    var y: Int { get set }
    func doIt()
}
let x = 0
let eq = struct Equatable & Foo {
    var x = x
    var y = x + 1

    func doIt() {
        print("doing...")
    }
}

```

If protocol requirements can be inferred from the context, they can be omitted. Trailing syntax is supported similar to closures.

```swift
func use<T: Equatable & Foo>(_ x: T) { .. }
f() struct {
    var x = x
    var y = x + 1

    func doIt() {
        print("doing...")
    }
}

```

Classes are supported too. I think anonymous classes might be an answer to lack of private protocol conformance in Swift:

```swift
// Need to retain somewhere, because `scrollView.delegate` is weak.
weak var zelf = self
self.scrollViewDelegate = class UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        zelf?.updateUI(offset: scrollView.contentOffset)
    }
}
scrollView.delegate = self.scrollViewDelegate

```

There are still 2 major open questions:

- syntax for calling `super.init` for classes
- disambiguating `self` and `Self` for both structs and classes.

For the last one simplest strategy would be to let `self` and `Self` to always refer to the anonymous struct/class and use workaround like in example above to use `self` from parent context.

Regardless of the disambiguation strategy properties of `self` from parent context are available by their name with `self`. But if they are used inside a closure, compiler require explicit self.

---

<div class="post-metadata">

**Author:** ![curt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/curt/32/1961_2.png) [@curt](https://forums.swift.org/u/curt)\
**Post date:** [December 14, 2019, 6:28am UTC](https://forums.swift.org/t/anonymous-structs/31424/96 "2019-12-14T06:28:14Z")

</div>

I think looking to anonymous inner classes in Java for inspiration is an excellent idea. That was what came to mind immediately when I read the proposal.

FWIW, Java uses “qualified `this`” to reference the outer object, spelled `OuterTypeName.this`. That’s wordy for Swift, but maybe better than `weak var zelf = self`? 🙂

---

<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:** [December 14, 2019, 8:46am UTC](https://forums.swift.org/t/anonymous-structs/31424/97 "2019-12-14T08:46:20Z")

</div>

I thought about that form and decided against it because it will confuse the compiler for sure, or it least make it difficult to parse user code correctly.

```swift
let eq = struct Equatable { ... }

```

Is this an anonymous struct `Equatable` or an attempt to shadow the `Equatable` protocol? There are `let eq =` tokens, but is this really what we want the compiler to look for to disambiguate the two different scenarios?

Therefore I prefer to use `any` or `some` keywords.

```swift
let eq: some Equatable = struct { ... }

```

---

<div class="post-metadata">

**Author:** ![laszlokorte](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/laszlokorte/32/13974_2.png) [@laszlokorte](https://forums.swift.org/u/laszlokorte)\
**Post date:** [December 14, 2019, 11:33am UTC](https://forums.swift.org/t/anonymous-structs/31424/98 "2019-12-14T11:33:06Z")

</div>

In Java it would be `new Equatable() { ... };`. Swift has no `new` keyaord but still uses `()` for constructor calls. So directly translateted it would be `let eq = Equatable() { ... }`

---

<div class="post-metadata">

**Author:** ![Jean-Daniel](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jean-Daniel](https://forums.swift.org/u/Jean-Daniel)\
**Post date:** [December 14, 2019, 11:59am UTC](https://forums.swift.org/t/anonymous-structs/31424/99 "2019-12-14T11:59:56Z")

</div>

It does not work with composition (and Java don't support it).

```swift
   let eq = struct Equatable & MyProtocol { }

```

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [December 14, 2019, 4:35pm UTC](https://forums.swift.org/t/anonymous-structs/31424/100 "2019-12-14T16:35:36Z")

</div>

Just thinking out loud.

### Option 0.

`self` inside anonymous stuct/class always refers to the instance of the anonymous struct/class. If self from the parent context needs to be captured - you need to store in a local variable.

### Option 1.

Anonymous structs/classes don't have their own `self`. `self` always refers to the instance of the named struct/class.

### Option 2.

`OuterTypeName.self` is already reserved in Swift - this returns a type object. This cannot be used.

### Option 3.

`self as OuterTypeName`. This gives a false promise that `self` of anonymous struct/class may be casted to `self` of the parent scope dynamically.

### Option 4.

Captured variables a turned into stored properties, probably with the same name. So, if `self` from parent scope would be captured, this would create a property with name ``self``, which would be escaped by backticks to distinguish from the keyword. For a moment I though that backticks could be used to disambiguate between keyword `self` referring to instance of anonymous struct/class and ``self`` referring to the `self` captured from the parent scope. But it is not that simple.

First of all, to capture `self` from the outer scope you need to refer to the `self` inside the anonymous struct/class. But when referring to ``self`` you are not really referring for `self`.

Second - what if there is already ``self`` in the parent scope? Nested anonymous structs/classes would produce such situation. If backticks would work somehow, probably it would be something like ``self`.`self`` to refer to `self` from grand-parent scope. And this leads us to

### Option 5.

Let `self` refer to the innermost struct/class, and `self.self` to the `self` from the parent scope, `self.self.self` to the `self` from grand-parent scope, etc.

* * *

### Summary

Out of this zoo, I think realistic ones are 0, 1, and 5

[Previous page](https://forums.swift.org/t/anonymous-structs/31424.md?page=4)

[Next page](https://forums.swift.org/t/anonymous-structs/31424.md?page=6)
