Tuesday, May 29, 2012

Libraries must become more than video stores

Libraries think of themselves as video stores. This is not surprising, as video stores thought of themselves as libraries. The two models are almost identical: a limited set of materials (with a limited number of copies), shared by customers (one at a time) for a finite period, with late fees.

Video stores failed. We moved to a different business model. Netflix, iTunes, Amazon.com, and YouTube introduced new ways of delivering movies and videos to customers. The 'old guard' of Blockbuster and Videotowne fell into the dustbin.

Libraries differ from video stores: they are not competitive businesses. Video store chains competed with other video store chains, and I think that they knew (on some level) that they competed with other media for customers. They probably thought that their main competition was cable TV, but certainly television, live events, and backyard activities were competing for customer time and attention. Video stores were businesses, in business to make a profit.

In contrast, libraries view themselves not as businesses but as a public service. Their purpose is to help people (and society), not to turn a profit. And libraries are often municipal-run monopolies. (Or county-run, or state-run.) They must balance their budget, but profit is not part of their thinking. (If anything, it would be considered inappropriate and counter to their mission.)

Nor do libraries view themselves as competing. One town's libraries do not compete with another town's, since their mission of serving the community (and community-granted monopoly) means that a library has no rival to outrun.

Which is not to say that libraries do not change. Libraries expanded from books and periodicals to books on tape (and later, books on CD), videotapes (and later, DVDs). Now libraries are expanding to e-books. Yet I believe that their thinking is muddled.

Libraries know that e-books are popular, and that they must offer them. But libraries have the mindset of e-books as another form of a book, a physical device in limited quantity. They jump through hoops to limit the number of copies that they lend out, and they mandate formats that automatically expire the books at the end of the lending period.

E-books are different things from paper books, periodicals, and all of the other things that libraries have lent out. They are not physical entities, and not subject to the scarcity of such objects. A library could lend out several thousand copies of "Harry Potter".

Part of the problem is that the publishing houses and the companies that supply e-book lending software reinforce the idea of e-books as scarce commodities. Publishers fear the loss of the sales market (if customers can borrow e-books with certainty, why should they buy?) and the software suppliers are simply taking advantage of publishers' fears and libraries' naivete.

Some company is going to come along and obsolete the libraries. Just as Netflix obsoleted video stores, a company will make libraries passe. Perhaps it will be Amazon.com. Perhaps it will be Google. Perhaps it will be a start-up. Whoever it is, they will make borrowing e-books easy and convenient. They will most likely tie into the book sales channel.

Once this new company comes along, libraries will be in a difficult spot. They will have lost their primary justification for their monopoly and taxpayer support. (I recognize that libraries perform functions beyond lending books and periodicals, but the communities that support they see these as their primary responsibilities. Lose that support and you lose the tax dollars.)

Since libraries see themselves as a public service, as not in competition with other activities or other library systems, and granted a public monopoly, I suspect very few (if any) will change.

Monday, May 28, 2012

Do it right the first time

Decisions made in the course of development must balance multiple needs: delivery time, quality, and cost. Over the course of my career, various people have exhorted me (and other developers) to "do it right the first time". The implication is that the team is being rushed, and a longer development effort will yield a better result.

The cynical version of this is "We don't have time to do it properly, but we always have time to do it again".

I know many developers, and not a one wakes in the morning with the thought "today I will do things wrong". Everyone I know wants to do the right thing.

Some folks believe that they are prevented from doing the "right thing" by their managers, or the bureaucracy, or marketing-originated specifications. Yet sometimes we prevent ourselves from doing the right thing.

To "do things right", one needs two things:

1) An understanding of "the right thing"

2) The belief that one has the resources to accomplish it

Inexperienced programmers will do what they think is the right thing, yet may be bad for the long term. They may duplicate code, or create unmaintainable code. It seems the right thing to do at the time, and with their expertise. Seasoned programmers know that code endures and should be written for future developers. Even temporary fixes endure.

Experience and sophisticated knowledge is not sufficient. If one thinks that the effort for the "proper" code is too great, or takes too long, then one might decide to make a set of "improper" changes. Business managers often must decide between multiple options, and sometimes choose compromising solutions. Managers often make choices that differ from those of the technologists.

Sometimes the technologists are right. Sometimes the managers are right. In any given situation, it is hard to tell who is truly right. Sometimes the answer becomes clear with time -- but not always.

Often I find that the proper way to do things requires discipline, care, and knowledge of the business requirements and the underlying technology. And often I find the the right way of doing things uses principles from earlier eras. (For example, the Model-View-Controller design pattern is mostly a separation of concerns, and this ideas was present in many system design methods of the 1960s. COBOL shops knew to separate input-output operations from processing operations; they just didn't use the phrase "MVC".)

So perhaps we should spend less time exhorting our fellow developers to "do the right thing" and a little more time on understanding the work of of predecessors. That might be the right thing to do.

Thursday, May 24, 2012

Microsoft Visual Studio Express abandons the desktop

Visual Studio 2011 Express Edition (the free version) does not support desktop applications.

By abandoning the desktop for entry-level users, Microsoft is sending a clear message: the Windows desktop is now a mature market. By "mature", Microsoft is limiting development of desktop applications to professionals -- people who are willing to pay for the tools. The hobbyists are "guided" into the web and Metro environments.

As I see it, Microsoft recognizes different futures for desktop and web/Metro applications. Web apps and Metro apps have a vibrant future with lots of growth and creativity. Desktop apps... don't. Desktop apps are maintained, but not enhanced.

This is not to say that desktop apps will go away. There are too many businesses with too many critical applications that run on the desktop.

But it does confirm a shift in the landscape. New apps will be mobile (iPhone/Android/Metro) apps. Or web apps, for those organizations that do not want to move to mobile.

Just as mainframe applications are still with us (billing systems, payroll, general ledger...) Windows desktop applications will remain with us. But the environment is now sterile. It bears no fruit.

Microsoft's choice with its latest offering of Visual Studio is the right one. Hobbyists and beginners must work in fertile environments.

Wednesday, May 16, 2012

Relearning the system design lessons of history

The scene: a local user group with a presentation on system design for Big Data.

The participants: technologists of varying degrees of experience.

The presenter made a number of points. Two were: separate data retrieval from processing, and design systems with low coupling between components.

It struck me that these two points had been made before. Not at previous meetings of this group, but in the IT industry.

Designing systems with low coupling between components has been around for decades, going back to the 1970s. Yourdon and Demarco both talk about low coupling (and high cohesion), as do others.

Separating data retrieval from processing has been around even longer, with IBM's "HIPO" methods (Hierarchy, Input, Process, and Output) for system design.

It seems that every generation of programmers re-discovers the concepts of prior generations.

And that though got me thinking.

A long time ago, in a galaxy (of hardware) far, far away, I was a young upstart. I was learning to program, learning to design systems, and learning to build applications. I was using microcomputers, the immediate predecessors to the IBM PC. The most common computers of the era were the Apple II, the Radio Shack TRS-80, and the Commodore PET. There were other computers; most were S-100 buss computers that ran CP/M.

We had little in the way of software. Programs were written in BASIC, or in assembly language. There were a few other options, usually expensive: FORTRAN, COBOL, or CBASIC.

Hobbyists and enthusiasts would band together in groups, to review new ideas and discuss problems. Some of us had experience in the older systems (minicomputers or mainframes) but not many. We fumbled our way to knowledge without the immediate aid of our predecessors.

In a word, we were arrogant. We felt that the programmers of mainframes and minicomputers would have little to offer us. (After all, they insisted on using old languages and old machine architectures. We were using shiny new processors and better languages.) We did little (if anything) to reach out to the programmers of the elder systems.

I think that the arrogance was not limited to us upstarts. The programmers of mainframes and minicomputer systems did little to reach out to us microcomputer users. (At least, I got that impression from the magazines devoted to mainframes and minicomputers, and their lack of coverage on microcomputers.)

But then, my perception may be incorrect. Perhaps the mainframe and minicomputer folks (and their magazines) were busy with issues of the day, busy with solutions relevant to business problems. Microcomputers were not a business problem, nor were they a solution to a problem. They were ignoring us not from malice but from pragmatism.

And perhaps that is the way our industry works. A lot of our systems are complex and a lot of our problems are hard. We tend to think that we are alone, and that we must devise a solution. And devise solutions we do.

Not only do we devise solutions, but we name them. We name lots of things, from programming languages to development methodologies. Each generation invents new terms. We often have generation-specific terms for identical or similar concepts (we "boot" PCs, but we "IPL" mainframes; PC programs "crash", mainframe programs "abend"). The different terms are barriers to communication.

In addition, we become tightly focused on set of practices and technologies. Programmers who know C++ work on C++ systems and become experts at it. Programmers in Java work on Java systems and become experts. Many programmers specialize; few generalize. Specialization begets jargon and argot, and additional barriers to communication.

The solution (and I am not the first to propose this) is a broad curriculum for software developers. The curriculum includes current technologies (mobile apps, Big Data) mainstream technologies (web apps and services), and legacy technologies (desktop). It includes general concepts (data structures, compilers) and specific knowledge (object-oriented programming). And most importantly, it includes history, to give people the knowledge that lots of current-day problems have been solved, albeit in other contexts.

As I see it, we can learn the lessons of history up front, or we can learn them later. But we cannot escape them.

I'm for learning those lessons up front.


Monday, May 14, 2012

Just how big is too big?

I recently read (somewhere on the internet) that the optimal size of a class is 70 lines of code (LOC).

My initial thought on such a size for classes was that it was extremely small, too small to be practical. Indeed, with some languages and frameworks, it is not possible to create a class with less than 70 lines of code.

Yet after working with "Immutable Object Programming" techniques, I have come to believe that classes of size 70 LOC are possible -- and practical. A recent project saw a number of classes (not all of them, but many) on the order of 70 LOC. Some were slightly larger (perhaps 100 LOC), some a bit larger (250 LOC), and a few very large (1000 LOC). A few classes were smaller.

The idea of smaller classes is not new. Edward Yourdon, in his 1975 work "Techniques of Program Structure and Design" states that some organizations set a limit on module size to 50 LOC. At the time, object-oriented programming was unknown to the profession (although the notions of classes had been around for decades), so a module is a reasonable substitute for a class.

What I find interesting is the similarity of optimal sizes. For classes, 70 LOC. For modules, 50 LOC. I think that this may tell us something about our abilities as programmers.

I will also observe that 70 lines is about the size of three screens of text -- if we consider a "screen" to be the olde standard size of 24 lines with 80 characters. That may tell us about our abilities, too.

Saturday, May 12, 2012

Icon rot

A number of folks have observed that commonly used icons in applications are no longer sensible.

Their observations are true: pictures of floppy discs are lost on the latest generation of computer users. ("What's a floppy disc?")

The implicit assertion is that we need a new set of icons to represent common functions such as "save" and "search". I disagree with this.

Let me state that I do agree with the assertion that the icons no longer make sense. The notions of floppy discs, radio buttons, paper calendars, and cassette tapes are not relevant to an entire generation of computer owners.

I disagree with the notion that we need a replacement set of icons.

I think that we can get by without icons -- for certain functions. Most prominent are the "save" and "save as" functions.

Classic desktop applications needed the idea of "saving data". They were designed to load data into non-permanent memory, allow the user to modify it, and they allow the user to either save the changed version or abandon the changes and revert to the original version.

Web applications and phone apps are designed differently. We have moved away from the "modify and save" design. Web applications and phone apps save data by default. They don't offer the user of "save or do not save". Saving is automatic. (The better phone apps allow the user to revert to earlier versions.)

I see few icons in web applications, and very few in phone apps. The few icons I see are usually singletons, such as the "send tweet" icon in Twitter apps. Instead of icons, I see buttons (or tap areas) with words. The Facebook app has tap areas with the words "status", "photo", and "post". The Google Gmail app has a tap area with an envelope with a wavy arrow, but to be honest I would be more comfortable with the word "send".

Windows set a number of standards for application design and provided the commonly used icons for those operations. Web and phone apps do not follow those standards, and do not need those common icons.

Rather than a set of standard icons (and therefore a set of standard operations) for all apps, look for app-specific operations. Web apps and phone apps will provide the operations that they need, the operations that make sense. They will not attempt to mold an app into a standard model; they will let the app be itself.

With no common set of functions, there is no need for a common set of icons. Indeed, icons will cause more confusion than they save, since custom icons are not universally understood. Look for more words, and fewer icons.

Tuesday, May 8, 2012

Why we change languages

An acquaintance asked me: "Why do computer programmers change their languages?"

The question gave me pause. Why *do* we change our languages? It seems that every few years we introduce a new language. (BASIC in the mid-1960s, Pascal and C in the 1970s, C++ in the late 1980s, Java in 1995, C# in 2000... the list goes on.)

It is not about switching from one language to another. The question is more about why we modify our languages. Why do we change the language syntax over time?

The obvious answer is that hardware gets more powerful, and we (as programmers) can do more with languages when they take advantage of that hardware. The original FORTRAN was little more than a macro-assembler, converting source code into op-codes for the IBM 704. Later systems had more memory and more powerful processors, so compilers and interpreters could take advantage of the hardware. What was considered extravagant in the days of FORTRAN would be considered acceptable in the days of BASIC.

I have a different idea of languages, and our (seemingly-infinite) desire for new languages.

A programming language is a representation of our thought process. It (the language) allows us to define data in specific structures (or types), organize it in collections (classes or containers), and process it according to well-defined rules.

We change our languages according to our understanding of data, the collections and relationships of data, and our ideas for processing. Part of this is driven by hardware, but a lot of it is driven by psychology.

FORTRAN and COBOL were languages that considered data to be structured and mostly linear. The COBOL record definition was little more than a flexible punch card. (FORTRAN, too.)

Pascal (and all of the Algol languages) viewed data as a linked list or tree.

C++, Java, and C# considered data to be something contained in classes.

Perl included hashes ("dictionaries", in some venues) as a first-class members of the language. Python and Ruby have done the same.

As our view of data has matured, so have our languages. (Or perhaps, as our languages have changed, so has our view of data. I'm not sure about the direction of causality.)

It is not so much the language as it is (in my mind) the data structures that the languages provides. Those structures are still evolving, still growing as out knowledge increases.

We might think that our current collection of arrays, hashtables, and lists is sufficient. But I suspect that our confidence is ill-founded. I'm fairly sure that the FORTRAN programmers believed that zero-based arrays were sufficient for their programming challenges.

When we find a set of data structures that are "good enough", I think we will find that our languages are also "good enough".

Thursday, May 3, 2012

In software, bigger is not better

For most things, bigger is better. Hamburgers, cars, bank accounts... generally everything is better when it is bigger. But not for software. Software is not necessarily better when it is bigger.

By "big", I don't mean "popular". I mean "lines of code".

Software runs on a platform. (We used to call it an "operating system", and in the Eldar Days, software ran on hardware.)

Platforms change. Over time, they evolve. Windows XP becomes Windows Vista, and then Windows 7. (And now, Windows 8.) Linux changes from kernel 2.2 to kernel 2.4, and then 2.6. The popular Linux windows manager changes from KDE to Gnome. The Java JVM changes from version 1.5 to 1.6, and then to 1.7. Popular languages change from FORTRAN to BASIC, from BASIC to C, from C to C++, and from C++ to Java (or from Perl to Python to Ruby).

A software solution -- something that meets a need of the business -- must live on these platforms. And since it lives for a significant period of time, it must move from one platform to another as platforms change.

We tend to think that a software solution, once written, tested, and deployed, is permanent. That is, we think the "soft" solution is "firm" or even "hard". But we're wrong. It's still soft -- and often fragile.

For software to endure it must evolve with the platforms. For it to evolve, it must change. For it to change, someone must be capable of modifying the existing code and mutating it into something new. Some changes are small (Java 1.5 to Java 1.6), and some changes are large (Visual Basic 6 to VB.NET).

To change software, one must understand it. One must know the source code and understand the effects of changes to the code.

Which brings us back to the size of the source code.

The larger the source code, the harder it is to understand.

To be fair, there are many factors that affect our ability to understand source code. The language, our knowledge of the problem domain, and the style and readability of the code all affect our ability to make changes. (Also, the presence of automated tests makes for easier maintenance, since it assures us that changes affect only those features that we want to change.)

Yet size matters. Large systems are difficult to port to new platforms, especially platforms that are significantly different than the previous platform. (Say, moving from Windows C++/SDK/MFC to Java/Swing/Struts.)

For an enduring system, we must not assume that the platform will endure. (Microsoft's Windows 8 is a good example.) For enduring systems, we must design applications that can move from one platform to another. A tricky proposition, since the "new" platform will probably not exist when we construct the application.

I expect that a large number of Windows applications will not move to the new platforms of Java, Android, iPhone, or even Windows 8. (The legacy "desktop" mode of Windows 8 does not count.) They will not move because they are too large, too complicated, and too opaque to migrate to newer platforms. Instead, organizations will re-write applications for the new platforms.

But re-writing takes time. It takes more time for larger applications than for smaller applications. And there is always the risk that some feature will be omitted or implemented improperly.

Bigger is not always better. Bigger, when it comes to software, entails risks. The wise product manager will be aware of the risks and plan for them.