Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

writing my first function without help... but now I need help

I just finished the Swift Functions course and am practicing writing functions before moving on to Objects. However, I ran into a pickle. I'm creating a function that automatically updates a "to do" list with two strings. But Xcode gives me the following error: " Missing return in a function expected to return 'String'. Can anyone help me fix my code WITHOUT telling me what to write?

var todoList: [String: String] = ["Monday": "Take out garbage", "Tuesday": "Study", 
"Wednesday": "Clean room", "Thursday": "Call parents", 
"Friday": "Do finances", "Sunday": "Cook for the week"]

func add(toDay x: String, withTask y: String) -> String {

    todoList.updateValue(y, forKey: x)
    print(todoList)

}

add(toDay: "Saturday", withTask: "Iron your bed")

7 Answers

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Hi there! For what it's worth, I think you're doing fantastic. The error you got from the compiler is actually very informative. It is expecting a string to be returned by the function. It's expecting this because you explicitly said there would be a String returned. You have a function named add which accepts two strings. Then you have stated that there will be a String returned. This is the -> String part. That's what indicates what type of value is being returned by the function. However, your function contains no return statement nor does it really need to.

Not all functions need to return a value. Your function updates a value in a dictionary and then prints the dictionary. The results of this do not need to be assigned to a variable or really held on to. The dictionary has been updated and printed.

The solution to this is to remove the return type or explicitly specify that the function will not return anything. There is a way to specify that a function will return nothing, but Swift style guides would suggest that you remove the type to be returned altogether.

Hope this helps! :sparkles:

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Ok, I expanded on your function a bit (or quite a bit) to try and demonstrate when we want to return something and when we don't. So here we go:

//: Playground - noun: a place where people can play

import UIKit

var todoList: [String: String] = ["Monday": "Take out garbage", "Tuesday": "Study",
                                  "Wednesday": "Clean room", "Thursday": "Call parents",
                                  "Friday": "Do finances", "Sunday": "Cook for the week"]

func add(toDay x: String, withTask y: String) {  // No return is needed here at all

    todoList.updateValue(y, forKey: x)
    print(todoList)

}

func displayList() {
    for (day, task) in todoList {
        print("\(day):  \(task)")
    }
}

func doToday(for day: String) -> String {  // a return is needed here
    return todoList[day]!  // This going to return the task that was found at the day that we ask for
}

add(toDay: "Saturday", withTask: "Iron your bed")
displayList()
print()
print("I need to do this today: \(doToday(for: "Wednesday"))")  // we search for a day and print the value returned to us

To fix your original code, all was needed was to erase the -> String. You didn't need to return a string as you were printing the list from right there. In fact, you didn't need to return anything. But if you tell a function you're going to return a String or int or any other data type, then it will absolutely demand that you do so. You could have also fixed it by returning any arbitrary string such as return "Hello World", but that "Hello World" would never have been visible anywhere.

I added a function to display the list to help differentiate the difference between keys and their values. The for loop goes through each pair and prints out the key and the value. The key is your day, and the value is the task you need to do.

I also included a print statement at the bottom. This print statement calls another function (which is also fairly unnecessary but serves to demonstrate what I mean) that passes the day into a function which returns what you're supposed to do on a particular day. I picked the day "Wednesday". At this point, the function executes and gets the task value located at the key "Wednesday". That value (a string) is then returned to the print statement that called it. The returned string is then inserted into the string interpolation and printed out with the rest.

Hope this helps! :sparkles:

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Thanks for your help! That all makes sense, except for one thing. I thought my dictionary had been defined as a string. So when I print it, I thought it was showing a string. At one point, within the function, I wrote return todoList but I got the same error as above.

So I guess the two questions still remain: -Why isn't my dictionary a string? -Could you help me better understand the difference between print and return and the importance of the latter?

Thanks again for your help.

Jennifer Nordell
seal-mask
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Hi there! Your todoListis not a String. It is a data collection known as a dictionary. The key is a string and the value is a string. These come in pairs. It contains lots of strings, but it is not as a whole a simple string. This is denoted by the [String : String]. You can also have dictionaries where the value may not be a string or the key might not be a string. In fact, the values may be of varying types. What if your dictionary were the information of a person? The value of their name would definitely be a string, but their age would be an integer. Their weight would be a double.

The print simply prints what you tell it to to the console. A return sends back a result to the call site of the function which might be used in some other way.

I've used this analogy before, so let's try it. I'm not a great cook, so I admit I use spaghetti sauce from jars. However, I sometimes have trouble opening these. I would take them to my husband and have him open them. You can think of this like me calling a function openJar(). But if he doesn't return the jar of spaghetti sauce to me when he's done, it doesn't really help me. I need the opened jar to continue.

I will wait for your response, but I did some example code to explain what I mean, but I'm not sure if you're open to seeing it. Let me know! :sparkles:

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

For the dictionary part, I understand that now. Apart from not returning anything (which works now), what could I have returned to make the function work? I tried all sorts of things but to no avail, FYI.

So for the return comment, the function basically performs the task (opening jar) and by returning it (handing back the jar) to the beginning of the function (where it was called) so that you could do other things with it, like make dinner. In that analogy, where would the return value be passed to make dinner? Because what's returned might not be able to pass through it again if, say, the function requires two arguments and but you're only returning one. So would the jar be passed through another function (or some other piece of code)?

Drawing off that analogy, say I fixed the return issue with my function and added another key and value to my dictionary. Once it's returned, where else would that information go/be used?

Also, yes. Example code would be helpful.

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Yes, that's super helpful!

I understand your answer to my original code. And I understand the displayList takes a pass through the dictionary and returns its key: value. I also understand the code in the last four lines. However, I'm getting tripped up by the following:

func doToday(for day: String) -> String { // a return is needed here return todoList[day]! // This going to return the task that was found at the day that we ask for }

I understand the concept behind the code and what it does, but from everything I've learned this far I haven't seen it represented this way before. Could you explain how it knows to get the value of the key without using forKey? Is for day the same as forKey but you can replace Key with anything you want and add space?

Also, what's the purpose of ! ? I've seen it used as != and know what that means, but not when it comes at the end.

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

And one more question. When I write functions, arrays, dictionaries, switch statements, etc. it takes me quite a bit of time, as I have to think really hard and reference my notes to make sure I'm doing it properly and understanding the logic. (trial and error helps too) But I want to get quicker, hence Pasan's comment about practicing the writing of several functions, etc. before moving on. That said, are there sites that have basic drills like this where I can pound it through my head with lots of repetition?

Jennifer Nordell
seal-mask
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

In my code, I introduced some things which you simply have not gotten to and they are a little more advanced ideas including the "!" at the end. The point of that was to force unwrap an optional, but I'm sort of doubtful that you've even gotten to "optionals" yet so just try and accept it for right now :smiley: You will get there, I promise.

Also, the last print method I did retrieves a value from a dictionary using a function and returns it. As I pointed out, this was unnecessary, but I wanted to demonstrate why we might need a return value. The same result could be achieved by writing this:

print("I need to do this today: \(todoList["Wednesday"]))  // print out the value from the todoList at the key "Wednesday"

I understand that you want to practice writing functions to become quicker and more used to them. But might I suggest writing simpler functions to start with? This that you've chosen for yourself is touching on subjects you haven't made it to yet. While I think it's great that you're out to experiment for yourself keep in mind that pacing is important. Don't burn yourself out by banging your head on a wall when the explanation is likely coming soon.

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

No, I haven't gotten to optionals yet. Thank you for your thoughtful responses. Been really helpful, and I will definitely work on pacing myself. :)