Monday, August 3, 2015

Swift Protocols, Arrays, and Casting

Brent Simmons (tweet):

But an EmailMessage is a NodeRepresentedObject, so it ought to work just fine.


The best way I’ve found to deal with this is to map it. […] That seems crazy. I’m using map to create an array whose members are absolutely identical to the original array.

Kevin Ballard:

It’s not a type-check. The in-memory representation is different. It has to allocate a new array with the new values.

Non-@objc protocols use a virtual function table (called a protocol witness table) rather than message-passing.

This means that objects typed as EmailMessage have a different table pointer than those typed as NodeRepresentedObject.

Brent Simmons:

I’d argue that, instead, there shouldn’t be a hidden performance gotcha.

Kevin Ballard:

That would be nice, but the only way to solve this without a new array basically requires all protocols to use message-passing

Message passing is a performance gotcha :P

Brent Simmons:

But barely. We can write fast apps in Objective-C.

Kevin Ballard:

Yeah, but you should be able to write faster ones in Swift.

Brent Simmons:

Except for when I have to make an exact copy of an array to satisfy the type system.

3 Comments RSS · Twitter

Obvious type system defect is obvious. The type system's job is to guarantee correctness, specifically "Is the runtime value of variable X guaranteeed to be a member of set Y of possible values?" Crap like this is what happens when C* implementation hackery starts sneaking into what is fundamentally a pure math problem. The language ends up so complicated and so riddled with special cases, entangled behaviors, and undocumented corners it becomes impossible to prove that the language itself is correct, never mind anything written in it.

Personally, my favorite is still this:

var foo:[Hashable:Whatever]

Because who'd ever want to do that, right? I mean, it's only a simple, clear, valid expression of one's requirements. The fact that Hashable is defined as a protocol, not a class, should have no bearing here: as long as a value conforms, it should be allowed.

I suspect a lot of this mess is the result of Swift's brain-damaged "reference type" vs "value type" split, which is exactly the sort of myopic C-ism that anyone coming from a formal math background would've instantly brought the banhammer down upon, never to be mentioned again. Note that this would not preclude the compiler from using by-value representations internally for efficiency, but that would be purely an internal optimization, not something that should ever impact the user's domain. Not to mention the neverending user confusion and frustration when valid code fails to compile, simply because the stupid compiler is using type signatures as a custom memory allocation crutch, a hacky workaround only required due to having two non-consistent, non-interchangeable data representations in the first place.

Seriously, you'd think this lesson was learned after Java repeated C's primitive vs pointer dichotomy - hell, even 70's Smalltalk knew to keep such micromanagement details private - but apparently not.

It's a simple, long-understood axiom in software development: 1. Get it working. 2. Get it right. 3. Then make it fast. What is it about certain language designers that makes them think they're a special exception to this rule? The joke is that by pushing such complexity out into the public interface and thus onto the user, they're only making it far harder on themselves to correct, evolve, and optimize internally in the long run.

Alas, for a language that claims to have learned from its predecessors and wants to be their successor for the next several decades, Swift's own overblown abstractions still leak like a sieve. So much for "pragmatic", I guess...

[…] Objective-C. I’m not enamored with generics, and protocols seem like a good idea that in practice is currently too much of a pain to use. Likewise, the standard library is still in flux and not […]

[…] Swift Protocols, Arrays, and Casting, Swift Protocols Question, Swift Protocols and […]

Leave a Comment