Archive for April 16, 2014

Wednesday, April 16, 2014 [Tweets] [Favorites]

My iPad mini (Retina)

I’ve been using an iPad mini with Retina display for almost six months now. The Mini itself is old news, but I wanted to write down some notes from using it.

I upgraded from a first-generation iPad and a third-generation Kindle. Not surprisingly, the Mini blows away the original iPad in every way. I think it’s actually the speed that I notice most. I had never really liked using the iPad because it seemed so inefficient compared with my Mac. In retrospect, I don’t think I appreciated how much this was due to the (lack of) processor speed and RAM, rather than inherent limitations of the touch interface (though those certainly still exist).

For basic reading, the Kindle’s low-resolution E Ink screen is easier on the eyes than the Retina display. But it’s a tradeoff I’m willing to make because the iPad is so much faster and more versatile. Screen aside, the Kindle iOS app is nicer than the Kindle’s own software. I used to read Instapaper on my Kindle, but that feature stopped working for me, and of course the app makes it easier to read articles out of order.

Others have reported problems with the iPad mini’s color gamut. The screen may not be as nice as the iPad Air’s, but the colors look great to me. What I notice more is that when the room is dark, and I’m looking at a dark background, I can see that the backlight is uneven. I see the image retention problem, but it goes away after a few seconds. It’s nowhere near as bad as on the MacBook Pro.

I have a smart cover, but I’m not very happy with it. It’s unstable when folded back and makes the iPad even thicker. But if I remove the cover, there often isn’t a good place to put it. The cover does work OK as a stand, and it’s good for wiping fingerprints off. I like the STM Jacket D7 Padded Case. It’s small enough for protecting the iPad within a larger bag and also works standalone.

It’s easier to type on the iPad mini than on a full-size iPad, but I still dread it. I find myself straining to remember my shortish, random Web passwords to avoid having to type my long master password for 1Password. Touch ID can’t come soon enough.

The worst part of the iPad mini is holding it. It’s decidedly heavier than the first-generation iPad mini, not to mention a Kindle. And it just doesn’t feel as nice in the hand. I still find it unnatural to hold it with my fingers over the edge of the screen, and sometimes this triggers unintentional touches. I’m not convinced that having the full iPad experience is worth this size and weight. I would rather have something in the 6–7″ range that’s optimized for reading. But I suspect that we’ll instead see a 5-5.5″ tweener iPhone.

WinFS, Integrated/Unified Storage, and Microsoft

Hal Berenson:

People have been bugging me to write about Integrated Storage for some time, and with Bill Gates having just disclosed that failure to ship WinFS was his biggest product regret  now seemed like a good time.  In Part 1 I’ll give a little introduction and talk about scenarios and why you’d want an Integrated (also refered to as unified) Store.


You can solve many of the problems I described for photos by putting an external metadata later on top of the file system and using an application or library to interact with the photos instead of interacting directly with the file system. And that is exactly how it is done without integrated storage. This causes problems of its own as applications typically won’t understand the layer and operate just on the filesystem underneath it. That can make functionality that the layer purports to provide unreliable (e.g., when the application changes something about the photo which is not accurately propagated back into the external metadata store). And with photos now stored in a data type-specific layer it is ever more difficult to implement scenarios or applications in which photos are but one data type.

Hal Berenson:

So from the earliest discussions I recall Integrated Storage was always a new, Win32-compatible, file system. Accessing new functionality would be done by a new API, but you always had to be able to expose traditional file artifacts in a way that a legacy Win32 app could manipulate them. Double-click on a photo in an Integrated Storage-based Windows Explorer and it had to be able to launch a copy of Photoshop that didn’t know about Integrated Storage. And since that version of Photoshop didn’t know about Integrated Storage it also couldn’t update metadata in the store, it could just make changes to the properties inside the JPEG file. So when it closed the file Integrated Storage had to look inside the file and promote any JPEG properties that had been changed into the external metadata it maintained about the object.

Much of the complexity of Microsoft’s attempts at delivering Integrated Storage is owed to all this legacy support. Property promotion and demotion (e.g., if you changed something in the external metadata it might have to be pushed down into the legacy file format) was one nightmare that wasn’t a conceptual requirement of Integrated Storage but was a practical one. Dealing with Win32 file access details was another.

Hal Berenson:

At Microsoft you can see numerous ways that the File System team tried to accommodate greater richness in the file system without perverting the core file system concepts. For example, the need for making metadata dynamic or adding some of the things that the Semi-Structured Storage world needs was met by adding a secondary stream capability to files.


The notion of a Property Bag seems easy enough and painless enough to understand, but it clashes with the world of Structured Storage. How does arbitrary definition of metadata clash with a world in which schema evolution is (mostly) tightly controlled? Do you add a column to a table every time someone specifies a new property? If two people create properties with the same name are they the same property? If a table with thousands of columns, all of which are Null 99.99% of the time, seems unwieldy then what is an alternate storage structure? And can you make it perform?

What was different about WinFS is that most of these barriers, including the organization structure, were addressed. And the failure to deliver an Integrated Storage File System when the conditions were as close to ideal as they’ll ever be is why the concept will probably never be realized. Meanwhile the world of storage has moved on in interesting ways.

Hal Berenson:

Because I was new to Microsoft (and thus could be objective) I was asked to intervene in a spat between the Exchange team (working on the first version of Exchange Server, nee Exchange 4.0) and the JET-Blue database engine over the performance of the Mailbox Store. What I learned along the way was that the intent was for Exchange Server to be built on OFS, but since OFS wasn’t ready Exchange was doing its own interim store for Exchange 4.0. The plan of record was for the second version of Exchange to move to OFS. However, in an email discussing the performance of the existing mailbox store the Exchange General Manager mentioned that he didn’t think Exchange would ever move to OFS. While the OFS project was still alive, it was clear to me that everyone in the company had already written it off.


Longhorn itself turned out to be too aggressive an effort and have too many dependencies. For example, if the new Windows Shell was built on WinFS and the .NET CLR, and WinFS itself was built on the CLR, and the CLR was a new technology itself that needed a lot of work to function “inside” Windows, then how could you develop all three concurrently? One story I heard was that when it became clear that Longhorn was failing and they initiated the reset it started with removing CLR. Then everyone was told to take a look at the impact of that move and what they could deliver without CLR by a specified date. WinFS had bet so heavily on CLR that it couldn’t rewrite around its removal in time and so WinFS was dropped from Longhorn as well.

The WinFS project continued with the thought that it would initially ship asynchronous to a Windows release before being incorporated into a future one. But now it had two problems. First, it was back to the problem of having no Microsoft internal client that was committed to use it. And second, they eventually concluded that there was no chance in the forseeable future of shipping WinFS in a release of Windows. With the move of Steven Sinofsky, who had been a critic of WinFS, to run Windows that conclusion was confirmed. WinFS was dead.

Tuples and NSError

Edge Cases episode 88:

Andrew Pontious talks with Wolf Rentzsch about the simplest of things, the tuple: what it is, how it is used in other languages (specifically Python), and how, in an alternate universe, it could bring some sanity to Cocoa error handling.

Tuples in Python are great, particularly because there’s syntax for unpacking (a.k.a. destructuring). It even works with nested structures.

They hypothesize that NSError was introduced in Mac OS X 10.4 with Core Data. My recollection is that it was added with Safari 1.0 and WebKit, which could be installed on Mac OS X 10.2 and was built into 10.2.7.

Although I would certainly welcome Objective-C support for tuples and language-level support for errors, I’m not sure that it makes sense to implement the latter using the former.

One of the few virtues of using (NSError **) parameters is that you can pass in NULL if you only care about success/failure, not the reason for the failure. I’ve found that this is sometimes very useful for performance reasons. There’s a tension between putting lots of useful information in the error object and creating the error object quickly. NULL lets you have your cake an eat it, too. If you know that you will be making many related calls that could fail, you can do this without creating any NSError objects. Then you can generate one higher level NSError to represent the whole operation, and possibly retry one of the lower level calls without NULL to get a suitable underlying error object. This level of control would not be possible if methods always returned a tuple with a full error object.

Secondly, tuples would require more lines of code because if you want to save the error you can’t use the return value in an if statement. Instead of:

if ([self fooAndReturnError:&error])

you would write something like:

BOOL ok, NSError *error = [self foo];
if (ok)

You can see what this is like by calling Cocoa APIs using PyObjC.