Skip to content
Jun 8 2012 / alecmce

Interviewing through Pair Programming

The best interview I ever had was a pair-programming session with Luke Bayes and Ali Mills. I was put at ease by their demeanour and attitude. They are coders, and I’m a coder – all that was left was to work out if I was as good as they hoped I was, and whether we could stomach working with one another. As it happened, all of the above, but I had to decide between enterprise work and gaming work, and I took a different route. But the interview was fantastic.

Recruiting good developers is a difficult discipline. Most of the time you get the impression that developers conducting interviews haven’t given the interview any thought until about 5 minutes before it starts. This is a mistake; recruiting good colleagues helps to solidify a team culture. Hiring the right candidate is important. Not hiring a wrong candidate is doubly important.

I have now been interviewer more than I have interviewed. In my experience, the most reliable approach for interviewing interactive developers has been to conduct the entire interview as a sort-of game, played through pair-programming. I have yet to recommend a candidate that I later regretted recommending as a result of this game, which is as good a testimony as an interview technique is likely to receive.

The Game

The game itself is trivially simple. Let’s start with a trivially simple structure – for example a static circle in the middle of the screen – and start adding functionality in turns as a sort of free-association game.

If we’re interviewing an interactive developer most familiar with AS3, I might start with something like this:

package
{
	import flash.display.Sprite;

	[SWF(width="800", height="600", backgroundColor="#FFFFFF")]
	public class Main extends Sprite
	{
		public function Main()
		{
			graphics.beginFill(0x1E90FF);
			graphics.drawCircle(400, 300, 50);
			graphics.endFill();
		}
	}
}

Imagine you’re an interviewee: We’re going to take it in turns to add features to this code. You choose the first feature, and I’ll drive implementing it. Then, I’ll choose a feature and you drive it… and so on. We are pair-programming however; we need to work together all of the time. If there’s something I do you dislike, you disagree with or you don’t understand, you should say so immediately.

This simple structure leads to all sorts of interesting opportunities. When using the circle as a starting point, most often the developer chooses to have the ball fall and ‘bounce’, but some want to make it a speaker and hook it into a sound file, or to make some art by putting other circles next to it, or have it wobble, or chase the cursor, or rotate…

What Is An Interview For?

Principally, an interview is a mechanism to parse candidates for suitability for a job. A candidate is suitable for a job if they can do the work that will be expected of them. A candidate is not suitable for a job if they are disruptive or poorly suited to the existing team culture.

Can They Code?

Evaluating whether a programmer is good enough to do the work expected of them requires evaluating their ability to code. This is commonly achieved by posing technical problems on a whiteboard. Whiteboard problems happen away from a computer, so that there is no safety net of a test suite or just running the code to make sure it doesn’t break. For this reason there is an impetus to solve the problem mentally and then to write down the results. This feeling is familiar: most students’ experience of school is very similar; the interview becomes a test. A maxim in education is that testing students is a fantastic way of measuring how good students are at doing tests. I don’t want to hire the best interviewee, I want to hire the best-fitting programmer.

Pair programming is extremely good at exposing an interviewee’s programming style. The game established above offers the green-field of a project with no built-in dependencies or external concerns. Every developer loves to write code at the start of a project! That’s why developers start so many projects and finish so few. At this point all potentialities are open. Interviewees may write solid, conservative code; they may write wildly creative prototype ideas; they might write badly designed spaghetti code… However the interviewer codes instinctively becomes apparent because the format is familiar and achievable.

What Are They Like To Work With?

After an hour of programming with someone you get to know them a little. If someone is thoughtful, open, aggressive or competitive, it is very difficult to sit side-by-side with someone discussing code with them without their personality expressing itself clearly. Programming is a coder’s natural environment, and they tend to act naturally doing it.

How Creative Are They?

Creativity is an important part of interactive developers’ jobs. Most of the time, requirements that come to interactive developers are poorly defined, or not thought through. An interactive developer needs to fill in the gaps or make the best out of obscure requirements. The reason for the open-choice task is to attempt to see the interviewee’s creative faculties.

The game borrows from improvised comedy the idea of accepting your partner’s idea and extrapolating. I tend to offer conservative extrapolations to the interviewee’s ideas, allowing them to drive the direction of the feature-set more. In almost every interview that I have conducted in this way, interviewees drive the agenda to more complex features, to find interesting features and interesting problems within the context we have made for ourselves. Sometimes the game can break down, or we have to back-track. All of this should be embraced as part of the game. Allowing and encouraging interviewees to run with an idea is informative, as well as being fun for both parties.

Can They Solve Complex Problems?

Another developer who has used pair-programming for interviews Ivan Moore argues that pair-programming it is not a good technique for evaluating a developer’s problem-solving skills.

However, he also points out that:

In typical enterprise IT projects, more problems are caused by over-complex solutions to simple problems, or by solving the wrong problem, than having problems that are unique and difficult and require a brand-new algorithm. Ivan Moore

I would contend that this is true not only for typical enterprise IT projects, but for almost all software. There exist very few software problems that can’t be solved by a team of software engineers iteratively using simple, elegant solutions written in clean, easy-to-read and easy-to-change code.

Of course, there are arcane areas in software development and there are a handful of extreme cases where programmers are being hired because of their niche abilities. In this case, of course I would not advocate using the pair-programming game to evaluate their niche abilities. This is a 0.1% problem however; if you’re reading this and think that you’re a niche programmer, you’re probably delusional.

But What About Problem Solving?

OK. Let’s suppose you really need developers to solve some fiendishly compelx problems. Some companies ask quirky, brain-teaser questions. Most notably, Google’s interviews ask famously inpenetrable questions to challenge interviewees’ inventiveness.

You are shrunk to the height of a nickel and thrown into a blender. Your mass is reduced so that your density is the same as usual. The blades start moving in 60 seconds. What do you do? (Google Interview question, from How to Ace a Google Interview)

This question is measuring a candidate’s ability to make some mental leap of logic. A good leap of logic in this case would be to propose a physical leap out of the blender; if you’re the same density then the ratio of strength to mass will have increased in your favour, so you can jump out of the blender.

Demonstrating such a leap of logic is a good positive indicator that an interviewee can think laterally, invent and innovate. It tests exactly those aspects that Moore argues are not well tested by the game. For this reason, it is worth considering asking such questions during an interview.

Conversely however, not demonstrating such a leap of logic is not a good negative indicator; an inventive problem-solver may fail to answer such a question successfully. Perhaps the question just didn’t chime with them; perhaps they were too nervous.

The utility of these questions for Google is more obvious when you consider that Google have around 130 candidates for each job. A question that reliably filters inappropriate candidates but also filters many good candidates is not a problem in a scenario where there are more candidates than can be readily handled.

Most silicon valley companies have difficulty keeping their engineers, let alone elsewhere in the world. There are too few developers for the work available (worth reflecting on, if you’re dissatisfied with your current working conditions). In a scenario with very few potentially appropriate candidates for a job, using questions like this may not be an appropriate strategy; there is no point in asking a question that nobody can answer!

Conclusions

I am not advocating pairprogramming as an ideal interviewing technique, but it has served as a functional approach for me. Interviewing people for coding positions is complex, and many good techniques or ideas are available. Different styles will fit different cultures better, but it is important and instructive to reflect on how you interview and what you are looking for while you interview, to ensure that you maximise your chances of hiring the best candidates for your team.

Nov 10 2011 / alecmce

Future Of Flash

Flash Is Dead!

Or so you’d think. It’s been a fascinating couple of days in the Flash community. Everyone has had their say. ZDNet are telling everyone that Without Mobile, Adobe Flash is irrelevant. CNN talks about the Beginning of the End for Adobe Flash.

Adobe Shrinks!

This week, Adobe laid off 750 jobs. We should remember that 1950 jobs have been lost at Adobe in the last three years now (600 in 2009 and 600 in 2008 – from daringfireball.net).

Part of this was belt-tightening was the entire US-based Flash Authoring team. This article blithely jumps from this premise to the conclusion that “offering a free Flash Player runtime subsidized by selling tools is no longer a business Adobe is interested in”. Does it? Had Adobe said that they no longer have that business interest, then things would be a lot clearer. They haven’t said that at all. The media and the community is jumping to apocalyptic conclusions. (The community should know better)

Tired Communities

Last night I watched a chunk of an online meeting about the Flash Platform of about 80 developers, that notably included @seantheflexguy, @j0eflash, Lee Brimelow and Thibault Imbert.

The most noticeable thing about that conversation for me was the exasperation and ill-feeling in the room directed towards Adobe. The Flash Platform Community feels that it has been ill-treated by Adobe.

On one level, that’s absurd. Without Adobe the community would be fragmented across myriad other communities. Adobe’s investment into the platform is a primary reason the community exists. For many years now, Adobe has given us tools that allow us to make best-in-class products (or bad, buggy products as per our abilities) and display them on the web, desktop and mobile.

Diluting Juice

There has definitely been a dilution of Adobe’s lead in the interactive experience space. HTML5 has taken a lot of the wind out of Flash’s sails. The player performance on Apple products has been frustrating. The gradual loss of Flash’s performance advantage against other platforms has been demoralizing. But it is hardly surprising that other platforms and developers have looked at what Flash did right and have tried to implement similar functionality targetting other platforms and other languages. What would we have Adobe do about this? Somehow continually out-compete all other vendors? If they don’t, should we consider it a betrayal?

Buoyant Communities

Right now, if you attend a JavaScript developer meetup there are a hundred kids in their 20s inventing the stuff we invented over the last decade (a lot of which was invented before us for other platforms, of course). They’re excited and young and vibrant.

At the equivalent Flash developer meetup down the street the picture is very different. There’s a mash of artists, Flex developers, game developers, developers who make banner ads for platforms, developers who use Flash to produce graphics for massive stadium gigs for rock stars. Meetup after meetup fewer developers attend, they are older, less enthusiastic, jaded.

So the apocalyptic conclusions are understandable, if misguided. You can understand why developers might be angry with Adobe, having watched the platform lose out to the new kids on the block over several years. Now it feels that Adobe have finally admitted as much, they are venting that frustration.

Flash Is Alive!

Could it be that the Flash Player has tried to be all things to all people? That the banner ad guy, the RIA guy building data grids and the game developer are all targetting the same platform could be a problem. Add into that mix a requirement that these games, RIAs and ads display on every browser on every desktop, but also on every browser on every mobile, and you can see what a headache Adobe has been contending with over years.

The rise of HTML5 simplifies this issue: gradually, banner ads and simple RIAs will be doable in pure JavaScript. That may upset a lot of Flex developers, but seriously, if you can actually do it better on another platform, wouldn’t you?

But games, and those more powerful RIAs that really juice the Flash Player are not going anywhere. They need not only the current Flash Player, but a beefed-up, more aggressively powerful Flash Player. These apps may remain in the browser for desktops, but will take over the screen on mobiles, wrapped in an AIR wrapper.

Flash Player can still deliver a particular set of experiences across desktop and mobile better than any other platform. The stats about Flash Player are indisputable and compelling. In an attempt to make bolster their business case against the brunt of criticism this week, Adobe published some of these stats.

Everything dies, even the Flash Player. Just because it isn’t a kid anymore, doesn’t mean it’s dead, and these stats demonstrate it pretty convincingly.

Where Does Flash Go?

Thibault Imbert wrote an article yesterday called Focusing, in which he made the case that what has happened this week is a good thing. I broadly agree with this commentary, if this frees up the team to innovate on the current Flash Player.

I have been arguing the case for generics in AS3 so long that it has become a standing joke. AS3 should also adopt inline functions, enums, typedefs and every other good idea that Nicolas Cannasse has baked into haXe. In fact, Adobe should have brought Nicolas into the fold long ago, and would be well advised to do so now, if they can. This sort of language innovation would free-up the open-source developers to create better, faster tools and architectures for other people to build their games on.

They should also be working hard to develop better tooling. That FDT remains broadly better than Flash Builder should be a cause of embarrassment. That we have to use a creaky buggy platform like Eclipse in the first place, when we are using tooling from the company that leads the world in creating tools for creative professionals is continually frustrating. It makes you think that they still don’t really understand what coders want.

They need to continue to improve the performance of the player and the compiler. That people are still doing things like byte-weaving or using Apparat means that Adobe continue to miss really simple tricks in this area.

Conclusions

The community has gone nuts, but you can understand why. They’re mostly wrong, and are probably largely jealous of those JS script kiddies who seem to be having so much fun! But, they also like their not-quite Java, not-quite JS middle-road language, and want to stick with it. They want Adobe to help them stick with it. Adobe are helping! It just doesn’t feel much like it, because Flash isn’t new anymore, and like all old things, it has its problems.

After a week or two, calmer heads will prevail, and the pendulum will swing back. People will think to themselves “when was the last time I used a Flash app in the browser on a mobile?” and also think “wasn’t the Flash IDE mostly junk?”, and on reflection, may even have something positive to say about Adobe.

Did I miss anything?

Oct 10 2011 / alecmce

TDD-ing Game Of Life in haXe

Last week I attended the inaugural Try Harder collaborative training week with a group of talented and dedicated developers. It was an extraordinary week, my brain is still fizzing with ideas and techniques that I learned there.

Image showing game of life implementation

One afternoon Mike Cann and I put together The Game Of Life following a largely test-driven-development process, using Mike Stead‘s MassiveUnit unit testing implementation for haXe.

This was Mike’s first time using a TDD approach, and one of the first times I’ve built in haXe, and it was fun and informative. You can read Mike’s post about the project here, and browse the source-code on Github here.

Sep 11 2011 / alecmce

(Unfolding) Platonic Solids

Before I was an ActionScript coder I was a mathematics teacher. It may have been a giveaway that coding was more my style than teaching when I made this, originally in AS2: (roll-over to activate)

Later on I ported it to AS3 for a game that was never published. I made these:

Then, I forgot about it, for a long time, but I just came across it again! It’s actually my own 3D library, back in the days before I had heard of Papervision or Away3D, or any of the others. It draws the polygons using Graphics. That part is worthless.

However, I haven’t seen the dihedral angle structure that allows me to define the solid to open and close in other code. Perhaps this will be useful to someone. If you would like it, then you’re very welcome!

The code is here: https://github.com/alecmce/ptolemy3D/tree/master/src. The unfolding parts here.

Sep 11 2011 / alecmce

CommandFlow – Another Approach to (RobotLegs) Asynchronicity

In this post I present another first draft of an extension for RobotLegs, my RobotLegs Flow Extension, which seeks to cope with problems surrounding asnychronicity in command-level code.

In my last blog post, I argued that Robotlegs is poorly equipped to cope with asynchronous processes, and offered an extension to RobotLegs to seek to solve this problem, "Async Processes Extension". This extension follows in the footsteps of other interesting libraries, such as Shaun Smith’s Oil Extension among many others.

Reflecting about Processes

Since I wrote that code and blog post, I have been reflecting on my approach. I have a few problems with it:

  • RobotLegs is fundamentally lightweight. It is my framework of choice because it’s hardly a framework at all. The Processes extension adds a lot of conceptual overhead and does a lot of work under-the-hood.
  • It separates the concept of a process from the concept of a command, but it can often be the case that previously synchronous code can become asynchronous (for example: when moving from mocked data to live data), or the other way (for example: once data is pre-loaded that was previously loaded just-in-time). Refactoring between commands and processes seems more trouble than it’s worth.
  • The under-the-hood part of the Process class means that it’s impossible to duck-type a Process. Duck-typing is good insofar as you know a framework that accepts duck-typable object has minimal dependencies.

These criticisms of the library led me to think about a more lightweight approach.

The Central Premise of Process

The central premise of my critique of asynchronous code is that this sort of code is bad because the Command contains both its own logic and sequencing logic:

// pseudo-code!

class Context
{
	signalCommandMap.map(runSecond, SecondCommand);
	signalCommandMap.execute(FirstCommand);
}

class FirstCommand
{
	[Inject]
	public var runSecond:Signal;
	
	public function execute():void
	{
		process = new SomeProcess();
		process.run().addOnce(onComplete);
	}
	
	private function onComplete():void
	{
		runSecond.dispatch();
	}
}

It would be preferable to abstract the sequencing logic, so that the FirstCommand can just report that it has completed what it needs to do without having to know what’s next.

I have often found that you end up drawing diagrams for code written this way with each command in a box with arrows between them. I want a class that encapsulates that diagram, ensuring that the individual commands are truly agnostic with respect to their context in the application.

A Different Approach

If we abandon the notion of a Process, then how can we retain this separation? My second approach has been to abstract the sequencing logic into a class, called CommandFlow. The intention is to use it like this:

// pseudo-code!

class Context
{
	injector.mapClass(ComamndFlow, CommandFlow);
	
	signalCommandMap.execute(InitCommand);
}

class InitCommand
{
	[Inject]
	public var flow:CommandFlow;
	
	public function execute():void
	{
		flow.push(FirstCommand);
		flow.push(SecondCommand);
		flow.next();
	}
	
}

class FirstCommand
{
	[Inject]
	public var flow:CommandFlow;
	
	public function execute():void
	{
		process = new SomeProcess();
		process.run().addOnce(onComplete);
	}
	
	private function onComplete():void
	{
		flow.next();
	}
}

The command sequencing is abstracted into InitCommand, so that FirstCommand doesn’t need to know anything more than that it is part of a sequence. CommandFlow is a helper that allows asnychronous command sequencing to take place with a minimum of impact on the classes’ functionalities themselves.

Each CommandFlow injected into a command is a separate instantiation, so that if nested command logic is required, then it is possible. For example:

// pseudo-code!

class Context
{
	signalCommandMap.execute(InitCommand);
}

class InitCommand
{
	[Inject]
	public var flow:CommandFlow;
	
	public function execute():void
	{
		flow.push(FirstCommand);
		flow.push(LastCommand);
		flow.next();
	}
}

class FirstCommand
{
	[Inject]
	public var flow:CommandFlow;
	
	public function execute():void
	{
		flow.push(SecondCommand);
		flow.push(ThirdCommand);
	}
}

In this structure, FirstCommand will trigger SecondCommand and ThirdCommand before LastCommand is executed.

Payloads can be passed in explicitly through the push method, as CommandFlow exposes this method:

public function push(command:Class, ...args):Boolean;

A working demo of the code-in-action is provided in the github repository here.

Notes

At the moment it is not clear how to handle commands being pushed into a CommandFlow once the flow has been started with a next() call.

If the CommandFlow approach is to be useful, I will need to add branching into the CommandFlow class, and it could quickly become very difficult to maintain. Careful thought will be needed to cope with this.

After my previous post, Camille Reynders made several good criticisms. One important one is how to handle failures. I think that this might be handled elegantly through branching, or possibly through some CommandFlow.error method that is a general ‘abandon-ship’ method. I’m not sure yet how to implement this, since I’m not yet committed to using this sort of approach to solving asynchronicity problems.

Brian Heylin also pointed me towards some interesting resources that led me to adjust my Notices classes (my implementation of the Signals concept) to expose what I am calling a ‘Future‘; essentially a single-dispatch Signal/Notice, such that if you bind to it post-dispatch, the bound method is immediately called with the data that was originally dispatched.

Last Thought

I am keen to emphasise that these ideas are not complete; they need refining, tweaking and using. Perhaps I have gone down another blind-alley? Perhaps the Processes idea is better after-all? Or perhaps I’m misunderstanding something fundamental about how to wire-up applications with asynchronous functionality that you can enlighten me about?

A blog is for nothing if not shared learning. If you have any comments (positive or negative) then I would really appreciate hearing them!

Aug 23 2011 / alecmce

Asynchronous Processes and RobotLegs

Asynchronous processes are a common feature of ActionScript applications: we often need to initiate some asynchronous process, wait for a response and handle it. We have good language tools and design patterns for solving these sorts issues.

RobotLegs is an MVCS framework that aims to decrease inter-dependency between different parts of code, so that code is more robust, and more reusable. It does this through a combination of dependency injection and the model-view-controller (+services) design pattern. The ‘controller’ portion of RobotLegs’ MVCS implementation is achieved by offering coders a simple way of implementing the Command pattern and binding commands to events that can be called from other areas of the code.

Problematically, commands are stateless and synchronous. They are not wired up to handle asynchronicity under-the-hood. “Async Commands” amend the Command structure to attempt to solve this problem, but they still contain architectural limitations that force us to restrict the way we code to the potential of the framework. Using Commands for asynchronous processes often require us to ‘double wire’ between different application elements to solve the problem of passing data between classes.

What I am calling Processes are a redesign of the Async Command concept that seek to resolve these issues. They can be used in parallel with Commands to elegantly handle the problems of asynchronous code in RobotLegs.

The Async Pattern

The event model exists explicitly because we often need to wire up code to be triggered at an indeterminate future event. Fundamentally, client-side programming is about state and asynchronicity: events handle the asynchronicity. We handle them with this sort of pattern:

public function init():void
{
	var process:AsyncProcess = new MyAsyncProcess();
	process.addEventListener(AsyncProcessEvent.COMPLETE, onProcessComplete);
	process.init();
}

private function onProcessComplete(event:AsyncProcessEvent):void
{
	var processs:AsyncProcess = event.process;
	process.removeEventListener(AsyncProcessEvent.COMPLETE, onProcessComplete);
	
	parse(process.data);
}

Signals improves upon this structure by removing the necessity of event classes and offers some added features like automatically handling the removal of listener functions:

public function init():void
{
	var process:AsyncProcess = new MyAsyncProcess();
	process.completed.addOnce(onProcessComplete);
	process.init();
}

private function onProcessComplete(process:AsyncProcess):void
{
	parse(process.data);
}

This pattern is simple but powerful – create an object to tokenise or act-as-delegate-to the process, bind to some generic event/signal defined on the token, then initialise the process. I take the signal implementation to be a substantial improvement to the original.

The Async Pattern across different objects

A more complex case emerges if one class wants to launch a process in another class and retrieve data from its result. Ideally we want to keep the same three-step process.

class Model
{
	public var service:Service;

	public function init():void
	{
		service.completed.addOnce(onServiceComplete);
		service.init();
	}
	
	private function onServiceComplete(process:AsyncProcess):void
	{
		parse(process.data);
	}
}

interface Service
{
	function get completed:Signal;
	
	function init():void;
}

Unfortunately, this pattern is now insufficient, because it is possible for two different objects to trigger an asynchronous process from the same service at overlapping times (such that the second one is triggered before the first response).

class InitModelsCommand
{
	public var a:Model;
	public var b:Model;

	public function execute():void
	{
		a.init();
		b.init();
	}
}

In this scenario, if modelA and modelB both call init() in turn, then modelB will receive the data for modelA, then remove its listener before its own data is retrieved (assuming that modelA’s data is returned first, otherwise vice-versa).

This problem comes about because the service exposes a single Signal for multiple requests. There are two options to remedy this limitation:

// option A - the calling service tells the response where to go
interface Service
{
	function init(signal:Signal):void;
}

// option B - the service generates a response signal on a per-call basis
interface Service
{
	function init():Signal;
}

There’s not a lot between the two solutions, but I prefer Option B because it keeps together the repsonsibilities for creating and managing delegates to the asynchronous process in the same place as the process itself.

The pattern morphs to this:

class Model
{
	public var service:Service;

	public function init():void
	{
		service.init().addOnce(onServiceComplete);
	}
	
	private function onServiceComplete(process:AsyncProcess):void
	{
		parse(process.data);
	}
}

interface Service
{
	function init():Signal;
}

Here, be aware that if the signal responds within the init() method then it will not be routed to onServiceComplete. This can be handled by defining a signal that once dispatched, will dispatch immediately to any methods that are then added.

Asynchronous Processes in RobotLegs

The point of RobotLegs is to keep as few dependencies between different parts of code as possible. Ideally a model and a service shouldn’t reference each other, so RobotLegs best-practises would suggest you separate their interaction into a Command:

class InitModelCommand
{
	[Inject]
	public var model:Model;
	
	[Inject]
	public var service:Service;

	public function execute():void
	{
		service.completed.addOnce(onResponse);
		service.init();
		
		commandMap.detain(this) // if we don't do this for an async command everything could explode
	}
	
	private function onResponse(process:AsyncProcess):void
	{
		commandMap.release(this) // if we don't do this for an async command commands stay in memory
	
		model.parse(process.data);
	}
}

There several problems with this implementation. Imagine that this command is called as part of an initialisation routine, and once complete, another command should be called:

class Context
{
	public function onStartup():void
	{
		signalCommandMap.mapCommand(InitModel, InitModelCommand);
		signalCommandMap.mapCommand(InitView, InitViewCommand);
	}
}

How should InitViewCommand be called? The only place where the InitModelCommand is known to be complete is in its own onResponse command:

class InitModelCommand
{
	[Inject]
	public var initView:InitView;
	
	...
	
	private function onResponse(process:AsyncProcess):void
	{
		model.parse(process.data);
		initView.dispatch();
	}
}

This is unsatisfactory. Without this, the command is neatly encapsulated and simple to describe and understand. Once this code is added, the command takes on two responsibilities: firstly to initialise the model, and secondarily to kick-off the InitViewCommand.

The stateless command design pattern is ill-suited for asynchronous processes, and the attempt to use them leads to poor code design.

An asynchronous process for RobotLegs

The simple cases at the start of this article are instructive if we try to design a preferred architecture from the ground up. While retaining the power of RobotLegs to remove class dependencies, we want to find a way to use the simple asynchronous process pattern to wire up processes.

These design considerations have led me to what I’ve tentatively called the robotlegs-async-process-extension. It’s very early stages, and as usual I’m sharing the code more to get feedback than as a polished piece of work, but it functions to provide what I think is a superior alternative to Async Commands.

The structure is roughly like this:

class Context
{
	public function onStartup():void
	{
		// a delegate is a new concept...
		processMap.map(InitModelDelegate, InitModelProcess);
		processMap.map(InitViewDelegate, InitViewProcess);
	}
}

Class InitModelDelegate extends ProcessDelegate {}

Class InitViewDelegate extends ProcessDelegate {}

class InitProcess extends Process
{
	[Inject]
	public var initModel:InitModelDelegate;
	
	[Inject]
	public var initView:InitViewDelegate;

	public function execute():void
	{
		initModel.execute().addOnce(onModelInited);
	}
	
	private function onModelInited():void
	{
		initView.execute().addOnce(onViewInited);
	}
	
	private function onViewInited():void
	{
		complete();
	}
}

Note the features here:

  • Like the SignalCommandMap extension, a different core structure, the ProcessMap is defined that allows Processes to be defined in a way similar to Commands;
  • Rather than binding an event or signal to a Process, we bind a ProcessDelegate. We need a little bit of extra functionality in the ProcessDelegate for the structure to work satisfactorily, but this is not functionally different from the SignalCommandMap extension;
  • When a delegate is executed, it passes back a signal that the calling object binds to in order to know when the process completes (it may also send back data through this callback);
  • Processes can’t be duck-typed, because they also need to inherit the functionality from their base class Process. Process exposes a complete() method that is called when the Process completes. If complete() is called inside execute(), then the Process becomes functionally equivalent to a Command.

In fact, this is not quite the library as developed, because I have started using Notices rather than Signals, so I have ported this across to Signals since it has a much broader adoption. Notices are pared down, simple implementations of Signals that allow you to expose very simple interfaces like the SingularNotice interface. It’s a preference thing; if anyone would like the original implementation with Notices, I’m happy to publish it.

I hope that this gives you some food for thought with respect to asynchronous processes. I’d love to know what you think about the idea, the implementation, the implied critique of RobotLegs. Let me know!

Jul 23 2011 / alecmce

gaia-tween

Today I have pushed the first version of a new open-source tween library to github/alecmce/gaia-tween. I have been working on it for some time, to provide a robust, flexible, extensible alternative to the Greensock stable of tween libraries (TweenMax, TweenLite, etc.).

I have several reasons for choosing not to use Greensock libraries for tweening:

  • I have great respect for TweenLite, but I have rarely used it in anger. Most of the time, the applications that I work on have some element of pay-to-play, and Greensock has an unusual license that has put-off at least two employers from using it. I do not want to learn a library that I can only use on some of my projects;
  • For all the clean code we try to write, Tweening libraries often jar with their funky APIs. I didn’t want my tweening library to be a statically-referenced black-box of almost unreadable code, I wanted it to have elements with well-defined responsibilities, objects that encapsulate concepts of time, tweens and eases. I wanted to be able to TDD these elements and offer my tests for public scrutiny. In short, I wanted my tweening library to feel more like the rest of my code and less like dark magic;
  • Probably most of all, I wanted to write it because I could, and because I hadn’t yet.

Speed and Memory

In the tests that I have done so far, gaia-tween is fractionally behind TweenLite on speed. However, it is ahead in memory consumption! Currently the strategy for gaia-tween is to instantiate the elements that it needs and pool them indefinitely, so there is no garbage collection taking place, but I am looking to add that in as a future iteration. During tweening, no object is constructed nor destroyed by the tweening engine. Compare the memory profile of the two tween engines, from the SpeedDemo test below (SpeedDemo source here):

gaia-tween memory graph

TweenLite memory graph

gaia-tween uses considerably less memory to run than TweenLite.

Structure

The API challenge was to find the right separation of responsibilities to keep the tween engine extensible without the extender having to do unnecessary work. The key features of this API are:

  • Time is an independent concept from the tweening engine. A Time object is passed into the Tweening engine, which responds to changes in milliseconds-elapsed appropriately;
  • The ease functions have been simplified so that eases take one parameter – a proportion between 0 and 1, and return back a proportion between 0 and 1. This should make it easier for custom eases to be implemented;
  • The duration of a tween, the delay before starting it and any ease that may be applied to it are defined at the moment that a tween is added;
  • All other definition depends upon the context of the tween, and can be defined in a TweenForm. Currently three different kinds of TweenForms exist: a PropertyTweenForm for performing classic property tweens on objects; a ColorTweenForm for tweening the ColorTranform.color property of a DisplayObject; a MethodTweenForm for defining a method that will take the proportion between 0 and 1.

This diagram may help explain the concepts more easily:

I have also added a convenience class that does the job of creating the TweenForms for you, GaiaTweens.as. This object-pools property tween forms and exposes a simplified API for those who want their tweening engine to keep everything under the hood.

Examples

The ColorTweenForm in action (roll-over to trigger):


By passing in a different Time class, timeline animations are possible:

Some issues with time-lining remain, and will be worked on for future improvements to the engine.

Notices and Signals

I am a huge proponent of the as3-signals library. When Robert Penner originally introduced Signals, I was working on something similar with my friend Simone. Since that time I have used Signals in almost every project I have worked on. However, One thing I really want to be able to do is to define a signal that only exposes an addOnce method. I have advocated this but there is clearly a disagreement about the direction that signals should take. So, I have created my own – simplified – implementation of signals. For want of a better name, I’ve called them Notices. However, if you are interested in using or trying-out gaia-tween but are committed to using Signals, there is a signals branch that replaces the Notices with Signals.

Feedback

I have produced this for my work at Gaia Interactive, but Gaia have agreed to it being released because we would greatly appreciate feedback about it so that it can be improved. Please comment on API decisions, code implementations, feature requests, and so on. The more feedback I get, the more likely I can produce a robust, scalable alternative to the Greensock tweening stable. Or of course, you could fork the library and help improve it more directly!

Jul 17 2011 / alecmce

Reflection on Code Design

I recently created a Time class which can cope with two distinct methodologies for pausing. Time will essentially be a wrapper for getTimer() that has a tick signal that fires once-per-frame and can be used as a replacement for Event.ENTER_FRAME listeners.

Sometimes, if you’re making a game like Asteroids, you want to be able to pause the game, and on resume, it continues precisely where it left off. Other times, if you’re making a social game, when you pause time continues. When you resume, your state has to suddenly catch-up.

You can think about this in terms of whether time is an intrinsic property of your game (if your game pauses, time pauses) or an extrinsic property that your game references (when your game pauses, time carries on).

Which leaves me with three possible designs for my Time class. I found it interesting that I actually went through each of these three designs, and am still unclear about whether the second or third strategy is the best.

Strategy One

public class Time
{

    public function Time();

    public function get now():uint;

    public function pause(strategy:PauseStrategy):void;

    public function resume():void;

    public function get tick():ISignal;

}

public class PauseStrategy
{
    public static const TIME_IS_EXTRINSIC;
    public static const TIME_IS_INTRINSIC;
}

The first strategy offers a great deal of flexibility. Each time you pause, you can decide whether in this case time is intrinsic or extrinsic. This seems flexible, but then it occurred to me that I couldn’t conceive of a case in which I would need to keep changing the ‘pause strategy’.

Strategy Two

public class Time
{

    public function Time(pauseStrategy:PauseStrategy);

    public function get now():uint;

    public function pause():void;

    public function resume():void;

    public function get tick():ISignal;

}

public class PauseStrategy
{
    public static const TIME_IS_EXTRINSIC;
    public static const TIME_IS_INTRINSIC;
}

That led me to the second strategy. I have dropped the PauseStrategy from the pause method and the API looks much easier to use, as it has fewer parameters.

I have left the PauseStrategy as stub-code, but the elegance of the whole PauseStrategy approach is that the TIME_IS_EXTRINSIC and TIME_IS_INTRINSIC constants could contain the core behavioural difference themselves, without needing switching inside either strategy one or two, like this:

PauseStrategy


public class PauseStrategy
{
    public static const TIME_IS_EXTRINSIC:PauseStrategy = new ExtrinsicPause();
    public static const TIME_IS_INTRINSIC:PauseStrategy = new IntrinsicPause();

    internal function onResume(timeAtPause:uint, timePaused:uint):uint
    {
        return Number.NaN;
    }
}

final internal class ExtrinsicPause extends PauseStrategy
{
    override internal function onResume(timeAtPause:uint, timePaused:uint):uint;
}

final internal class IntrinsicPause extends PauseStrategy
{
    override internal function onResume(timeAtPause:uint, timePaused:uint):uint;
}

In this way both the first two strategies can find out what the time after the pause should be by asking the strategy. The different strategies are geniunely encapsulated.

I am a little uncomfortable in enumerating in this way. There are plenty of ways that you can attempt to make this type-safe, but it does upset me that I have broken many a coding law by making the PauseStrategy class itself broken. It should probably be an interface itself… and then do I need a PauseStrategy factory? bah…

The neat API of the second strategy presents a third strategy:

Strategy Three

public interface Time
{
    function get now():uint;

    function pause():void;

    function resume():void;

    function get tick():ISignal;
}

public class ExtrinsicTime implements Time;
public class IntrinsicTime implements Time;

Here the different functionalities of the two different PauseStrategy objects would be shifted into the two different implementations of Time. Unless I ended up having an internal BaseTime class, the third strategy would mean giving up a certain amount of code DRYness, since there would be a lot of repeated code in the two different Time implementations. I am always a little uncomfortable defining both an interface and a base class, though I have never been able to explicate exactly why.

So I have replaced two PauseStrategy implementations with two Time implementations. What have I gained? It seems unfeasible that there would be a third time strategy that someone could independently develop and satisfy the API for Time, so is there any good justification for interfacing Time?

What would The Perfect Coder Do?

The correct decision for the design of this class is that it should satisfy the current use-case. TDD purists might argue that once the current use-case is satisfied, other design decisions are moot. I am sympathetic to this way of thinking, and cannot offer a counter-argument stronger than suggesting that this design thought-process is in-itself valuable; I do not want to minimally satisfy requirements, I want to satisfy them in the most elegant, satisfying way.

But which is more satisfying? While writing this I have drafted arguments that assert that both strategy 2 and strategy 3 are the best, and have found those arguments unconvincing. I am probably going to settle on strategy 2 for the time-being. Not being The Perfect Coder though, I would welcome a bit of wisdom from the community.

May 27 2011 / alecmce

Working remotely and SVN

I am working remotely with a company in Beijing from Aberdeen, UK. The Beijing team is primary, they have setup an svn server to host code and have a QA team for testing. Whatever other test harnesses are in play, a commit isn’t solid until it passes QA. This is a diary of events, written retrospectively.

Abereen 9am, Beijing 5pm

Conference call with Beijing to decide what I’m working on. All goes well, I start working.

Aberdeen 2pm, Beijing 10pm (Commit +0 hours)

I try to commit and discover that the svn server has gone down. I am stuck with a commit that I cannot commit. What do I do? The Beijing team will want this commit first thing their time, but that’s 11 hours away, at 1am my time. I can’t sit on it until then, and I don’t want to do nothing. I decide to create a patch

svn diff > mywork.diff

Now, if I get stuck, I can

svn revert -R *
patch -p0 -i mywork.diff

and I’m back to what would be HEAD if svn wasn’t down! Essentially I’ve found a way to store atomic commits before they’re committed, marvellous. And so I continue…

Aberdeen 4pm, Beijing: 12pm (Commit +2 hours)

svn revert -R *
patch -p0 -i mywork.diff

15 out of 15 hunks failed
8 out of 8 hunks failed
3 out of 3 hunks failed
...

What!? The patch failed? How can this be!? It makes no sense! Slowly it dawns on me that the Beijing office is universally PC, whereas I am using a Mac. diff and patch expect unix line-endings, and something in there has confused them. Without any external changes at all, I’ve screwed myself. My work is gone, and I’ll have to manually apply my diffs back to the source.

Now, clearly I’m at fault here. I make no bones about the fact that I should have thought long and hard before I svn reverted, but I didn’t. More fool me.

Aberdeen 6pm, Beijing 2am (Commit +4 hours)

I have manually applied my diffs to the source and now I’m going to stop working on that and do work on a personal project. The last thing I want to do is to have to do that again!

Aberdeen 1am, Beijing 9am (Commit +11 hours)

I’m asleep, meanwhile Beijing sort out the svn server and get my emails. They don’t dare touch the diff, especially after my problems.

Aberdeen 9am, Beijing 4pm (Commit +19 hours)

I awake, and commit my code. I do other work…

Aberdeen 1am, Beijing 9am (Commit +36 hours)

This is the first opportunity Beijing has had to test my work.

If we’d been using git

Imagine what would have happened if we’d been using git. I put it to you that I would have saved maybe 6 hours of my time and my work would have been QAed 25 hours sooner.

Aberdeen: 2pm, Beijing: 10pm (Commit +0 hours)

Having git committed incrementally into a local branch in my locally cloned repo, I decide it’s time to merge back to master and push. Push fails, seems like their repo is down. Oh well. I’ll keep working.

Aberdeen: 1am, Beijing 9am (Commit +11 hours)

Beijing comes in, sort out the git server and get my emails. Realising what has happened they pull from my repo as a remote, which I have made sure is available for them in as a conscientious guy, not only that commit but also the other work I could have done in the 4-6 extra hours I had during that day to do work. My work can be QAed, 25 hours sooner than it actually was.

Discussion

Is git better than svn, or svn better than git? Almost certainly your reaction to this question is that the one that you use most and are most comfortable with is better. Of course it is, and I’m not going to be able to dissuade you with one anecdote.

Don’t delude yourself: most people when asked this question don’t say or even think “well, I use x more so x is better”, they think of all the reasons why x is better… but here’s the thing, they do so after they make their mind up, and usually their minds are made up by emotion rather than rationality. Think about it; it happens a lot. It happens to me, and to everyone at one time or another.

So I’m not going to tell you that git is better than svn categorically, I’m just going to say that in this scenario, I think wouldn’t git have been much better?

Mar 31 2011 / alecmce

Working with Firefox

Just a quickie, that you probably already know. I don’t think have I updated Firefox in a while, and suddenly when I did I was getting a lot of firefox Flash crashes when I was studying code on a breakpoint.

It turns out that recent versions of Firefox run the Flash Player on a separate process that has a timeout of 45 seconds. If the player hangs for that long then the Flash Player will be crashed. That’s fine for people consuming content, but for developers it is not acceptable.

The solution is to modify about:config, and to amend the value of dom.ipc.plugins.timeoutSecs to the number of seconds before a crash is triggered. You can choose -1 for never, or some sufficiently long period of time.