Thursday, October 3, 2013

Capitalism + Socialism = America 2.0

Anthony Bourdain wrote a nice perspective piece on gun culture in America. It made me think.

Guns may not be a part of your culture, they're not part of mine, but they're definitely part of America's culture, past present and future. They are definitely deadly weapons, but so are cars. Neither are going away anytime soon.

Guns may not be what congress is fighting over today, but different cultures are definitely clashing. Do we individually pull ourselves up by our own bootstraps or do we collectively pull each other up? Do you spend your hard earned money to help some stranger you don't even know? Are people in need fellow humans down on their luck or mooching free loaders? That's what the fight is over.

If you're the mathematical type you might even recognize both issues from game theory, the study of conflict and cooperation between intelligent rational decision-makers. We could jest about congressional intelligence and rationality, but lets not miss the wide ranging implications. Eight game-theorists have won the Nobel prize, including John Nash for his idea of Nash equilibrium, the idea that the optimal solution for multiple competing game players is not just to play your own strategy but to adapt your strategy to the strategies of your competitors. If you ignore everyone else's priorities and goals and strategies you will lose.

I've applied this to corporate politics already, but it also applies to national politics. Granted, there are many complexities, like Bayes-Nash equilibrium, differing belief systems, random chance, incomplete information, risk avoidance or corruption. The core concept is still intuitive enough to apply (obviously the details are non-trivial). In general tho, we can't just think of ourselves and we can't just think of the collective. We need to think about what's best for us AND our community, me AND my neighbor, the state AND the country.

Our constitution may be a great document, but it's woefully lacking in these kinds of mixed-strategy incentives. It relies primarily on checks and balances, a strategy for combating the aggregation of power, but checks and balances are mostly disincentives, not incentives to do the right thing. Our constitution is great at stopping any one person or branch of government from becoming too powerful, but it's pretty terrible at motivating optimal behavior or continual improvement. What feedback loop is there to motivate your congressional representative to think about what's best for the country? If they please their constituents they get elected again, but where's the motivation to come to the table and do what's best for the other 99%+ of the people in the country? Instead of multiple incentives and enlightened thinking we have a government run on head butting competition that enables and glorifies pure selfish greed.

"Screw you, got mine" selfishness is poison the same way utopianaltruism is. Cooperation is nothing without a little self-interest, but too much self-interest unbalances the system so that everyone loses. Romanticized Capitalism is just as flawed as utopian Socialism. It's time for a new -ism; one where we think about us AND them.

Sunday, September 22, 2013

Exponential Improvement Is The New Growth

Here's a sneak peak at a future S.A.T. analogy. Fill in the blank.
Velocity : Acceleration : Jerk :: Growth : Continuous Improvement : _________
We'll get to the answer, but first a history lesson!

Buckminster liked to make up new words. "Ephemeralization" was his from the 1930's. The classic definition of ephemeralization is "doing more with less", but it's more precisely the observation that things happen more quickly and easily over time, requiring less resources. The easier things become, the faster they become easier. The cheaper things become, the faster they become cheaper. Generally this is attributed to the adoption of scientific management, as exemplified in early industrialization (especially by Henry Ford).

Gerald Hawkins in the 1980's described the idea that each stage of change had an inflection point where a paradigm shift ('mindsteps', as he called them) occurred, advancing the rate of change forward. He also observed that the rate of paradigm shifts was increasing. Change was accelerating.

In 1986, Masaaki Imai popularized "Kaizen", the idea of continuous improvement in business management. Ideally improvement doesn't need to be limited to discrete (continual)  jumps based on scheduled analysis after designated periods of time (iterations), but could instead be driven by slack in the system to allow (continuous) improvements every day. The acceleration of change requires faster measurement and analysis, but with built-in slack the workers on the factory floor can do it better than managers at a distance.

In 2010, David Anderson documented "Kanban", a method of software development that integrates Agile concepts with Japanese Kaizen improvement techniques. The practices and policies Anderson describes are great management techniques based on years of experience and an evolution of Agile methodology. His primary focus is on work in progress limits to create slack, but the real power comes from empowering workers with information and constant feedback so that they can use the slack for continuous improvement.

So with the implementation of continuous improvement in Japanese factories (like Toyota) and later Silicon Valley software developers (like Google), managers found themselves with less management to do because they'd empowered their employees to do their job for them. Many people have been confused by this, thinking that managers are now obsolete in an organization of continuous improvement (like Valve software), but the truth is simply that managers need to level up, the same way factory workers replaced by automation had to become educated to produce, maintain, and improve automation. Managers won't manage people in the future, they'll manage their own empowerment of people.

Managers don't just provide feedback any more. They empower employees to provide and receive feedback. Just like employees need feedback to improve, management needs feedback to improve as well. If you really want to get better at getting better you need to level up again. "It's much less about 'What kind of knowledge advantage do I have right now?' but 'How fast am I creating new knowledge?'."

This is where executives come in. The new job of executives isn't to manage the managers any more or even just to manage external expectations, but to empower the managers to manage themselves. Empowered managers get better at empowering workers to get better, inovating on innovation. As we've seen on the previous level, old style executives are becoming obsolete, even a liability. They need to educate themselves and raise to the challenge of faster change, to manage the empowerment of managers. They need to not just set a culture, but grow a culture of change. Business doesn't just need to evolve; it needs to improve its ability to evolve.

Back to the analogy...

Velocity is position over time. Acceleration is velocity over time. Jerk is acceleration over time. Growth is improvement of state over time (the new role of workers). Continuous Improvement is positive growth over time (the new role of managers). So Exponential Improvement is faster continuous improvement over time (the new role of executives).  Jerk is the third time-derivative of position. Exponential Change is the third time-derivative of state. Exponential Improvement is positive Exponential Change.

No, this doesn't mean future executives will all be jerks, but they might need to be good at calculus. The executive needs to enable Exponential Improvement, and the easiest way to do that is to derive it from the employee improvement metrics over time. They'll have to analyze metrics and behavior to figure out how to improve exponentially. They'll have to identify synergistic ways to empower managers that increase their rate of empowerment.

To be fair, Continuous Improvement will get you a long way. Most organizations haven't even figured out that yet, but they will. And the more that figure it out, the faster the movement will grow. But if you really want to succeed in the future you can't stop there. You have to get better at getting better at getting better.

Future Shock is no longer in the future, it's now. Change is and will be. Change is continuous and accelerating and decentralized. This isn't a revolution; revolutions end. Businesses that didn't change are already dead. Businesses that aren't changing fast enough are dying. The new race is how fast you can innovate. It's a race you can't conclusively win; you can only win now and survive until you win again. Growth is slowing down. To grow linearly you'll need to improve exponentially.

Stop watching the world improve and start participating in making it improve faster.

Saturday, September 21, 2013

SteamLevel

SteamLevel.com Forwards Here.

SteamLevel was a site for comparing gamer profiles on Valve's Steam digital distribution platform.

The primary reason I wrote SteamLevel was to be able to decide what game to play at LAN parties with my friends. We could add all the people there to the search list and it would generate a big table of all our games, making it easy to see which ones we all had.

But hosting a web application is expensive. There was no ad revenue and not many users. I tried Amazon sponsered links to games, but that just felt like a slap in the face to my users, who were there because of Steam, not Amazon's digital distribution platform.

But the real problem was that I had heavily cached everything. So it took gobs of memory. And web hosts really hate to give you memory. Memory turns out to be the hardest thing to increase. It's easier to get a dozen CPU cores than it is to get more than 4GB of memory, and my host had capped me at 2GB. I was hosed. The application needed a rewrite to even continue using that web host and anything with more memory was 10x as expensive. I just really didn't want to pay that much for hosting. it would have been cheaper to buy my own box and upgrade my ISP to business class.

So SteamLevel is down, indefinitely.

It may get resurrected at some point. I still own the domain. But not today. Sorry.

Monday, September 9, 2013

Tablets: 7" vs 10"

Seven inch tablets are better at two thumbed typing in portrait orientation, while ten inch tablets are better at two handed typing in landscape on a flat surface.

Seven inch tablets are small enough to fit in purses and large pockets.

Seven inch tablets are holdable in one hand for extended periods.

If you want to use your tablet like a computer, get a 10 inch. If you want to use it more like a smartphone, get a 7 inch.

Listening to music on the go on any tablet makes you look silly. Thankfully people don't care enough to comment.

I've based the above generalizations solely on my own iPad 3 and Nexus 7.

Sunday, August 25, 2013

Updating Nexus 7 (2013) from JWR66N to JSS15Q on Windows

So the Nexus 7 had 2 issues at launch: GPS & Multitouch

The launch android build that comes with the Nexus 7 is JWR66N. The fixes are in JSS15Q.
Find your build number: Settings > About Tablet > Build Number

There was a patch soon after launch, JSS15J, but it doesn't fix either of the above issues. If you don't already have JSS15J google probably wont give it to you over the air (OTA) any more, because it doesn't fix the issues and might make them worse. If you already have JSS15J don't worry, you can still upgrade.

Now if you're squeamish about developer mode you shouldn't be here, just wait for Google to give you JSS15Q over the air. But if you want to get your hands dirty you can resolve those pesky issues now!

1) You'll need developer mode enabled on your tablet.
http://www.androidcentral.com/how-enable-developer-settings-android-42

2) You'll need to change the USB mode on your tablet to "Camera(PTP)".
http://zacktutorials.blogspot.ca/2012/08/nexus7-android-development.html

3) You'll want "stay awake" and "usb debugging" enabled in your developer options on your tablet.
http://zacktutorials.blogspot.ca/2012/08/nexus7-android-development.html

4) You'll need to download and unzip the Android SDK for Windows.
http://developer.android.com/sdk/index.html

5) Launch the "SDK Manager" in the zip you just downloaded and install the "Google USB Driver". (It'll probably ask to install the SDK and Android 4.3 while you're at it.)

6) Modify the USB driver to add the device ID of the nexus 7 when in recovery mode.
http://blog.dantup.com/2012/10/fixing-adb-device-not-found-with-nexus-7-in-recovery-mode

7) Plug in your tablet via USB (it will attempt to install drivers if it's the first time or it has failed before).

8) Install the newly modified device driver.
- Go to the Windows Device Manager, select your tablet from the "Other devices" category, right click and select "Update Driver Software".
- Opt to browse your computer for driver software and point it to "\extras\google\usb_driver".
- Note that the modified driver won't pass checksum and thus wont pass signature validation. So you'll have to approve it when it warns you.

9) Run adb to request device debug authorization.
- Open the command prompt (cmd in the start menu).
- Navigate to \platform-tools
- Run "adb devices"
This should print out one device as unauthorized.

10) On your tablet, authorize your computer. Select "always allow from this computer".

11) Run "adb devices" again to make sure your device says "device" and not "unauthorized".

12) Download the "JWR66N->JSS15Q OTA" or "JSS15J->JSS15Q OTA" depending on which version you have on your tablet (Settings > About Tablet > Build Number).
http://forum.xda-developers.com/showthread.php?t=2415497

13) Use adb to reboot your tablet into recovery mode and side load the update.
- Follow Step 11 onward from http://www.droid-life.com/2013/02/12/guide-how-to-use-adb-sideload-to-update-a-nexus-without-root-or-custom-recovery/

14) Do a happy dance!

For the record, I found the responses on this stack overflow question helpful when trying to figure this all out:
http://stackoverflow.com/questions/11974700/nexus-7-not-visible-over-usb-via-adb-devices-from-windows-7-x64#14106931

Apparently this process is easier on the Mac, because the device drivers don't have to whitelist device IDs and "just work".

Sunday, August 18, 2013

Iterable is an Anti-Pattern

I couldn't decide I hated UnsupportedOperationException or Iterator more, so I decided to pick on Iterable instead...

Iterable limits the implementer to having one interesting iterable attribute. 

Having a single iterator producing method (Iterable.iterator()) restricts the implementing object to only ever have one interesting quality to iterate over. This requires that it be obvious from the name of the iterable class and the class name of the iterable components (that you often can't control) what it is you're allowed to iterate over.
Company workCo;
for(Position currP : workCo) { ... }
What are we iterating here? Positions within the Company? What does that even mean? Is it even ordered? Is it open positions or filled positions? These are all things you'd normally hit at with a well named method. 

The JDK authors at least sort of figure this out for Map, but in order to make it work they had to expose the inner workings of how a Map works, and in doing so dictate implementation details in an interface. Your Map must implement entries() and it can't just be a view; it has to be mutable (or explosive) and tightly coupled with the Map it came from. This is terrible for asynchronous execution and expensive to implement.

Now, to play devil's advocate, one might say that if you have multiple iterable attributes you shouldn't be iterable... That's valid. Maybe the Company class really needs to contain multiple iterable collections, like currentEmployees() and openPositions(). But this just hammers home my point by pulling "an Apple" and telling users they're holding/using it wrong.

Iterable is not extensible.

Your object may only have one iterable element, but what about extensions? Iterable forces any extensions with any other iterable attributes to be via compositions and views. This is especially true for elements with multiple attributes or multiple views.

Liskov's Substitution Principle requires that all extensions demonstrate an "is-a" relationship to their parent. If you missed that day in CS class, it means that "Nissan370Z" can extend "Car", but "Truck" can't. Even if a trunk does all the same things a car does, a truck is not a car.

The more API you define the harder it is to extend. 

Iterable is poorly composable. 

So when you can't extend to add another view type what do you do? You compose the class with a view.
class Sizes implements Iterable {
  Collection> stuff;
  Viewer(Collection stuff) {
    this.stuff = stuff;
  }
  Iterable iterable() {
    return new Iterator() {
      [impl goes here]
    };
  }
}
So you took your collection of collections and composed it, and now you get to write your own custom Iterator... Yay.

Terrible. 

Interface method names shouldn't hide what they return. 

If an object has multiple Iterable fields, for example, and it implements Iterable... which field does the returned Iterator, from the method iterator(), actually iterate over? The method name doesn't tell you, and that means the code that iterates the object doesn't tell you, and is thus less readable.

Abstract the type, sure, but don't abstract the method name. Otherwise you end up with and API with:
Iterator iterator();
What does that return?
It might make sense if the type is more specific, but are you really going to wrap your String in an object just to give it a better name? No, that's stupid and expensive.

You shouldn't have to implement something to say you're not doing it.

Iterator is an anti-pattern itself, with its mutability baked right in. You have to explode with an UnsupportedOperationException if you want to tell the user (at runtime) that the view you're iterating over isn't mutable.
@Override
public void remove() {
    throw new UnsupportedOperationException("Sorry, No.");
}
How many times have you had to write that crap?
Google Guava even has an abstract class to clean up their code, but that doesn't legitimize it.

To be honest, UnsupportedOperationException is pretty bad all by itself. Just it's existence means that the JDK regularly violates the Liskov's Substitution Principle.

All JDK collections are mutable. 

This is really one of the core problems with the JDK and the reason Iterator is bad. The API for immutable objects is conceptually a subset of a mutable API with the primary exception that a builder or constructor from a mutable is required. 

So what's the fix?

There isn't one really. The JDK is hosed. It's never going to get fixed, because it would break reverse compatibility horribly, and because we can't delete those old classes we can't really reuse their names either, they're already taken.

I've considered spinning up an alternative JDK, starting with collections, taking what we've learned about immutability and substitution and composition and starting over.... Who's with me?

We'll start with this:
interface ForwardCursor {
  boolean hasNext();
  T next();
}
interface BackwardCursor {
  boolean hasPrevious();
  T previous();
}
interface BidirectionalCursor extends ForwardCursor, BackwardCursor {
}
And we'll add some magic syntactical sugar similar to the for each loop to work with ForwardCursor, except we're goign to call it "for rest" because it will start where the cursor is currently, and never needs to worry about making a new cursor. That way your object can have multiple cursor'd attributes, each with their own methods:
CollectionOfCollections {
  Collection> collections();
  BidirectionalCursor sizes();
}
Granted, that last usage example is a little silly... Let me know if you come up with a better one!