Swift Method Swizzling (almost!)

Previously I was wondering how to test precondition() and assert() in my code. Well, Nikolaj Schumacher suggested something clever: shadow the precondition() and assert() functions.

My implementation his suggestion can be found here: https://github.com/owensd/swift-fix/blob/master/Assertion.swift. There is still a slight problem with this version though: normally precondition() and assert() will terminate the execution of the function, but unless you use my throwing version of those functions, your code path will continue to execute. This may or may not be a problem for you, so beware.

But wait… if we can shadow the functions and replace them with our own implementations, then this means that method swizzling is back on the table!

Here's an example:

Let's say, we have a scenario, where isEmpty on an array is just utterly broken. Too bad for us, right? Well… not exactly.

extension Array {
    var isEmpty: Bool {
        print("monkey patch!")
        return false
    }
}

let a: [Int] = []
a.isEmpty           // guess what this outputs? =)

Now, there is a caveat here… I don't know how to call the base implementation, so you're stuck with re-implementing the entire thing for member functions. For global functions though, we can fully qualify them to explicitly get the version we want.

Maybe someone else knows how to do that part?

Update, later that evening…

So, it turns out this really only works for the following:

  1. Global functions
  2. Properties on non-@objc types.

Oh well, and interesting hack. It does seem strange that some things can be shadowed and other things cannot.

Swift Method Swizzling (almost!)

precondition() vs types

I have a bit of a design conundrum. I have an API that looks like this:

public func next(index: ContentType.Index?) throws -> TokenizerResult<ContentType>? {
    precondition(rules.count > 0, "There are no rules specified for your tokenizer.")
    // ...
}

This belongs on a protocol Tokenizer and a default implementation is provided in an extension. The rules are static per type, at least in the default case.

So… the problem? I cannot write a test for this code because precondition fails with an uncatchable runtime exception. What I really want is a type ArrayOfOneOrMore<Element>. However, this requires a lot of code and method forwarding to work; I don't want to do that.

It seems my options are:

  1. Be ok with not being able to write a test for this.
  2. Relax the condition, but this hides a logical implementation error.
  3. Do all of the work to implement ArrayOfOneOrMore<Element>.

Is there another option I'm missing?

Update July 9th, 2015

So I've been thinking about this some more. There is a workaround that can be done: change precondition() to assert() and compile out the assertions in a new Debug-unchecked build for testing. This keeps all of the good debugging symbols and optimizer changes at bay while still allowing for testing your code flow.

Steps to get this to work:

  1. Create a new build config Debug-unchecked
  2. Change the Other Swift Flags (OTHER_SWIFT_FLAGS) compiler options to -assert-config Release
  3. Change precondition() to assert()
  4. Update your code to handle the code path for the error state

    public func next(index: ContentType.Index?) throws -> TokenizerResult?

    assert(!rules.isEmpty, "There are no rules specified for your tokenizer.")
    		if rules.isEmpty { throw TokenizerError.NoTokenizerRulesPresent }  
    		  // ...
    		

    }

This has the benefit of raising the error immediately on failure for debug builds, providing a testing path, and still providing the error in a catchable way in release builds.

Of course, if I do this a lot, I'll probably just do this:

public func next(index: ContentType.Index?) throws -> TokenizerResult<ContentType>? {
      try assert(!rules.isEmpty, "There are no rules specified for your tokenizer.", TokenizerError.NoTokenizerRulesPresent)
      // ...
}

And create these helpers that I just use all the time:

func assert(@autoclosure fn: () -> Bool, _ error: ErrorType) throws {
    return try assert(fn, "", error)
}

func assert(@autoclosure fn: () -> Bool, _ message: String, _ error: ErrorType) throws {
    let result = fn()
    assert(result, message)
    if !result { throw error }
}

At least with these helpers it's no extra work for me. The biggest drawback I see is that it requires compiling my code again, which could suck.

precondition() vs types

init? vs init throws

Now that we have some proper error handling measures, I've been having a bit of a rough time deciding between init? and init() throws.

What I've come to realize is, my problem is really about the callsite, I actually always want to use throws. The simple fact is that I can return more information about the failure and let the caller decide if they care about it or not.

Here's an API that currently uses init?() that I think would actually value from providing the failure reason instead of just a blanket nil.

/// Construct from an ASCII representation in the given `radix`.
///
/// If `text` does not match the regular expression
/// "[+-][0-9a-zA-Z]+", or the value it denotes in the given `radix`
/// is not representable, the result is `nil`.
init?(_ text: String, radix: Int = default)

Ok, back to my usage problem example:

enum Error : ErrorType {
    case NotImplemented
}

struct Foo {
    init?(failable: Int) { return nil }
    init(throwable: Int) throws { throw Error.NotImplemented }
}

func example1() {
    guard let f = Foo(failable: 0) else {
        print("error")
        return
    }

    print("Foo(failable:) creation passed")
}

func example2() {
    do {
        let t = try Foo(throwable: 0)
        print("Foo(throwable:) creation passed")
    }
    catch {
        print("error: \(error)")
    }
}

example1()
example2()

The throws version really sucks in comparison. It's especially egregious because I'm going to be handling the failure case in exactly the same way.

Ok, so let's make it better:

func trythrow<T>(@autoclosure fn: () throws -> T?) -> T? {
    do { return try fn() }
    catch { return nil }
}

func example3() {
    guard let tt = trythrow(try Foo(throwable: 0)) else {
        print("error")
        return
    }

    print("Foo(throwable:) creation passed")

}

example3()

This gets us into a happy place again. We can turn failures where we do not care about the specific reasons into a code path that is more natural. If this becomes a pattern, it begs the question why this wouldn't be just built into the language.

Enter try?.

See this thread for some more great discussion.

// this won't compile, hypothetical syntax
func example4() {
    guard let tt = try? Foo(throwable: 0) else {
        print("error")
        return
    }

    print("Foo(throwable:) creation passed")
}

example3()

I think this is a big win. Note that while this appears to be encouraging one to ignore errors, it in fact doesn't. Many types we only care that a failure happened. This syntax simply reduces the complexity of the code when that is the case.

Also, try? is very searchable so it is trivial to audit your code for all of the uses of it to ensure error handling is indeed not needed in a fuller form.

Finally, because an Optional<T> is being returned, you are still forced into unwrapping it in order to use it.

I like it. Until we get it, trythrow() is going to be my goto.

P.S. Someone already logged rdar://21692462 on it. Great!

init? vs init throws

Apous – Swift Script Package Manager

So I've had this project on my mind for a few months now: Swift script management system. While I was doing the planning for it, I was dreaming big… like how could we replicate the Python system.

That's a lot of work though… and I had other things going on. And really, who would want to use it besides just me?

Then I saw this talk by Ayaka Nonaka and thought to myself, "OK, maybe people would actually like to have something like this."

Instead of going big, I figure I'd just start small and do it the hackiest way possible: concat files together and call it good!

So if you're looking for a way to write Swift scripts and manageme dependencies, check out Apous.

Apous – Swift Script Package Manager

‘RE: Should I use a Swift struct or a class?’

There is a post about using structs or classes in Swift here: Should I use a Swift struct or a class?. If you like functional programming or reducing state mutations, be warned, it's somewhat antagonistic to your position.

The fundamental problem I find with the piece is that it creates a false selection of choices to the problem statement posed while misrepresenting much of the advice about chosing when to use value types. I think it also confuses the purpose of the proposed "inner class device".

1. We have a protocol defined as:

protocol CanSend {
    typealias Message
    func send(messgage: Message) throws
}

2. We need to implement this protocol in two manners: one that mutates and one that does not.

Specifically, the desire is to create a MockServer<T> that can be used to keep track of state for testing. Ok, this sounds reasonable. So the following is presented:

struct MockSender<T> {
    var sentMessages: [T] = [] //you inspect this property to study 
    //what messages were previously sent for unit test purposes
}

extension MockSender : CanSend {
    typealias Message = T
    func send(message: T) {
        self.sentMessages.append(message) //error: Immutable value 
        //of type '[T]' only has mutating members named append
    }
}

This, as pointed out, does in fact present a problem. The protocol function send is not marked as mutating yet the implementation clearly attempts to mutate itself.

However, this is the conclusion that is drawn:

Right, so the problem is our protocol says the function is non-mutating, but in reality it needs to be mutating.

So we go change the protocol, right? I mean after all, by definition this program has no legacy code, so we can structure the protocol however we want.

After some clammering about how this is the wrong approach, which I agree, there is no need to mark the function as mutating, we get to this conclusion:

We can solve this problem with a device called an "inner class", which you probably have already seen, but if you haven't just imagine that there is some god-awful way to create a mutating implementation of a non-mutating func, and we will cover the details later.

This, is actually the wrong conclusion. The entire purpose of the "inner class" is to provide value semantics while maintaining effeciency of implementation. In addition to that, if some of the quoted advice in the article had been followed with regards to struct usage, a different conclusion would have presented itself. Let's look at this piece of advice:

Don't use classes when structs will do. Use classes if you want reference types. Use structs if you want value types. You can add functionality to both (and to enumerations) in Swift. When in doubt, err on the side of value types. If your construct doesn't have a life cycle, or two constructs with similar values should be considered as the same thing, use a struct. (Do take advantage of Swift structs. They're neat.)

I emphasized the interesting bit from there.

You see, MockSender<T> does indeed have a lifecycle; it has a history of all messages sent that varies over time.

Also, this piece of advice:

Unless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead… Rationale: Value types are simpler, easier to reason about, and behave as expected with the let keyword.

In addition to that, we have a protocol in which we do not want to enforce a mutation contract across all conforming types. A class provides us the functionality that only it provides. So why not simply follow the advice and create this version instead?

{} class MockSender

var sentMessages: [T] = []

}

extension MockSender : CanSend

typealias Message = T
func send(message: T) {
    self.sentMessages.append(message)
}

}

This solution does exactly what we want. It also does it by maintaining the protocol can be conformed by immutable value-types and my mutable reference types. This is a validation of the "Structs Philosophy‚Ñ¢"; `MockServer<T> is not a value-type, don't try and make it one. 

The problem with the first example is that, in my opinion, the author conflated two separate things: the desire to create a value type and the usage of inner classes in value types for performance reasons. If, we really wanted immutable value-types from the protocol and allow state changes, the protocol should have been defined as such:

protocol CanSend

typealias Message
func send(messgage: Message) throws -> Self

}

The weird part about the piece is that we end with the conclusion that we should have just started with, and that conclusion isn't in disagreement to much of the advice out there about starting with a struct and move to a class when/if necessary: 

> In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.

So...

 - Yes, make your `MockServer<T>` a class.
 - No, do **not** write the "struct with inner class wrapper" so you can simply make it pseudo-mutable.
 - You should still start with the question: is my type a value-type or a reference type? This is also the advice from Apple.

 **Update Sunday, July 5th @ 4:03PM**
 Here's a follow-up [conversation thread](https://gist.github.com/drewcrawford/752b2bfef7d8574eab01).
‘RE: Should I use a Swift struct or a class?’

Swift’s Scripting Is Not Magical

Ever since Swift has debuted, there's been a bit of a fuss about how it can be used for scripting. Yes, yes it can, but so can every other language that has an interpreter, or more accurately, a binary that can do something with the input file.

In fact, we can even make such a thing for C.

Here is what our little "c script" will look like.

#!/path/to/cscript

#include <stdio.h>

int main() {
    printf("I want to be a cool kid too!\n");
}

Now, the astute among you may have noticed something… the magic SHEBANG (#!) is, well, it is currently pointing to some magic place.

I've actually created a little tool to help us out (of course it's in Swift!).

import Foundation

let path = NSProcessInfo.processInfo().arguments[1]
let code = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)

let newCode = code
    .componentsSeparatedByString("\n")
    .filter { $0.rangeOfString("#!/") == nil }
    .reduce("") { $0 + $1 + "\n" }

try newCode.writeToFile("_script.c", atomically: true, encoding: NSUTF8StringEncoding)

var task = NSTask()
task.arguments = [ "_script.c", "-o", "_script" ]
task.launchPath = "/usr/bin/clang"
task.standardOutput = NSFileHandle.fileHandleWithStandardOutput()
task.standardError = NSFileHandle.fileHandleWithStandardError()

task.launch()
task.waitUntilExit()

var script = NSTask()
script.launchPath = "_script"
script.standardOutput = NSFileHandle.fileHandleWithStandardOutput()
script.standardError = NSFileHandle.fileHandleWithStandardError()
script.launch()
script.waitUntilExit()

try NSFileManager.defaultManager().removeItemAtPath("_script.c")
try NSFileManager.defaultManager().removeItemAtPath("_script")

First, compile that Swift code into an executable cscript. Next, modify the #! reference in your C source to point to this new cscript tool. Finally, be sure to chmod +x on the

"c script" file.

Then, it's simply a matter of running it like any other script:

> ./script.c
I want to be a cool kid too!

Anyhow, I just wanted to point out that this is not some black-magic that Swift is doing; it is simply a by-product of the Swift REPL environment. This is just one of the great things about our lovely OS X being backed by a unixy foundation.

Swift’s Scripting Is Not Magical