Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Hello.
[ Applause ]
Thank you very much
for coming today,
and if you're watching later
on video thanks so
much for watching.
I'm Ken Kocienda, and
this session is called
"A Strategy for Great Work."
So I think we all
try to do great work.
I certainly always
try to do great work.
Regardless of the
results and the outcome,
certainly the effort is directed
towards doing something great.
I think that's probably
the same for all of you,
that's why you're here
at the conference today,
that's maybe why you're
watching later on video.
Now this is a subject,
that's very important to me,
I like talking about it,
I like thinking about it.
And I was last on stage
in 2012 with a talk called
"Basics + Habits,"
where I talked
about some technical concerns,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about some technical concerns,
some real certain nuts-and-bolts
things about how to set
up a project and then how
to run projects once
you have them going.
But, again, this is very
tactical, sort of down
into the details, things
like code review and working
with your other people that
you might have on a team.
So today it's different.
I would like to in
this session talk
about some higher level ideas,
kind of move it up to the level
of strategy rather than tactics.
And so I went out and got a
helpful quotation from Wikipedia
to sort of think about
what the difference
between strategy and tactics is.
And so tactics are the actual
means used to gain an objective,
while strategy is the
overall campaign plan,
which may involve complex
operational patterns, activity
and decision-making that
lead to tactical execution.
Certainly, the complex
operational pattern sounds
like programming to me, right?
Definitely.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Definitely.
So I think that really sort
of strategy is you're having a
big idea of what you might want
to do, and that really should
hopefully be driving what you
actually do to accomplish
the goal, right?
So today I'd like to talk
about some of these ideas,
these high level
ideas that inspire
and inform my everyday work.
But really this session
is not sort of how
to make a great project
in 21 days, right?
I mean it's not going to be,
it's never that simple, right?
Every time you see
something like that X
or 21 days it's never,
ever, ever that simple.
So it's not simple; you
kind of need a plan for kind
of attacking the problem here.
And so today how I'm going
to do that is tell you some
of my stories, projects
that I've been involved in.
But, you know, but there's
kind of like a note of caution
when you hear stories
and maybe try
to apply it to your own life.
And I have an example here.
Let's say you're in Las
Vegas and you see somebody go
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let's say you're in Las
Vegas and you see somebody go
by who is carrying
a big pile of chips
over to get them cashed in,
and you stop the person.
You say, "Wait, what did you do
to get that big pile of chips?"
And the answer comes,
"I put it all on 14."
Okay, so it's true, but not
so useful to you, right?
You go over and put
it on 14, you may
or may not get the same
result, most likely not.
So hopefully the stories
will be interesting to you,
but the real goal before, during
and after the story, right,
particularly after is to extract
out the lessons from the stories
because I think the
lessons if you take them
in the aggregate starts
stringing together some lessons.
That sort of points
toward a strategy,
it certainly does for me.
So today eight stories, 11
lessons, take all those lessons,
put them together and really
that is what informs my work.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And, again, of course, I'm
always trying to do great work,
so hopefully this
will all come together
in a nice big circle at the end.
So to begin with the stories.
Number one, the story is
"Like a Crystal Ball,"
and the lesson is know a
good idea when you see it.
So I joined Apple in June of
2001, and if you think back
to that time, Mac OS X,
version 10.0, was released
about three months before.
Now that's kind of
a long time ago.
When you think about
it the browser
on the platform was
Microsoft Internet Explorer,
and that's the browser
that's shipped
with the operating
system from Apple.
Not only that, there
was no framework to load
and render web content, right?
So we just had an
app, but no framework.
So my job, along with someone
else, a fellow named Don,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So my job, along with someone
else, a fellow named Don,
we joined the same day.
Our job became make
Apple a web browser
and an Objective-C
Framework, too.
Again, load and render web
content and make that available
as an API to you all,
to the developers.
So we started looking
at some options.
Well, what were the options
available at the time?
And you see sort of the
leading candidates there.
Some of these were commercial
products, kind of a buy option.
Some of them were Open
Source projects out there
in the world going on.
We could go and make perhaps,
adopt that source
code for our project.
We could also start
from scratch,
we considered it, absolutely.
So my job was to begin to do
some technical investigation
of particularly the
Open Source options.
And I downloaded Mozilla.
There's one story, I took
about a week, I remember,
to try to just get Mozilla
to build on the Mac.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I remember at one point one
of the steps in this long recipe
of steps that needed to get
done to get Mozilla to build,
I needed to rebuild the C,
metro work C library,
was one of the steps.
So this was not a
straightforward thing,
but I eventually got it
building and, you know, okay.
But this process went
on for weeks, and I went
and got these programs.
The commercial products,
you know,
what I did for that
was got them running
and started doing some
performance analysis
and say Unicode compatibility.
And so between the commercial
products, those test results,
and the Open Source projects,
some sort of reckoning
of how much source code was
there, how easy it would be
to adapt it and so forth.
Some test results, I
printed out on paper,
but I didn't have a demo.
No demo, just test results.
So right about that time we
got a new engineer on our team,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
a fellow named Richard.
And so I showed him, described
to him basically as I described
to you what I'd been doing,
showed him the test results.
And he said really what
have you been doing?
Six weeks and this
is all you have?
So I was like, well, yeah.
I just kind of shrugged and
said that's what I have.
So he just didn't
think very much
of that, and so he went away.
And two days later
he had a demo.
He took one of those
options, KHTML,
which is the web rendering
engine that was part
of the KDE desktop
environment for Linux.
He grabbed that source code,
got it running on a Mac,
just did whatever kind of
hacks that he needed to do
to get it running, and had
Konqueror, the KDE's browser,
running on a Mac in an X window.
This was amazing.
It was absolutely amazing.
We were just standing
there and like looking
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We were just standing
there and like looking
at a browser running on
the Mac, that's like --
it was like a crystal ball,
it was absolutely amazing.
And we saw all the people who
were involved in, you know -
not only us on the project,
but then decision makers
at the company - saw that
KHTML was our future.
This was just like he'd opened
up this tunnel to,
like, the future.
It was absolutely amazing.
And so the lesson from
this experience is
to know a good idea
when you see it.
I mean really for me, I kind
of felt like a bumbling idiot.
There I was for six weeks
trying to figure out what to do
and really had nothing,
and someone new came in
and in two days he had
the future right there
that we could use.
Now sort of the sub-lesson
for this is really
what does this mean,
know a good idea
when you see it?
Is even if something like this
happens to you and you're made
to look like an idiot,
it doesn't matter.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to look like an idiot,
it doesn't matter.
I didn't care.
It shouldn't matter
to you either
because there's actually
some, a couple of good things
about this experience.
Number one, I had a great new
team member who I was going
to be now involved with, who was
going to be helping me to kind
of make this project happen,
and he really proved in two days
that he was really good.
And so it was just like,
boy, the next day, well,
we kind of know what
to do, right?
We're going to start
making this future real.
And so that's kind of the
story of "Like a Crystal Ball,"
but there's a bonus
lesson here, too.
Not only know a good
idea when you see it,
but kind of this extra lesson
of make demos and prototypes.
If you're starting on
a new idea don't --
test results, that's all well
and good, but you should also
at the same time make something
that you can actually begin
to use like you want to use the
real thing that you're going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to use like you want to use the
real thing that you're going
to be making ultimately
in the future.
Get that, open up your own
tunnel to the future, right?
Get something in front of you
and working as soon as you can.
So that's "Like a Crystal
Ball": Know a good idea
when you see it, and make
demos and prototypes.
So the next story, number
two, is "The Black Obelisk,"
and the lesson is don't try to
solve every problem at once.
So continuing right
on from the end
of that last story:
KHTML, fantastic.
The more we looked at the code,
the more we were confident
that this was really
the way for us to go.
But really what do
we do now, right?
I mean what do we do, right?
And so, as you can imagine,
Open Source we go and it's part
of the KDE desktop, so we went
and we downloaded all of KDE.
But the thing is we
only wanted KHTML,
only the HTML rendering
engine, and we also wanted KJS,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
only the HTML rendering
engine, and we also wanted KJS,
the JavaScript engine.
So the job became to
sort of draw a line
around just the HTML part of
this whole desktop environment
so that we could just
extract that and use it.
And this turned out to be
about 100 source files.
It seems tractable.
So the next step was to bring
those files over to the Mac
and start compiling them,
one at a time, right?
Of course, it didn't compile
because we just took
this source code
that expected this whole other
desktop environment around it,
and now we just sort of pulled
the whole rug out from under it.
So, you know, it didn't compile.
We had a whole bunch
of missing things,
and so we just began
stubbing them in,
stubbing in missing
functions one at a time.
And these were very,
very light stubs.
These were only stubs
in header files, right?
So we only wanted to sort of
define the problem in terms
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So we only wanted to sort of
define the problem in terms
of all of the missing things
that we needed to add.
This was very, very slow work.
It took about another six
weeks - six weeks was kind
of a magical number
for this project.
This took about six
weeks of just compiling.
It would be like 10, 11 hours
of compiling every single day.
So it was pretty
painstaking, and then even
at this step nothing linked
because as I mentioned
these are only header files.
So we were only running,
we weren't --
I made a custom make file,
I said don't even try
to run the linker, just like try
to show us what we were missing.
So after we were done with that,
right, we had another six weeks
to get everything to link,
actually going in and finishing
out sort of the header
file, actually putting
in some stub implementation
for everything.
And even then we had lots
of crashes because in a lot
of functions that
returned strings,
we returned empty strings,
and obviously that's
not really what a lot
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and obviously that's
not really what a lot
of the code was expecting.
So we also added in a
whole lot of log statements
to our implementation, saying,
yes, this is not implemented
at all, I mean it
returns a value,
but sort of not implemented
at all, partially implemented.
Yes, we think we're pretty
close, and implement it.
So we had a whole bunch of log
statements that we would see;
we had a whole bunch of messages
getting written to the log
as we actually tried
to use the program.
And after this whole
process of many, many weeks,
we eventually wound up with a
Mac program that used KHTML,
and then one day
the lights came on.
So my coworker, Richard, was
actually off on vacation.
He was really kind of
doing this, sort of leading
up the effort to get things
to link and not crash so much,
and then I came in and
took over the process
and actually got the first
thing to draw on the screen.
So I loaded a URL, in this
case www.yahoo.com, and reams
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So I loaded a URL, in this
case www.yahoo.com, and reams
and reams and reams
of log messages go by,
and the program didn't crash,
and then there was a
short pause, and it drew.
The Black Obelisk [applause].
So this is the first thing
that WebKit, and Safari ever,
you know, what became
Safari, ever rendered.
Now, see, it's a little bit of
a secret, as it actually turns
out that this was a reversal,
that Obelisk should have been
on the other side of the
screen, but we fixed that sort
of little geometry
problem very soon after.
But you can imagine that once
I got this going, go ahead
and fetched everybody who
was disclosed in the project,
and we're all sitting
around sort of like
"2001 Space Odyssey" with this
Black Obelisk, going "whoo."
So that was a very
happy, happy moment.
Now the lesson from this
experience is don't try
to solve every problem at once.
At this point we had
almost no knowledge
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
At this point we had
almost no knowledge
of now the innards
of KHTML worked.
This was simply a
mechanical process
of making the compiler happy,
making the linker happy,
making it so the program
didn't crash when we tried
to do something with it.
It was all very,
very mechanical.
The compiler says
there's something missing,
go add that thing so that
it's no longer missing, right?
Now it turns out, of course, a
web rendering engine is a very,
very complicated
piece of software,
and but we just didn't have
the bandwidth to think about it
at this point as we were trying
to just get those
lights to come on.
That began to happen as
soon as we had a program
that would no longer
crash, right?
So don't care.
If you're trying to
attack a new, big problem,
and you've got this big
problem space, particularly
if that problem space is new
to you, just try to figure
out what the most
important thing is
to do first and do that.
Don't think about the whole
problem or try to operate
on solving the whole
problem at one time, right?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on solving the whole
problem at one time, right?
So don't try to solve
every problem at once,
and that's "The Black Obelisk."
So the next story, number
three, is "The Hardest Problem.
And the lesson is find smart
friends and listen to them.
So fast forward to
the fall of 2003,
and my job became
editing to WebKit.
So we wanted to use WebKit
to edit HTML mail in mail.app
on Mac OS X, and we wanted to
make editing in WebKit look
and work like a text
editor, okay?
So the problem that
we were trying
to solve is somewhat
obvious, right?
A lot of other platforms,
in particular Windows,
sends HTML mail from
Outlook, and we wanted
to not only render it, which we
could now that we had WebKit,
but we also wanted to edit it.
Because if you think about it,
before WebKit had editing
the web content would show
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
before WebKit had editing
the web content would show
up in your mail message as an
attachment in our TF document
with a big blinking
insertion point after it,
you could just kind of delete
the whole thing with one --
delete an entire web
page with one back space.
So that's not what we wanted,
we wanted to be able to get
into the details
of the web content
so we could edit it, right?
So now, the hardest problem I
have ever, ever worked on in my,
well, many, many years
of programming is arrow
navigation through web content.
Now what do I mean by that?
So picture a tiny little
web document, like this,
and what you do then is you hit
the arrow key the right number
of times and the insertion
point winds up at the end.
That's it: just go
character by character,
have the insertion point show
up in the right place each
time you press the arrow key,
and then similarly
press the arrow key
to go back the other way
and send the insertion
point back to the start.
That was it.
This turned out to be
very, very difficult.
Now why is this?
Because, you know, unlike
say an RTF document,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Because, you know, unlike
say an RTF document,
which is just a series of
characters and indexes into,
basically an array
of characters,
web content is a tree structure.
So if you see on the top
where the insertion point is
at the end, and then if you look
at the model, the web document,
the insertion point
would blink at the end
if in the web document, the
insertion point was there
or there or there
or there, right?
So what I had here was a
complex model of view relations
where the model changed, but
the view didn't change, right?
So now to begin thinking
about this I used the DOM,
the web DOM, the
document object model,
the API for addressing web
content, and used positions
in the web content
to try to understand
where to make the
insertion point blink.
And so, as I just illustrated,
I came up with this notion
of then equivalent
DOM positions.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of then equivalent
DOM positions.
DOM positions that would
make different DOM positions,
but that would make the
insertion point blink
in the same spot, okay?
So I started writing some
code: very simple, right arrow,
algorithm here, get the
insertion point position
in a DOM position,
then find this function
and use this function,
equivalent downstream position
to find the DOM position
that would still make
the insertion point blink
in the same spot, but was closer
to the end of the document.
And then go to the next position
and then set the
insertion point there.
Now that seems reasonable,
but kind of focus
in on these two important
functions here, right?
Well, naturally it's
just a program, right?
I mean so if you wanted perfect
results the functions need
to work perfectly.
And the problem with that was
that equivalent downstream
position was implemented
in terms of get next
DOM position,
so sometimes I would have
this feedback process going
where bizarre things happened
because a bug would then feed
into itself, right, and cause
something that was very,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
into itself, right, and cause
something that was very,
very difficult to understand
and diagnose simply by looking
at the result in the view.
So it was complicated,
right, to get right.
And then other issues
come up, as well.
What if you're already at
the end of the document,
the visual end of the document?
As you know, if you've
ever probably viewed source
on an HTML document, there's
often many, many things,
at the very least sort
of a closing body
tag, closing HTML tag.
A lot of times there's
script content.
There might be style content.
There could be any sort of
information that's not visible
after the visible
end of the document.
And by DOM position it will,
you know, if you just kind
of send it off to a position
it will merrily go there,
and there won't be a place for
the insertion point to blink,
so this was a problem, as well.
And then what if you
want to move by word
because the ultimate goal was
to make a text editor, right?
So you hold down the
option key and arrow,
and then you move word by word,
not character by character.
And so I was nowhere,
I was stuck.
I was working on this,
well, just for the sake
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I was working on this,
well, just for the sake
of argument say six
weeks, the magical number,
but for many weeks
without really feeling
like I was making progress.
So I asked for help,
and fortunately I had some
very smart people in my team,
which of course the
other stories have
already illustrated.
And I explained the problem to
them, much as I just did to you,
and their solution
came back very,
very clear that DOM
positions were too low level.
I was trying to build
a very complex edifice,
but I was using too
fundamental an abstraction
to get the job done.
So I needed a more
powerful abstraction.
So they came up with
one, they gave me one.
They called it VisiblePosition.
And all this was, this is C++
code, so this is C++ class
that represented a
place in a document
where the insertion
point can blink,
and then secondarily a
library called visible-units
that could take a
VisiblePosition and move
by words, lines and
documents, okay?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by words, lines and
documents, okay?
So they gave me this design.
Now the point is that I
still had the hard work
of figuring everything out, but
now I had a complete outline
of all the code that I needed,
every place, word by word, well,
I knew now there was actually
a place in the document,
there was a stub function
that was where the move word
by word code should go,
where that should live.
And so this, really this set of
abstractions really helped me
to just organize
the work and figure
out where this solution
should live.
It also made it easier to
think about the problem
so that I wound up with fewer
of these kind of functions
that fed back on each other
producing bizarre results.
So when you're blocked
don't be blocked.
Find smart friends
and listen to them.
In this case they said
VisiblePositions, visible-units.
I said, OK, I will do that, and
it worked, it absolutely worked.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I said, OK, I will do that, and
it worked, it absolutely worked.
I certainly went back and
got some more of their help,
some details, but this
was the big, big help.
Find smart friends
and listen to them,
particularly when you're stuck.
Do not stay blocked.
And this is how I got through
my hardest programming problem.
And so the next story,
number four, is "QWERTY,"
and the lesson is work
should explain itself.
So fast forward to 2005 now,
and I joined the iPhone
development project pretty
early on.
And initially I joined to work
on WebKit because it seemed
like a good match for my
skills and experience at Apple,
but I soon transitioned
to work on keyboards.
So now if you think about
it, right, and this is kind
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So now if you think about
it, right, and this is kind
of what we had when we
started with the iPhone.
We had a screen, and
we had this notion
that the keyboard
would be on the bottom
and the app content
would be on the top.
And, of course, the
big question was, well,
what should the keyboard
do, how should it work,
what should it look like?
And if you had seen even
from the very beginning the
Steve Jobs' announcement
of the iPhone, the original
announcement in 2007,
he pointed out very,
very clearly this virtue
of the iPhone that it didn't
have those plastic keys
on the bottom, we could draw
the keyboard and make it look
like whatever we wanted.
So now jumping back to the
beginning of that story,
because Steve on stage was
the end of that story, right,
we didn't have plastic keys
so we needed to experiment
of what we were going
to do, right?
How were we going to
replace those plastic keys
with software?
And we came up with many, many
ideas for how we would do this.
Now there are a lot of
challenges, particularly
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now there are a lot of
challenges, particularly
at the beginning, when we
were all new with dealing
with a touchscreen keyboard,
particularly touchscreens
in general and touchscreen
keyboards, specifically.
So one of the challenges is
that small targets are hard
to tap, it's pretty logical.
I'm sure you even
experienced that now,
the smaller the targets get the
more difficult they are to tap.
And not only that, but as you go
for a target, as you get close
to it your finger covers up the
thing that you're looking for,
so the smaller that it is
the more difficult it is
to do some fine-grained
adjustments as you get close.
So these were - we,
in our experiments,
we were seeing the result.
This was very challenging
to make a keyboard
that worked, at all.
And so in the beginning,
we were pretty clear,
or at least we thought
we were clear,
that bigger keys would
be the solution -
this would solve both problems.
So I have an example of
something in the spirit of one
of the experiments we
tried, not an exact example,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the experiments we
tried, not an exact example,
but something very, very much
in the spirit of what we tried,
and I call it the
keyboard keyboard
because if you think about, you
know, other things in the world
that accept a lot of
touch input, right,
well it's a piano
keyboard, right?
So you could maybe conceive of
a keyboard that looks like this.
So now how does this work?
Well, I'm going to try to -
I'm going to type the T key,
and so how do you get a T?
Well, you look on all the
keys, and you do make a chord,
multitouch motion, to find all
the keys that have a T on it.
Okay, so then we could go T.
H, H has actually got two of the
same keys as T, but H is only
on those two keys
and the, T-H-E.
So you can see how
this would work, right,
a chording keyboard, right?
And this is good
because the keys are big.
You can even maybe think of like
it's just like home keys, right?
You just kind of keep your
five fingers right on top
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You just kind of keep your
five fingers right on top
of the keys and, you know, you
can use the keyboard like that.
And so it's easy to press the
correct key, so that's good,
but it's bad because there's
a learning curve, right?
The first-time experience
is a mystery.
You see this alphabet soup
on this thing that looks
like a piano keyboard.
Well, how do I use this, right?
And so we were thinking
that, well,
the solution would be
we'd have a tutorial
to teach the people how
to use the keyboard.
Now it's actually, you know,
this is not - this is an idea
that actually has
some history at Apple
because the original Mac
shipped with a tutorial
to teach people how
to use the mouse,
since that was new, right?
So we figured we'd come up
with a tutorial, and you think
about it, is that
even if we didn't have
that keyboard keyboard,
but if you imagine
that if we did we could maybe
even come up with a keyboard
that used music to
try to teach people
that you could maybe
play a tune, right?
So it wasn't the craziest
idea in the world.
But after each of these
experiments and each
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But after each of these
experiments and each
of the times that we thought
through how to make a tutorial,
we always came back to QWERTY
because you all already
know how to use it.
There's no need for
a tutorial, right?
You see the thing,
and instead of, gosh,
what is this, and
how do I use it?
Right? Instead of that you have
this, where you look at it and,
okay, it's different
because it's a touchscreen
and it's small, but we're sort
of calling on and invoking,
right, a lot of these kind
of these familiar notions
that you're already very,
very comfortable with.
So that's why we wound up with
this and ultimately, right,
we have this today because we
thought it was more important
that the work should
explain itself, right?
You already know
how to use QWERTY.
We don't need a tutorial.
And so this was really
the key to that decision,
key I guess is a funny
word, but it's the keyboard.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
key I guess is a funny
word, but it's the keyboard.
But it's the real reason why we
chose to go with QWERTY because,
again, we thought that
work should explain itself.
So the next story, number five,
"Every Word on Every Keystroke."
And so the lesson is choose the
simplest thing which might work.
So continuing on
in the development
of the iPhone keyboard, it
became my job to do the work
to make QWERTY possible, right?
We had this challenge of small
keys, difficult to tap now,
and of course you all don't
care about my problems,
you just want to type quickly.
So the software was
going to need to help.
And so the eventual solution
for that was auto correction,
which is, of course, what you
meant and not what you did,
taking what you did and figured
out what you meant from it.
And, of course, there's quite a
bit of smart people have thought
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And, of course, there's quite a
bit of smart people have thought
about text processing
and text prediction,
and so some of the terms that
are in the state of the art,
you know, then as now
Bayesian statistics
and Stochastic programming,
Conditional Random Fields.
And a lot of these involve
large statistical models
to make them work, that they
rely on, language models.
And these were not going to
be possible given the hardware
and software environment
of the original iPhone.
Not only that, but
I last studied math
in the eleventh grade,
which was in the'80s,
and it was in the early'80s.
So I was kind of looking
at Stochastic programming,
oh, okay, well, you know.
So really what I decided was
I needed something simple
because math is hard, okay?
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
And so here is a little bit
of an idea, a little bit
as to how this auto
correction works, right?
Certainly, in the, you know,
way back then and the first time
that I tried to get
this idea together.
So you're typing a letter, "I."
Well, since the keys are small
maybe you meant those keys,
as well.
So "I" was highlighted,
but maybe you missed
and maybe you meant one
of the keys around "I."
Okay, and then you type a
T, and, well, similarly,
maybe you meant one of
those letters around it.
So even just with
two characters,
you can see that there are
a number of possibilities.
All right.
And so in one column are
words that are real words
and are going to be in
an English dictionary,
and in the other column there
are just those words that are -
they're letter combinations,
but they're not words.
We have words that, the one
column has words that are
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have words that, the one
column has words that are
in the dictionary and the
other column has just letter
combinations that aren't words.
And so what do you do with this?
This is now raw material, right?
And so auto correction, really
ultimately sort of a big part
of it, is just speculation,
you know.
Did you mean this one?
Did you mean that one?
Did you mean the other one?
Did you mean this one?
And this involved many, many,
many dictionary lookups
to just check.
Are these letter combinations?
Are these words in
the dictionary
that is selected by the user?
So I needed something that
worked really, really fast.
And so the idea was offered to
me that, well, you could maybe
as the user is typing
just kind of send
that dictionary lookup stuff
on a background thread and sort
of post the results
back when it's done.
And, of course, being back
then we didn't have GCD,
and so the Pthreads would
have been the solution.
And it's like, I'm scared
of multithreaded code.
It's hard; it's hard
to get right.
I'll tell you a secret, it's
just like there was actually -
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'll tell you a secret, it's
just like there was actually -
I did have one little
bit of multithreaded code
in the keyboard in the beginning
to do some initialization,
and that was as large
a source of bugs -
it was a tiny little piece
of code, and that was
as large a source of bugs,
dealing with app startup
and you launch an app and then
suspend it, it was a huge source
of bugs even if it was
just a little bit of code.
And so I wanted to
keep multithreading
out of auto correction, which
was much more complex, right?
Because I wanted us
to keep things simple
because I can understand simple.
All right, multithreading
is hard.
I can't even like make
an egg and breakfast
in the morning, right?
I make the egg, make
coffee, then make the egg,
keep it single threaded, right?
Because otherwise I wind
up with a messy kitchen.
OK, so keep it simple.
So here is actually
a little algorithm
for searching a dictionary.
Word list on one side,
and a little algorithm
on the other side.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and a little algorithm
on the other side.
And this was actually
thought up by the same fellow
who did the KHTML demo.
And so he came up with that
good idea, and as part of some
of our other experiments,
and, boy,
I saw that good idea
and I used it.
So what do you do?
You have a list of words in a
dictionary, you memory map it,
you iterate the list once
to find the line endings,
you store those addresses
in a pointer array,
you can then binary search and
you can find whether a word is
in the dictionary
really, really fast.
Really, really fast, and so next
after that I wrote a
custom C++ string class
that could wrap any string
in that memory map area.
Each of those strings were
null terminated on the end,
so you could just kind of
go and wrap an address,
and you have a string, as long
as you're at a line start.
And so this turned out to
be really, really fast.
I could check dictionary
membership in microseconds,
even on the original
iPhone hardware.
So this was now really,
really fast.
And so what this did was
it made speculation really,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so what this did was
it made speculation really,
really cheap, and that in turn
made auto correction possible.
So I could go from this and
take all of those permutations,
even for as long a word as
you might find in a language,
and actually go and figure out
whether that word is going to be
in the dictionary or not
and whether similar
options would be as well.
And this turned out
to be so fast
that I stored no state
for the current word.
I didn't store previous results.
All I did was actually store the
string for the user's typing.
If we think back here, all
I've had stored is I T.
What have you typed?
The actual characters
that were lit up, right?
Not the neighboring ones.
But the only thing
stored was the characters
that were lit up, okay?
So only store that string.
So it's actually, I reran
the entire algorithm
on every keystroke from
scratch, which means of course
that it searched the
whole dictionary,
70,000 plus words,
on every keystroke.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
70,000 plus words,
on every keystroke.
Because, to me, this
was the simplest thing,
as I was thinking about it,
it was the simplest
thing which might work.
And by coming up with
sufficiently fast
implementations of this,
it turned out that the
simplest thing did work.
Simple is often speedy,
and simple was something
I could understand.
And when there are
bugs I could understand
where those bugs
might have been,
and that's every word
on every keystroke.
Choose the simplest
thing which might work.
And again if you're kind of
looking from the beginning
of a project trying to think
to the end of a project
and what you might have
when you're all done,
that's why it's termed this way,
choose the simplest
thing which might work.
If you did actually have a
crystal ball you could tell
whether maybe your
idea would work.
But I think this is,
even from the beginning,
if you kind of think
of the simplest thing
which could possibly just
give you what you need,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which could possibly just
give you what you need,
go with that first.
I think that's a good idea.
And so the next story,
number six,
is "We Only Need One
of These, Right?"
And the lesson is only
show your best work.
And so fast forward to 2009.
I joined the efforts
to develop the iPad,
and the iPad needed a keyboard,
and so it's by this point I had
two signs pasted onto my back -
one said "Kick me,"
and the other one said
"Because keyboards."
So it was sort of something
that seemed to be in my area.
And so I noticed that in
landscape, you turn an iPad
to landscape, that the number
of keys that you could fit
across the top was
close to the size
of a full-sized desktop
keyboard.
And so here is a representation
of a full-sized desktop
keyboard, and there is the size
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of a full-sized desktop
keyboard, and there is the size
of the keys that we
could fit on an iPad.
And if you see, overlay
one on top
of the other, it's pretty close.
It's not exact - the iPad
is smaller - but it's close.
And so I was thinking
that, hey, well, you know,
it's not exactly the same size,
but auto correction
could maybe help you
to type comfortably, right?
So, yes, big keys across the top
that seemed like a good idea.
But then we also had the
question in our minds of what
if you wanted more keys?
We now had space for them.
Allocating the space
on the original iPhone
keyboard was tortuous
because we couldn't even
fit the period character
on the first keyboard
that you saw.
We had to put that onto
a secondary key point.
And so we didn't
have that problem.
Now we could have more keys.
We had the room for them,
and so you can imagine
that we can start
getting some more keys.
In this case I put in
shift and caps lock and tab
and a couple extra
characters off at the side.
And then I direct your
attention to this here,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And then I direct your
attention to this here,
so we would have a switch that
would allow you to go very,
very quickly between the
one with the big keys
and then the one
with the more keys.
And sort of similar to what we
have where you change to numbers
and punctuation, but this was
really keeping the letters the
same and just bringing
in more keys.
And so, you know, a bunch of
us who were working on this,
we thought this was the
best of both worlds.
It was cool, right?
So I got to demo this for
Steve, which is a gulp.
And so, so bringing
the iPad, you know,
you kind of have the demo
room, and go in there and he's
in there, and it's
like "He's in there."
And then, okay, so you put
the iPad in front of him,
and fortunately the
work explained itself,
so the description was
as short as we're looking
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so the description was
as short as we're looking
at iPad keyboard options
today, here are two options,
press the switch key, done.
So he did.
He looked at the first keyboard,
and he pressed the switch
key, saw the animation.
He looked at the
second keyboard,
he pressed the switch key again,
he saw the first one come back.
A third time, presses
the switch key,
sees the second one come in, and
he looks at this for a moment,
and then he looks
up at me and says,
"We only need one
of these, right?"
And he's looking at me.
And so I gulped a
couple more times.
And so and he says, "Well, which
one do you think we should use?"
And I said, "Well, you know,
I think we should use the one
with the bigger keys because
it's just easier to type,
it's close to the size of
a full-sized keyboard."
And he said, "Okay,
we'll go with that one."
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Laughter & Applause ]
And that was it, really.
I mean that really was it.
It was just quick, and so
that's why we wound up with this
and then ultimately today, this.
And, of course, the lesson
is only show your best work.
Perhaps more than anyone
else, Steve understood this.
Go out and think of all
the ideas that you can
and not only just think
of the ideas, but get them
and make them and
use them and live
with them and think about them.
And then try to figure
out which is the best one.
So what was interesting
to me about that story is
that even though I was
under a lot of pressure,
when he asked me which one
I thought was better I knew,
but I didn't have the
courage to just go in there
and show him the one
that I thought was really
the best the first time.
It needed his extra
prodding, that little bit
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It needed his extra
prodding, that little bit
of extra investigation, that
little bit of extra poking
to say, wait a minute, right?
Which is the best one?
Which is the second best one?
Let's not show the
second best one, right?
Only show your best work.
You have to go through all of
the effort to generate lots
of ideas to come up with
one that's really worth it.
And that's "We Only Need
One of These, Right?"
Only show your best work.
Okay, story number seven,
is "Let's Try It 2% Darker,"
and the lesson is iterating
quickly leads to better work.
And so 2012 I joined the effort
to develop iOS 7 and, of course,
as you know one of the big goals
for iOS 7 was a whole new look.
And you ask the question, well,
how do you make all
of these choices?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
how do you make all
of these choices?
And a lot of times coming up
with these new design ideas,
it felt like a game
of Whac-A-Mole
because every decision
affects every other decision
that you make, right?
You change one thing, and you
have these things over there
that kind of familied well with
the thing the way it was before,
and now it doesn't seem
like that, now it seems
that the thing that you've just
changed doesn't really work well
with everything else.
And so this required a
tremendous amount of tuning,
iterating and iterating
and iterating,
version after version,
effort after effort to try
to get things so
that they all looked
like they belonged together.
And so if you kind of break
that down from the process
of actually trying to do that
work, one design iteration most
of the time looks
like this, okay?
A guy, like me, will bring
a demo to the designer.
The designer will have feedback.
I'll take notes.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'll then go away to
make those changes
that the designer has requested.
Then we schedule the next demo,
and then we have that next demo,
and we go back to the beginning.
So this process can
take hours or days
because people are busy, right?
And sometimes, you know, it's
just hard to get together.
And so we wanted a
way to go faster.
Can we go faster?
And so one of my very,
very smart friends, again,
smart friends, it's a real key,
one of my very smartest
friends came
up with this idea of settings.
And what are settings?
Well, settings are
tunable values, right?
You take all of the settings
that you might want to tune
and put them in just an object
that just is a bag
of properties.
You use KVO, so that
when you change one
of those properties the parts of
the system that are interested
in those values changing
can know about it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in those values changing
can know about it.
She also came up
with this way to save
and restore these options,
and then there was also a way
that you could have
settings, which own settings,
which own settings, so you
could have a tree of settings.
And also came up
with an editing UI,
and it's the editing
UI I want to show you.
So here's just a very simple
example, a very simple app
that lets you manipulate
geometric shapes.
So I've got now one blue
circle, and you can go
and with the settings UI you
can then bring up a hud right
in the app, twiddle a
couple of sliders and change
from one blue triangle to
three red triangles, great.
And then similarly we
can go to this other one
that actually support
those nested settings,
that would use sort of iPhone
style, side-to-side navigation
to show you the different
levels of settings.
And so if I take the red
triangles and move it back
to the settings for the
blue circle, you have this.
And so what did this do?
This did something
very important.
This reduced iteration time
because once you had the right
settings surfaced in the app,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because once you had the right
settings surfaced in the app,
you could sit with the
designer, an engineer could sit
with the designer, and try
many, many, many options.
And so we got to the point where
you kind of tried to figure
out what control
center could look like,
and the designer
could say, well,
what if we made it
2 percent darker?
I don't even know if you can
see that up on the big screen?
It's the point of it, is that
we were trying to get tuning
to this level, 2 percent
darker, 2 percent darker
on your left than on your right.
We wanted that level
of polish and attention
to every single value in the OS.
So when we had a tuning
session like this, it was great
because I could just go back to
my desk now, copy the defaults
that got saved from
the tuning session,
copy those to the new
defaults, and commit.
It's great, and this made
it cheap and easy to tune;
we could just do it over and
over and over and over again.
And this was the way that we
wound up with just a handful
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And this was the way that we
wound up with just a handful
of blur styles for iOS 7
that are used consistently
everywhere.
It was very, very difficult
to come up with those,
with that set of blur styles.
And this is how we did it by
just iterating and iterating
and making iterating
easy and cheap.
The lesson really, right,
is iterating quickly
leads to better work.
I think my experience from
iOS 7 was there was a direct
correlation between how easy we
made it to try out new things
and what the quality of
the final work product was.
And so that's "Let's
Try 2% Darker,"
and the lesson is iterating
quickly leads to better work.
Okay, story number eight.
Three lessons from
making this session.
And so this is not
the original session.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I wrote an entirely
different set of slides.
And not only that.
I did three full
rehearsals with them.
I like to rehearse a lot
before, I mean it's important
that this session
goes well for you all.
You all came here, and I want
to make sure they're
giving you a good product,
I mean so I put a
tremendous amount of effort
into preparing the
slides and rehearsing.
And so with that other set of
slides I used up a big portion
of my time rehearsing
that set of slides.
See, the good thing was, it
was done way ahead of time.
It was great.
It felt good to just
be like preparing
for WWDC can be really,
boy, it just always seems
like everything is down to
the wire, and this year, boy,
I was really ahead of time.
But I had one more review
for the content that I had
in my slides, just go over
the material and the content,
particularly because I'm talking
about some past Apple work.
And it turns out, yeah, that
version just got shot down.
Yeah, you can't show that.
There were just issues
that couldn't be resolved.
The details aren't
important, but there's kind
of the one big detail which is
I don't have a session anymore.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the one big detail which is
I don't have a session anymore.
Three weeks ago I had
something that was rehearsed,
and two weeks ago I didn't know
if I was going to be here today.
So I needed to rewrite.
And there were three
important lessons
that I took away from that.
And the first was during this
review session, where the person
who I was submitting my
slides for review to,
said "You can't show that."
He didn't raise his voice, it's
just like "You can't show that."
And here's why, he gave me the
reasons, but he was very calm.
And even after, I mean it was
clear, it was bad news to me,
and even he found me later
and made sure that I was okay
with this decision that was a
very hard one to share with me.
And so the lesson from this is
be kind to people, but be honest
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so the lesson from this is
be kind to people, but be honest
about the work, right?
There's no reason to like be
shouting and berating people
who are trying hard
and doing their best.
If you have ever found
me in a lab or maybe even
with what little
time we have left
in the conference before
it ends, if you find me
in a lab today, I hope I
will do my utmost to be kind
to you personally because
I'm so glad that you're here
and so glad you're
contributing to our platform.
And I want to see you
do great work, too.
But if you show me a piece of
work, I'm going to be honest
on what I think about it.
And those things just
need to be kept separate,
the personal kindness and
the honesty about the work.
And, secondly, it's kind of
like sort of this different side
of the same coin, is
that I didn't take his
feedback personally.
And the lesson is to separate
yourself from your work.
Now and I always invest a
tremendous amount of care
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now and I always invest a
tremendous amount of care
and emotion into my work, it's
my nature, I can't help it.
But after I'm done making
something and bring it
to the stage that
it's ready to demo,
I just try to then divorce
myself from that thing
that I just sweated over
making because that's not me,
that thing that I
just made, all right?
I'm ready to accept whatever
feedback anybody has and ready
to go and do the
next thing, right?
So you need to kind of divorce
yourself, when you get feedback,
people hopefully are not
giving you the feedback,
they're giving you the
feedback about the work.
So separate yourself
from the work,
regardless of how
much time and effort
and how much investment
you have in it.
And the third lesson
is, well, obviously,
I needed to get back to work.
If I wanted to have a
show, right, at all,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If I wanted to have a
show, right, at all,
I needed to figure
out how to make a set
of slides that would work.
And the lesson here is
that you're never done.
Kind of seems like some sort
of nightmare, if you think
about it one way it's that
you're never done, really?
But you think about it,
no, we're never done.
We loved the first version of
the iPhone when we shipped it,
and then we went right back
and we made version two.
And earlier this week we
showed iOS 8 and Yosemite
and a whole bunch of
other great things, right?
You are never done.
If you're committed to
working in this industry,
working in high tech,
right, you are never done.
The world keeps moving;
you've got to try
to keep moving with it.
So do the best that you
can do at any one time.
And basically you're always
shipping your latest demo,
if you think about it that way,
it's just that these demos get
to be very, very polished,
polished to the point
where you're going
to actually share it
with the rest of
the world, right?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with the rest of
the world, right?
So still on this idea, this
is a quotation that's actually
up on the wall -
very, very large.
In Cupertino, a quote from
Steve Jobs, and he said,
"If you do something and
turns out pretty good,
then you should go do
something else wonderful,
not dwell on it too long,
just figure out what's next."
And I think this is true, not
only when you do something
that turns out well, but it's
even as in the case for me,
for this session, I did
something that didn't turn
out so well, I needed to
figure out what was next.
I could give up, or I could
try again, and I tried again,
and I'm very glad that I did.
I'm very happy to be here today.
And so the kind of the big,
sort of joined up lesson
from this section is that the
stories and lessons never end.
I thought this was going to be
a session just about stories
and lessons and had no idea
that I had started a process
that would teach
me more lessons.
And so those are my
stories, and there they are.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so those are my
stories, and there they are.
Again, and I think, I hope,
at least that you found
them entertaining,
but really I think the important
part is these, the lessons,
that you can take out from
them, because you're never going
to find yourself in exactly
the same situations that I did.
But I think that you'll
find yourself in situations
where you can apply some
of these ideas usefully
and productively.
So, again, those are my stories.
And so now I ask you,
I urge you, to go out
and make your own stories,
tell your own stories,
extract the lessons
out from them, right?
And then figure out how you're
going to use that experience
to go and do some more
great work of your own.
So thank you very much.
[ Applause ]