22 December 2009

Dusty decks

A couple of archive sites from my bookmarks: First (via things magazine), the bitsavers project, an archive of software and documentation "for minicomputers and mainframes, from the 50's to the 80's." Doesn't look like the archive is being curated and catalogued at this point.

Hmm. I have some old listings in my storage unit. I wonder whether I can coax Gary and Greg to place SPREAD (a report writer for timesharing services, minicomputers—really, anything with a FORTRAN compiler) in the public domain.

Second, Karl Kleine's Historic Documents in Computer Science, a mix of archived material and links elsewhere. Some examples: The first FORTRAN manual, by John Backus and others, from 1956; Dennis Ritchie's C reference manual from about 1976. Unfortunately, the archive's last update was in October 2003, which may explain why it's missing some key material, like (ahem) anything on BASIC or COBOL.

18 December 2009

Regex mystery

One little bit of the app that I've been working on for the past several months is an HTML text box where the editor/producer can enter a relative URL that identifies an image file. But, in reality, it's common for the editor to have an absolute URL that he/she is pasting into the text box (maybe context-clicking to grab a URL from elsewhere on the web site), so one of the bits of processing to be done in JavaScript is to remove the scheme and server name from the URL. My client has multiple media servers within its client.org domain. So I wrote this tiny function, which in essence is nothing but

var URL_REGEX = /(http:\/\/)?(\w+\.{0,1})*client\.org/i;

function stripUrlPrefix (url) {
return url.replace(URL_REGEX, '');

stripUrlPrefix() removes the scheme, if present, and the server name, and it usually works like a champ.

However, Tony on the testing team found that the following input string (a real path name from one of our servers) sends the regex engines in IE 7 and Firefox 3 completely out to lunch:


On my middle-of-the-line Windows XP laptop, IE 7 takes about 10 minutes to execute stripUrlPrefix(), given this input string; Firefox just pegs the CPU and never does return. Jason is going to give this code a spin on Chrome to see what happens.

I have somehow stumbled into some kind of backtracking morass with a regex that looks pretty vanilla to me, and an input string that's likewise not too gnarly.

It turns out that we can fix the problem by trimming leading whitespace from the input and adding a beginning of string anchor to the regular expression, thus:

var URL_REGEX = /^(http:\/\/)?(\w+\.{0,1})*client\.org/i;

I haven't checked to see whether explicitly using the RegExp class would make a difference.

15 December 2009

All your database are belong to us

The current number of IEEE Annals of the History of Computing is loaded with tasty pieces: the theme is early DBMSs, and there are articles on the roots of Adabas, IDS, Total, IDMS, System 2000, IMS -- all those pre-relational acronyms that once filled the job listings for programmer/analysts. I once had limited familiarity with Adabas and IMS: in each case I was writing application code in COBOL and I used some glue-layer code (macros called Adamints, IIRC; and proprietary code written by AMS) to talk to the DB.

Plus, for dessert, Dan Murphy writes about the origins of TECO. Back in graduate school, the guy that turned over to me the project supporting the marketing research study tried to teach me TECO, but I bailed out and made do with SOS.

16 November 2009


IEEE Spectrum posts a short article and lovely slideshow documenting the restoration of IBM 1401 mainframe by volunteers at the Computer History Museum.
In the 1401's heyday, in the 1960s, some 9300 units were in use. Together with 6000-odd units of various successor models, by 1967 the 1400 line accounted for half of all the computers in the world.

The 1401 was a decimal arithmetic machine, designed expressly for business applications. It preceded the unifying System/360 line (all apps, commercial and scientific) by about five years.

04 November 2009

Someday, maybe

Mark Pilgrim reminds us that less than seventeen years ago, the web's forefathers were trying to figure out how to incorporate images into HTML. He carefully extracts from and annotates the relevant threads, explaining acronyms that even I don't remember.

This proposal was never implemented, although the idea of text-if-an-image-is-missing is an important accessibility technique which was missing from Marc [Andreesen]’s initial proposal. Many years later, this feature was bolted on as the attribute, which Netscape promptly broke by erroneously treating it as a tooltip.

(Via kottke.org.)

16 October 2009

Oracle numeric test

A colleague and I found ourselves needing to write a one-off bit of SQL that used a character column in a join condition. The character column is performing double duty, sometimes acting as a (numeric) foreign key, and sometimes holding other data.

I was perplexed by the lack of some kind of "is numeric" test in Oracle's dialect of SQL. I scrounged around forums and found something that I thought would work, but my colleague finally put me straight and we used this condition:

REGEXP_LIKE(char_column, '^[[:digit:]]+$')

03 October 2009

News from Montevideo

The Economist reports on the success of the XO laptops in Uruguay. Interim results: mixed to negative.
In Escuela 95, up to half of the students in some classes have broken their machines, usually by cracking the screen or snapping the antennae that pick up a Wi-Fi signal.

28 September 2009

All that is the case

I'm working on a short piece of code to capitalize all the initials in a given sentence (headlines for news stories from a wire service, to be specific), in order to match house style. At first, I was a little surprised that I couldn't find a Java class to do most of the work for me. But once I waded into the actual sentences that I had to process, with their variations and exceptions, I came to the conclusion that some degree of RYO was called for. Here's my current draft:

import java.util.regex.*;

* * *

private String capitalizeAllInitials(String text)
//capitalize the first letter of every word in the passed text
//(including little words like "a," "the," "and," "to")
//also capitalize words in quoted and hyphenated phrases

//NOTES: The pattern requires a leading space; I have found that
//ingested stories already capitalize the first word of the title.

Pattern p = Pattern.compile("(-|( (`|\\\"|\\\')?))([a-z])");
Matcher m = p.matcher(text);

StringBuffer sb = new StringBuffer();
while (m.find())
m.appendReplacement(sb, m.group(1) + m.group(4).toUpperCase());

return sb.toString();

As the comments note, this code will handle ordinary words (The quick brown fox jumps over the lazy dog becomes The Quick Brown Fox Jumps Over The Lazy Dog), hyphenated phrases (Senator proposes pay-as-you-go plan becomes Senator Proposes Pay-As-You-Go Plan), and quoted phrases (Accused confesses, "we did it" becomes Accused Confesses, "We Did It") with single, double, or backquotes. The code assumes that the first word is already capitalized, so if that's not the case with you, you would need to add a ^ to the regular expression.

This code also doesn't handle the common forms of title casing, whereby articles, prepositions, and other small words are not capitalized. Also, this code capitalizes proper names and trademarks indiscriminately.

20 September 2009

Respect the pomodoro

With Patricia R. Olsen, Jim Remsik writes a good first-person account of pair programming as it is practiced at Hashrocket:
When senior and junior developers are paired, junior programmers might feel intimidated. If this happens, the junior programmer might be asked to start as the driver, which may encourage the senior person to become a better teacher. It’s also a way to bring junior programmers up to speed quickly, because they benefit from the more senior employee’s knowledge.

15 September 2009

We used to call that a dirt road

Via RISKS Digest: complaining of poor bandwidth through Telekom (South Afica's leading ISP), an information technology company strapped a data card to the leg of a carrier pigeon, sent it flying 80 kilometers, and exceeded internet throughput by a factor of 50.

27 August 2009

Eval of jQuery data grid plugins

[Adapted from a wiki entry I made for my current project:]

Starting from a brief review article, I looked at five tools:

Flexigrid and jTPS have very little documentation and have not been updated for nearly a year, and so I did not try to get these tools working. I downloaded jqGrid, Ingrid, and FireScope Grid and assembled test harnesses for all three.

Of these three, all use Ajax to populate the grid. All of them accomplish sorting by an Ajax call back to the server, passing a parm to specify the sort column and direction. So we would accomplish sorting of dates (or any other data types with unusual sort requirements) with server-side logic.

All three tools provide paging navigators, but all require some paging logic to be performed on the server. I didn't fully eval this area, because I used a static file of data to populate the grid.

Ingrid and FireScope Grid only support HTML data. jqGrid, according to its wiki entry, provides these options for its datatype parameter:

  • xml
  • json
  • local or clientSide
  • xmlstring
  • jsonstring
  • script
  • function (…)

I tested the tool with XML, but JSON support would appear to be consistent with other technologies we're using on the project.

jqGrid is not bug-free: in particular, I'm seeing a one-off issue with specifying the number of rows to display, and there are some formatting weirdnesses with the navigation bar. But it is the only tool of the five with a wiki for documentation (albeit the wiki's spelling and grammar are a little wonky), and it is the most fully-featured tool. Indeed, the download page offers a choice of optional components to download.

I will proceed with building out a prototype of the new search results page with jqGrid.

26 August 2009

From Babbage to EDVAC

A tidy history of early mechanical, analog, and electronic computing, fully referenced, by B. Jack Copeland for the Stanford Encyclopedia of Philosophy—with a fairly clear explanation of how mercury delay line memories worked.

12 August 2009

Old friends and new

Via ReadWriteWeb: a recap by Mick MacComascaigh, Toby Bell, and Mark R. Gilbert for Gartner of the current players in the web content management (WCM) marketplace. A few of the companies I remember from the turn of the decade are still around (like Open Text), but there are many new names, too.

28 July 2009


36 hours, more or less, after the launch of the new npr.org, and we're all feeling pretty chuffed. The coverage in the New York Times and elsewhere didn't hurt.

From Andy's pics of the late-morning launch meeting (we had to take over the Music end of the floor to fit in everybody—that's my elbow in front of the window, far right), to roving Callie's skewed-angle portraits, to the steady stream of tweets, our launch activity was meticulously documented. I think Daniel and crew were particularly bold to live blog the proceedings, when you consider that the process took more than twice as long as we planned. There are lots of tweets like:

  • We are moving a lot of data in our migration scripts. Taking longer than expected in the live env. @daniel_jacobson Sunday, July 26 13:44:58
  • Final stages of migration before the QA starts. Taking longer than expected... @daniel_jacobson Sunday, July 26 14:13:51

I remain astonished at how smoothly this boat got into the water, with a minimum of schedule slippages, sharp words (and some of those from me), late nights. Beyond this, standards of excellence have been maintained. And the emphasis on transparency is something I've never seen before, with my background in proprietary software products and financial applications.

The back-end application still shows its age in places, but to its credit, the project planners made this an opportunity to give it a feature boost while also building the public-facing site.

It really has been a great project. What's the opposite of a perfect storm?

06 July 2009

Putting it together

We've been code-reviewing some of the Java code on the project, and the question of optimal string concatenation came up. While others on the team were loyal to StringBuilder.append(), I had relied on the + operator, following the advice of Ian Darwin in his Java Cookbook 2/e:

3.4.1. Problem

You need to put some String pieces (back) together.

3.4.2. Solution

Use string concatenation: the + operator. The compiler implicitly constructs a StringBuilder for you and uses its append( ) methods. Better yet, construct and use it yourself.

I scratched a little deeper, and found that a more complete answer to "which is better?" depends in part on what compiler optimizations you're using, as Apurba and Pavitar point out. Schneide Blog also notes that it's hard to measure string concatenation performance in isolation from the real-world context where you're performing the operation.

Another point to keep in mind: what are we trying to optimize? Run-time speed, memory usage, or something else? Nicholas Hagen, in his benchmarking tests, helpfully provides both execution times and object creation counts. Hagen gives some rules of thumb. I have added emphasis to the most important one for us, and fortunately it matches our informal shop standards.

  • DO use the plus operator if all operands are constants

  • DO use String.concat if only concatenating 2 strings

  • DO use StringBuilder within a for loop when updating values

  • DO use StringBuilder if concatenating more than 2 strings

  • DO use StringBuilder rather than re-assigning variables multiple times

  • DO ensure StringBuilder has proper sizing

Fortunately for this project, all the Java string manipulation is done in backend systems on an moderate-volume intranet, so these general guidelines are sufficient; we haven't needed to do extensive profiling to find hot spots. The public-facing web site uses different technology altogether.

01 July 2009

Everything's better on a stick

Ryan Paul reports on the first official release of the Sugar educational software platform for removable media. Sugar was the Linux-derived OS distributed with the first generation of XO computers. With the release of Sugar on a Stick (SoaS), now it is the case that
When Sugar runs from a memory stick, the user's files can be stored directly on the device. This completely portable and self-contained approach makes it possible for students to use at school and at home. It also makes it easy for schools to repurpose existing computers and get them up and running with the Sugar learning environment with minimal difficulty and investment.

30 May 2009


Steve Chamberlin has hand-built a computer using logic chips, a wire-wrapping tool, and a lot of patience. Meet BMOW (Big Mess o' Wires).

07 May 2009

Ce n'est rien

I love my user representatives on this project. They were so pleased by a feature that I've just finished—something simple that took me less than a week to write, but will make the editors' and producers' job so much easier, eliminating repetitive clicking and typing steps—that they asked me to add "Hooray!" to the text of the confirmation dialog box. Who am I to refuse?

28 April 2009

Karma points

Thanks to posts from Philipp Feigl and Stickman, I put together script to detect the insertion point in a <textarea> or simple text box (so that, for instance, another script could automatically insert markup tags). Internet Explorer has a different object model for accomplishing this than the other browsers (using the TextRange object), and our solution isn't bulletproof, but it will make some editors happy.

18 April 2009

Job search post mortem: 1

On my last job campaign, I scrupulously updated my resume on a number of job boards, including Monster.com and WashingtonPost.com, and changed the privacy settings to public so that recruiters could find me. But next time around, I don't think I'll bother to make the resume public.

Oh, I got plenty of e-mail interest in my credentials, but nearly all of the correspondence was for positions either where the technology requirements really didn't fit my background; or with companies that I wouldn't want to work for (defense contractors, law firms); or for jobs outside of the metro area; or for short-term contracts—or all four! That is to say, when I could figure out anything about the position at all: nearly all of the contacts were from third-party recruiters rather than the actual hiring firms, and often all they would write would be "several challenging positions that are a good fit with your background." After my go-around in 2006, I specifically included a statement in my career objective section that I was looking only for full-time work and that I was not available for relocation. The steady stream of messages seeking contractors for six months in Hartford, or Waltham, or Texas, or Kalamazoo, or wherever tells me that the automated tools that recruiters use to make initial contacts are making them lazy: they're not really reading the resumes that they respond to.

I got a lot of mail driven by specific matches on technology keywords from years ago in my career. I cite technologies like Documentum and OpenText in my resume because (at least I believe that) it shows flexibility and willingness to learn. But when someone asks me to respond to a position that requires several years of current experience with one of these tools, again, I have to conclude that they're not troubling themselves to read what I wrote.

For this job search, I did work together with two recruiting agencies to the extent of coming in for a meet and greet. Out of that, I got one (1) phone screen for an interesting company that was a mismatch on job responsibilities (they wanted pre- and post-sales support people) and one (1) invitation (that I declined) to phone interview with a slimy astroturfing lobbying group.

As I look back into my e-mail archives, I see that the briefest query was this: under the subject line of "Please contact in reference to your resume on Career Builder [sic]," the entire message body was
Please call me at your earliest convenience.
followed by a signature block and disclaimer. I got queries looking for test engineers, and embedded software programmers, and O.R. guys (well, I do have a degree in it), and config management specialists, even someone looking for COBOL people (I haven't listed that skill on my resume in years). But my favorite "what were you thinking?" message sought a "Systemutvikling på Java- og .Net-plattform" to work in Oslo with a reply-to address in the .no domain. Since Google Translates "Systemutvikling" to just "system," I still don't know who or what they were looking for. I also got a (thankfully) smaller number of solicitations that were more spam than genuine contacts: the worst of these I reported back to the job boards.

I scrounged up all my other interviews from replying to job board postings and solicitations on the hiring company's web site. I got some interview traction with one consultancy because I was acquainted with one of the managers there. The job that I ultimately accepted (with Siteworx) I found with some networking help: a former colleague from a previous job forwarded an e-mail posting to me. And this is the first job since 1987 that I've taken without knowing someone on the inside.

I'm accustomed to today's practice that, even after a phone screen or in-person interview, employers don't call or write you back with a "no, thank you." But one recruiter did something that perplexed me: I had sent a resume in response to a posting, and about two months later he e-mailed back asking for a time slot when we could discuss the position by phone. I replied by e-mail the next day, and by phone a couple of days later, but he never followed up.

To be sure, once I got in the door for an interview, I was always treated fairly, professionally, competently, and courteously by recruitment staff and hiring managers (well, there was one guy who was in over his head). I'm just not convinced that it makes any sense to publish a resume on the big boards.

12 April 2009

Where the wheel meets the steel

Take a quick anonymous survey to help Tony Gorschek of the Blekinge Institute of Technology and Ewan Tempero of Auckland University to understand the adoption of object-oriented design principles in real-world software development projects.

10 April 2009

Sign me up

Behrooz Parhami of the University of California, Santa Barbara has designed a freshman seminar for computer science majors built on ten classic families of puzzles—everything from Collatz's conjecture to sorting cars in a rail yard to that pencil and paper diversion they gave me as a kid to keep me quiet for a while—you know, connecting the three houses to the three utility lines.

04 April 2009

Are you open?

Something that's really interesting, just unfolding: the release by traditional media companies of no-fee API access to their content. The term "API" means different things to different people, but in this context it generally means, "throw me an HTTP GET, and you'll get a sliver of my content" in machine readable format, usually XML or JSON. Generally the HTTP query must include a key, easily obtainable from the API provider, so that usage can be monitored. As a software developer, you can take that sliver of content and present it more or less anyway you like: plot New York Times restaurant reviews on a map, or show top technology stories from NPR in a blog sidebar, or do an information visualization of stories from the Guardian. Think of an API as exposing content with a web service without all that mucking around with something like SOAP. As a consumer, you can take advantage of some nifty apps that other hackers have put together.

Frederic Lardinois and other columnists at ReadWriteWeb have been tracking these developments closely. Of the current API offerings, that of the Times appears to be the most full-featured and sophisticated, especially the controlled ontology that the Times calls facets. The Guardian is just getting started, but it has an interesting list of partners in its Application Gallery. On my current project, I've had the privilege of an insider's view of the API from National Public Radio. I especially like the Query Generator, which step by step takes you through the assembly of a query and understanding the results.

27 March 2009

Data rot

David Pogue interviews Dag Spicer, curator of the Computer History Museum, on storage media old and new.

24 March 2009

March 24

Today is set aside to honor Ada Lovelace, often described as the world's first computer programmer, and all women of excellence in technology. Our friend Liza has a few women that she'd like to recognize.

19 March 2009

Look out for funny characters

Interesting post by Ross Harmes on client-side search of a Flickr user's contacts list (sorry that I lost track of the referral). The team tried approaches that turned out to be either slow, insecure, or completely bloated. The winner was a custom format and good old split().

12 February 2009

At the limit

I reread my copy of Gödel's Proof, by Ernest Nagel and James R. Newman. It's a compact outline (102 pages, not counting the back matter) of the work published by Kurt Gödel in the 1930s on the limitations of formal, deductive methods of proof in mathematics. I recommend it to anyone, mathematician or humanist, who is interested in the idea of what it means to say we have proved something mathematically.

In high school, we're introduced to the axiomatic method, usually through a class in geometry. Given the ground rules: definitions of mathematical objects (points, lines), axioms (also called postulates: these are statements to be accepted without proof, like "any two points can be joined with a line"), and a few rules of logic, the student learns to prove more complex statements about the objects. The most interesting, general-purpose of these statements we call theorems, like that of Pythagoras concerning the sides of a right triangle.

While definitions and rules of logic seem to be given to us a priori, our choice of axioms seems to offer some conceptual leeway. Euclid did a lot of good geometry with his five axioms, but mathematicians wondered whether they were the "right" axioms. In particular, would it be possible, given a set of axioms, to prove every true thing that could be said in geometry, or algebra, or arithmetic? In other words, would there be "nothing you can see that isn't shown?"

Gödel answered this question decisively with a No. For a field as seemingly simple as the arithmetic of the integers, no matter what axioms we choose, there will be true statements that can't be proved from those axioms. There will always be a place where "you can't get there from here."

Well, then, we'd at least like to know that the axioms are consistent, that is, that they can't be used to prove contradictory statements. But to know something, to a mathematician, is to prove it. Without, of course, making inferences that assume that it's true already, or using logic more complicated than the original ground rules. And Gödel established that, again for a simple field like arithmetic, its axioms cannot be proved to be consistent using arithmetic's own ground rules.

Nagel and Newman walk the reader through the proof, illustrating some points in detail, skimming over others. In particular, they explain Gödel's clever way of using primes to assign a unique number to every statement in arithmetic. In this way, every logical relationship among theorems and axioms can be represented by a numerical relationship among their corresponding numbers. Their treatment is easy to follow, although the sailing gets a little rough on p. 89, at the crux of Gödel's proof. (My copy includes some loose sheets of notes from my last reading, about 20 years ago, in which I invented some new notation to help me wrap my head around the argument.)

So how does this work apply to software development? Well, for one thing, it establishes an upper bound, perhaps only in theoretical space, on the effectiveness of formal methods of proving program correctness. (Since I've never written avionics software, this isn't a field I spend too much time in.)
Today's calculating machines have a fixed set of directives built into them; these directives correspond to the fixed rules of inference of formalized axiomatic procedure. The machines thus supply answers to problems by operating in a step-by-step manner, each step being controlled by the built-in directives. But, as Gödel showed in his incompleteness theorem, there are innumerable problems in elementary number theory that fall outside the scope of a fixed axiomatic method, and that such engines are incapable of answering, however intricate and ingenious their built-in mechanisms may be and however rapid their operations. Given a definite problem, a machine of this type might be built for solving it; but no one such machine can be built for solving every problem.
Gödel's Proof has recently been reissued in a new edition, edited by Douglas Hofstadter. Andrew Hodges wrote an appraisal of the original 1958 edition, pointing out the proof's direct influence on Alan Turing and computability theory.

02 February 2009

But avoid .Replace()

Jeff Atwood puts the performance meter on various methods of string concatenation in C# and finds that no one has to be a shlemiel.
...you should be more worried about the maintainability and readability of your code than its performance. And that is perhaps the most tragic thing about letting yourself get sucked into micro-optimization theater—it distracts you from your real goal: writing better code.

28 January 2009

Into the blue, too

I see that my old colleague David Alison has emerged from the workshop to launch Shared Status, a refreshingly low-tech small-footprint solution to managing punchlists for distributed teams. It's clearly a tool informed by many hours of sitting through deadly dull, interminable team status meetings. What I think is bold about David's model is that a task is either done or not done. You can hand it off to someone else, but it's still only done or not done. No more cheeseparing about tasks that are 90% complete, forever.

Into the blue

I attended a presentation by Microsoft technology evangelists Ashish Jaiman, Zhiming Xue, and Sanjay Jain to a small group, organized by the IEEE CS local chapter, on Microsoft's Software + Services paradigm and its Azure technology suite. The talk filled in some of the gaps in my understanding.

A key point of the Software + Services model is to characterize the gray area between traditional apps and SaaS apps as either "building block services" or "attached services," with the additional term "finished services" to describe software as a service. But I haven't yet grasped why the distinction is helpful.

Attached services provide a higher level of functionality compared with building block services. Applications leverage attached services to add functionality.

Sanjay demonstrated Microsoft Dynamics CRM 4.0 as an example of a finished service. Surprise, surprise, the extensibility features map on to what I already know from Salesforce.com. I smiled to myself at the naive remark that the features would allow a salesperson to enhance the system "without any programming." (Didn't someone once say that about COBOL?) Last time I checked, there were Dynamics CRM and Salesforce.com consultants making a tidy living.

We moved on to Azure, an "OS for the cloud," and the supporting suite of services on top of it:

  • Live Services: ID and directory
  • .NET Services: service discovery and the "service bus," workflow, access control
  • SQL Services
  • SharePoint Services
  • Dynamics CRM Services

SQL Services is kinda important, because the persistent storage features offered by bare Azure will be hard for the garden variety developer to assimilate: blobs, tables, queues, and locks are all you get. Also rudimentary are the facilities for session management.

And Zhiming noted that e-commerce features like a shopping cart and credit card processing are not there yet, although Microsoft Office Live Small Business can provide them.

He closed with a quick demo of Wikipedia Explorer, one of a handful of apps linked to from the Azure Gallery. The Explorer is actually pretty slick: give it a search term and it produces a network of related Wikipedia articles, rooted on the original term. Also found in the gallery is Steve Marx's blog, which has helpful posts like this one that explain how to go about writing an app for the cloud.

08 January 2009

Finding composites

Another brain-teaser for Jeff and Jefrrey that I missed while my subscription was interrupted: Andrew Koenig reintroduces the 2-3-5 problem, attributed to Dijkstra and Hamming:
Write a program that produces, in ascending order, the sequence of positive integers that have only 2, 3, and 5 as their prime factors. The first such integer is 1 (which has no prime factors at all; hence all of its prime factors are either 2, 3, or 5); the sequence continues with 2, 3, 4 (which has only 2 as a prime factor), 5, and 6. It skips 7, which is prime, continues with 8, 9, and 10, skips 11, includes 12, and so on.

Not System R

Ashlee Vance introduces the open-source statistical analysis programming environment R, one that challenges proprietary packages.
"R has really become the second language for people coming out of grad school now, and there's an amazing amount of code being written for it," said Max Kuhn, associate director of nonclinical statistics at Pfizer. "You can look on the SAS message boards and see there is a proportional downturn in traffic."