I was just experimenting with some Swift code samples and by making a mistake I’ve found our very weird behaviour (to me) that I don’t understand.
I’ve defined this function:
func makeIncrementer(number: Int) -> ((Int) -> Int) {
func incrementer(inputNumber: Int) -> Int {
return inputNumber+1
}
return incrementer
}
*yes, the parameter number in not used, that was unintentional mistake, but lead to finding out this weird behaviour I’m asking now.
Then I called the code:
let functionVariable = makeIncrementer(number: 7)
print(functionVariable)
print(functionVariable(7))
which resulted in this output:
(Function)
8
after this I realized that the number parameter in makeIncrementer function does not make sense, so I’ve deleted the parameter in makeIncrementer invocation, but xCode didn’t show any error message. So I just tried to rebuild this:
let functionVariable = makeIncrementer(number: )
print(functionVariabl
print(functionVariable(7))
And I’ve received this output:
(Function)
(Function)
Here are my questions:
- How is it possible it can be built? Parameter number is not optional, or is it?
- Even if the parameter number would be optional, how can it result in two objects that are type of function?
Thank you very much for a explanation
2
Answers
In your second example you aren’t calling the function, but assigning it to the variable using its overload identifier. This is also why it is printing
(Function)
twice; the first is the original function, the second is the returned curried function.Here is an example defining an overload for your function that accepts a
String
showing thatlet functionVariable1 = makeIncrementer(number:)
is assigning the specific overload of your function that accepts anInt
to the variable. Calling this variablefunctionVariable1(4)
now no longer needs (and won’t accept) a parameter label, and returns your curried function. Thus, callingprint(functionVariable1(4)(11))
will now print the input + 1 as expected.For function definitions that accept more than one parameter you can list parameter labels sequentially to assign to a variable, this also removes the need for labels in later calls.
This code
causes
functionVariable
to point to yourmakeIncrementer(number:)
function, not to a call to that function. (That syntax is a function signature, not a call to a function.If you then execute this code:
You’ll tell
incrementer
to give you its result function (With a throw-away value of 7), and then pass that function the value 3. Thus the result will be to print the value 4.you should declare your code like this:
That does what you intend: In the line
let incrementer = makeIncrementer()
you are callingmakeIncrementer()
, and it is returning an incrementer function.The output of
print(incrementer(3))
will be to print "4" as you are expecting.