Sam Croft

Full-stack developer

Quick tip: return from functions as soon as possible

  • 0 comments

Filed in: best practices, coding, programming

Programming: always return as soon as possible

I wish I could recall where I first read about this programming approach, it’s something that has made my code much more readable over the last few years and I’d love to credit the author.

Avoid heavily indented/pointy code, return as soon as possible

The idea is simple; whenever you’re using conditional statements, always return (or throw an exception) as soon as possible to avoid complex nested if/else blocks.

Consider the following pseudo code for a log in process:

public someLoginMethod(login) {
	if (login) {
		if (login->user) {
			if (user->isActive(login->user)){
				user->doLogin(login->user);
			} else {
				user->reactivateUser(login->user)
				user->doLogin(login->user);
			}
		} else {
			return false;
		}
	} else {
		return false;
	}
}

There is nothing wrong with the above code, but it’s not as readable or as logical as it could be. It’s visually inefficient. The horizontal indenting is getting out of hand—add a few more conditions and you’d have some pointy code! If you were to add comments and several more layers of statements and function requests you’d be looking at a mess that would be very difficult to develop with, not to mention understand when revisiting it after a month or year.

This can be simplified by returning as soon as possible with the following:

public someLoginMethod(login) {
	if (!login) {
		return false;
	}

	if (!login->user) {
		return false;
	}

	if (!user->isActive(login->user)){
		user->reactivateUser(login->user);
	}

	user->doLogin(login->user);
}

This is a lot more readable and executes, visually, in a more logical order. There is no excessive horizontal tab indentation (no pointy code!). Even with empty lines between our conditional blocks there is still fewer lines than the first example.

Another big benefit is that it gets you thinking about the target (or desired) flow vs unexpected/invalid flow. In the first example the emphasis was on getting to the desired flow as quickly as possible. By this I mean in terms of the line number of the start of the statement vs the line number of the target function execution. It means that all the unexpected/invalid flow occurs after the line number of the target execution and you end up returning, or throwing exceptions, lower down in your function. Again, that’s fine, but it’s not logical. Get the unexpected/invalid flow out of the way before you begin handling the desired flow. Return as soon as possible.

About the author

I'm Sam Croft a full-stack developer with over 15 years experience in web and app development. For the last six years I have been a partner of Running in the Halls, an app and game design studio based in Huddersfield, UK. During this time I have developed many web and applications. Highlights include a node.js/socket.io app to create the worlds largest crowd-based game on the first series of Channel 4's Gadget Man with Stephen Fry and Librarygame, a Library gamification platform for Universities. Librarygame is being played by over 6,000 students at The Open University, The University of Manchester, The University of Glasgow and The University of Huddersfield.

In my spare time I enjoy long distance running, watching all sports (especially F1) and playing video games. I live in the Holme Valley in West Yorkshire with my wife, Alex.

Sometimes I tweet.