Living in the Past

Oh, we won’t give in,
We’ll keep living in the past.

— Jethro Tull

Lots of other stuff going on in the world, but for a moment, let’s go living in the past, shall we?

Let’s go back to a time when I wrote a website with a godawful color scheme and a prescient name. When Subversion was new, Unix was still old (but new to the Mac), and I used terrible puns for post titles — well, that hasn’t changed, has it?

When I closed down helpfultiger.com, I removed its posts from the Internet entirely. Now, with the relaunch of my blog on apontious.com, I’ve brought ’em all back, under the tag “From Old Helpful Tiger Blog”.

The technical how-to posts are mostly out of date, but there are lots of philosophical posts I still agree with. Have a look!

Edit: forgot to mention that the comments came over, too!

Boom Boom Enum

To quote a fairly awful movie: “We were so, so wrong.” — me

Remember I said you couldn’t use Swift value types for a linked list? The real reason is because you can’t have references to other value instances, just copies (thus making bi-directional linked lists a recursion nightmare), but the compiler error was “a value type can’t refer to itself”.

Turns out, one Swift value type can refer to itself: enumerations. By adding the indirect keyword, you can use Swift enums to, for example, represent a binary tree structure:

indirect enum Tree {
	 case node(Int, left: Tree?, right: Tree?)
}

And it works! But is it a good idea? Hell, no!

Why not? Because accessing the “properties” of your data structure is a pain in the ass:

switch node {
case let .node (data, left, right):
	// Do something with data, left, and right
}

As far as I know, you need an otherwise extraneous switch statement, a case statement, and an extra set of local variables just to access the values. (Whereas for a class all you need is dot syntax.) And you need to do that everywhere you want to access them, every method.

And the compiler will complain if you don’t use all of the enumeration values, so you have to remember to use _ for those:

switch node {
case let .node (_, left, _):
	// Do something with left
}

I tried writing a full tree traversal implementation in Swift with enum-based trees and it was an unholy mess that I would not repeat.

Learn from me. Don’t use cool language features at the expense of maintainability.

Interview Hullabaloo

I have one major piece of advice, if you’re interviewing for a developer job, or really if you’re interviewing for any job.

If you get the sense that the interviewer is dissatisfied with how you did, don’t hesitate to ask what they’re dissatisfied about.

For example: “It feels like I didn’t completely answer your question. Is there anything I could expand on for you?”

Or: “Did my solution to the exercise cover everything you wanted me to cover?”

If they just say yes, but they still seem dissatisfied, well, then there’s nothing you can do.

But I’ve often found that this will bring forward whatever reservations they have, and give you a second crack at them.

Dictionary Fictionary

See update below: it’s more complicated than I thought.

Over the last, what, decade or so? maybe more? people have been using the word “literally” to mean…not literally.

“Literally a monster.”

“Literally the worst thing ever.”

They don’t mean literally literally. They’re using it because it feels right, regardless of its actual definition. It can lead to some amusing results.

I’ve seen something similar in Objective-C.1

When array, dictionary, and number literals and object subscripting were introduced in Objective-C in 2012, people really liked them. Me too! They were literally mostly just compiler syntactic sugar, but they derived their usefulness in part from being vastly more compact and readable.

Because the new syntax is so nifty, people want to use it everywhere.

NSMutableDictionary *foo = @{}.mutableCopy;

instead of

NSMutableDictionary *foo = [NSMutableDictionary new];

for example. Are they equivalent? Well, this is what the first sample is generating:

NSMutableDictionary *foo = [NSDictionary new].mutableCopy;

Making two dictionary instances, only to throw one away immediately, just because you want to use shiny syntax, doesn’t seem like the best idea to me.

Array and dictionary literals derive the rest of their useful from not having quite the same rules as the old syntax.

Unlike for the old creation APIs, now nil is no longer used as the ending sentinel for the list of input values. So because they could, the designers of the new syntax disallowed it completely.

The amusing part? Recently, I had a coworker who swore you couldn’t set a dictionary value to nil, like this:

foo[@"key"] = nil;

What he was doing was confusing the new literal syntax rules with plain old NSDictionary APIs. It’s an easy mistake to make. The only reason I didn’t is because I have years and years of experience with the old APIs, which didn’t have the same hangups about nil.

So I could compartmentalize the new nil rules to just the new literal syntax, where they belong.

I literally needed to run example code for him to convince him that the above line wouldn’t assert.

Update: Looks like I was right for the wrong reasons.

Instead of it always working the way I thought, the current behavior is a recent addition. See Foundation Release Notes for OS X v10.11 and iOS 9, specifically this part:

NSMutableDictionary subscript syntax change
In OS X 10.11 and iOS 9, NSMutableDictionary now allows you to use its subscript syntax to assign nil for a key. Like Swift’s Dictionary type, doing so will remove an existing object for that key from the dictionary. In effect, the following lines of code are now equivalent:

[dictionary removeObjectForKey:@"Key"];
dictionary[@"Key"] = nil;

These new semantics exist only when building with the OS X 10.11 or iOS 9 SDKs. If your application’s deployment target is earlier operating system, then runtime support will be implicitly linked into your binary by Xcode to ensure the behavior works on any targeted operation system.

My mistake was assuming the subscript setter syntax was an unmodified usage of NSMutableDictionary’s setObject:forKey:, which in my recollection always allowed nil, but of course there’s no reason it would have to be.

And now, with nullability annotations, setObject:forKey: no longer allows nil at all! (Plus, on reflection, I think I was wrong about it allowing nil in the past.)

Thanks to Jordan Rose and others for the correction.


1. Somebody get me a storyboard, cuz I just made a killer segue! ↩︎

Link or Swim

I learned today that you can’t make a linked list in Swift using value types. The reason why ties into the pointers issue I was recently discussing.

Here’s how a linked list struct might look in C:

struct LinkedList {
	struct LinkedList *next;
	int data;
};

And here’s how you would do it in Swift:

struct LinkedList {
	var next: LinkedList?
	var data: Int
}

The difference is, in C, you can have a reference to a struct without making a copy — without it being the thing itself. By adding an asterisk and making it a pointer.

In Swift, you can’t do that. So a reference to another struct might as well be that other struct, even if it isn’t always, under the hood.

If I try to compile that Swift, I get the error “value type ‘LinkedList’ cannot have a stored property that references itself”.

If I change the declaration from struct to class, then it compiles fine, because the property representing the “next” instance is now a reference to it.

I wasn’t expecting this issue to come up again so soon in my work.

Poll Position

I conducted a Twitter poll recently because I was curious: when I use Objective-C for my coding examples on this blog, does that still seem normal to my readers, or does it seem like some weird ancient relic of a bygone era?

Now, my Twitter followers and my blog readers might not be exactly the same, and there were < 40 responses so it’s not a huge sample, but I still think the results are illuminating:

poll-results

There’s no clear majority. About the same number are using primarily Swift as primarily Objective-C.

That sounds about right to me.

And it means I don’t need to change my ways this second.

But I do plan on switching over to using Swift for my coding examples at some point during the year.

Entirely Missing the Pointer

Whenever I read about Swift, I read about the distinction between reference types and value types.

In the C-based languages I used (and still use), I never thought about it like that. Instead, I thought in terms of pointers1 and everything else, which here I’ll call non-pointers.

You could have a pointer to anything, but in Objective-C they are used especially for class instances. And you could have a “non-pointer” to anything, including scalars, structs, and (in C++) class instances.

And it’s always been visually easy to distinguish between the two: one has an asterisk, and one doesn’t.2

Check it out. The ones with the asterisks have reference-based semantics, and the ones without the asterisks have value-based semantics:

Reference:

@interface Foo : NSObject
@property int bar;
@end

@implementation Foo
@end

struct Bar {
	int foo;
};

void referenceTest() {
	int intStorage = 0;
	int *myInt1 = &intStorage;
	int *myInt2 = myInt1;
	*myInt1 = 10;
	printf("%d\n", *myInt2); // Result: 10, same as myInt1
	
	struct Bar barStorage = { 0 };
	struct Bar *bar1 = &barStorage;
	struct Bar *bar2 = bar1;
	bar1->foo = 10;
	printf("%d\n", bar2->foo); // Result: 10, same as bar1
	
	Foo *foo1 = [Foo new];
	Foo *foo2 = foo1;
	foo1.bar = 10;
	printf("%d\n", foo2.bar); // Result: 10, same as foo1
}

Value:

// Same declarations/definitions as above

void valueTest() {
	int myInt1 = 0;
	int myInt2 = myInt1;
	myInt1 = 10;
	printf("%d\n", myInt2); // Result: 0, not same as myInt1
	
	struct Bar bar1 = { 0 };
	struct Bar bar2 = bar1;
	bar1.foo = 10;
	printf("%d\n", bar2.foo); // Result: 0, not same as bar1
}

Note in Objective-C we can’t have a value-based version of the class. (Though we could in C++.)

Swift has a completely different philosophy. Reference vs. value isn’t syntax-based, it’s identity-based. The exact same syntax will produce different results depending on the original definition of what you’re working on.

Reference:

class Foo {
	var bar: Int = 0
}

var foo1 = Foo()
var foo2 = foo1

foo1.bar = 10
foo2.bar // Result: 10, same as foo1

Value:

struct Foo {
	var bar: Int = 0
}

var foo1 = Foo()
var foo2 = foo1

foo1.bar = 10
foo2.bar // Result: 0, not same as foo1

The only difference in the two samples above is the class vs. struct keyword.

Because that’s such a stark philosophical gap, and for me, an unexamined one, it was quite hard for me to get my mind around it at first.

Notes:

  • For me, Java was the first mainstream language that removed the asterisk for reference types and stopped calling them “pointers”. Though amusingly, they still have a java.lang.NullPointerException, which I’ve always assumed has to be confusing to newbies!
  • Swift further muddies my concept of reference-as-pointer and value-as-non-pointer by allowing multiple value type instances to actually point to the same memory as long as you don’t modify their contents, which C-based value types never did. So Swift value types can now actually be implemented by C-style pointers under the hood.
  • For Objective-C users, our first taste of this kind of thing was with blocks. A newly-created block is kind of a “value” type, created on the stack like all other non-pointer C types. But then you copy it, and it becomes a kind of “reference” type you can pass around outside of the function scope. Same syntax for either type, just like Swift.

1. Here, I define “pointer” as an explicit C reference to memory, detached from its management. Non-pointers are still referencing memory locations, but the runtime manages their creation and destruction as part of something larger: the stack, a class or struct, etc. ↩︎
2. C++ muddied this distinction a bit by introducing references, though they had the decency to give it a difference punctuation mark. ↩︎

Keyboard out of My Mind

Four years ago (!) I wrote up the best practices I could find for dealing with the appearance and disappearance of the keyboard on iOS.

Since then, did they break? Any guesses?

Anyone?

Actually, they mostly still work.

If you’ll remember, the big problem was that iOS simply wouldn’t tell us when we were rotating. Instead, the news was delivered in separate, unconnected keyboard-will-hide and keyboard-will-show notifications.

We got around that by, in the will-show notification, starting our animation from the current point (via UIViewAnimationOptionBeginFromCurrentState), instead of from all the way at the bottom of the screen.

On iPhone for iOS 10, as far as I can tell, that trick doesn’t work anymore. (It still does on iPad.) Your animation begins at the bottom of the screen, out of sync with the actual keyboard movement, no matter what options you set.

But in the meantime, iOS has introduced an API that does give us access points both for the start and end of a rotation animation, viewWillTransitionToSize:​withTransitionCoordinator:.

This method is called at the start of the rotation, so that’s one access point accounted for.

And if you call the transition coordinator’s animateAlongsideTransition:​completion: method with a completion block inside it, per Apple’s best practices, the completion block is where you can do things guaranteed to occur after the rotation is over. So that’s the second access point accounted for.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    // BEGINNING OF ROTATION
    [coordinator animateAlongsideTransition:^(id  _Nonnull context) {
    } completion:^(id  _Nonnull context) {
        // END OF ROTATION
    }];
}

Now, this API is meant to be more general-purpose than just rotation: it’s called for every multitasking size change on iPad. But we can find out whether it is a rotation transition by checking whether the new size’s width and height are the same as the old size’s height and width. If it is, now we set a flag that, in our will-hide logic, can be used to not animate at all under these circumstances.

So that’s it! One fairly small fix.

However, since it has been four years (!), I’ve made a number of changes beyond that in the GitHub project:

  • A new project, Corrected Keyboard Schmeeboard2, has been updated to Xcode 8 standards, Auto Layout, and more, without otherwise changing the code.
  • A second new project, Corrected Keyboard Schmeeboard3, has the iOS 10 iPhone rotation fix on top of the changes from 2.
  • And the last new project, Corrected Keyboard Schmeeboard4, converts the whole thing into Swift.

I’ll have more to say about Swift in future posts.