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.
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 &
.