So I've actually been doing a lot of thinking about this, because I have a use case that doesn't work as well as in Swift.

You have some problems. The first problem you have, is that static compilation provides so many routes for cross-applicaton optimization that this is one of the major ways that Swift can be faster than its predecessors. For example, if you have this

func min<T: Comparable>(x: T, y: T) -> T { //Generic functions
if x < y {
return y

return x
}

min(3,5)

min(5.0,2.0)

The compiler has a lot of possibilities. For example it could translate this function very literally, producing the generic min function that you wrote. It could realize that you only use this for floats and ints, and emit 2 particular specializations of the min function. It could specialize the float function and use the generic function for ints, or vice versa. Next, it could inline any of these, none of them, or some of them. Finally it could do three different things depending on if you're x86-64, armv7s, or arm64.

I have no idea what the right thing to do is in this situation, but having all those possibilities gives the compiler a better chance of producing faster code. When you introduce message passing, you basically forbid all of those optimizations, because now the function might be swizzled, go pass a "minX:Y:" string to objcMsgSend to find out what pointer we should jump to today.

Swift already does have a way to opt-in to message passing, it's called the @objc flag (and performSelector:). It works fine, but it's extra work to opt into it and use it. But, I don't think that's bad given that it disables so many useful optimizations.

What may be bad is that the name "@objc" is a dead giveaway that this is a feature with a deprecation date. So I think we need some other, reflectionish system going forward.

For mocks one idea would be to selectively turn on message-passing as the dispatch method at the compiler level. So you could compile your application for unit testing with a "-fmessage-passing" like we have "-fobjc-no-arc" and get all the dynamism in debug builds and turn them off for release builds (or not, as the case may be).

For everyday power programming I think the answer is a lot simpler: functions are first-class objects in Swift, so just take your functions, put them in a dictionary somewhere and implement your own run-time dispatch. Having done this, I can say with certainty that there are some ways the language could improve this use case but it is possible, and if you are Chris Espinosa wrestling a bit with the type system is not a problem.

Things are tricky when you don't have the source code, but here again I see a reflection-ish API as being the key. I expect at some point we will be able to enumerate other classes' public methods, and dynamically dispatch into them, and that is certainly a missing feature with valid use cases.

Finally, I fundamentally and strongly disagree with Michael about method swizzling and OSX extensibility. Adding PGP to Mail via hooking functions sounds like an incredibly deranged idea. The suggestion that programs should cooperate with a badly-misguided reverse engineering effort by disabling optimizations that make the program faster for the other 99% is just insane. The way to approach this is to build new kinds of extensions that provide known, safe, documented extension entrypoints for hooking arbitrary code. Yes that is more work, and yes it requires actually talking with people and convincing them of your point of view, but so do most things.