# \[Pitch\] Amend SE-0368 to remove prefix \`+\` operator

**URL:** <https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173>\
**Category:** Pitches\
**Created:** [December 22, 2022, 12:21am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173 "2022-12-22T00:21:05Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [December 22, 2022, 12:21am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/1 "2022-12-22T00:21:05Z")

</div>

[SE-0368](https://forums.swift.org/t/se-0368-staticbigint/59421) included the following operation on `StaticBigInt`:

```swift
/// Returns the given value unchanged.
public static prefix func + (_ rhs: Self) -> Self

```

This was included so that prefix `+` could be included as a literal prefix _in contexts where values are desired to be type `StaticBigInt`, rather than literals of another type_, for symmetry with `-`:

```swift
let signs: [StaticBigInt] = [-1, 0, +1]

```

It turns out that this was a source breaking change, because of examples like the following:

```swift
let a: Int = 7
let b = +1 // Inferred as `StaticBigInt` because concrete `+` beats
               // the generic one on `AdditiveArithmetic`
let c = a + b // Error: Cannot convert `b` from `StaticBigInt` to `Int`

```

(Previously, `b` was given type `Int`, and this example compiled correctly.)

I propose amending SE-0368 to remove this operator. This is a minor inconvenience for code that wants to use `StaticBigInt` values, but:

- no such code exists today, because the type doesn't exist in 5.7.
- such code can omit the leading `+` as a workaround.
- we can investigate other options to restore the desired syntax at our leisure once the source break is resolved.

There's a PR showing the proposed change here: [Remove prefix+ from StaticBigInt by stephentyrone · Pull Request #62733 · apple/swift · GitHub](https://github.com/apple/swift/pull/62733)

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [December 22, 2022, 12:36am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/2 "2022-12-22T00:36:24Z")

</div>

This makes sense to me!

Doug

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [December 22, 2022, 12:52am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/3 "2022-12-22T00:52:52Z")

</div>

The right long-term solution here is probably to recognize a leading `+` on a numeric literal as part of the literal rather than an operator applied to a literal, the same way that it works for leading `-`. There's certainly a possibility that that would have source-compatibility consequences of its own, though.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [December 22, 2022, 1:00am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/4 "2022-12-22T01:00:10Z")

</div>

It would at least not have _this particular_ consequence, and I agree that it's probably the right thing to do.

---

<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:** [December 22, 2022, 2:06am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/5 "2022-12-22T02:06:33Z")

</div>

> [@scanon](#):
>
> we can investigate other options to restore the desired syntax at our leisure once the source break is resolved.

A kludgy but not entirely preposterous workaround which would deliver on the goals here without removing functionality would be to put this operator on equal footing by moving it to an extension of an underscored `_StaticBigIntProtocol` to which only this type conforms.

Agree entirely on the longterm solution and wouldn’t be fussed if we didn’t have this, but worth pointing out that there is a path which would maintain support for the desired syntax. It’s not elegant but it doesn’t actually make anything worse IMO.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [December 22, 2022, 2:35am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/6 "2022-12-22T02:35:05Z")

</div>

Unlike functions, we can’t emit protocols into client, so we’d be stuck with the kludge forever.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [December 22, 2022, 2:40am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/7 "2022-12-22T02:40:44Z")

</div>

> [@scanon](#):
>
> ```swift
> let b = +1 // Inferred as `StaticBigInt` because concrete `+` beats
> // the generic one on `AdditiveArithmetic`
> 
> ```

if the default `IntegerLiteralType` is `Int`, and `+(1 as Int)` typechecks, why isn’t the `1` inferred to be type `Int`?

---

<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:** [December 22, 2022, 2:41am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/8 "2022-12-22T02:41:25Z")

</div>

> [@scanon](#):
>
> Unlike functions, we can’t emit protocols into client, so we’d be stuck with the kludge forever.

Indeed, that is part of the kludginess.

I wonder, though, if we _could_ add this as an always-emitted-into-client extension method of `ExpressibleByIntegerLiteral`.

It should lose out to the existing method owing to the protocol hierarchy, and it closely reflects our intention to support this syntax for all integer literals.

If possible, _that_ would be kinda elegant as far as kludges go.

---

<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:** [December 22, 2022, 2:43am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/9 "2022-12-22T02:43:39Z")

</div>

> [@taylorswift](#):
>
> if the default `IntegerLiteralType` is `Int`, and `+(1 as Int)` typechecks, why isn’t the `1` inferred to be type `Int`?

Concrete parameter types win out here over default literal type resolution; right or wrong we couldn’t change this without risking (possibly widespread) unanticipated changes in inferred type.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [December 22, 2022, 2:45am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/10 "2022-12-22T02:45:11Z")

</div>

Yes, that’s plausible. However, for 5.8 my preference is to simply remove the operation, as we’ve already branched.

---

<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:** [December 22, 2022, 2:50am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/11 "2022-12-22T02:50:18Z")

</div>

Entirely fair—am curious to prototype this for the main branch though. Might mean that we can achieve substantially most or all of our desired end goal without mucking around with parsing.

---

<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:** [December 22, 2022, 3:36am UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/12 "2022-12-22T03:36:02Z")

</div>

I am going to regret this, because I have every expectation that something will go wonky that we don't currently expect, but I'm now convinced after having played around with this idea that we _should_ add the method to `ExpressibleByIntegerLiteral` (in a near-future version)—for the reason you've outlined here, because it's actually a bit more generally applicable than we'd like to think maybe:

_Any_ well meaning person who's designing an `ExpressibleByIntegerLiteral` type and who wants to have their users enjoy every convenience that built-in integer literal types can offer, adding this `static prefix func +` to their own type, will inadvertently mess up default integer literal type inference in the same way we have here. We shouldn't leave this trap for people, penalizing the most conscientious API designers and their users.

There are ~~two~~ three fixes here of varying degrees of finality, which are not mutually exclusive:

1. We can make prefix `+` Just Work™ for all integer literal types by adding these extension methods to `ExpressibleByIntegerLiteral`; users won't need to write their own and so they're unlikely to try unless they're seeking actively to be evil
2. We can also, or instead, add these to all concrete built-in integer and floating-point types, like we do with homogeneous comparison operators and for the same reason (i.e., to "win" overload resolution): this will work, it's precedented, and we can make it all `@_alwaysEmitIntoClient`, but it's a lot of code to generate and it's kludgy, and it leaves the responsibility to end users to add this to their own custom types
3. We can revamp parsing so that `+` is part of the literal—which could break other things and doesn't entirely make (1) or (2) superfluous (someone might want to write `+x` (note the non-literal), and we do currently provide this for free for arithmetic types, and there's not really a reason to take this away for non-arithmetic integer literal expressible types)

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [December 22, 2022, 7:57pm UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/13 "2022-12-22T19:57:52Z")

</div>

i feel like i really need to be devils advocate here and ask:

_do we really need this?_

we have many things in the standard library that have low, but non-zero utility, such as `isMultiple(of:)` ([SE-0225](https://github.com/apple/swift-evolution/blob/main/proposals/0225-binaryinteger-iseven-isodd-ismultiple.md)). but prefix `+` stands out to me because it quite literally _does nothing_.

my instinct when using something like prefix `+` is to check the godbolt to make sure that it really is compiling to a no-op, and when i’m going to the trouble of verifying a zero-cost abstraction is really a ZCA it usually needs to meet at least one of the following criteria:

1. it improves readability, or

2. it improves type safety.

prefix `+` has no type safety benefits. and i don’t think prefix `+` improves readability either, it is just visual noise, and it’s especially jarring if you are using an editor with semantic highlighting, because `-` is “literal”-colored, but `+` is “function”-colored.

and even if you are a fan of prefix `+`, it’s not like `StaticBigInt` is meant to be a commonly-used type. `StaticBigInt` is a shim that library authors use to bootstrap actual user-facing numeric types, like [`KeyValuePairs<Key, Value>`](https://swiftinit.org/reference/swift/keyvaluepairs) is used to bootstrap ordered collections. i think it is a very rare use case that someone would be passing a `StaticBigInt` to an API.

---

<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:** [December 22, 2022, 10:56pm UTC](https://forums.swift.org/t/pitch-amend-se-0368-to-remove-prefix-operator/62173/14 "2022-12-22T22:56:05Z")

</div>

> [@taylorswift](#):
>
> do we really need this?

I would suggest that this is not the correct question to ask: we already have this for all numeric types, and it cannot be removed—the question is, then, only whether it can be made to work consistently.

> [@taylorswift](#):
>
> and even if you are a fan of prefix `+`, it’s not like `StaticBigInt` is meant to be a commonly-used type

Yup, I think we can all agree it’s fine that we don’t have this working on `StaticBigInt` for the moment.
