Wednesday, August 13, 2014

Playing With Swift: Extensions

I am finally getting around to playing with Swift, Apple's new language for Mac and iOS development. I have to say, I am excited to have a new language to learn. Swift looks very interesting as it pulls in many great features of other modern languages.

Like Objective-C, and Ruby, and probably others that I don't know about, Swift allows us to add functionality to any class, including the built-in classes like String and Array.

Here are a couple of examples of extending the Array and the String built-in classes to add a join() method.

First, let's extend the Array class to add a join(sep:String) method that returns a string containing all of the elements of the Array, delimited by the separate value passed in.

extension Array {
    func join(sep:String) -> String {
        var s = ""
        if let firstItem = self.first {
            s = "\(firstItem)"
            for i in 1..<self.count {
                s = s + sep + "\(self[i])"
            }
        }
        return s
    }
}

Pretty cool, right? But what if our religion thinks it's better to extend String and pass in the list to be joined (Python style)?

extension String {
    func join<T>(list:Array<T>) -> String {
        var s = ""
        if let firstItem = list.first {
            s = "\(firstItem)"
            for str in list[1..<list.count] {
                s = s + self + "\(str)"
            }
        }
        return s
    }
}

Just as easy. Did you notice the slight variation to use a slice of the array, rather than a for-loop?

While I love a good pedantic discussion about which class is more "proper" to extend, you probably don't have time for such things, so let's just extend them both. And to keep it DRY, let's alter our Array extension to call the String extension via the separator argument. (Yes, I've been influenced by Python.)

extension Array {
    func join(sep:String) -> String {
        return sep.join(self)
    }
}

One enhancement I would like to make to these methods is to use a default parameter value for the separator. Unfortunately, as of this writing, defining a default parameter causes a segfault in Xcode. It is beta software, after all!

Saturday, August 9, 2014

The Real Value of Writing Automated Tests

The product manager asks in the standup, "Why did this start to fail? Don't we have tests that cover this?"

"Yes, we have tests. They all passed," we respond.

"Then your tests aren't very good."

Well, maybe. It's true, we could write a lot more tests. In general, if your software team is committed to automated testing, you'll write at least as much test code as application code. Project estimators should plan on writing two applications - the one with all the features, and a second one to test the first one.

In our case, the unit tests were all passing, but some of the integration tests started failing. These are the tests that verify the interactions among the various parts of the application. Of course, each time we find a new situation where a test fails, we try to figure out why, and cover that scenario with yet another test. In this way, what evolves is a system that informs us when our software parts interact in ways we didn't expect.

Or maybe it devolves? It takes a lot of discipline in a team (even a team of one) to keep your testing system clean and orderly. Often it becomes a hodgepodge of bolted on test cases that can start disagreeing even with themselves! We've all been victims of someone else's failure to tearDown() completely.

Even in mature projects, the tests don't seem to catch everything, no matter how thorough we think we've been.

So why go to all the extra effort? If the tests require as much maintenance as the application itself, what value do they really bring to the project?

First, tests make sure existing interfaces between parts of the application remain consistent.

Second, tests make you as a developer consider the more subtle interfaces than you might not have been aware of. If you consider that your module's interface might be more than just the method signature and return value, you begin to understand some of these more subtle interfaces "Whoa, why did that fail? I didn't even touch that?!" It could be because that code you just refactored had a side effect that other code has come to depend upon. Oops. Good thing the test caught that. Of course, sometimes the tests don't catch every subtle interface impact. But they work often enough that their value to the project cannot be disclaimed.

Finally, and in my opinion, most importantly, when tests are automated (and hopefully executed by a continuous integration system), they keep you from cutting corners when it becomes crunch time. I've developed software under various methodologies. Regardless of the individual tenets of each methodology, they always seem to slip into a "just get it done" mode as milestones approach. Often, when a trouble ticket arrives, the developer jumps right in, makes a quick fix, commits the code, gets a buddy to review it, merges it into the head (tip, trunk, whatever), then receives the email from the CI server that they broke the build. The automated tests catch the fact that the developer didn't think about everything they should have thought about when they made their change.

I once worked in a team that rewarded the build-breaker with a rubber chicken that had to hang over their cubicle until the build turned green again. Yes, I flew the rubber chicken a lot. My role in that team was mostly in the infrastructure of the application, so when I goofed up, it broke a lot of things. Fortunately, we had a decent test system in place, and the CI server let me know about my shortcomings very quickly. So in crunch time, when everyone's focus is naturally narrowed to a dangerous tunnel vision, our automated testing system forced us to widen our vision and take a breath, and think more broadly about everything our simple little change might affect.

Summary

  • Testing is hard work. Plan on writing two applications.
  • Testing helps maintain a consistent interaction between software modules.
  • Automated testing helps you consider more of the overall effect of your change when under pressure.
And finally,
  • Fly a rubber chicken in the team. It's a lot of fun. The look on other teams' managers' faces when they walk down the hall is priceless.

Saturday, July 12, 2014

Thoughts on Software Development Job Interviews

TL;DR I interview people for programming jobs. I'm turned off by a lack of confidence, by an inability to talk tech with me, by profanity, and by an unwillingness to try when facing something new. I'm impressed by energy, enthusiasm, and competence.

My dream career is one in which I work for myself, creating software that people enjoy and find useful, and earning enough to provide a comfortable lifestyle for my family.  For me, this will be a work in progress as I've already tried the "cut all ties on Friday and start a new career on Monday" thing.  It didn't work for me, largely because I jumped into something I was unprepared to do, and lacked any real passion for.  (For the curious, I lived in poverty for five years trying to start a financial advising practice working for Edward Jones.)  When that little side trip ended, I ran back, wholeheartedly to the software development world, and yes, the passion had returned.  My next shot at setting my own priorities and timelines will be aligned with what I have energy to do every day.  I like creating things and I like writing (although I hate writer's block).  But I digress...

In my current day job I work as a senior software engineer at a small company to which larger companies outsource development jobs.  There are a lot of benefits to working at this company.  Foremost, I don't have to switch jobs in order to do something different.  As a contract company, we get lots of new opportunities every year, most of them are interesting, and a lot of them are fun.  We've got a great culture, and lots of people want to come work for us.  As a team leader, I have the privilege of interviewing candidates on a regular basis.  I've interviewed new grads and people with much more experience than I have, some arrogant jerks and some humble giants.  I am actually easy to impress -- show me you're a nice person, you're willing to work, and that you're competent in the types of work we will be expecting you to do.

Here is a short list of things that can make or break you in a job interview.

Please don't apologize for taking our time

Everyone feels a little inadequate sitting on that side of the table.  One candidate prefaced (and closed) the interview with a polite...
I know I'm not the most qualified candidate, but thank you for taking time to interview me anyway.
If you didn't think you had a shot, why did you apply? Without revealing too much about this case in particular, it was a person who had been out of the business for a while (for a good reason), and was trying to get back into it.  They had skills and knowledge that were still relevant, but their complete lack of confidence was a deflater.  Now, several months later, that's pretty much all I remember from the interview.

My recommendation

When interviewing for a job for which you feel underqualifed, there are two things that would impress me.
  1. Spend some of your spare time getting up to speed on the skills you're going to need.  Get a book.  Play around.  Make something.  Anything.
  2. Address your perceived lack of skill early by saying something like, "My skills are a little rusty, but I've been tinkering with things in my spare time, and I'm anxious to dive into it full time."

Please try to give a good answer

We work in a profession that is geared toward solving problems. It should be expected that there would be a problem solving question at some point during the interview.  If we do ask you to solve a problem,  please try.  One candidate simply said...
I have no idea how to do that.
Understandable, it may be something you've never considered before.  Fair enough. We offered to let them think about it for a minute before replying.  They wouldn't.  They simply replied the same.
I wouldn't even know where to start.  I'm sorry.
At that point, the interview essentially was over.  The rest was just being polite.  If I'm going to have to work with you on a daily basis, I want to know you're going to try to do your share of the work.

Recommendation

I personally don't fault someone for not knowing how to solve a problem they've never considered.  The following responses impress me.
  1. Can I think about this for just a minute?
  2. Are there any tools available that could accomplish a specific part of a potential solution?  This question shows you've started to think about a possible solution, but may not be aware of everything in your tool chest.
  3. Can I make a few assumptions? Sure. This shows you're still trying to wrap your head around the problem.  It shows you're trying.

Don't say you know something you do not know

Résumés are great sales pieces.  Good ones give us a good sense of the work you've done.  When listing skills, please be sure you have at least some level of competency with them.  If you say you've been a C programmer, for example, please be prepared to answer questions about pointers, stack and heap, integer overflow, and so forth. This is basic stuff.

Recommendation

If you mention it in your résumé, please be prepared to talk about it in depth.

Show energy and passion

Some folks (myself included) get passionate about things like text editors and operating systems.  That's not necessarily the kind of passion I'm talking about (although I would love to have a candidate talk about those things with me for a few minutes).

I recall one interview where we asked the candidate about jobs he listed in his résumé. He spoke in great detail and with fondness about a project he had worked in over 10 years ago.  It impressed me that he remembered the details and spoke of them energetically.  He was proud of the work he had done.  I liked that.

Avoid profanity

Disclosure: I don't like the use of profanity. To me, it seems like a lazy way to express strong feelings.

There's a little dance that is done in the workplace when you meet someone new.  For the first little while, everything is clean and sober.  Then one of the parties will lob a soft one over to see how it's received.  A "D" or an "H", maybe even an "S".  If it's well received (or at least not acknowledged as inappropriate), they'll quickly move to dropping an F-bomb. To me, it just seems so unprofessional.  Shockingly, this dance has even been done in job interviews.  Sadly, it's often initiated by our side of the table.  For that, I can't really blame someone who would naturally assume it was an invitation to relax.  Just know this, it won't impress me in any way, other than to think you should probably work harder at broadening your ability to communicate effectively.

Recommendation

Keep it clean, even when "invited" to relax by the interviewer.  It's  likely nobody will ever remember that you didn't use foul language in a job interview.  But someone will probably remember if you did.

Wrap up

This post simply sums up some of the things that I have seen strengthen or weaken a candidate during an interview.  All of this is my opinion. Others will definitely have different opinions.  Feel free to add them at the bottom.

Saturday, June 28, 2014

Why I can't stop using Vim

In 1992 or 1993, my brother-in-law hired me to help him with some maintenance on a software system he had written for a customer. It ran on SCO Xenix.

"Hey, Bro, why doesn't 'EDIT' work on this computer?" I was a DOS rookie back in those early days, having just started my major in Computer Science.

"Um, there's no EDIT command on Xenix. Let me introduce you to vi. You use hjkl to move around, plus a few other keystrokes. Once you get used to it, it's not that bad." I swear he had a sly grin on his face as he said that, but he was serious. Vi was what I was going to have to use. Only now, as I write this, do I recall that he was, at that time, working in Windows with a shiny graphical editor. Oh, well, he was the boss, after all.

Anyway, I learned to move around pretty quickly, hitting 'i' to start typing, and 'Esc' to move around again. I wouldn't say I was a wizard, but I got the work done. We would tap away on Wednesday nights and Saturday mornings in our work sessions, while our wives played Super Mario Brothers out in the front room. Good times. I really miss it sometimes.

That was the side job. The day job kept me programming on OS/2 and some Windows. The stock editor on OS/2 was a decent editor - you typed text, and it saved it just fine. I cranked out many, many lines of code using that editor.

We're programmers. Editing text is the very essence of what we do. We get excited about these sorts of things.

Fast forward to 1997. My brother-in-law once again helped me get my foot in the door at a small telecommunications company in Phoenix. My first workstation was a Sun SPARCstation 20, running Solaris. Cool, I thought, I can use vi to get going. But by now, everyone was using UltraEdit on their Windows machines. I didn't have one of those, but I really needed the productivity boost of a better editor. A little Yahoo searching turned up some vi clone called Vim. There was a new release of it, version 5, and it came with syntax highlighting! Take that, UltraEdit!

This is getting long... Let's just say, I used Vim for all my editing on that SPARC station. And when I finally got a Windows PC, I was elated to find that there was a Windows version of Vim, with a GUI and everything!

Vim and I have had a bit of a fickle relationship over the years. Although it does an amazing job helping you type text, it's not flashy, and it's not perfect, and because of those imperfections, I strayed from time to time, looking for something to fix those imperfections, and still give me the second-nature editing reflexes I had come to enjoy from Vim.

Here's a list of the things that have caused me to look beyond Vim.
  • viml - Vim's built in scripting language is tedious to work in. Some folks have done some amazing things with it, but, try as I have, I can't get myself to enjoy it.
  • Glossy finish - I admit, I'm guilty of a little editor envy when I see some of the prettier interfaces out there, especially these days.
  • Emacs's Org Mode - this is such a killer emacs app. Others have tried to replicate it for Vim. Someday.
  • Context-aware code completion - OmniComplete provides a decent framework, but nobody has really matched the power of Visual Studio, Eclipse, or Xcode.

Yes, I have strayed, and flirted with many other editors...

  • JEdit (Ugh, looks like a Java Swing App, and too much clutter everywhere)
  • Emacs (Love the features and the eLISP, but can't tolerate the myriad key chords needed to navigate around my files.)
  • Emacs + Evil Mode (Evil mode is REALLY good. The only thing that made me frown was poor code navigation via ETAGS.)
  • J (A tiny little Java based editor, built around ABCLisp from Armed Bear. I really loved this editor, but it fell behind in features, and I needed more power.) EDIT: This editor is still alive (somewhat) on github: https://github.com/kevinkrouse/j/tree/master/j. Thanks to bokchoi on ihackernews.com for the link.
  • Programmers Notepad (Decent editor, but not enough features).
  • Editra (a Python/WxWindows based editor, with Vi emulation. But it also lacked things like smart indent and other features I have come to take for granted.)
  • Notepad++ (A very respectable editor. Tons of features. But for some reason, I just don't enjoy using it. Maybe it's all the visual clutter around the borders of the screen?)
  • Visual SlickEdit (I actually bought a license for this once, about a decade ago. I liked using it, but I could only afford one platform, and there are lots of free editors that do most of the same things. With Vim in my toolbox, I'll never pay $300 to edit text.)
  • TextMate (When on a Mac, it had to be tried. The free TextMate 2 is a great editor, and I flirted with this one the longest. Were it not for the things I'm about to mention below, I'd be using this editor as much as possible.)
  • A whole slew of respected MacOS based editors: Kod, Smultron, SublimeText, TextWrangler, etc.

Here's where they all fell short, and what took me back to Vim every time...
  • hjkl for navigation
  • / for searching (really, no other editor has made it this simple)
  • m to bookmark a spot, ' to hop back to it
  • and ctags
  • q to record a macro; @ to execute it again
  • 1G to go to the top of the file, G to go to the bottom
  • ^, $ to go to the front, or end, of a line.
  • Text Objects! Holy cow, if you're a Vim user and you're not using these, you're missing something special.
  • Platform ubiquity. (Mac, Linux, Windows - Vim works great on all the platforms I use day in and day out.)

What it boils down to, really, is that the above keys have become a part of me. They are so ingrained in my brain and reflexes, that I think of what I want done in the text and my hands just naturally do it for me. It's like drinking water. I don't have to think about how to go about bringing the cup to my mouth and tipping it just right. I just do it, and keep going on about my business.

THAT's what keeps me coming back to vim.

Yes, it still has its imperfections. I end up using IDE's for a large part of the work I do, and they provide a lot of what I wish vim would do better. But there are some plugins that bring the above features into those environments...

For Eclipse, I use the Vrapper plugin. Works great!

For Xcode, I have used XVim. It's not perfect, and crashes Xcode in a couple of situations. But it's getting better, and is actively developed.

As a special bonus for having read my lengthy article all the way to the bottom. Here's a chunk of my .vimrc that allows me to have nested "project" settings in my directory tree...
" Search for any .vimsettings files in the path to the file.
" Source them if you find them.
function! ApplyLocalSettings(dirname)
    " Don't try to walk a remote directory tree -- takes too long, too many
    " what if's
    let l:netrwProtocol = strpart(a:dirname, 0, stridx(a:dirname, "://"))
    if l:netrwProtocol != ""
        return
    endif

    " Convert windows paths to unix style (they still work)
    let l:curDir = substitute(a:dirname, "", "/", "g")
    let l:parentDir = strpart(l:curDir, 0, strridx(l:curDir, "/"))
    if isdirectory(l:parentDir)
        call ApplyLocalSettings(l:parentDir)
    endif

    " Now walk back up the path and source .vimsettings as you find them. This
    " way child directories can 'inherit' from their parents
    let l:settingsFile = a:dirname . "/.vimsettings"
    if filereadable(l:settingsFile)
        exec ":source " . l:settingsFile
    endif
endfunction
autocmd! BufEnter * call ApplyLocalSettings(expand("<afile>:p:h"))

I posted it to Reddit a couple of years ago, and the feedback was overall positive. There were a few good ideas posted in the comments, so here's the link.

Thanks for reading. I'd love to hear your feedback below.

EDIT: spelling corrections; added links to other editors

Thursday, May 1, 2014

A Simple State Pattern Applied to Game Design

When it comes writing software, less is better, generally speaking. The fewer lines of code you have, the lower the chance of doing something wrong. For me, this is most obvious when it comes to the number of if-statements in my code.

Here's an idea for reducing the number of if-statements used to transition between game states. It's not a new idea. In fact, it's an old design pattern from the GoF Design Patterns book.

Toggalight, my second game, is small in scope, but has the usual need of presenting different UI elements, and responding to user interaction differently depending on whether the game is running, paused, or over.

When I started on this project, I decided I wasn't going to stick myself into an if-statement quagmire again. So I broke out the trusty State pattern and went to work.

Overview

The game has four buttons that cause state changes: Start, Pause, Resume, Start Over. The GameScene class implements a library of functionality that is available to both the view controller and the various state classes.

Note: I'm using a python-like pseudo-code, and will be abstracting most of the details so we can focus on the state structure and transitions. The game is actually written for iOS in Objective-C, using SpriteKit.

BaseGameScene

This is the base class for all game states, and defines the interface expected by the GameScene.

abstract class SceneState
  property gameScene

  // state management - empty base class methods that don't do anything
  method enterState()
  method exitState()

  // Events - empty base class methods that don't do anything
  method onFrameUpdate()
  method onLightTouched()

  method onStartButton()
  method onPauseButton()
  method onResumeButton()
  method onStartOverButton()


RunningState

I'll spare you the details of all the states, but here's the gist of what's in the most complex state, the one that's active while the game is being played.

class RunningState : SceneState

  method enterState()

    // set up UI for state
    gameScene.pauseButton.show()
    gameScene.startButton.hide()
    gameScene.startOverButton.hide()
    gameScene.resumeButton.hide()
    gameScene.helpButton.hide()
    gameScene.calibrateButton.hide()
    gameScene.highScoreLabel.hide()

    // Physics are different between running and game over states
    gameScene.setGameRunningPhysics()

    // If this is a new game (not a resume), layout a new field
    // and reset the clock.  Yes, I know it's a nasty if statement.
    // I'll probably refactor this in the next release.
    if (gameScene.shouldReset)
       gameScene.generateNewField()

    // Unpause the scene
    gameScene.frozen = false


  method exitState()
    // Do nothing. The base class defines an empty method for this

  method onFrameUpdate()
    // Respond to device motion (accelerometer and gyroscope)
    motion = os.getCurrentMotion()
    gameScene.physics.gravity = Vector(motion.roll, motion.pitch)

    // Check time remaining
    // Yup, more refactoring needed here, too. onClockExpired would be
    // a good event to handle at the state level.
    if gameScene.clock.isExpired()
      gameScene.transitionToState(gameScene.gameOverState)

  method onLightTouched(light)
    // Toggle it off/on
    light.on = not light.on
    gameScene.updateScore()

    // If all the lights are turned on, layout a new field
    // This if-statement seems appropriate, actually.
    if light.container.allOn()
      gameScene.generateNewField()


  method onPauseButton()
    gameScene.transitionToState(gameScene.pausedState)


You get the idea. The other states follow the same pattern, doing what they're supposed to do when the events are triggered.

GameScene

Here are the relevant parts of the GameScene class.

class GameScene

  property preStartState
  property runningState
  property pausedState
  property gameOverState

  property currentState

  method init()
    // Lots of code to set up the scene.

    preStartState.gameState = self
    runningState.gameState = self
    pausedState.gameState = self
    gameOverState.gameState = self

    transitionToState(preStartState)

  method transitionToState(newState)
      // Objective-C lets me get away with not checking for 
      // null first. Lazy? yes.
      currentState.exitState()
      currentState = newState
      currentState.enterState()

  method onStartButton()
    currentState.onStartButton()

  method onStartOverButton()
    currentState.onStartOverButton()

  method onPauseButton()
    currentState.onPauseButton()

  method onResumeButton()
    currentState.onResumeButton()

  // This method is called by the "os"
  method frameUpdate()
    currentState.onFrameUpdate()

There you have it. PreStartState goes to RunningState. RunningState goes to PausedState and GameOverState. PausedState goes to RunningState, setting the shouldReset flag or not depending on whether the Resume or Start Over button was pushed. GameOverState goes to RunningState.

Each state sets up the UI according to its context. In the case of this game on iOS, touch events are translated by the OS into the "onButton" events in the view controller, which delegates the events to the GameScene, which in turn delegates them to the current SceneState, which is where the knowledge of what to do is programmed.

That's the essence of the State design pattern applied to my game architecture. It's not necessarily revolutionary, but it's made a world of difference in the way I track down problems and solve them.