Saturday, 19 March 2016

On Pair Programming

Pair programming is one of those widely known programming methodologies. Most of us would certainly nod in agreement when its benefits are described. By pair programming we simply mean that two developers work side by side, one is the 'driver' that writes the code while the other is the 'observer' or 'navigator' in charge or reviewing the code that gets written. The former ends up having a more tactical approach, concentrating on the current line of code being written; while the later tends to think more strategically about the problem. 

In this brief article I'll describe some of the benefits that can be derived from it as well as simple ways it can be introduced into your current workflow in order to achieve some immediate benefits. It's worth noting that it's effectiveness is reduces is there is a big gap in the knowledge of the two participants. In that case, pair programming becomes more of a teacher-student situation, which has its own pros and cons.

1. Getting up to speed with a new codebase

When a new member joins an existing project or team, it can take some time (depending on size) to get fully comfortable with the existing codebase. Pair programming can speed up this process substantially as the existing team member can provide context as well as check the assumptions that the new team member is making. Furthermore, existing bugs might be found through this process.

2. Producing higher quality code

Working in isolation means that are assumptions are seldom checked, or are checked at a later stage if code reviews are in place. With pair programming, chances are that we can end up with a better architecture as both peers discuss the best way to structure a problem and negotiate a common approach. Furthermore, the final solution might be a blending of two different yet complementary approaches.

3. Solving a complex problem faster

When faced with a complex problem we can occasionally get stuck trying to find a way around it. Although we will eventually find a satisfactory solution, we might end up wasting a significant amount of time. Perhaps a little time spend pair programming with a more experienced college can help us overcome the block and find an effective solution to our conundrum. We might even have the advantage of ending up with a higher quality solution.

4. Job interviews

The traditional job interview tends to involve a coding test or programming questions. Sometimes a small, self-contained project will put together by the candidate. This artificial project tends to be over-engineered as the candidate seeks to show how she would architecture an application or how many of the more esoteric features of the language they know. 
Pair programming can provide a better alternative: The candidate doesn't work on an artificial, isolated code-base and the employer can get a better idea if the candidate would be a better fit as they work with existing members of the team. The candidate would be driver, while one of the existing employees would review their code. In this way, they can understand the candidate's train of thought as she writes the code.

Conclusion

We've seen here some of the ways that pair programming c###an easily be put into practise. Hopefully, this gives you an idea on how you can try it out.

Wednesday, 16 March 2016

Extending Swift generic types

TL;DR - Generic Swift types such as Array or Dictionary can be easily extended to provide methods to specific types by making their associated type(s) either conform to a protocol or inherit from a class
Back in the days of Objective-C it was very common to extend NSArray using a category to add convenience methods. However, as far as I know since Objective-C did not have generics it was not possible to constrain these category method to a specific type of NSArray. In Swift, typed arrays are the norm and sometimes it's necessary and very useful to extend these typed arrays to suit own needs. This post looks at how can Swift generic types be extended.

Extending an array of strings (i.e. Array<String>)

A few weeks ago I wanted to add a convenience method to an array of strings for a project I was working on. The first thing that came to my mind was to literally constrain the Array to a String. However, the moment I did this I got the following error: Same-type requirement makes generic parameter 'Element' non-generic.

 Back to the drawing board then...
What this is error is saying is that we cannot make an associated type non-generic because Swift does not support this. Presumably, this is because it would defeat the purpose of having an associated type originally. This error can be reproduce by the following code:
protocol MyGenericProtocol {
  associatedtype MyGenericProtocolType  //typealias in swift 2.1 and below
}

struct MyGenericStruct<MyGenericStructType>: MyGenericProtocol {
  typealias MyGenericProtocolType = MyGenericStructType
}

extension MyGenericStruct where MyGenericStructType == String {} // compiler error
The only way to constrain an extension for Array is either through a protocol or class and not a struct. An associated type can be constrained by inheritance or conformance but not equality because that would mean it would cease to be an associated type.

Naturally we cannot inherit from a struct

Attempting to constrain an Array by inheriting from a struct would look something like this:
struct MyStruct {}

extension Array where Element: MyStruct {
  // Functions that should only work for an array of MyStruct
}
Annoyingly, attempting to do this throws a compiler error but it's only shown when used on an Xcode project and not a playground. Not even the line of code of the error is marked. This code produces this error: Type 'Element' constrained to non-protocol type 'MyStruct'.
Therefore, the following are valid cases to constrain an Array:

1. By constraining the Element so that it conforms to a protocol:

protocol MyProtocol {}

extension Array where Element: MyProtocol {
  // Functions that should only work for an array of MyProtocol
}

2.a. By constraining the Element so that it inherits from a class:

class MyClass {}

extension Array where Element: MyClass {
  // Functions that should only work for an array of MyClass
}

2.b. The Element can also be constrained to an Element that inherits from a root final class

This is unusually valid, considering the original compiler error, Same-type requirement makes generic parameter 'Element' non-generic. Unless I'm missing something, by constraining an Array to a final class it means that the Element in the Array is no longer generic. Hence, maybe the error should say something about equality not being allowed:
final class MyRootFinalClass {}

extension Array where Element: MyRootFinalClass {
  // Functions that should only work for an array of MyRootFinalClass
}

3. By constraining the Element so that it inherits from a class and conforms to a protocol

class MyClass {}

protocol MyProtocol {}

extension Array where Element: MyClass, Element: MyProtocol {
  // Functions that should only work for an array of MyClass objects that conform to MyProtocol
}

Practical example

Using what we learned, we can now solve the original problem. The first thing would be to create a custom protocol, StringProtocol, to be used to extend our Array. Within the protocol we need to declare the functions we need to use inside our extension. Finally, we need to declare that String conforms to StringProtocol.
protocol StringProtocol {
  func hasPrefix(prefix: String) -> Bool
}

extension String : StringProtocol {}

extension Array where Element: StringProtocol {
  
  func filterByPrefix(prefix: String) -> [Element] {
    return filter { (element) -> Bool in
      element.hasPrefix(prefix)
    }
  }
  
}

let strings = ["aa", "ab", "bc"]
strings.filterByPrefix("a") // ["aa", "ab"]

Dictionary example

A similar and also highly useful scenario is about constraining a Dictionary for JSON decoding as it's the case of version 2.x of JSONUtilities. With a simple extension we can use type inference to decode a JSON that has a String key to the correctly inferred type. For example, for decoding a String from a dictionary of weakly typed AnyObjects:
protocol StringProtocol {}
extension String : StringProtocol {}

// Error enum for handling missing mandatory keys
enum Error : ErrorType {
  case NoValueForKey(StringProtocol)
}

public protocol DecodingSupportedType {}
extension String : DecodingSupportedType {}

extension Dictionary where Key: StringProtocol {
  
  func decodingKey<ReturnType : DecodingSupportedType>(key: Key) throws -> ReturnType {
    
    guard let value = self[key] as? ReturnType else {
      throw Error.NoValueForKey(key)
    }
    return value
  }
  
  func decodingKey<ReturnType : DecodingSupportedType>(key: Key) -> ReturnType? {
    return self[key] as? ReturnType
  }
}
This Dictionary extension could then be easily using to decode a [String: AnyObject]while keeping the type safety.
let dictionary: [String: AnyObject] = ["key": "value"]

/// Type inference from variable type
let mandatoryValue: String = try! dictionary.decodingKey("key") //"value\n"
let optionalValue: String? = try? dictionary.decodingKey("key") //"Optional("value")\n"

// Handling failures with mandatory keys
do {
  let mandatoryValue: String = try dictionary.decodingKey("otherkey")
} catch let error {
  print(error) // "NoValueForKey("otherkey")\n"
}

Conclusion

It's certainly not immediately obvious how to extend an Array, a Dictionary or any generic type for that matter. However, by understanding these simple concepts it's possible to create highly reusable and strongly type functions that only work for the type you expect.