Tripped up on closures…again!

I’ve posted before about learning closures. Earlier this year, I was really making an effort to understand how they work. My examples, though, were contrived, or rehashes of other peoples’ examples. As such, my ability to remember them suffers. Context is so crucial to understanding something. I was working on a problem at work today where I need to sort an array of data.  For some reason, I kept blanking on how to do it.  I could write the code that does it, but I couldn’t explain it to myself.  Here was my problem…

var meetings : [Meeting] = [
Meeting(startTime: 0, endTime: 1), Meeting(startTime: 8, endTime: 11),
Meeting(startTime: 2, endTime: 8), Meeting(startTime: 10, endTime: 12),
Meeting(startTime: 9, endTime: 10)]

I wanted to sort the array by startTime. Had this been just an array of numbers, I could have sorted it pretty quickly. For some reason, though, having instances of a Meeting class was throwing me off. I knew that this code would give me what I needed:

let sortedArray = (meetings.sorted { $0.startTime < $1.startTime }) 

This is really shorthand syntax. I know it works, but I could not explain to myself. So I tried the long hand way. Unfortunately, when I tried to write it in a way that made sense to me, I kept getting errors from the Swift Playground page I was working in. Undaunted, I went looking for answers. The Apple documents offer this when working with closures:

{ (parameters) -> (return type) in (statements) }

Hmmm…okay, the parameters I want to pass in, I thought, were the startTime of the meetings. So I wrote something like this.

let sortedArray = meetings.sorted(by:
 { (s1,e2), (s2, e2) -> Bool 
in return s1 < s2 }
)

What I thought I need to pass into the closure were the start times and end times and sort it that way. I was way off.

As it turns out, when I create a new array like I did with sortedArray, if I declare the type of Array it is, in my case [Meeting], that is the parameter that is passed into the closure, not the properties within the Meeting instance. I didn’t discover this until I explicitly typed it out, and used my old friend, Option-click, which told me what type sortedArray was. When I began typing in the sorted function on the meetings array, Xcode offered this little gem:

Screen Shot 2017-08-28 at 8.02.04 PM

As it turns out, I’m not passing in meeting.startTime or meeting.endTime into the closure. I’m passing the entire Meeting instance. In fact, the closure, as seen in the screenshot, takes two meetings from the array and compares them to return a Boolean value. What it evaluated is everything after in. Once I have the meetings passed in, I can access any of it’s properties to do my comparison.

Screen Shot 2017-08-28 at 8.12.52 PM

What I didn’t understand before is that m1 and m2 are just parameter names for the objects I’m passing in. They represent the meeting instance, not the properties contained within the meeting…which is what I really wanted to evaluate.

So in the end, in order to explain something to myself, my code wound up looking like this:

let sorting : [Meeting] = meetings.sorted(by: 
 { (m1, m2) -> Bool 
in return m1.startTime < m2.startTime}
)

Yes, it’s not very “Swifty” and in the future, I can use the shorthand trailing closure syntax and be able to look at it and know exactly what is going on. However, using code and being able to explain what the code is doing is a better indication of understanding than blindly trusting something I find on the internet, see that it works, but have no idea why.

I realize this topic is pretty junior for many developers, but it further reinforces what I discovered when taking calculus in college. If you don’t use something often, you forget it. Code is no different. It also helps when learning something, you have a problem you are trying to solve rather than seeing someone else’s example and saying “Yeah, that makes sense.” I do not expect this to be my last post on closures. Especially since I still have more functional programming to learn!

On the upside, at least as I see it in my growth as a developer, I went to Apple documentation rather than Googling for an answer in StackOverflow. As tempting as it was to ask my fellow iOS Slack channel mates, I decided to see if I could figure it out first. When time isn’t urgent, it’s amazing how much patience I have when solving a problem!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s