So he was playing dumb earlier for the benefit of the jury - to make the advocates spell out their case clearly. This is what he was responding to:
> This copying allowed them to use fewer resources and accelerate that. Suppose they
> accelerated it two days. They're making $3 million a day now [...] If you just get
> one or two days' acceleration, that's $6 million
This is a good point; it's common to underestimate how long it takes to code something. And time to market is often strategically crucial - that is, productivity isn't just efficient, but can be the difference between success and failure. rangeCheck is trivial; but writing, testing, debugging, naming and documenting take time. A trivial typo bug in rangeCheck can cost a disproportionate amount of time - and it's amplified here, when rangeCheck was used to test other code. (Who shall unit test the unit tests?)
To answer Groklaw's final question as to why Alsup couldn't decide on API copyrightability yet, he clearly said he needed to do a lot of reading. He not only has to decide according to law, he is in effect creating law, since this specific issue hasn't been decided earlier. His ruling has wider significance than just this particular case. Future potential litigants will read his ruling, and will avoid court if it's clear who would win. Although he is only one judge and so his precedent won't be binding on a full bench/higher court, those judges would also carefully read his judgment. He'd better get it right, not only in the result, but in the reasoning, and integrating it with related cases.
It's great that Groklaw is making these transcripts - because the court is a public institution, I think the official transcripts should be available (and why not video too? The emphasis in oral argument sometimes isn't captured in a transcript.)
I don't think it's a good point at all. I think it's completely disingenuous. The analysis quoted assumes that the implementation of the rangeCheck function is on the critical path to shipping, which is preposterous in my opinion.
I think it was mentioned that this code was used in testing other code - when you're reverse-engineering, conformance testing is about as critical as you can get. You could start coding without it, but it's quicker to catch bugs early. [NB: I don't know whether it actually is used in testing]
He only copied it because he was planning to submit the code to the OpenJDK and writing his own would have led to unnecessary duplication of code. The copied code would no longer be needed when the new code was added to the same package.
Bashing it out cowboy style would have been faster and in no way harmed Android. It's Oracle's codebase he was spending time and energy improving with good engineering practice.
My point is that it's worse than nonsense, it's actually arguing the opposite of the truth. The "copying", rather than speeding up Android development to Google's benefit, actually slowed Android development in an attempt to help OpenJDK/Oracle.
That this is the only direct copyright infringement they could find is highly ironic, but I guess either the lawyers didn't understand the subtleties here, or thought the jury wouldn't as this argument wasn't made (except obliquely in Bloch's statements).
While the basic line of reasoning is valid, it is absurd in the context of the rangeCheck function.
There might be a nine line function that takes a day or two to get right, but for even a bad programmer, rangeCheck would take a few minutes. With thorough tests, maybe ten minutes. I've barely touched Java code in over a decade, but I could write that function -- with tests -- in less than two minutes.
RangeCheck is the kind of function you'd get on a quiz in your first week of your first CS class in college.
I was simply trying to show that even seemingly-simple functions can have surprising bugs. Binary search isn't week 1 of CS101 - I think it was week 4 for me. Bentley's published version had a bug, Bloch's original corrected version had a bug, etc.
Working on it myself, after having read what the code does and being committed to re-implementing it myself, it took me 3.5 minutes and there were 2 bugs. (I needed to look at the original code again to determine that to == length and to == from were both allowed -- those were the bugs.)
Did you include the time it took to read what was needed, including the different exceptions? I would estimate, if one wasn't fresh and up for a challenge, 15 minutes (against your approx 10 minutes). And given that a day of programming isn't pure programming, I'd double it to 30 minutes. It feels way too long, but it's a realistic, day-in-day-out estimation.
Programming takes time... which is why it's so powerful if you can reuse code (as Bloch did), and even better if you can find a way to reduce the code needed, or best, to avoid needing any code.
sub rangeCheck {
my ($len, $from, $to) = @_;
if (($from > $to) || ($from < 0) || ($to > $len)) {
die "Illegal index $len ($from / $to)";
}
}
Java, as usual, makes a big hairy deal out of it. If the lack of types bothers you it's trivial in Haskell too. (Though trying to be idiomatic would lead you down a very different road. Perl is more similar to Java than Haskell, even as they are all very distant from each other.)
As it happens I've recently written somewhat similar code in Perl where I want to explicitly deal with out-of-range accesses (in a way other than silently receiving undefs) in a particular case, so this isn't even that odd.
You're throwing a generic exception; Bloch's version throws two specific exceptions, together with appropriate information. Java tends to have excellent error reporting.
All this reminds me of people saying that could code stackoverflow or facebook in a weekend. The difference is that rangeCheck actually is trivial - it's just that it's easy to underestimate the work involved in coding something. Even something trivial.
>>You're throwing a generic exception; Bloch's version throws two specific exceptions, together with appropriate information. Java tends to have excellent error reporting.
I know. I reduced it to one generic exception because that is what the person I was replying to did. Bloch's version is better of course.
I think in defining a range, the toIndex means up-to-but-not-including the element at that index. Thus, to include the full array, you'd use the range fromIndex=0, toIndex=length (one past the last one, since the index of the last element is length-1). With this notation, you can then make ranges of any width, from 0 up to length. If instead you included the element at that index, you couldn't have 0-width ranges (unless you allowed toIndex to equal one less than fromIndex).
I don't know whether 0-width ranges are directly useful for the Timsort algorithm; or whether it's just a convenient notation that happens to have that ability as an unused side-effect.
Maybe not 2, but less than 20. I've never written any Java, don't code regularly, and consider myself more of plodder than a coder, but it only took me a minute to figure out what the function was doing and why. Knowing when to put such functionality into your code is a larger challenge than actually coding it; this is a very trivial piece of procedural code.
Your parent poster didn't imply agreement with the line of reasoning he explained. He was just illustrating why the question is important to begin with.
Releasing two days earlier or later doesn't imply loss/gain of market share. Practically nobody buys mobile phones on a horizon of days.
Thus, if we do suppose that Android was accelerated two days, the benefit wasn't $6 million - it was having that money in hand a little earlier. The interest on $3 million for a day at 7% pa is $575/day - or $1725 total. Or less money than it costs Oracle's counsel to sneeze.
It's an interesting point, about which Oracle might argue entertainingly. e.g. if a market has a limited life, then 2 days delay means 2 days less to make money (markets don't last forever). e.g. being earlier to market is well known to does make a difference for getting a foothold in a market (mindshare, word of mouth, technical feedback, supplier relations), but especially because you are judged relative to your competitors - releasing your next version before their next version helps you win.
Except that Android's first release was a beta and SDK, almost a full year before phones shipped.
From that, it's not remotely clear whether saving 2 days to beta would have even resulted in 2 days of savings in the creation of any device.
To say nothing of whether Google/TMobile/HTC pre-selected a launch date in advance for the Dream, in which case they easily may have squandered a handful of days waiting for their desired PR timing.
Furthermore, adding two days' development time doesn't mean shipping two days later, especially if that time is spent reimplementing functionality for which you already have a perfectly useful (although not shippable) alternative.
All it means is you'd have had to allocate two more days worth of some programmer's time away from some less important task. For something like this, the programmer wouldn't even need to know thing one about the Android project - just that "we need our own implementation of this standard Java function".
Official transcripts are available, usually, but the transcriptionists are private contractors rather than employees of the court, and are hired by one or both sides to create a record of the trial for appeal - essentially the attorneys are outsourcing that bit. Most documents in a court case are easily accessible online at moderate cost (typically ~$0.08 per page, to cover the cost of hosting) but transcripts can be insanely expensive, running into the hundreds or thousands of dollars. It's a bit of a racket to be honest, but court-employed transcriptionists would either raise the cost of filing in court or require more taxes, and legislatures keep courts on pretty tight budgets.
I don't like the idea of court video that much...bad memories of the OJ trial.
Even if it took 1 engineer 2 days to program rangeCheck, it doesn't mean Android would have been delayed by 2 days, since development of this magnitute is done in parallel.
Note he said "suppose". His argument also applies to the copied test code (that was removed).
Parallelization is limited similarly to http://en.wikipedia.org/wiki/Amdahl%27s_law (usually called critical path when applied to development). I don't know the dependencies for this code, though it is part of a sort (Timsort) which was likely used by a few things, being a utility. As for test code, although TDD advocates doing it first, it's not a functional dependency. But, given the crucial importance of compatibility in this situation (reverse-engineering standard libraries), you might well want it first, to catch problems ASAP when they are cheaper to fix.
> Q. Why did you copy the rangecheck function for Timsort?
> A. It's good engineering to reuse the same function if possible
That's Joshua Bloch (it was his own code he copied).
http://www.groklaw.net/articlebasic.php?story=20120419221941... I think "good engineering" includes the accelerating factors I mentioned above (also, future modifications/bugs-fixes can be made in one place, when the same code is called, which was Bloch's long-term expectation).
BTW: Some other people are responding without reading fully - please take the time to do so. It elevates the discussion, making it interesting and engaging. I am really delighted to be shown wrong and to learn something, but it's hard for a response to a comment to be persuasive if it doesn't address that comment.
A good point? I think it is false to equate a day's worth of work -- were rangeCheck to take a day of "writing, testing, debugging, naming, and documenting" -- to a day's worth of profits, but say you [they] are right, I expect Oracle can get away with $2083 -- 3e6/(24*60) -- of Google's earnings, assuming the first days of Android can be as profitable as "now." We'll see how Oracle equates their "nexus" between those lines of code and their profits, but it can't be as simple as Boise is trying to elide in this statement.
And how many developers work on Android? If it were 200 developers, then this one person day would equate to 1/200th of a day, or $150,000 in lost profits (according to Oracle's math).
I'm sure there are more than 200 developers, so that lost person day would mean much less than $150,000 in lost profits.
The thing I don't get is, rangeCheck doesn't actually _do_ anything. If it was taken out, the code would still function exactly the same, you just wouldn't get a nice exception when you pass in the wrong parameters (it'd still be an exception, just not as useful).
Actually, that's not entirely true. If you swapped the "hi" and "lo" parameters, the function would return an unmodified array if rangeCheck were taken out, rather than throwing an exception. But that's the only functional change.
So the idea that rangeChange is in any way significant is disingenuous at best, I think.
To answer Groklaw's final question as to why Alsup couldn't decide on API copyrightability yet, he clearly said he needed to do a lot of reading. He not only has to decide according to law, he is in effect creating law, since this specific issue hasn't been decided earlier. His ruling has wider significance than just this particular case. Future potential litigants will read his ruling, and will avoid court if it's clear who would win. Although he is only one judge and so his precedent won't be binding on a full bench/higher court, those judges would also carefully read his judgment. He'd better get it right, not only in the result, but in the reasoning, and integrating it with related cases.
It's great that Groklaw is making these transcripts - because the court is a public institution, I think the official transcripts should be available (and why not video too? The emphasis in oral argument sometimes isn't captured in a transcript.)