# Associate result builders with types

**URL:** <https://forums.swift.org/t/associate-result-builders-with-types/77476>\
**Category:** Pitches\
**Tags:** result-builder\
**Created:** [January 27, 2025, 10:14am UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476 "2025-01-27T10:14:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [January 27, 2025, 10:14am UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/1 "2025-01-27T10:14:40Z")

</div>

Some types and protocols are strongly associated with a result builder (`View` and its `@ViewBuilder` from SwiftUI comes to mind, but there are several others).

In a `View` conforming type you need to remember to decorate your private `→ some View` returning functions with `@ViewBuilder` or you'll get compilation errors if you introduce e.g. conditionals.

In the following code, the commenting in or our the line causes the code to compile, or not compile. It is almost always the intention of the user to use `@ViewBuilder` on this function:

```swift
struct MyView: View {
  // ...

  private func buttonRow() -> some View {
    if condition {
       HStack {
         createButton("Foo", true, "fooo")
         createButton("Yes", true, "yeees")
         // createButton("Bar", false, "barrrr")
       }
    } else {
       HStack {
         createButton("Qux", true, "quiz?")
         createButton("Frup", true, "frappapapapapp")
         createButton("Boik", false, "boioioink")
       }
    }
  }
}

```

Shold Swift have some mechanism of associating a result builder with a type or protocol, so that all of these syntaxes Just Do The Rigth Thing?

```swift
// auto-apply @HTMLBuilder to functions that return
// `some` protocols with associated result builder?
func foo() -> some HTML { ... }  

// auto-apply @HTMLBuilder and infer return value when
// constructing values with a closure?
let html = HTML { ... }

```

These ideas are not mature, I'm not sure if we should just apply the attribute to the type (currently resultbuilders aren't applicable on types or extensions):

```swift
@HTMLBuilder
protocol HTML { ... }

```

Or maybe some `associatedtype`-magic?

I'm not sure. But Do you think the idea has merit?

---

<div class="post-metadata">

**Author:** ![ellie20](https://avatars.discourse-cdn.com/v4/letter/e/6f9a4e/32.png) [@ellie20](https://forums.swift.org/u/ellie20)\
**Post date:** [January 28, 2025, 6:38pm UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/2 "2025-01-28T18:38:02Z")

</div>

I think this has merit. I shared my thoughts on something like this a while ago:

> [@Result builder attributes in types](https://forums.swift.org/t/result-builder-attributes-in-types/66304):
>
> Right now, result builder attributes can be added to protocol requirements, properties, and functions. This pitch allows result builder attributes to be added to types. For example, a hypothetical HTML type that comes with an HTMLBuilder result builder can be annotated like so: @HTMLBuilder struct HTML { ... } or in an extension: @HTMLBuilder extension HTML { ... } A result builder attribute on a type does the following: Closure syntax (including trailing closure syntax) can be used to con…

I think in addition to what you said, there is another benefit in associating result builders with types, which is that it could allow for more natural function signatures. To quote that post:

> **Quote**
>
> > [@Result builder attributes in types](https://forums.swift.org/t/result-builder-attributes-in-types/66304/1):
> >
> > Another problem is that functions are often forced to use unnatural type signatures. Library authors often make use of trailing closures to allow for convenient syntax using result builders. For example, we might want to add a `link(to:label:)` function to let users form hyperlinks like so:
> > 
> > ```swift
> > func link(to: URL, label: @HTMLBuilder () -> HTML) -> HTML {
> > ...
> > }
> > 
> > let html = HTML {
> > link(to: "https://www.example.com") {
> > span {
> > "my link label"
> > }
> > }
> > }
> > 
> > ```
> > 
> > Currently, the `link` function is forced to use a function type for its argument, even though conceptually, it just takes a `label` of type `HTML` by value. This comes with some drawbacks:
> > 
> > - Users are forced to think about result builders to make their own functions that take `HTML` arguments with convenient syntax. The function signature can be cumbersome to write, especially when writing multiple of these functions.
> > - The function cannot be called with a variable, literal, or other expression without it being wrapped in a closure (without overloads). For example, we might want the `HTML` type to conform to `ExpressibleByStringLiteral` for convenience, so the user can use a string literal instead:
> > 
> > ```swift
> > link(to: "https://www.example.com", label: "my link")
> > 
> > ```
> > 
> > With a result builder attribute on the `HTML` type, the function signature becomes easier to understand:
> > 
> > ```swift
> > func link(to url: URL, label: HTML) -> HTML
> > 
> > ```

---

<div class="post-metadata">

**Author:** ![Pippin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pippin/32/24826_2.png) [@Pippin](https://forums.swift.org/u/Pippin)\
**Post date:** [January 28, 2025, 8:22pm UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/3 "2025-01-28T20:22:20Z")

</div>

> [@sveinhal](#):
>
> `auto-apply`

I wish that result builders and other attributes were required on protocol conformers rather than being implicitly applied. When I was learning about result builders it took me a while to understand why something like `body` didn’t require `ViewBuilder` but all of my variables and functions did. I think that implicitly hiding a declaration like this would make result builders even more “magic” and equally more frustrating for everyone.

---

<div class="post-metadata">

**Author:** ![flexlixrup](https://avatars.discourse-cdn.com/v4/letter/f/50afbb/32.png) [@flexlixrup](https://forums.swift.org/u/flexlixrup)\
**Post date:** [January 28, 2025, 9:29pm UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/4 "2025-01-28T21:29:48Z")

</div>

I have to say, I haven’t been working much with `ResultBuilder` before besides SwiftUI so I cannot comment on any advantages of implicitly applying it or not.

I can just say that I apply `@ViewBuilder` to any var or func that is part of a SwiftUI view so I can easily see what is UI and what not, so just from the looks perspective, I prefer it staying there explicit.

If there are some more technical differences, I‘m happy to change my opinion though.

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [January 29, 2025, 1:56am UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/5 "2025-01-29T01:56:12Z")

</div>

> [@sveinhal](#):
>
> Shold Swift have some mechanism of associating a result builder with a type or protocol, so that all of these syntaxes Just Do The Rigth Thing?

I like the premise that this case is probably well diagnosable by the compiler, yet I am hesitant about implicit behaviour there. Maybe I don’t want builder there. I think it would make a ton of difference if compiler could suggest as fix-it to add an annotation in such cases.

---

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [January 30, 2025, 8:15am UTC](https://forums.swift.org/t/associate-result-builders-with-types/77476/6 "2025-01-30T08:15:54Z")

</div>

Yes, the more I think about it, I also see the downsides of implicitly applying attributes to functions. I'm especially sympathetic to the point raised by @flexlixrup above, that seeing the `@ViewBuilder` attributes makes code more glanceable, and I do think we should prioritize readable code, over easy to write code.

But the problem that subtle differences in a function implementation can render code uncompilable is certainly real. Could we somehow allow the type to be decorated, and that it mostly affects compiler diagnostics?

I.e. that a e.g. `HTML`-returning (or `some HTML`-returning) function could get better diagnostics if the `HTML` was decorated with `@HTMLBuilder`, or had an `associatedtype ResultBuilder = HTMLBuilder`?
