Vincent Gable’s Blog

October 22, 2009

iPhone Shows the Irrelevance of the Programmer User

Filed under: iPhone,Usability | , , , ,
― Vincent Gable on October 22, 2009

There’s a lot of discord over Apple’s draconian “closed” handling of the iPhone and App store. And rightly so. But there are a few interesting lessons in the current situation. The one I want to discuss now is that,

Being able to program your own computer isn’t enough to make it open

As things stand today, Apple can’t stop you from installing any damn iPhone app if you build yourself.

To do that you have to join the iPhone developer program of course. And there’s a $99/year fee. That’s inconvenient, but it’s just using a subscription-based way of selling iPhone OS: Developer Edition.

That’s the kind of dirty money-grabbing scheme I’d expect from Microsoft. It’s a bit shady, because it’s not how most OSes are sold. But it’s not without precedent. And unless you are against ever charging money for software, I don’t think there’s an argument that it’s actually depriving people of freedom.

Yes, it’s an unaffordably high price for many. But the iPhone is a premium good that costs real money to build — it’s inherently beyond many people’s means, even when subsidized.

Observation: Only Binaries Matter

If you have a great iPhone app that Apple won’t allow into the store, you can still give it to me in source code form, and since I have iPhone OS: Developer Edition, I can run it on my iPhone.

But clearly that’s not good enough.

In fact, I’m not aware of any substantive iPhone App that’s distributed as source. By “substantive” I mean an app with a lot of users — say as many as the 100th most downloaded App Store app — or an app that does something that makes people jealous, like tethering (See update!), which we know is possible using the SDK. I realize this is a wishy-washy definition — what I’m trying to say is that distributed-as-source iPhone Apps seem to be totally irrelevant.

“It’s not open until I can put Linux on it”

I believe it’s technically possible to run Linux on an iPhone without jail-breaking it. (Although it’s not terribly practical.) Just build Linux (or an emulator that runs Linux) as an iPhone app, and leave it running all the time to get around the limitations on background processes.

Apple won’t allow such a thing into the App Store of course —but how does that stop you from distributing the source for it? As best I can tell, it doesn’t.

So as things stand today, yes you can distribute source code that lets any iPhone OS: Developer Edition user run Linux. It’s technically challenging, but it’s doable.

Conclusion

It’s possible to build open systems on top of closed systems. We’ve done it before when we built the internet on Ma Bell’s back.

But the iPhone remains a closed device. User-compiled applications have 0 momentum. And I think that clearly shows the irrelevance of the rare “programmer user”, who is comfortable dealing with the source code for the programs he uses.

UPDATE 2010-01-21: iProxy is an open-source project to enable tethering! Maybe the programmer-user will have their day after-all.

October 20, 2009

JavaScript Nailed ||

One thing about JavaScript I really like is that its ||, the Logical Or operator, is really a more general ‘Eval Until True‘ operation. (If you have a better name for this operation, please leave a comment!) It’s the same kind of or operator used in Lisp. And I believe it’s the best choice for a language to use.

In C/C++, a || b is equivalent to,

  if a evaluates to a non-zero value:
    return true;
  if b evaluates to a non-zero value:
    return true;
  otherwise:
    return false;

Note that if a can be converted to true, then b is not evaluated. Importantly, in C/C++ || always returns a bool.

But the JavaScript || returns the value of the first variable that can be converted to true, or the last variable if both variables can’t be interpreted as true,

  if a evaluates to a non-zero value:
    return a;
  otherwise:
    return b;

Concise

JavaScript’s || is some sweet syntactic sugar.

We can write,

return playerName || "Player 1";

instead of,

return playerName ? playerName : "Player 1";

And simplify assert-like code in a perl-esq way,

x || throw "x was unexpectedly null!";

It’s interesting that a more concise definition of || allows more concise code, even though intuitively we’d expect a more complex || to “do more work for us”.

General

Defining || to return values, not true/false, is much more useful for functional programming.

The short-circuit-evaluation is powerful enough to replace if-statements. For example, the familiar factorial function,

function factorial(n){
	if(n == 0) return 1;
	return n*factorial(n-1);
}

can be written in JavaScript using && and || expressions,

function factorial2(n){ return n * (n && factorial2(n-1)) || 1;}

Yes, I know this isn’t the clearest way to write a factorial, and it would still be an expression if it used ?:, but hopefully this gives you a sense of what short-circuiting operations can do.

Unlike ?:, the two-argument || intuitively generalizes to n arguments, equivalent to a1 || a2 || ... || an. This makes it even more useful for dealing with abstractions.

Logical operators that return values, instead of simply booleans, are more expressive and powerful, although at first they may not seem useful — especially coming from a language without them.

October 19, 2009

Less is More

Fundamentally, a computer is a tool. People don’t use computers to use the computer, they use a computer to get something done. An interface helps people control the computer, but it also gets in their way. Inevitably, any on-screen widget is displacing some part of the thing the user is trying to manipulate.

As an infamous example, expanding Microsoft Word’s toolbars leaves no room for actually writing something,

word-all-toolbars-small.png

(Screenshot by Jeff Atwood)

Users don’t want to admire the scrollbars. Truth be told, they don’t even want scrollbars as such, they just want to access content and have the interface get out of the way.

Jakob Nielsen

Show The Data

I highly recommend Edward Tufte’s The Visual Display of Quantitative Information. It’s probably the most effective book or cultivating a distaste for graphical excesses.

Tufte’s teachings are rooted in static print. But many of the principles are just as valuable in interactive media. (And static graphics are still very useful in analysis and presentation. Learning how to graph better isn’t a waste of time.)

Tufte’s first rule of statistical graphic design is, “Show the data” , and it’s an excellent starting point for interface design as well.

Cathy Shive has an excellent post expanding on Tufte’s term Computer Administrative Debris.

The Chartjunk blog showcases a few real-world examples of Tuftian redrawings.

Get Out of My Mind

Learning happens when attention is focused. … If you don’t have a good theory of learning, then you can still get it to happen by helping the person focus. One of the ways you can help a person focus is by removing interference.

–Alan Kay, Doing With Images Makes Symbols.

Paradoxically then, the better the design, the less it will be noticed. We should strive to write our interfaces in invisible ink.

October 16, 2009

Hack: Counting Variadic Arguments in C

This isn’t practical, but I think it’s neat that it’s doable in C99. The implementation I present here is incomplete and for illustrative purposes only.

Background

C’s implementation of variadic functions (functions that take a variable-number of arguments) is characteristically bare-bones. Even though the compiler knows the number, and type, of all arguments passed to variadic functions; there isn’t a mechanism for the function to get this information from the compiler. Instead, programmers need to pass an extra argument, like the printf format-string, to tell the function “these are the arguments I gave you”. This has worked for over 37 years. But it’s clunky — you have to write the same information twice, once for the compiler and again to tell the function what you told the compiler.

Inspecting Arguments in C

Argument Type

I don’t know of a way to find the type of the Nth argument to a varadic function, called with heterogeneous types. If you can figure out a way, I’d love to know. The typeof extension is often sufficient to write generic code that works when every argument has the same type. (C++ templates also solve this problem if we step outside of C-proper.)

Argument Count (The Good Stuff Starts Here)

By using variadic macros, and stringification (#), we can actually pass a function the literal string of its argument list from the source code — which it can parse to determine how many arguments it was given.

For example, say f() is a variadic function. We create a variadic wrapper macro, F() and call it like so in our source code,

x = F(a,b,c);

The preprocessor expands this to,

x = f("a,b,c",a,b,c)

Or perhaps,

x = f(count_arguments("a,b,c"),a,b,c)

where count_arguments(char *s) returns the number of arguments in the string source-code string s. (Technically s would be an argument-expression-list).

Example Code

Here’s an implementation for, iArray(), an array-builder for int values, very much like JavaScript‘s Array() constructor. Unlike the quirky JavaScript Array(), iArray(3) returns an array containing just the element 3, [3], not an uninitilized array with 3 elements, [undefined, undefined, undefined]. Another difference: iArray(), invoked with no arguments, is invalid, and will not compile.

#define iArray(...) alloc_ints(count_arguments(#__VA_ARGS__), __VA_ARGS__)

This macro is pretty straightforward. It’s given a variable number of arguments, represented by __VA_ARGS__ in the expansion. #__VA_ARGS__ turns the code into a string so that count_arguments can analyze it. (If you were doing this for real, you should use two levels of stringification though, otherwise macros won’t be fully expanded. I choose to keep things “demo-simple” here.)

unsigned count_arguments(char *s){
	unsigned i,argc = 1;
		for(i = 0; s[i]; i++)
			if(s[i] == ',')
				argc++;
	return argc;
}

This is a dangerously naive implementation and only works correctly when iArray() is given a straightforward non-empty list of values or variables. Basically it’s the least code I could write to make a working demo.

Since iArray must have at least one argument to compile, we just count the commas in the argument-list to see how many other arguments were passed. Simple to code, but it fails for more complex expressions like f(a,g(b,c)).

int *alloc_ints(unsigned count, ...){
	unsigned i = 0;
	int *ints = malloc(sizeof(int) * count);
	va_list args;
    va_start(args, count);
	for(i = 0; i < count; i++)
		ints[i] = va_arg(args,int);
	va_end(args);
	return ints;
}

Just as you'd expect, this code allocates enough memory to hold count ints, and fills it with the remaining count arguments. Bad things happen if < count arguments are passed, or they are the wrong type.

Download the code, if you like.

Parsing is Hard, Let's Go Shopping

I didn't even try to correctly parse any valid argument-expression-list in count_arguments. It's non trivial. I'd rather deal with choosing the correct MAX3 or MAX4 macro in a few places than maintain such a code base.

So this kind of introspection isn't really practical in C. But it's neat that it can be done, without any tinkering with the compiler or language.

September 17, 2009

Installing Mac Apps

Filed under: Accessibility,MacOSX,Programming,Usability | , , ,
― Vincent Gable on September 17, 2009

Today’s Daringfireball article on the shortcomings of the Mac application-install procedure is worth a skim. Gruber’s suggestion that Mac OS X automatically move 3rd-party applications into the /Applications/ folder on first-run, (a la the dashboard widget install process) is a good one1. Since Mac OS X already prompts you on first run (“Are you sure you want to run a program Apple didn’t write?”) it’s hard to see any downsides to this idea.

But that’s not the behavior we have today1.

Don’t Use a Damn .dmg!

As it stands today, I don’t see a good reason to ship your apps as a .dmg. I’ve been suspicious of disk images for a few years now; and usability tests show that people get confused by them.

Distribute your application as a single .app in a .zip archive. What possible use are other files besides the application? If a “Readme” file should be read before using the application, then show it when the application is first launched.

Installers are opaque and un-Mac like. There’s always a risk that they’ll install something that breaks the computer. As a developer I am even more suspicious of installers on the Mac, because I know how broken Apple’s installer tools are.

Of course, as a developer, I know that applications do sometimes need to install components. And here the best solution is for the application to check it’s environment and ask to install missing components as needed (in essence be it’s own installer). It’s more robust, since it detects-and-corrects missing or damaged components. It always preserves the user-facing abstraction that the icon is the application.

Applications shouldn’t install hacks dangerous enough to require a bundled user-facing unisntaller. To make IMLocation work, I had to install a background process — but I made it intelligent enough that it would uninstall itself if the main application had been deleted. Yes, this is more work, but it’s worth it.


1Another idea is to make Safari and Firefox smart enough to download applications directly into the right /Applications/ folder, bypassing the usual downloads folder. This elegantly solves the instillation problem, although it creates some new problems.

2Although it would be a cool hack to write.

August 19, 2009

iPhone Password Correction

Filed under: Accessibility,iPhone,Security,Usability | , , , ,
― Vincent Gable on August 19, 2009

Idea: your iPhone knows your passwords, so when you make a small typo, it corrects it for you.

There are obviously major security concerns here. But I believe they can be acceptably mitigated by the phone itself. Someone would have to physically use the iPhone to get password correction, and correctly could only happen on the first or second password attempt. Also, correction could be limited to the kinds of typos a person would make.

Passwords are broken by machines, not people. I believe password correction can help people, without substantially helping machines, and compromising security.

It’s hard to type precisely on an iPhone’s virtual keyboard. That prevents people from using secure passwords, and that hurts security. Because password correction helps people actually use strong passwords, it should be to be a net security benefit.

July 14, 2009

Dozen Page Impression: Design your Life

Filed under: Accessibility,Announcement,Design,Usability | , , , ,
― Vincent Gable on July 14, 2009

I had some time to kill today, waiting for a catalytic converter replacement, and the book Design Your Life: The Pleasures and Perils of Everyday Things caught my eye. It’s loosely about about the value of design and how to apply UX to everyday life. I’ve only read1 a dozen or so pages of it in a bookstore, but so far I definitely recommend the book.

Visually it’s is appealing (but of course it has to be!), and accessibly written.

But what really impressed me the most, is that it gives you a critical eye and a reason to ask ‘why?’. And I think that’s the most important thing you can get out of a book on UX/design/accessibility.

The authors also have have a website which looks to be every bit as good as the book.


1You’re probably wondering why I didn’t buy the book if I like it enough to recommend it. Well, I had my iPhone with me in the store, and I looked up the price on amazon. It was half what the brick-and-mortar store was asking. So I didn’t buy it. Speaking of which, if you order the book through any of the links on this page, I get a small commission from Amazon. So please do doubt my recommendation — that’s what critical thinking is all about!

July 10, 2009

Build Dumb Interfaces to Smart Brains

Filed under: Accessibility,Design,Quotes,Usability | , , ,
― Vincent Gable on July 10, 2009

control interfaces must not be intelligent. Briefly, intelligent user interfaces should be limited to applications in which the user does not expect to control the behavior of the product. If the product is used as a tool, its interface should be as unintelligent as possible. Stupid is predictable; predictable is learnable; learnable is usable.

Mencius Molbug

Jeff Raskin calls this principle it monotony, and explains it comprehensively in The Humane Interface.

I’ve always felt a little uneasy about the idea. Computers are supposed to free us from tedium and repetition, by doing things for us. A fluid interface is unnatural yes, but the goal of computing should be to exceed what’s possible in the corporal word, not to copy it imperfectly.

But fundamentally, I think Raskin and Molbug are more right than wrong. Paradoxically, dumb interfaces beat smart interfaces most of the time.

July 3, 2009

Thank you sir, may I have another?

Filed under: Design,Quotes,Usability | , , ,
― Vincent Gable on July 3, 2009

Apparently by 1958, mankind’s subservient relationship with computers was sadly well established,

AT THE Vanguard Computing Center – in Washington, D. C, I watched a young woman present a machine with an extremely complex problem in ballistics involving hundreds of variables. At once lights on a control panel twinkled and winked as the computer checked to see that all equipment was operating properly. Then it set briskly to work. Magnetic tapes spun in their shiny glass-and-steel vacuum cabinets, the high-speed printer muttered. Suddenly the machine stopped and the electric typewriter wrote: “Last entry improperly stated!”

A little embarrassed, the young operator corrected her error, and the machine started again. Four minutes later it gave an answer that had required several million individual calculations.

“This is a wonderful machine” the girl said, “but it makes you shiver sometimes, especially when you give it a wrong figure. Once in a while we give it an incorrect figure on purpose—just to see it sneer at us.

THINKING MACHINES ARE GETTING SMARTER (Oct, 1958)

I’d never discourage anyone from making the most fun error messages and interactions possible. But when being sneered at by the machine gives operators more of a connection to it than using it normally, I think something is broken. I can’t imagine that fostering a healthy operator-machine relationship. Honestly though, I don’t know that it’s worse than the same boring regular interactions, but with boring error messages instead.

July 2, 2009

Design for Mental Imperfections

When it comes to building the physical world, we kind of understand our limitations. We build steps. … We understand our limitations. And we build around it. But for some reason when it comes to the mental world, when we design things like healthcare and retirement and stockmarkets, we somehow forget the idea that we are limited. I think that if we understood our cognitive limitations in the same way that we understand our physical limitations, even though they don’t stare us in the face in the same way, we could design a better world. And that, I think, is the hope of this thing.

Dan Ariely, concluding a very entertaining TED talk. The transcript is up, but I liked his delivery so much I watched the video.

Stairs and ladders aren’t an implication that you’re too weak to pull yourself out of a pool. Yet amazingly people sometimes get insulted by simplified interfaces, as if it somehow implies they are so stupid they can’t handle complexity.

I was fortunate enough to hear Jonathan Ive talk about launching the iMac. As he was leaving a store on launch-day, a furious technology reported accosted him in the parking lot, shouting What have you done? He was incensed that the iMac was so cute, approachable, and untechnical — everything that he thought a computer shouldn’t be.

Some of this behavior is explained by simple elitism. If computers are hard to use, than it keeps the idiots out, and proves what a macho man you are if you can use them.

But I suspect refusal to accept our cognitive limitations is also related to our cultural refusal to accept mental illness. Quoting Mark C. Chu-Carroll’s experience with depression,

How many people have heard about my stomach problems? A lot of people. I need to take the drugs three times a day, so people see me popping pills. … Out of the dozens of people who’ve heard about my stomach problem, and know about the drugs I take for it, how many have lectured me about how I shouldn’t take those nasty drugs? Zero. No one has ever even made a comment about how I shouldn’t be taking medications for something that’s just uncomfortable. Even knowing that some of the stuff I take for it is addictive, no one, not one single person has ever told me that I didn’t need my medication. No one would even consider it.

But depression? It’s a very different story.…

Somewhat over 1/2 of the people who hear that I take an antidepressant express disapproval in some way. Around 1/3 make snide comments about “happy pills” and lecture me about how only weak-willed nebbishes who can’t deal with reality need psychiatric medication.

I confess to being thoroughly mystified by this. Why is it OK for my stomach, or my heart, or my pancreas to be ill in a way that needs to be treated with medication, but it’s not OK for my brain? Why are illnesses that originate in this one organ so different from all others, so that so many people believe that nothing can possibly go wrong with it? That there are absolutely no problems with the brain that can possibly be treated by medication?

Why is it OK for me to take expensive, addictive drugs for a painful but non-life-threatening problem with my stomach; but totally unacceptable for me to take cheap harmless drugs for a painful but non-threatening problem with my brain?

If we can accept that our brains are fallible, like everything else, and that this isn’t somehow immoral, we can build a better world.

« Newer PostsOlder Posts »

Powered by WordPress