0

Ola,

Let's say that there is a function named fnOuter(name:String, mks:Double...). I want this function to return another function which I could separately write like fnInner(msg:String)->(String, Double, Double, Character). How one could achieve this? I am a newbie to Swift and tried out the following. But ultimately it ends up with function 'std' was used as a property; add () to call it thrown by the Swift compiler. What am I doing wrong here? How could I fix this? Or is this even possible?

func fnRetFn(name:String, mks:Double...) -> (() -> ((String, Double, Double, Character))){
    var msg = "Hello " + String(name) + "!"

    func calculate() -> (String, Double, Double, Character){
        var total:Double = 0.0
        var i: Double = 0.0
        for mk in mks{
            total += mk
            i += 1
        }

        var avg = total / i

        var grd : Character
        if avg >= 75.0{
            grd = "A"
        }

        else if avg >= 55.0{
            grd = "B"
        }

        else{
            grd = "F"
        } 

        return (msg, total, avg, grd)
    }

    return calculate
}

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn
print("\(std.0)")
print("\(std.1)")
print("\(std.2)")
print("\(std.3)")

Edit 1 Please note that the fnInner(msg:String) should return a tuple, not another function.

4
  • 2
    Add parentheses to actually call the function: var std = outputFn(), as the compiler suggests. Commented Nov 15, 2016 at 9:26
  • @MartinR Thank you for the prompt response. The thing is, I want fnInner() to return a tuple, not a function. Pardon me that this was not clear in the initial question. Commented Nov 15, 2016 at 9:32
  • I am aware of that, and it does not change what I said above. – Did you try it? Commented Nov 15, 2016 at 9:33
  • Yup. That works. I have tried it previously. What I can't figure out is why do I have to call it? Why isn't it accessible like we do when we return a tuple instead of a function (i.e. std.0 instead of std().0). Commented Nov 15, 2016 at 9:40

1 Answer 1

2

With

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn

both outputFn and std are references to the same function which was returned by fnRetFn(...):

print(std) // (Function)

To call the function you'll have to append the argument list in parentheses. For a function taking no arguments that is the empty list ():

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn()

And now std is the tuple returned from calling the "inner" function:

print(std) // ("Hello Mike!", 162.5, 81.25, "A")
print(std.0, std.1, std.2, std.3) // Hello Mike! 162.5 81.25 A

(Unrelated to your problem, but note that both variables should be constants declared with let.)

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @MartinR. I figured out the mistake I have done. I have missed to put on parenthesis in the outputFn() call. I realized it only when I read up to the second line of your answer. Thanks again for enlightening me. You saved my day... :)
@MartinR "Unrelated to your problem, but note that both variables should be constants declared with let" almost the best part of it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.