Feeds:
Posts
Comments

Archive for August 25th, 2016

One of the challenges in learning a new language, be it human or computer, is learning to think in the language. Learning Swift is no different.

I’ve been spending the past several months working on the first iOS (iPhone) app that I’ll be releasing through the Apple app store. I’m writing it entirely in Swift 3, the latest version of the language. Yesterday, I was looking over the code to see if there were any places where I’d been thinking in a non-Swift fashion. This moment of reflection was triggered by my viewing of a very recently released class in Swift from one of the major online education sites. I was disappointed that the instructor was using an idiom that I knew was easily simplified in Swift. My disappointment made me wonder if I had similar issues.

The following is actual code from my upcoming app. I had originally created it’s core in C as an extensible example for teaching that language. The setup is as follows:

  • the map is an array of connections from each room
  • the number of connections from each room is fixed
  • we are explicitly tracking the number of a given type of hazard

We want a function that returns true if there is hazard in one of the connecting rooms. Here’s the original code:

var hazardNear = false
        
if hazardCount > 0
{
    for nextRoom in 0 ..< numberOfConnections
    {
        if hazardRooms.contains(exits[room][nextRoom])
        {
            hazardNear = true
                    
            break
        }
    }
}
        
return hazardNear

Pretty conventional C-esque stuff. The first thing that jumped out at me was the reliance on knowing the number of connections. Swift arrays are true collections. Let’s treat them as such.

var hazardNear = false
        
if hazardCount > 0
{
    for nextRoom in exits[room]
    {
        if hazardRooms.contains(nextRoom)
        {
            hazardNear = true
                    
            break
        }
    }
}
        
return hazardNear

When viewed this way, it’s obvious that we’re just filtering the collection based on a condition. So, just do that.

var hazardNear = false
        
if hazardCount > 0
{
    hazardNear = exits[room].filter{hazardRooms.contains($0)}.count != 0
}
        
return hazardNear

We’re filtering the array of rooms for ones that contain the hazard and checking for a non-zero count. But this is still a bit clunky. Let’s examine what we’re really asking.

var hazardNear = false
        
if hazardCount > 0
{
    hazardNear = !exits[room].filter{hazardRooms.contains($0)}.isEmpty
}
        
return hazardNear

It’s far more clear to simply ask if the filtered array is non-empty directly. What’s left is one final simplification.

return hazardCount > 0 && !exits[room].filter{hazardRooms.contains($0)}.isEmpty

One might ask whether having an explicit count is necessary as the hazard array has a count. True. Although the hazard array is built based on the number of hazards, so I still need it to be around.

Overall, I fairly pleased with the results of the exercise. In the end, the code is much clearer in intent.

Read Full Post »

%d bloggers like this: