Search code examples
swiftfunctional-programming

Behaviour of inout within Swift operators


I'm playing around with some functional programming and defining operators in Swift and noticed this quirk which confused me. If I have a generic function which takes in an inout operator and passes it to a function:

func operatorEquivalent <A> (input: inout A, function: (inout A) -> Void )
{
    function(&input)
}

then I call it like so:

operatorEquivalent(&myStruct, myInoutFunction) 

with the ampersand.

But if the the generic function is translated to an operator like so:

infix operator >!

func >! <A> (input: inout A, function: (inout A) -> Void )
{
    function(&input)
}

then I call this operator like so:

myStruct >! myInoutFunction

without the ampersand.

Could anyone explain why this is so and / or point to any documentation on this detail? Curious.


Solution

  • The &-prefixed expression is called a in-out expression. As the Swift language reference says, this is only used when you pass inout parameters to function call expressions.

    An in-out expression marks a variable that’s being passed as an in-out argument to a function call expression.

    The expression myStruct >! myInoutFunction is not a function call expression. It is an infix expression, which doesn't require special syntax for passing inout parameters.

    I suspect one of the reasons why it is this way comes down to aesthetics. With compound assignment operators, the code looks more C-like with such a design. Compound assignment operators have their first parameter declared as inout. For example, see AdditiveArithmetic.+=:

    static func += (lhs: inout Self, rhs: Self)
    

    Arguably, the code would look rather weird if you had to add an extra & and write &foo += x instead of foo += x. The idea of adding & in the first place is to indicate that the call might change the argument. One could argue that with operators like +=, the intent is already clear, even without &.