[swift-evolution] Proposal: Allows operator overloads in struct or classes based on return type

Tommaso Piazza tommy.piazza at ymail.com
Sun Dec 11 04:30:28 CST 2016

Hello Derrick,
I did not think of this as a bug but rather as an intentional limitation that to me seems a little odd.
Yes, overloads 2,3 have at least ONE operand of type NonEmptyArray so when declared as static function on NonEmptyArray they work fine. However Overload 1 just mentions NonEmptyArray in the return type. I propose that it should also be allowed as a static function on NonEmptyArray.
As for the why it should be allowed my motivation is that all overloads that mention NonEmptyArray in their type signature should be allowed to be declared in the same namespace.Or one could argue that no overloads should be declarable inside NonEmptyArray. 
However this comes at a price.
Note that because overload 1 in the current situation must be left out of NonEmptyArray, the accessor modifier for properties and function in NonEmptyArray is fileprivate.With the change I propose this is no longer the case and the modifier is just private.
    On Sunday, December 11, 2016 5:49 AM, Derrick Ho <wh1pch81n at gmail.com> wrote:

 I placed he code you wrote in the proposal in playgrounds and it works perfectly.  (reproduced below). Overloading operators used to only happen globally and since swift 3 they allowed you to put then inside the class/struct
public struct NonEmptyArray<Element> {

    fileprivate var elements: Array<Element>

    fileprivate init(array: [Element]) {
        self.elements = array

//Overload 1
public func •|<Element>(lhs: Element, rhs: [Element]) -> NonEmptyArray<Element> {
    return NonEmptyArray(array: rhs + [lhs])

//Overload 2
public func •|<Element>(lhs: Element, rhs:  NonEmptyArray<Element>) -> NonEmptyArray<Element> {
    return NonEmptyArray(array: [lhs] + rhs.elements)

//Overload 3
public func •|<Element>(lhs: NonEmptyArray<Element>, rhs: NonEmptyArray<Element>) -> NonEmptyArray<Element> {
    return NonEmptyArray(array: lhs.elements + rhs.elements)
However, as you have detailed when you place those overloads inside the struct/class, it does not work.  Actually I get an error that says that at least ONE of the arguments needs to be the same type.  In this case one of them needs to be NonEmptyArray<Element>. It is clearly not a bug, but rather a swift rule.
My recommendation is to just keep those overloads as global.  Is there a particular advantage to putting them inside the struct/class?

On Sat, Dec 10, 2016 at 8:36 PM David Sweeris via swift-evolution <swift-evolution at swift.org> wrote:

On Dec 10, 2016, at 5:29 PM, David Sweeris via swift-evolution <swift-evolution at swift.org> wrote:

On Dec 10, 2016, at 4:54 PM, Tommaso Piazza via swift-evolution <swift-evolution at swift.org> wrote:
I have written a small proposal that would allow overloads of operators in structs/classes non only based on the types of the operands but on the return type as well.
Please let me know you thoughts,/Tommaso

That seems like a bug to me… Dunno, maybe it’s intentional and I’m just not aware of the reasoning.

Actually, since the error message correctly parses the code, it probably is intentional… I don’t see the problem, myself, but I guess I’d have to know why it’s considered an error before judging whether I think we should remove the restriction.
- Dave Sweeris_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161211/1d3e62ba/attachment.html>

More information about the swift-evolution mailing list