# \[Pitch\] \`With\` functions in the standard library

**URL:** <https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716>\
**Category:** Pitches\
**Created:** [June 20, 2023, 10:53pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716 "2023-06-20T22:53:40Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![Jeehut](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeehut/32/21743_2.png) [@Jeehut](https://forums.swift.org/u/Jeehut)\
**Post date:** [July 3, 2023, 4:16pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/43 "2023-07-03T16:16:30Z")

</div>

I think there's a real problem to solve here for more concise code. But I don't like the solution, I find it counter-intuitive having to reach into a global function called `with`. I'd much rather have a function called `with` that I can call on an instance of any type.

I actually defined a `Withable` protocol in my open-source library HandySwift [here](https://github.com/FlineDev/HandySwift/blob/main/Sources/HandySwift/Protocols/Withable.swift#L11-L17) which looks like this:

```plaintext
public protocol Withable { /* no requirements */ }

extension Withable {
  public func with(_ config: (inout Self) throws -> Void) rethrows -> Self {
    var copy = self
    try config(&copy)
    return copy
  }
}

```

Usage is like this, which I find much more intuitive:

```plaintext
let components = URLComponents().with { components in
  components.path = "foo"
  components.password = "bar"
}

```

The only downside is, you have to make any type you want to call it on to conform to `Withable` like so:

```plaintext
extension URLComponents: Withable {}

```

It's easy but inconvenient. If baked into the language, the conformance could become unnecessary.

---

<div class="post-metadata">

**Author:** ![ExFalsoQuodlibet](https://avatars.discourse-cdn.com/v4/letter/e/bbce88/32.png) [@ExFalsoQuodlibet](https://forums.swift.org/u/ExFalsoQuodlibet)\
**Post date:** [July 3, 2023, 6:01pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/44 "2023-07-03T18:01:55Z")

</div>

> [@Jeehut](#):
>
> The only downside is, you have to make any type you want to call it on to conform to `Withable`

It's the only downside, but it's a very major one that ultimately lead me and my team to abandon this approach, and use an operator instead.

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [July 3, 2023, 6:06pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/45 "2023-07-03T18:06:04Z")

</div>

I mentioned this in the future directions.

---

<div class="post-metadata">

**Author:** ![tourultimate](https://avatars.discourse-cdn.com/v4/letter/t/85f322/32.png) [@tourultimate](https://forums.swift.org/u/tourultimate)\
**Post date:** [July 3, 2023, 7:33pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/46 "2023-07-03T19:33:22Z")

</div>

I like the general idea but not a fan of the name `with`. Even [objective-c name translation rules have a rule about that particular function name and the like](https://github.com/apple/swift-evolution/blob/main/proposals/0005-objective-c-name-translation.md#pruning-restrictions), calling it "absurdly vacuous":

> - **Never transform a name into "get", "set", "with", "for", or "using"** , just to avoid creating absurdly vacuous names.

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [July 3, 2023, 7:43pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/47 "2023-07-03T19:43:23Z")

</div>

I don't really think that applies here. `With` is a vacuous name, but the function is also vacuous; it does a very simple thing implied by the name `with`. A longer name seems pointless and self-defeating.

```swift
withMutableCopy(of: 5) {
 $0 += 2
}

```

It does seem like a lot of people aren't happy with the name `with`. A few names have been proposed in this thread.

- `with`
- `modify`
- `modifying`
- `mutated`
- `modified`
- `mutate`
- `withMutableCopy`

In addition, people have proposed various alternate solutions to this problem.

- A global function
- A magical extension on `Any`
- An operator paired with dynamic member lookup and key paths
- The builder pattern
- An operator paired with a closure

It seems like most of the people in this thread can agree that this functionality could be useful, but not exactly how to do it. I picked a free function because, since it was a small change, it seemed more likely to pass through Swift Evolution. And I picked the name `with` because of its existing use in the standard library. However, all of these proposed solutions have merit; should we add more than one to the standard library? Otherwise, which one should we pick?

---

<div class="post-metadata">

**Author:** ![austintatious](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@austintatious](https://forums.swift.org/u/austintatious)\
**Post date:** [July 4, 2023, 3:59am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/48 "2023-07-04T03:59:27Z")

</div>

I kinda think `.` would be a better operator and allowing the closure that follows to start its lookup by default on the object it is being run 'on'.

```swift
UIView().{
     frame = .init(x: 0, y: 0, width: 100, height: 100)
     backgroundColor = .blue
}

```

---

<div class="post-metadata">

**Author:** ![austintatious](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@austintatious](https://forums.swift.org/u/austintatious)\
**Post date:** [July 4, 2023, 4:44am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/50 "2023-07-04T04:44:25Z")

</div>

What was the reason using `.` would’t be possible? Does it cause some sort of unresolvable interference?

> [@anon9791410](#):
>
> But you can't do that

I understand it can’t be used as a custom operator because it’s reserved , but I think ultimately this should’t just be a function in the standard library but rather a whole new language feature.

Of course I haven’t put enough thought into it to realize any interference with current syntax.

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [July 4, 2023, 5:17am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/51 "2023-07-04T05:17:01Z")

</div>

> [@austintatious](#):
>
> Does it cause some sort of unresolvable interference?

Not exactly. But with an operator, you can use a named closure.

```swift
URLComponents()…mutateURLComponents

func mutateURLComponents(_ components: inout URLComponents) {
  components.path = "foo"
  components.password = "bar"
}

```

Just `.` would require parentheses, because it's the same syntax that properties or methods-as-closures use. I.e.

```swift
URLComponents().(mutateURLComponents)

```

---

<div class="post-metadata">

**Author:** ![sspringer](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sspringer](https://forums.swift.org/u/sspringer)\
**Post date:** [July 4, 2023, 6:23am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/52 "2023-07-04T06:23:27Z")

</div>

It was mentioned a few times but nonetheless I would like to emphasize the following:

You would also like to be able to change a value by _appending_ something to the according expression.

Also you would like to do it in a way that cannot be confused with an `if ` block, e.g. when using `applying(…)` instead of the `&>` operator:

```plaintext
if let x = myValue?.getOtherValueFromValue().applying({ otherValue in
    otherValue.property1 = propertyValue
}) {
   …
}

```

The `with` syntax would not allow an elegant chaining, and I am not sure about the block of the `&>` operator in the context of `if`.

As general remark I would be cautious to not only use one simple application as the only use case. _It should be considered how it composes in different, also more complex situations._

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [July 4, 2023, 1:27pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/53 "2023-07-04T13:27:41Z")

</div>

If extensions on `Copyable` are allowed, we could declare it that way; since the function involves a copy it wouldn't make sense for a non-copyable type.

```swift
extension Copyable {
  public func with(transform: (inout Self) throws -> Void) rethrows -> Self {
    var copy = self
    transform(&copy)
    return copy
  }
}

```

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 4, 2023, 5:36pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/54 "2023-07-04T17:36:56Z")

</div>

> [@aggie33](#):
>
> If extensions on `Copyable` are allowed

`Copyable` is spelled `Any`, and extensions are not allowed.

---

<div class="post-metadata">

**Author:** ![christopherweems](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/christopherweems/32/22736_2.png) [@christopherweems](https://forums.swift.org/u/christopherweems)\
**Post date:** [July 4, 2023, 7:10pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/55 "2023-07-04T19:10:59Z")

</div>

I'm using this as just an overload on `&&`.

```swift
public func &&<T>(_ value: T, modifications: (inout T) throws -> Void) rethrows -> T {
    var value = value
    try modifications(&value)
    return value
}

```

and in use:

```swift
let spellOutNumberFormatter = NumberFormatter() && {
    $0.numberStyle = .spellOut
}

```

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [July 4, 2023, 7:12pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/56 "2023-07-04T19:12:03Z")

</div>

Adding an overload to such a commonly used operator might cause regressions in compile time, but it does remove the need to add a new operator.

---

<div class="post-metadata">

**Author:** ![austintatious](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@austintatious](https://forums.swift.org/u/austintatious)\
**Post date:** [July 5, 2023, 12:29am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/57 "2023-07-05T00:29:52Z")

</div>

I see.

I think what I am suggesting is that we just introduce new syntax altogether. Something like `.` followed by a closure.

So instead of having to even define any of this:

```swift
extension UIView {
     @discardableResult func with(_ closure: (UIView) -> ()) {closure(self); return self}
}

let view = UIView().with({$0.backgroundColor = .red})

```

you could just write

```swift
let view = UIView().{
   backgroundColor = .red
}

```

Maybe `.{` automatically calls some function called something like `with(_ closure:)` if you want to provide additional customization. Otherwise the compiler just synthesizes it for you.

Would that solve a lot of this?

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [July 5, 2023, 4:28am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/58 "2023-07-05T04:28:06Z")

</div>

The `.{` syntax has some drawbacks compared to `with`:

- The `.{` syntax has to be implemented in the compiler, which makes it harder to understand than the `with` function. You can ask Xcode (or, I assume, other IDEs) to navigate to the `with` function's documentation or definition in a way that is not (currently) possible with syntax like `.{`. Furthermore, the `with` function is a short function, written in Swift, and uses only very old, mainstream parts of the language. IMHO, it should not take long for any new Swift programmer to understand all of the concepts involved and be able to understand the function's definition completely. Syntax built in to the compiler cannot be learned this way.

- The `.{` syntax, as suggested, either replaces `self` in the scope chain, or inserts a new scope in the scope chain. I'm not sure which is being suggested. Either way, it makes it more difficult to understand where any (leading) identifier used in the block is defined. An IDE can help here, but not needing to ask the IDE for help is even better. If it inserts a new scope in the scope chain, then it is (ironically) much like the deprecated, widely criticized [JavaScript `with` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with).

- The `.{` syntax, as suggested, makes the properties of the receiver shadow names that would otherwise be in scope. Here's an example from one of my projects. I use the `with` function like this:

- You can pass a function that's not a literal to the `with` function. That is, if you already have a function `mutations` with signature `(inout Value) -> Void`, you can say `with(x, update: mutations)`. There's no obvious way to do this with the `.{` syntax; you can only use a closure literal. FWIW, of the dozens of calls to `with` I found in a few of my projects, only one passes a non-literal function, so this is a pretty minor complaint.

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [July 5, 2023, 4:54am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/59 "2023-07-05T04:54:07Z")

</div>

> [@mayoff](#):
>
> There's no obvious way to do this with the `.{` syntax; you can only use a closure literal.

I addressed this in my last post. This thread seems to be oversaturated and will therefore very sadly not go anywhere. Unsubscribing. 😿🫠

---

<div class="post-metadata">

**Author:** ![austintatious](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@austintatious](https://forums.swift.org/u/austintatious)\
**Post date:** [July 5, 2023, 5:13am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/60 "2023-07-05T05:13:54Z")

</div>

I think it would be pretty clear that at least left hand side identifiers are properties/functions of the object on which `.{` is called since that is precisely what the purpose of the syntax is for.

> [@mayoff](#):
>
> But with the `value.{ block }` syntax, I cannot access `init`'s `calendar` parameter inside the block:

In the same way that `self.something` is used to disambiguate similar situations, `$0.something` would be required to disambiguate in those conditions.

---

<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:** [July 5, 2023, 7:22am UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/61 "2023-07-05T07:22:51Z")

</div>

> [@ExFalsoQuodlibet](#):
>
> > [@anon9791410](#):
> >
> > While I've been using this operator for about 7 years, the fact that `|>` _is_ used is not evidence that it's a good choice. It doesn't look like anything. And the `|` portion implies "or", which isn't actually part of what it does.
> 
> I agree, personally I think operator shapes are purely conventional, the "way they look" is completely subjective to me.

> [@](#):
>
> I consider the pipe operator `|>` state of art, and it's used extensively in functional languages like `F#` and `Elixir`, and I think the shape comes from the fact that `|` is the pipe operator in Unix, and the `>` simply suggest a flow to the right.

Also, all major coding fonts render this a right pointing triangle, here are some:

- [Fira Code](https://github.com/tonsky/FiraCode)
- [Hasklig](https://github.com/i-tu/Hasklig)
- [Jetbrains Mono](https://www.jetbrains.com/lp/mono/)
- [Iosevka](https://github.com/be5invis/Iosevka)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 18, 2023, 9:37pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/62 "2023-07-18T21:37:19Z")

</div>

### Language steering group guidance

As various ideas related to this topic have percolated since at least 2016, the language steering group discussed if any guidance might help the discussion to coalesce.

Consensus among the steering group is that we wouldn't entertain something like a non-semantic `Withable` protocol to circumvent the restriction against extending `Any`. While it's true that arbitrary members can't be added to all types via an extension in the standard library, a restriction we're comfortable maintaining, there _is_ precedent for simulating such a member via built-in "magic": besides `self`, we've added the `keyPath` subscript in [SE-0161](https://github.com/apple/swift-evolution/blob/main/proposals/0161-key-paths.md). A `with` feature—_if_ adopted—would likely become a part of idiomatic Swift usage; so, if a convincing case is made that the best design for this feature would have it spelled as a member, it'd be justifiable to take a similar implementation approach. We'd prefer a fair consideration of the merits of a free function versus a member here (whether spelled `with` or some other name) not to be clouded by this implementation detail.

As a group, we're not yet sure that we'd all reject an operator spelling off the bat, but a _very_ convincing argument would have to be made for why it's clearly superior to alternative designs. Our concerns are several: (1) Existing standard library operators are largely well-known from C-family languages (or, in the case of `&`-prefixed operators, are deliberately more esoteric "flavors" of well-known operators). From that vantage, it's hard to imagine that any operator for this feature would have the readability of a spelled-out word. Indeed, lately, the direction of the language has favored pronounceable words (`repeat each T`) over punctuation (`...T`). (2) Any succinct enough sigil could start to look like line noise with broad adoption. Part of a convincing argument would, in our view, include a robust selection of realistic code examples that demonstrate how well a proposed operator spelling would perform as compared to a free function or method. (3) The addition of a single operator can immediately invite consideration of filling out a whole family of related operators, and we don't think that would be desirable here.

Could this be a language feature—a `with` statement, in other words? The steering group ultimately considered the implications of using compiler "magic" beyond simulating `extension Any` to be undesirable. In particular, we think any feature proposed should take a _bona fide_ closure: we'd like to avoid inventing language rules that are unique in Swift to create some DSL-like block here, such as rebinding `self` as some of Kotlin's scope functions do. We understand that at least a contingent of developers who've used such features in other languages find them to be confusing sharp edges.

Lastly, a variation of this feature that takes its argument `inout` has also been proposed. We'd avoid this sort of design so as not to expose idiomatic ways to "hide" mutations in a chain of operations. The situation is analogous to assignment operators, which do not return a value in Swift (unlike most C-family languages). Moreover, any `inout` version of the proposed feature would require the user already to have a mutable binding "on hand" that they could mutate directly, and we expect `inout` bindings to address use cases where one might want to repeatedly mutate some deeply nested member.

— Xiaodi Wu, on behalf of the language steering group

---

<div class="post-metadata">

**Author:** ![aggie33](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aggie33/32/29896_2.png) [@aggie33](https://forums.swift.org/u/aggie33)\
**Post date:** [July 18, 2023, 11:02pm UTC](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716/63 "2023-07-18T23:02:40Z")

</div>

So, basically...

```swift
// free function
with(NumberFormatter()) { formatter in
  formatter.numberStyle = .spellOut
}

// magical method
NumberFormatter().with { formatter in 
  formatter.numberStyle = .spellOut
}

// operator | not recommended without a convincing argument
NumberFormatter() &> { formatter in
  formatter.numberStyle = .spellOut
}

// inout version | not recommended
var formatter = NumberFormatter()
with(&formatter) { formatter in
  formatter.numberStyle = .spellOut
}

// statement | undesirable
NumberFormatter().{
  numberStyle = .spellOut
}

```

[Previous page](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716.md?page=2)

[Next page](https://forums.swift.org/t/pitch-with-functions-in-the-standard-library/65716.md?page=4)
