Wednesday, March 25, 2009
Safari Flash Fail
Take a look at the stack trace that gets sent to Apple:
So I think this is being caused because I set the storage allowed by the Flash player to 0 KB. The default is 100 KB. Why do I have it set at 0 KB? It's not because I am some privacy fanatic, just the opposite in fact. It was because I was debugging some PayPal code a few months back that required that Flash local storage be unavailable. Most sites then ask to set it back to the default 100 KB. However, if the SWF in question is too small to show the settings dialog, then it can't show the dialog to ask the user to set the amount of local storage for the site. You can right-click any SWF to bring this setting up, well any SWF that is biggest enough to display the settings manager. This is on a per site basis, but you can set things globally as well. Dealing with the error that is thrown when setting data fails is what I helped PayPal with. Obviously there are a lot of sites that do not deal with this error, and that seems to bubble up in Safari and cause it to crash.
Friday, March 20, 2009
iPhone OS/SDK 3.0: Remote Notifications
Monday, March 16, 2009
Karma's Bitch: The Denver Broncos
Sunday, March 15, 2009
Hiring Developers
Monday, March 09, 2009
Covariance, Contravariants, Invariants, Help!
public static void invariance(List<Number> nums){
nums.add(1.1D);
for (Number n : nums){
System.out.println(n.doubleValue());
}
}
Invariance implies implies problems with the following code:
List<Integer> ints = Arrays.asList(1,2,3);
invariance(objs); // won't compile
List<Object> objs = new ArrayList<Object>(ints);
invariance(ints); // won't compile
You have go to match things exactly if you want to call an invariant method. Sometimes this is too restrictive, but not in this case. In the example above, you both read and write from the collection. If we could pass in the List of Integers, then adding a double to it would be invalid. If we could pass in a List of Objects, then calling the doubleValue method would be invalid. The only option here is invariance.
If you only need to read from the collection, then you can have covariance:
public static void covariance(List<? extends Number> nums){
for (Number n : nums){
System.out.println(n.doubleValue());
}
}
Now you can pass in anything that adheres to the API of Number, i.e. anything that is a subclass of Number.
List<Integer> ints = Arrays.asList(1,2,3);
covariance(ints); // compiles!
List<Object> objs = new ArrayList<Object>(ints);
covariance(objs); // won't compile
Not that you still cannot pass in the List of Objects. They don't have a doubleValue method, so it would be trouble if the compiler let them in. Now in the covariant method, if you tried to add a double to the list, the compile will not let you. You might protest and say "a Double is a subclass of Number, so I should be able to add it to a collection of objects that are a subclass of Number." This is shortsighted. You don't know exactly what kind of collection was passed in, just that everything in the collection should implement a particular interface. It could be a List of Integer or a List of Double or a List of Byte. So you cannot just add to the collection. For covariance, you want methods that do not mutate the state of the collection. Now technically, you could remove objects from the collection and the compiler will let you get away with it. Still it might helpful to think of covariance as read-only.
What if you want to add things to the collection? That is where contravariance comes in. Here is an example:
public static void contravariance(List<? super Number> nums){
nums.add(1.1D);
}
Here I say that want anything that is a superclass of Number. In other words, I am willing to say that I cannot be anymore specific about the elements in the collection than they are Numbers.
List<Object> objs = new ArrayList<Object>(ints);
contravariance(objs); // compiles!
List<Integer> ints = Arrays.asList(1,2,3);
contravariance(ints); // won't compile
Now I can send in a List of Objects, and since Object is a superclass of Number, the compiler is happy. If I send in a List of Integer, the compiler will stop me. I could try a List of Double too, and it will still stop me. My collection needs to very permissive, so that my contravariant method can add to it.
Neal Gafter's proposal to simplify some of this, looks like:
public static void covariance(List<out Number> nums){
for (Number n : nums){
System.out.println(n.doubleValue());
}
}
public static void contravariance(List<in Number> nums){
nums.add(1.1D);
}
I think this is intuitive. If I only want to take things out, I want covariance. If I want to put things in, I want contravariance. One of the things that made me re-think (and maybe confuse me) this subject was how things work in Scala. There you use + and - for covariance and contravariance, respectively. By default, a List in Scala is covariant. However, Lists are immutable. Adding to a Scala List produces a new List, it does not mutate the original List. The mutable cousin of List, like ArrayBuffer, is invariant, just like a List in Java.
Sunday, March 08, 2009
Day of Infamy
Last week I wrote about a day of infamy, but did not get around to talking about this. I was too happy about President Obama following through on his pledge to get our military forces out of Iraq. On that same day, the government did something that was not so good. The Fed essentially took control of Citibank.
But wait, we've heard Secretary Geithner and Chairman Bernake both say that they oppose nationalization of our banks, and assure us that what we are doing at Citibank is not nationalization. This is a classic case of mincing words. The Fed has not only assumed a commanding position of ownership, but they have already begun dictating the company's policies. They have remade the board of directors and mandated policies on employee compensation and lending standards. This is de facto control. It's like in The Sopranos when Uncle Junior was the nominal leader of the Jersey mafia, but everybody knew that Tony was calling the shots. This is what has happened with the US and Citibank. The US is Tony and Citibank is the Jersey mafia. The actual executives might as well be old, senile, and in jail.
Now the government has taken control of banks before, most notably in the S&L runs back in the 80's. This was always done to liquidate the assets of the bank. Maybe that is what is going on with Citibank, and the government is misleading the public because ... well who knows.
I do not think so. The government wants banks to loan money. They want businesses to borrow and hire workers. They want consumers to borrow and spend. This is not happening, for many very good reasons. If you are a bank, you need to clean up your balance sheet by increasing your cash and reducing your risky investments. If you are a consumer, you need to increase your savings and reduce your debt. But if the government has control over large banks, they can make the bank forget about increasing cash and reducing risk. They can offer up loan to any and everybody. They can make it really hard on consumers to resist the temptation of free money. Imagine getting a letter in the mail everyday saying that you have been pre-approved for a new credit card with a 0% interest rate and a $100,000 limit! It's the modern day version of the chicken in every pot.
And so it is that I think February 27 will be a day of infamy in American history. It may be the beginning of an era where the government is an essential part of all economic activity in America. Want to buy a house? Ask the government. Want to buy a car? Ask the government. Want to send your kids to college? Oh wait, nevermind on that one. Want to plan for retirement? Umm ...