Sunday, December 18, 2022

Moving fast and breaking things is not enough

Many have lauded the phrase "Move fast and break things". Uttered by Mark Zuckerberg, founder of Facebook, it became a rallying cry for developing at a fast pace. It is a rejection of the older philosophy of careful analysis, reviewed design, and comprehensive tests. And while the pace of "move fast and break things" has its appeal, it is clear that "move fast and break things", by itself, is not enough.

Moving fast and breaking things results in, obviously, broken things. Broken things can be useful (more on this later) but they are, well, broken. A broken web site does not help customers. A broken database does not produce end-of-month reports. A broken... you get the idea.

Clearly, the one thing that you must do after you break something is to fix it. The fix may be easy or may be difficult, depending on the nature of the failures that occurred. A developer, working in a private sandbox, can break things and then restore them to working order with a "revert" command to the version control system. (This assumes a version control system, which I think in 2022 is a reasonable assumption.)

Moving fast and breaking things in the production environment is most likely a larger problem. One cannot simply revert everything to last night's backup -- today's transactions must be maintained. So we can say that moving fast is safer in developer sandboxes and riskier in production. (Just about everything is riskier in production, I think.)

But breaking things and fixing them is not enough, either. There is little point in breaking something and then fixing in by putting things back as they were.

As I see it, the point of breaking things (and fixing them) is to learn. One can learn about the system: its strengths and weaknesses, how errors are propagated, the dependencies of different components, and the information contained in logs.

With new information, one can fix a system and provide a solution that is better than the previous design. One can identify future areas for improvements. One can understand the limitations of external services and third-party libraries. That knowledge can be used to improve the system, to make it more resilient against failures, to make it more flexible for future enhancements.

So yes, by all means move fast and break things. But also fix things, and learn about the system.

Monday, November 21, 2022

More Twitter

Elon Musk has made quite the controversy, with his latest actions at Twitter (namely, terminating employment of a large number of employees, terminating the contracts for a large number of contractors, and discontinuing many of Twitter's services). His decisions have been almost universally derided; it seems that the entire internet is against him.

Let's take a contrarian position. Let's assume -- for the moment -- that Musk knows what he is doing, and that he has good reasons for his actions. Why would he take those actions, and what is his goal?

The former is open to speculation. My thought is that Twitter is losing money (it is) and is unable to fill the gap between income and "outgo" with investments. Thus, Twitter must raise revenue or reduce spending, or some combination of both. While this fits with Musk's actions, it may or may not be his motivation. 

The question of Musk's goal may be easier to answer. His goal is to improve the performance of Twitter, making it profitable and either keeping the company or selling it. (We can rule out the goal of destroying the company.) Keeping Twitter gives Musk a large communication channel to lots of people (free advertising for Tesla?) and makes him a notable figure in the tech (software) community. If Musk can "turn Twitter around" (that is, make it profitable, whether he keeps it or sells it) he builds on his reputation as a capable business leader.

Reducing the staff at Twitter has two immediate effects. The first is obvious: reduced expenses. The second is less obvious: a smaller company with fewer teams, and therefore more responsive. Usually, a smaller organization can make decisions faster than a large one, and can act faster than a large one.

It is true that a lot of "institutional knowledge" can be lost with large decreases in staff. That knowledge can range from the design of Twitter's core software, its databases, and its processes for updates, and its operations (keeping the site running). Yet a lot of knowledge can be stored in software (and database structures), and read by others if the software is well-written.

I'm not ready to bury Twitter just yet. Musk may be able to make Twitter profitable and keep a commanding presence in the tech space.

But I'm also not ready to build on top of Twitter. Musk's effort may fail, and Twitter may fail. I'm taking a cautious approach, using it for distributing and collecting and non-critical information. 

Wednesday, November 2, 2022

Twitter

Elon Musk has bought Twitter and started making changes. Lots of people have commented on the changes. Here are my thoughts.

Musk's actions are radical and seem reckless. (At least, they seem reckless to me.) Dissolving the board, terminating employment of senior managers, demanding that employees work 84-hour weeks to quickly implement a new feature (a fee for the blue 'authenticated' checkmark), and threatening to terminate the employment of employees who don't meet performance metrics are no way to win friends -- although it may influence people.

Musk may think that running Twitter is similar to running his other companies. But Tesla, SpaceX, The Boring Company are quite different from Twitter.

Twitter has a number of components. It has software: the various clients that provide Twitter to devices and PCs, the database of tweets, the query routines that select the tweets to show to individuals, and advertising inventory (ads) and the functions that inject those ads into the viewed streams.

But notice that the database of tweets is not made by Twitter. It is made by Twitter's users. It is the user base that creates the tweets, not Twitter employees. (Nor are they mined from the ground or grown on trees.)

The risk that Twitter now faces is one of reputation. If the quality (or the perceived quality) of Twitter falls, people (users) will leave. And like all social media, the value of Twitter is mostly defined by how many other people are on the service. Facebook's predecessor MySpace knows this, as does MySpace's predecessor Friendster.

Social media is like a telephone. A telephone is useful when lots of people have them. If you were the only person on Earth with a phone, it would be useless to you. (Who could you call?) The more people who use Twitter, the more valuable it is.

Musk's actions are damaging Twitter's reputation. A number of people have already closed their accounts, and more a claiming to do so in the future. (Those future closures haven't occurred, and it is possible that those individuals will decide to stay on Twitter.)

As I see it, Twitter has technical problems (all companies do) but their larger issues are management and leadership issues. Musk may have made some unforced errors that will drive away users, advertisers, employees, and future investors.

Thursday, October 20, 2022

The Next Big Thing

What will we see as the next big thing?

Let's look at the history of computer technology -- or rather, a carefully curated version of the history of computer technology.

The history of computing can be divided into eras: The mainframe era, the minicomputer era, the micro/PC era, and so forth. And, with careful editing, we can see that these eras have similar durations: about 15 years each.

Let's start with mainframe computers. We can say that it ran from 1950 to 1965. Mainframe computers were (and still are) large, expensive computers capable of significant processing. They are housed in rooms with climate control and dedicated power. Significantly, mainframe computers are used by people only indirectly. In the mainframe age, programmers submitted punch cards which contained source code; the cards were fed into the computer by an operator (one who was allowed in the computer room); the computer compiled the code and ran the program; output was usually on paper and delivered to the programmer some time later. Mainframe computers also ran batch jobs to read and process data (usually financial transactions). Data was often read from magnetic tape and output could be to magnetic tape (updated data) or paper (reports).

Minicomputers were popular from 1965 to 1980. Minicomputers took advantage of newer technology; they were smaller, less expensive, and most importantly, allowed for multiple users on terminals (either paper-based or CRT-based). The user experience for minicomputers was very different from the experience on mainframes. Hardware, operating systems, and programming languages let users interact with the computer in "real time"; one could type a command and get a response.

Microcomputers and Personal Computers (with text displays, and without networking) dominated from 1980 to 1995. It was the age of the Apple II and the IBM PC, computers that were small enough (and inexpensive enough) for an individual to own. They inherited the interactive experience of minicomputers, but the user was the owner and could change the computer at will. (The user could add memory, add disk, upgrade the operating system.)

Personal Computers (with graphics and networking) made their mark from 1995 to 2010. They made the internet available to ordinary people. Graphics made computers easier to use.

Mobile/cloud computers became dominant in 2010. Mobile devices without networks were not enough (the Palm Pilot and the Windows pocket computers never gained much traction). Even networked devices such as the original iPhone and the Nokia N800 saw limited acceptance. It was the combination of networked mobile device and cloud services that became the dominant computing model.

That's my curated version of computing history. It omits a lot, and it fudges some of the dates. But it shows a trend, one that I think is useful to observe.

That trend is: computing models rise and fall, with their typical life being fifteen years.

How is this useful? Looking at the history, we can see that the mobile/cloud computing model has been dominant for slightly less than fifteen years. In other words, its time is just about up.

More interesting is that, according to this trend (and my curated history is too pretty to ignore), something new should come along and replace mobile/cloud as the dominant form of computing.

Let's say that I'm right -- that there is a change coming. What could it be?

It could be any of a number of things. Deep-fake tech allows for the construction of images, convincing images, of any subject. It could be virtual reality, or augmented reality. (The difference is nontrivial: virtual reality makes full images, augmented reality lays images over the scene around us.) It could be watch-based computing. 

My guess is that it will be augmented reality. But that's a guess.

Whatever the new thing is, it will be a different experience from the current mobile/cloud model. Each of the eras of computing had its own experience. Mainframes had an experience of separation and working through operators. Minicomputers had interactive experience, although someone else controlled the computer. Personal computers had interaction and the user owned the computer. Mobile/cloud let people hold computers in their hand and use them on the move.

Also, the next big thing does not eliminate the current big thing. Mobile/cloud did not eliminate web-based systems. Web-based systems did not eliminate desktop applications. Even text-mode interactive applications continue to this day. The next big thing expands the world of computing.

Wednesday, October 19, 2022

Businesses discover that cloud computing isn't magic

Businesses are now (just now, after more than a decade of cloud computing) discovering that cloud computing is not magic. That it doesn't make their computing cheap. That it doesn't solve their problems.

Some folks have already pointed this out. Looking back, it seems obvious: If all you have done is move your web-based system into cloud-based servers, why would things change? But they miss an important point.

Cloud computing is a form of computing, different from web-based applications and different from desktop applications. (And different from mainframe batch processing of transactions.)

A cloud-based system, to be efficient, must be designed for cloud computing. This means small independent services reading and writing to databases or other services, and everything coordinated through message queues. (If you know what those terms mean, then you understand cloud computing.)

Moving a web-based application into the cloud, unchanged, makes little sense. Or as much sense as moving a desktop-based application (remember those?) such as Word or Excel into the web, unchanged.

So why use cloud computing?

Cloud computing's strengths are redundancy, reliability, and variable power. Redundancy in that a properly designed cloud computing system consists of multiple services, each of which can be hosted on multiple (as in more than one per service) servers. If your system contains a service to perform address validations, that service could be running on one, two or seven different servers. Each instance does the same thing: examine a mailing address and determine the canonical form for that address.

The other components in your system, when they need to validate or normalize an address, issue a request to the validation service. They don't care which server handles the request.

Cloud systems are reliable because of this redundancy. A traditional web-based service would have one address validation server. If that server is unavailable, the service is unavailable for the entire system. Such a failure can lead to the entire system being unavailable.

Cloud systems have variable power. They can create additional instances of any of the services (including our example address validation service) to handle a heavy workload. Traditional web services, with only one server, can see slow response times when that server is overwhelmed with requests. (Sometimes a traditional web system would have more than one server for a service, but the number of servers is fixed and adding a server is a lengthy process. The result is the same: the allocated server or servers are overwhelmed and response time increases.)

Cloud services eliminate this problem by instantiating servers (and their services) as needed. When the address validation server is overwhelmed, the cloud management software detects it and "spins up" more instances. Good cloud management software works in the other direction too, shutting down idle instances.

Those are the advantages of cloud systems. But none of them are free; they all require that you build your system for the cloud. That takes effort.


Tuesday, October 11, 2022

Technical interviews

Businesses -- large businesses that have HR departments -- have a problem: They find it difficult to hire new staff.

The problem has a few aspects.

First is the processes that businesses have developed for hiring. Businesses have refined their processes over decades. They have automated the application process, they have refined the selection process to filter out the unqualified candidates, and they have documented job descriptions and made pay grades equitable. They have, in short, optimized the hiring process.

But they have optimized it for the pre-COVID market, in which jobs were few and applicants were plentiful. The selection processes have been designed to filter out candidates: to start with a large number of applications and through multiple steps, reduce that list to a manageable three (or five, or ten). The processes have been built on the assumption that many candidates wanted to work at the company, and were willing to undergo phone screens, interviews, and take-home tests.

The current market is a poor fit for these practices. Candidates are less willing to undergo day-long interviews. They demand payment for take-home tests (some of which can take hours). Candidates are especially reluctant to undergo the process multiple times, for multiple positions. The result is that companies cannot hire new staff. ("No one wants to work!" cry the companies, but a better description might be "Very few people are willing to jump through all of our hoops!")

One might think that companies could simply change their hiring processes. There is an obstacle to this: Human Resources.

Most people think that the purposes of Human Resources are to hire people, occasionally fire them, and administer wages and benefits. They miss an important purpose for HR: to keep the company out of court.

Human Resources is there to prevent lawsuits. Lawsuits from employees who claim harassment, candidates who were not hired, employees whose employment was terminated, employees who are unhappy with their annual performance review, ... you get the idea.

HR meets this objective by enforcing consistency. They administer consistent annual evaluations. They document employee performance prior to termination of employment. They define and execute consistent hiring practices.

Note that last item: consistent hiring practices. One of the ways that HR deflects lawsuits is by ensuring that hiring practices are consistent for all candidates (or all candidates in broad classes). Consistency is required not only across employees but also over time. A consistent approach (to hiring, performance review, or termination of employment) is a strong defense against claims of discrimination.

The suggestion that HR change its hiring practices goes against the "consistency" mandate. And HR has a good case for keeping its practices consistent.

Companies must balance the need for staff against the risk of lawsuits (from a change in practices). It is not an easy call, and one that should not be made lightly. And something to keep in mind: The job market may shift back to the previous state of "many candidates for few openings". Should a company adjust its practices for a shift in the market that may be temporary? Should it shift again when the market changes back?

I don't have simple, definite answers. Each company must find its own.

Wednesday, October 5, 2022

Success with C++

Having recently written on the possible decline of C++, it is perhaps only fair that I share a success story about C++. The C++ programming language is still alive, and still useful. I should know, because a recent project used C++, and successfully!

The project was to maintain and enhance an existing C++ program. The program was written by other programmers before I arrived, over a period of years. Most of the original developers were no longer on the project. (In other words, a legacy system.)

The program itself is small by today's standards, with less than 300,000 lines of source code. It also has an unusual design (by today's standards): The program calculates economic forecasts, using a set of input data. It has no interaction with the user; the calculations are made completely with nothing more than the input data and program logic.

We (the development team) have successfully maintained and enhanced this program by following some rules, and placing some constraints upon ourselves. The goal was to make the code easy to read, easy to debug, and easy to modify. We made some design decisions for performance, but only after our initial design was shown to be slow. These constraints, I think, were key to our success.

We use a subset of C++. The language is large and offers many capabilities; we pick those that are necessary. We use classes. We rarely use inheritance. Instead, we build classes from composition. Thus, we had no problems with slicing of objects. (Slicing is an effect that can occur in C++, when casting a derived class to a base class. It generally does not occur in other OOP languages.) There are a very small number of classes that use inheritance, and in those cases we often want slicing.

We use STL but not BOOST. The STL (the Standard Template Library) is enough for our needs, and we use only what we need: strings, vectors, maps, and an occasional algorithm.

We followed the Java convention for files, classes, class names, and function names. That is, each class is stored in its own file. (In C++, we have two files, for the header file and the source file.) The name of the file is the name of the class (with a ".h" or ".cpp" extension). The class name uses camel-case, with a capital letter at the beginning of each word, for names such as "Year" or "HitAdjustment". Function names use snake-case with all lower-case letters and underscores between words. This naming convention simplified a lot of our code. When creating objects, we could create an object of type Year and name it "year". (The older code using no naming conventions, and many classes had lower-case names, which meant that when creating an object of type "ymd" (for example) we had to pick a name like "my_ymd" and keep track mentally of what was a class name and what was a variable name.)

We do not use namespaces. That is, we do not "use std" or any other namespace. This forces us to specify the namespace for every class. While tedious, it provides the benefit that one can easily see the class for function names. There is no need to search through the code, or guess about a function.

We use operator overloading only for a few classes, and only when the operators are obvious. Most of our code uses function calls. This also reduces guesswork by developers.

We have no friend classes and no friend functions. (We could use them, but we don't need them.)

Our attitude towards memory management is casual. Current operating systems provide a 2 gigabyte space for our programs, and that is enough for our needs. (It has been so far.) We avoid pointers and dynamic allocation of memory. STL allocates memory for its objects, and we assume that it will manage that memory properly.

We do not use lambdas or closures. (We could use them, but we don't need them.)

We use spacing in our code to separate sections of code. We also use spacing to denote statements that are split across multiple lines. (A blank in front and a blank after.)

We use simple expressions. This increases the number of source lines, which eases debugging (we can see intermediate results). We let the C++ compiler optimize expressions for "release" builds.

----

By using a subset of C++, and carefully picking which features make up that subset, we have successfully developed, deployed, and maintained a modest-sized C++ application.

These constraints are not traditionally considered part of the C++ language. We enforce them for our code. It provides us with a consistent style of code, and one that we find readable. New team members find that they can read and understand the code, which was one of our goals. We can quickly make changes, test them, and deploy them -- another goal.

These choices work for us, but we don't claim that they will work for other teams. You may have an application that has a different design, a different user interface, or a different set of computations, and it may require a different set of C++ code.

I don't say that you should use these constraints on your project. But I do say this: you may want to consider some constraints for your code style. We found that these constraints let us move forward, slowly at first and then rapidly.


Monday, September 26, 2022

The end of C++

The language wars are back!

Well, one war -- between C++ and Rust.

Perhaps "war" is too strong a word. A better description is "a discussion".

Programmers do like to participate in language wars. Or they used to, back in the days prior to open source and the internet. Back then, a programmer worked with the language that was chosen by his employer, or a language for which he (and programmers were overwhelmingly men) had spent money to acquire the compiler or interpreter. One's programming language was fixed, either by company mandate or by finances. That caused false pride in their programming language.

Open source and the internet made it possible for programmers to easily switch. They could try one and change if they found it better than their current language. With the ability to change, programmer's didn't need false pride, and didn't have to argue the merits of a language that they were most likely unhappy with. The language wars faded.

Until now. There were two events this past week, both concerning programming languages.

The first involved the Linux kernel. Linus Torvalds, the chief maintainer for the Linux kernel, announced that he would allow code written in Rust (an up-and-coming programming language) to be part of the kernel. (The kernel, up to now, has been written exclusively in C.) This announcement angered the C++ advocates, who would have preferred that language. Various arguments bounced across the internet, extolling the virtues of each. (Mostly "Rust is a safe language, designed to prevent many mistakes that can happen in C and in C++." and "C++ is a time-tested language with a mature toolset and a large base of experienced developers.")

It wasn't a war, or even a battle, but a discussion with lots of emotion.

The second event was an announcement from Microsoft's CTO for Azure. He stated that organizations and individuals should stop choosing C++ for new projects, and instead pick other languages. (I don't think he listed the languages, but I suspect he would prefer languages supported by the Azure platform.)

That announcement received much less interest. But still, it counts as a volley in the language disputes.

(I suspect that the Microsoft CTO is right, but for a different reason: the size of applications. C++ was designed for large systems, and today's cloud-based services are much smaller. They don't need C++; they need a language larger than C, smaller than C++, and safer than both.)

I find the timing of these two announcements interesting. It may be that we are seeing the beginning of the end for C++.

It may be that historians, in some distant future, draw a line and say "Here, here in 2022, is where C++ began its decline. This is the time that the IT world started to move away from C++."

I don't expect C++ to disappear. Some programming languages have "disappeared" in that they are used for nothing outside of a few museum exhibits and systems run by die-hard fans. Programming languages such as Flowmatic, Neliac, BASIC, and Modula-2 are all but unused in the modern world.

Yet other old languages continue to be used: Cobol, Fortran, and even RPG are running systems today. I expect C++ to join their ranks. They will remain, they will continue to do useful work, and they will be present in popularity surveys. But they won't be at the top.


Sunday, August 14, 2022

Where has the FUD gone?

A long time ago, the IT industry was subjected to FUD (Fear, Uncertainty, Doubt) advertising campaigns.

FUD was a marketing strategy used by IBM. When competitors announce a new product (or worse, a breakthrough product), IBM would announce a similar product, but only in broad terms. The idea was to encourage people to wait for IBM's product, thereby reducing sales of the competing product. (It also created hype for the IBM product.)

To be effective, a FUD announcement had to describe a future product. It created doubt and uncertainty, and fear of making a bad choice of technology.

I haven't seen a FUD announcement for a long time.

They were common when IBM was the dominant manufacturer for computing equipment. The FUD campaign may have ended shortly after the introduction of the PS/2 (itself a product with a FUD announcement) line of computers. The market rejected the PS/2's Micro Channel Architecture, and accepted Compaq's ISA (the old PC standard architecture) with its 80368 processors. (Although the market did adopt IBM's VGA display and 1.44 MB hard "floppy" disk as standards.)

Compaq didn't use FUD announcements to take the lead from IBM. It delivered products, and its announcements for those products were specific. The message was "our products have this technology and you can buy them today".

There is one company today which has something similar to FUD announcements. But they are different from the old-style FUD announcements of yesteryear.

That company is Apple.

Apple is the one company that announces future products. It does it in a number of ways, from its annual marketing events to its reliable product schedule. (Everyone knows that Apple releases new iPhones in September, for example.)

Apple's FUD campaign seems to be accidental. I don't think that Apple is playing the same game that IBM played in the 1980s. IBM made FUD announcements to deter people from buying products from other companies. Apple may be doing the same thing, but instead of affecting other companies, I think it is Apple itself that suffers from these announcements.

Apple announcing a new processor for its MacBook line doesn't deter people from buying Windows laptops. They need laptops, they have already chosen Windows (for whatever reason) and they are going to buy them. Very few people change their purchasing decision from Windows to a yet-to-be-defined MacBook.

But a lot of Apple users defer their purchases. Many Apple users, in the middle of planning an upgrade, put off their purchase until the new MacBook was released.

Trade publications advise people to defer the purchase of Mac Minis, based on Apple's announcements and regular product schedule.

This behavior is the same as IBM's FUD from thirty years ago -- but with the difference that the (unintentional) target is the company itself.

It may be that Apple is aware of customers deferring their purchases. Perhaps Apple wants that behavior. After all, if Apple withheld new product information until the release of the product, those who recently purchased the older version may feel betrayed by Apple. It may be that Apple is forgoing immediate revenue in exchange for customer goodwill.

I'm happy to live in a world without FUD announcements. The IT world with FUD has challenges for planning, and a constant fear of missing out on important technology. The current world is a much more relaxed place. (That may sound odd to technology managers, but believe me, today's world is much better than the older one.)

Tuesday, August 9, 2022

E-mail Addresses Considered Harmful

PCWorld lost (temporarily) their YouTube account because their e-mail address changed.

YouTube, like many web services, uses e-mail addresses for customer IDs. This, I think, is a poor practice.

Many web services and many cloud services create dependencies on an email address. Your account ID is your email address. (This is a cheap way to ensure unique IDs.) When updating my e-mail address on these sites, I am changing my ID.

IDs should be unique, short, and permanent. E-mail addresses are unique, and they are usually short, but they are not permanent. E-mail addresses can change. Specifically, e-mail addresses can change outside of the control of the organization that uses them as IDs. I changed my main e-mail address recently, and had to go through all of my accounts (I keep a list) and update each of them.

For most sites, I was able to change my e-mail address. Some sites let me change my contact e-mail address but did not allow me to change my ID. Those sites send e-mails to my new address, but I must use my old e-mail address to log in. Other sites let me change my e-mail address as ID, but kept sending notifications to my old e-mail address. (Their web site stores the e-mail addresses for notifications as a copy of the login ID, and those e-mail addresses are not updated when the ID is changed.)

Clearly, different web sites have different ideas about the separation of ID and e-mail.

Companies running web services, or cloud services, should carefully select their IDs for customers. How do they use those IDs? Are they stored in databases? Are they keys in databases? If a customer changes their e-mail address, what happens to the records with the old e-mail address? How does a new e-mail address affect queries? Do the two e-mail addresses appear as two different customers?

This is why database keys (and user IDs) should be unique and permanent.

Banks and insurance companies understand this. I am a customer to a few insurance companies and several banks. All of them -- without exception -- use their own IDs for my account. Not email addresses.

The underlying concept here is ownership. When I open an account with a bank and they ask me to provide an ID (not an e-mail), they are really asking me to pick an ID from a (very) large set of unused IDs that conform to their rules (so many letters and digits). I pick the ID, but they own it. They can change it if they want. (I've never seen that happen, but it could.) And if they change it, nothing else in my electronic life changes.

An e-mail address, in contrast, is owned by the e-mail provider (GMail, Yahoo, Microsoft, etc.). I don't own it, I merely "rent" it. Anyone I give it to, either a friend, colleague, or web service, is only borrowing it. It can be withdrawn from circulation at any time, either by me or the e-mail service.

Building a service on data that you don't own is risky. I understand the appeal of e-mail addresses as IDs. (It is easy, everyone else does it, it doesn't require our own code to create new IDs for customers, and anyway customers don't want another ID for our service and that is a disincentive for them to use our new service so use the e-mail addresses because the folks in marketing want it that way.)

Yet I must balance those appealing factors with the risks. For individuals, the e-mail address may be an acceptable ID. For corporate accounts, e-mail addresses as ID pose risks to the customer. (Just as PCWorld.)

In essence, using e-mail addresses as IDs is simple for the service, but imposes risks on customers. That may not be the best of business practices.


Thursday, August 4, 2022

Eggs and baskets

PCWorld, a venerable trade publication-now-website of the IT realm, recently lost its YouTube video channel. The channel was disabled (or suspended? or deleted?) and no content was available. For more than eight days.

From what I can discern, IDG's YouTube account was controlled by an IDG e-mail address. Everything worked until IDG was purchased by Foundry, and Foundry changed all of IDG's e-mail addresses to Foundry addresses, didn't change the account at YouTube, and YouTube, seeing no activity on the IDG e-mail address or maybe getting bounce messages, cancelled the account.

Thus, the PCWorld video channel was unavailable for over a week.

Why didn't PCWorld restore its channel? Or make its content available on another service? 

My guess is that IDG stored all of their video content on YouTube. That is, the only copy was on YouTube. IDG probably relied on YouTube to keep backup copies and multiple servers for disaster recovery. In short, IDG followed the pattern for cloud-based computing.

The one disaster for which IDG failed to prepare was the account cancellation.

I must say here that a lot of this is speculation on my part. I don't work for PCWorld, or at IDG (um, Foundry) or at YouTube. I don't know that the sequence I have outlined is what actually happened.

My point is not to identify exactly what happened.

My point is this: cloud solutions, like any other type of technology, can be fragile. They can be fragile in ways that we do not expect.

The past half-century of computing has shown us that computers fail. They fail in many ways, from physical problems to programming errors to configuration mistakes. Those failures often cause problems with data, sometimes deleting all of it, sometimes deleting part of it, and sometimes modifying (incorrectly) part of the data. We have a lot of experience with failures, and we have built a set of good practices to recover from those failures.

Cloud-based solutions do not eliminate the need for those precautions. While cloud-based solutions offer protection against some problems, they introduce new problems.

Such as account cancellation.

Businesses (and people, often), when entering into agreements, look for some measure of security. Businesses want to know that the companies they pick to be suppliers will be around for some time. They avoid "fly by night" operations.

A risk in cloud-based solutions is account closure. The risk is not that Google (or Oracle) will go out of business, leaving you stranded. The risk is that the cloud supplier will simply stop doing business with you.

I have seen multiple stories about people or businesses who have had their accounts closed, usually for violating the terms of service. When said people or businesses reach out to the cloud provider (a difficult task in itself, as they don't provide phone support) the cloud provider refuses to discuss the issue, and refuses to provide any details about the violation. From the customer's perspective, the results are very much as if the cloud provider went out of business. But this behavior cannot be predicted from the normal signal of "a reliable business that will be around for a while".

It may take some time, and a few more stories about sudden, unexplained and uncorrectable account closures, but eventually people (and businesses) will recognize the risk and start taking preventative actions. Actions such as keeping local copies of data, backups of that data (not local and not on the main cloud provider), and a second provider for fail-over.

In other words:

Don't put all of your eggs in one cloud basket.

Tuesday, July 26, 2022

Mental models of computers

In the old movie "The Matrix", there is a scene in which the character Cipher is looking at code and another character, Neo, asks why he looks at the code and not the presentation-level view. Cipher explains that the code is better, because the presentation level is designed to fool us humans. At this the moment that Neo re-thinks his view of computers.

That scene (some years after the debut of the movie) got me thinking about my view of computers.

My mental model of computers is based on text. That is, I think of a computer as a device that processes text and talks to other devices that process text. The CPU processes text, terminals display text to users and accept text via the keyboard, printers print text, and disks store text. (Disks also store data in binary form, but for me that is simply a strange form of text.)

This model is perhaps not surprising, as my early experiences with computers were with text-oriented devices and text-oriented programs. Those computers included a DEC PDP-8 running BASIC; a DECsystem-10 running TOPS-10 with FORTRAN, Pascal, and a few other text-oriented languages; a Heathkit H-89 running HDOS (an operating system much like DEC's RT-11) and BASIC, assembly language, FORTRAN, C, and Pascal.

The devices I used to interact with computers were text terminals. The PDP-8 used Teletype ASR-33s, which had large mechanical keyboards (way more mechanical than today's mechanical keyboards) and printed text on a long continuous roll of paper. The DECsystem-10 and the H-89 both used CRT terminals (no paper) and mostly text with a few special graphics characters.

In those formative years, all of my experience with computers was for programming. That is, the primary purpose of a computer was to learn programming and to do programming. Keep in mind that this was before much of the technical world we have today. There was no Google, no Netflix, no Windows. Spreadsheets were the new thing, and even they were text-oriented. The few graphs that existed in computing were made on special (read that as "expensive and rare") equipment that few people had.

In my mind, back then, computers were for programming and programming was a process that used text and the computers used text so they were a good match for programming.

Programming today is still a text-oriented process. The "source code" of programs, the version that we humans write and that computers either compile or interpret into executed code, is text. One can write programs in the Windows "Notepad" program. (One must save them to disk and then tell the compiler to convert that saved file, but that is simply the process to get a program to run.)

So what does this have to do with "The Matrix" and specifically why is that one scene important?

It strikes me that while my experience with computers started with programming and text-oriented devices, not every (especially now-a-days) has that same experience. Today, people are introduced to computers with cell phones, or possibly tablets. A few may get their first experience on a laptop running Windows or macOS.

All of these are different from my text-based introduction. And all of these are graphics-based. People today, when they first encounter computers, encounter graphical interfaces, and use computers for many things other than programming. People today must have a very different mental model about computers. I saw computers as boxes that processed text. Today, most people see computers as boxes that process graphics, and sound, and voice.

What a shock it must be for someone today to start to learn programming. They are taken out of their comfortable mental model and forced to use text. Some classes begin with simple "hello, world" programs that not only use text source code but also produce text output. How primitive this must seem to people familiar with graphical interfaces! (Some classes begin with simple programs that present web pages, which is a bit better in that the output is familiar, but the source code is still text.)

But this different mental model may be a problem for people entering the programming world. They are moving from a graphical world to a text-based world, and that transition can be difficult. Modern IDE programs ease the transition by allowing many operations in a graphical environment, but the source code remains text.

Do people revolt? Do they reject the text-oriented approach to source code? I imagine that some find the change in mental models difficult, perhaps too difficult, and they abandon programming.

A better question is: Why has no one created a graphical-oriented programming language? Not just a programming language in an IDE -- we already have those. I'm thinking of a new approach to programming, something very different from the text approach of today.

It might be that programming has formed a self-reinforcing loop. Only programmers can create new programming languages and programming environments, and these programmers (obviously) are comfortable with the text paradigm. Perhaps the see no need to make such a large change.

Or it might be that the text model is the best model for programming. Programming is the organization of ideas into clearly specified collections and operations, and text handles that task better than graphics. Visual representations of collections and operations can be clear, and they can be ambiguous. (But then, text representations can also be ambiguous, so I'm not sure that there is a clear advantage for text.)

Or possibly we simply have not seen the right person to come along, with the right mix of technical skills, graphics abilities, and desire for a visual programming language. It may be that graphical programming languages are possible, and that we just haven't invented them.

I want to think it is the last of these reasons, because that means there is a lot more for us to learn about programming. The introduction of a visual programming language will open new vistas for programming, and applications, and computing.

I want to think that there will always be something new for the programmers.

Wednesday, July 20, 2022

The Macbook camera may always be second-rate

A recent article on MacWorld complained about Apple's "solution" of a webcam for MacBooks, namely using the superior camera in the iPhone.

It is true that iPhones have better cameras than MacBooks. But why?

I can think of no technical reason.

It's not that the iPhone camera won't fit in the MacBook. The MacBook has plenty of space. It is the iPhone that puts space at a premium.

It's not that the iPhone camera won't work with a MacBook processor. The iPhone camera works in the iPhone with its A12 (or is it A14?) processor. The MacBook has an M1 or an M2 processor, using very similar designs. Getting the iPhone camera to work with an M1 processor should be relatively easy.

It's not a matter of power. The MacBook has plenty of electricity. It is the iPhone that must be careful with power consumption.

It's not that the MacBook developers don't know how to properly configure the iPhone camera and get data from it. (The iPhone developers certainly know, and they are just down the hall.)

It's not a supply issue. iPhone sales dwarf MacBook sales (in units, as well as dollars). Diverting cameras from iPhones to MacBooks would probably not even show in inventory reports.

So let's say that the reason is not technical.

Then the reason must be non-technical. (Obviously.)

It could be that the MacBook project lead wants to use a specific camera for non-technical reasons. Pride, perhaps, or ego. Maybe the technical lead, on a former project, designed the camera that is used in the MacBook, and doesn't want to switch to someone else's camera. (I'm not convinced of this.)

Maybe Apple has a lot of already-purchased cameras and wants to use them, rather than discarding them. (I'm not believing this, either.)

I think the reason may be something else: marketing.

When Apple sells a MacBook with an inferior camera, and it provides the "Continuity Camera" service to allow an iPhone to be used as a camera for that MacBook, Apple has now given the customer a reason to purchase an iPhone. Or if the customer already has an iPhone, a reason to stay with the iPhone and not switch to a different brand.

It's not a nice idea. In fact, it's rather cynical: Apple deliberately providing a lesser experience in MacBooks for the purpose of selling more iPhones.

But it's the only one that fits.

Maybe I'm wrong. Maybe Apple has a good technical reason for supplying inferior cameras in MacBooks.

I hope that I am. Because I want Apple to be a company that provides quality products, not inferior products carefully crafted to increase sales of other Apple products.

Thursday, July 14, 2022

Two CPUs

Looking through some old computer magazines from the 1980s, I was surprised at the number of advertisements for dual-CPU boards.

We don't see dual-CPU configurations now. I'm not talking about dual cores (or multiple cores) but dual CPUs. Two actual, and different, CPUs. In the 1980s, the common mix was a Z-80 and an 8086 on the same board. Sometimes it was an 8085 and an 8086.

Dual-CPU boards were popular as the industry transitioned from 8-bit processors (8080, Z-80, 6502, and 6800) to 16-bit processors (8088 and 8086, mainly). A dual-CPU configuration allowed one to test the new CPU while still keeping the old software (and data) available.

Dual-CPU configurations did not use two CPUs at the same time. They allowed for one or the other CPU to be active, to run an 8-bit operating system or a 16-bit operating system, much like today's dual-boot configuration for multiple operating systems on a single PC.

Computers at the time were more expensive and more modular than they are today. Today's computers have a motherboard with CPU (often with integrated graphics), slots for memory, slots for GPU, SATA ports for disks, and a collection of ports (video, USB, ethernet, sound, and sometimes PS/2 keyboard and mouse). All of those items are part of the motherboard.

In contrast, computers in the 1980s (especially those not IBM-compatible) used a simple backplane with a buss and separate cards for CPU, memory, floppy disk interface, hard disk interface, serial and parallel ports, real-time clock, and video display. It was much easier to replace the CPU and keep the rest of the computer.

So why don't we see dual-CPU configurations today? Why don't we see (for example) a PC with an Intel processor and an ARM processor?

There are a number of factors.

One is the cost of hardware. Computers today are much less expensive than computers in the 1980s, especially after accounting for inflation. Today, one can get a basic laptop for $1000, and a nice one for $2000. In the 1980s, $1000 would get a disk subsystem (interface card and drives) but the cost of the entire computer was upwards of $2000 (in 1980 dollars).

Another factor is the connection between hardware and operating system. Today, operating systems are tightly bound to hardware. A few people use grub or BootCamp to run different operating systems on the same computer, but they are few. For most people, the hardware and the operating system are a set, both coming in the same box.

Booting from a floppy disk (instead of an internal fixed disk) puts a degree of separation between hardware and operating system. One can easily insert a different disk to boot a different operating system.

Computers today are small. Laptops and micro-size desktops are convenient to plunk down almost anywhere. It is easy enough to find space for a second computer. That was not the case in the 1980s, when the CPU was the size of today's large tower unit, and one needed a large terminal with CRT and keyboard. Space for a second computer was a luxury.

Finally, today's processors are sophisticated, with high integration with the other electronics on the motherboard. The processors of the 1980s were quite isolationist in their approach to other circuitry, and it was (relatively) easy to design the circuits to allow for two CPUs and to enable one and not the other. The connections for today's Intel processors and today's ARM processors are much more sophisticated, and the differences between Intel and ARM are pronounced. A two-CPU system today requires much more than the simple enable/disable circuits of the past.

All of those factors (expense of hardware, ease at replacing a single-CPU card with a dual-CPU card, limited space, the ease of changing operating systems, and the ability to link two unlike CPUs on a single card) meant that the dual-CPU configuration was the better choice, in the 1980s. But all of those factors have changed, so in 2022 the better choice is to use two different computers.

I suppose one could leverage the GPU slot of a PC, and install a special card with an ARM processor, but I'm not sure that the card in the GPU slot can operate as a buss master and control the ports and memory of the motherboard. But such a board would have limited appeal, and probably not a viable product.

I think we won't see a dual-CPU system. We won't see a PC with an Intel processor and an ARM processor, with boot options to use one or the other. But maybe we don't need dual-CPU PCs. We can still explore new processors (by purchasing relatively inexpensive second PCs) and we can transition from older CPUs to newer ones (by purchasing relatively inexpensive replacement PCs).

Thursday, June 23, 2022

Web pages are big

Web pages load their own user interface code.

There are two immediate consequences of this.

First, each web page must load its own libraries to implement that interface. That slows the loading of web pages. The libraries include more than code; they include stylesheets, fonts, graphics, images and lots of HTML to tie it all together. The code often includes bits to identify the type of device (desktop web browser, mobile web browser, etc.) and functions to load assets when needed ("lazy loading").

I imagine that lots of this code is duplicated from page to page on a web site, and lots of the functions are similar to corresponding functions on other web sites.

Second, each web page has its own user interface, its own "look and feel", to use a term from the 1980s.

Each web page (or perhaps more accurately, each web site) has its own appearance, and its own conventions.

Even the simple convention of "login and logout links are in the top right corner" is not all that common. Of the dozens of web sites that I frequent, many have the "login" and "logout" links in the top right corner, but many others do not. Some have the links close to the top (but not topmost) and close to the right side (but not rightmost). Some web sites bury the "login" and "logout" links in menus. Some web sites put one of the "login" and "logout" links in a menu, but leave the other on the page. Some web sites put the "login" link in the center of their welcome page. And there are other variations.

Variation in the user interface is not evil, but it is inconsistent and it increases the mental effort to visit different web sites. But what do the owners of each web site care? As long as customers come to their web site (and pay them) then the web site is working, according to the company. The fact that it is not consistent with other web sites is not a problem (for them).

Web sites have to load all of their libraries, which increases overall load time for the site. The companies running the web sites probably care little, as the cost is imposed on their customers. The attitude that many companies take is probably (I say "probably" because I have not spoken to companies about this) is that the user (the customer), if dissatisfied with load time, can purchase a faster computer or a faster internet service. The company feels no obligation to improve the experience for the customer.

* * * * *

The situation of individual, differing user interfaces is not unique. In the 1980s, prior to Microsoft Windows, PC software had different user interfaces. The word processors of the time (WordPerfect, WordStar, and even Microsoft Word which had a version for MS-DOS) each had their own "look and feel". The spreadsheets of the time (Lotus 1-2-3, Quattro Pro, and Microsoft Multiplan) each had their own user interfaces, different from each other and different from the user interfaces for word processors. Database packages (dBase, R:Base, Clipper, Condor) each had their own... you get the idea.

Windows offered consistency in the user interface. (It also offered graphics, which is what I think really sold Windows over IBM's OS/2, but that's another topic.) With Windows, programs started the same way, appeared the same way, and provided a set of common functions for opening files, printing, copying and pasting data, and more.

Windows arrived at an opportune time. Computers were fairly common, people (and companies) were using them for serious work, and applications had their various user interfaces. Windows offered consistency across applications, and reduced the effort to learn new applications. A spreadsheet was different from a word processor, but at least someone who was familiar with a word processor under Windows could perform basic operations in a spreadsheet under Windows. People, when learning new applications, could focus on those aspects that were unique to the new applications, not the common operations.

The result was that people learned to use computers more rapidly than in the earlier age of MS-DOS. Windows was sold on the reduction of effort (and therefore costs) in using computers.

* * * * *

Will we see a similar transition for the web? Will someone come along and sell a unified interface for web apps, advertising a lower cost of use? 

In a sense, we have. The apps on smart phones have a more consistent user interface than web sites. This is due to Apple's and Google's efforts, providing libraries for common UI functions and guidelines for application appearance.

But I don't see a unifying transition for web sites in traditional (desktop) browsers. Each company wants its own look and feel, its own brand presence. It doesn't care that web sites take a long time to load, and it probably doesn't care that web sites require a lot of expensive maintenance. Microsoft was able to sell Windows from a position of strength, in a market that had few options. With the web, any company can set up a web site and offer it to the world. There is no convenient choke point, and there is no company strong enough to offer a user interface that could meet the needs of the myriad web sites in existence.

Which means that we are stuck with large web pages, long download times, and different interfaces for different web sites.

Thursday, June 16, 2022

Consolidation of processors, and more

We're in an age of consolidation. PCs are moving to the ARM processor as a standard. Apple has already replaced their entire line with ARM-based processors. Microsoft has built ARM-based laptops. The advantages of ARM (lower production cost, lower heat dissipation) make such a move worthwhile.

If this consolidation extends to all manufacturers, then we would see a uniform processor architecture, something that we have not seen in the PC era. While the IBM PC set a standard with the Intel 8088 processor, other computers at the time used other processors, mostly the Zilog Z-80 and the Mostek 6502. When Apple shifted to the Macintosh line, is changed to the Motorola 68000 processor.

Is consolidation limited to processors?

There are, today, four major operating systems: Windows, mac OS, zOS, and Linux. Could we see a similar consolidation among operating systems? Microsoft is adding Linux to Windows with WSL, which melds Linux into Windows. Apple's mac OS is based on Net BSD Unix, which is not that far from Linux. IBM's zOS supports Linux as virtual machines. IBM might, one day, replace zOS with Linux; they certainly have the ability to build one.

If both of these consolidations were to occur, then we would see a uniform processor architecture and a uniform operating system, something that has not occurred in the computing age.

(I'm not so dreamy-eyed that I believe this would happen. I expect Microsoft, Apple, and IBM to keep some degree of proprietary extensions to their systems. But let's dream a little.)

What affect would a uniform processor architecture and uniform operating system have on programming languages?

At first glance, one might think that there would be no effect. Programming languages are different things from processors and operating systems, handling different tasks. Different programming languages are good at different things, and we want to do different things, so why not keep different programming languages?

It is true that different programming languages are good at different things, but that doesn't mean that each and every programming language have unique strengths. Several programming languages have capabilities that overlap, some in multiple areas, and some almost completely. C# and VB.NET, for example. Or C# and Java, two object-oriented languages that are good for large-scale projects.

With a single processor architecture and a single operating system, Java loses one of its selling points. Java was designed to run on multiple platforms. It's motto was "Write Once, Run Everywhere." In the mid 1990s, such a goal made sense. There were different processors and different operating systems. But with a uniform architecture and uniform operating system, Java loses that point. The language remains a solid performer, so the loss is not fatal. But the argument for Java weakens.

A pair of overlapping languages is VB.NET and C#. Both are made by Microsoft, and both are made for Windows. Or were made for Windows; they are now available on multiple platforms. They overlap quite a bit. Do we need both? Anything one can do in C# one can also do in VB.NET, and the reverse is true. There is some evidence that Microsoft wants to drop VB.NET -- although there is also evidence that developers want to keep programming in VB.NET. That creates tension for Microsoft.

I suspect that specialty languages such as SQL and JavaScript will remain. SQL has embedded itself in databases, and JavaScript has embedded itself in web browsers.

What about other popular languages? What about COBOL, and FORTRAN, and Python, and R, and Delphi (which oddly still ranks high in the Tiobe index)?

I see no reason for any of them to go away. Each has a large base of existing code; converting those programs to another language would be a large effort with little benefit.

And I think that small, niche languages will remain. Programming languages such as AWK will remain because they are small, easy to use, good at what they do, and they can be maintained by a small team.

The bottom line is that the decision is not practical and logical, but emotional. We have multiple programming languages not because different languages are good at different things (although they are) but because we want multiple programming languages. Programmers become comfortable with programming languages; different programmers choose different programming languages.

Wednesday, June 1, 2022

Ideas for Machine Learning

A lot of what is called "AI" is less "Artificial Intelligence" and more "Machine Learning". The differences between the two are technical and rather boring, so few people talk about them. From a marketing perspective, "Artificial Intelligence" sounds better, so more people use that term.

But whichever term you use, I think we can agree that the field of "computers learning to think" has yielded dismal results. Computers are fast and literal, good at numeric computation and even good at running video games.

It seems to me that our approach to Machine Learning is not the correct one. We've been at it for decades, and our best systems suffer from fragility, providing wildly different answers for similar inputs.

That approach (from what I can tell) is to build a Machine Learning system, train it on a large set of inputs, and then have it match other inputs to the training set. The approach tries to match similar aspects to similar aspects.

I have two ideas for Machine Learning, although I suspect that they will be rejected by the community.

The first idea is to change the basic mechanism of Machine Learning. Instead of matching similar inputs, design systems which minimize errors. That is, balance the identification of objects with the identification of errors.

This is a more complex approach, as it requires some basic knowledge of an object (such as a duck or a STOP sign) and then it requires analyzing aspects and classifying them as "matching", "close match", "loose match", or "not a match". I can already hear the howls of practitioners, switching their mechanisms to something more complex.

But as loud as those complaints may be, they will be a gentle whisper compared to the reaction of my second idea: Switch from 2-D photographs to stereoscopic photographs.

Stereoscopic photographs are pairs of photographs of an object, taken by two cameras some distance apart. By themselves they are simple photographs. Together, they allow for the calculation of depth of objects. (Anyone who has used an old "Viewmaster" to look at a disk of transparencies has seen the effect.)

A stereoscopic photograph should allow for better identification of objects, because one can tell that items in the photograph are in the same plane or different planes. Items in different planes are probably different objects. Items in the same plane may be the same object, or may be two objects in close proximity. It's not perfect, but it is information.

The objections are, of course, that the entire corpus of inputs must be rebuilt. All of the 2-D photographs used to train ML systems are now invalid. Worse, a new collection of stereoscopic photographs must be taken (not an easy task), stored, classified, and vetted before they can be used.

I recognize the objections to my ideas. I understand that they entail a lot of work.

But I have to ask: is the current method getting us what we want? Because if it isn't, then we need to do something else.

Friday, May 27, 2022

The promise of Windows

Windows made a promise to run on various hardware, and allow different hardware platforms. This was a welcome promise, especially for those of us who liked computers other than the IBM PC.

At the time Windows was introduced, the IBM PC design was popular, but not universal. Some manufacturers had their own designs for PCs, different from the IBM PC. Those other PCs ran some software that was designed for IBM PCs, but not all software. The Victor 9000 and the Zenith Z-100 were PCs that saw modest popularity, running MS-DOS but with different specifications for keyboards, video, and input-output ports.

Some software was released in multiple versions, or included configuration programs, to match the different hardware. Lotus 1-2-3 had packages specific to the Z-100; WordStar came with a setup program to define screen and keyboard functions.

Buying hardware and software was a big effort. One had to ensure that the software ran on the hardware (or could be configured for it) and that the hardware supported the software.

Windows promised to simplify that effort. Windows would act as an intermediary, allowing any software (if it ran on Windows) to use any hardware (if Windows ran on it). Microsoft released Windows for different hardware platforms (including the Zenith Z-100). The implications were clear: Windows could "level the playing field" and make those other PCs (the ones not compatible with the IBM PC) useful and competitive.

That promise was not fulfilled. Windows ran on various computing hardware, but the buyers were trained to look for IBM PCs or compatibles, and they stayed with IBM PCs and compatibles. It didn't matter that Windows ran on different computers; people wanted IBM PCs, and they bought IBM PCs. The computers that were different were ignored and discontinued by their manufacturers.

And yet, Windows did keep its promise of separating software from hardware and allowing programs to run on different hardware. We can look at the history of Windows and see its growth over time, and the different hardware that it supported.

When USB was introduced, Windows supported it. (The implementation was rough at first, but Microsoft improved it.)

As displays improved and display adapters improved, Windows supported them. One can attach almost any display unit, and any display adapter to a PC and Windows can use them.

Printers and scanners have the same story. Windows supported lots of printers, from laserjets to inkjets to dot-matrix printers.

Much of this success is due to Microsoft and its clear specifications for adapters, displays, printers, and scanners. But those specifications allowed for growth and innovation.

Microsoft supported different processors, too. Windows ran on Intel's Itanium processors, and DECs Alpha processors. Even now Microsoft has support for ARM processors.

Windows did keep its promise, albeit in a way that we were not expecting.


Thursday, May 19, 2022

More than an FPU, less than a GPU

I think that there is an opportunity to enhance, or augment, the processing units in our current PCs.

Augmenting processors is not a new idea. Intel supplied numeric coprocessors for its 8086, 80286, and 80386 processors. These coprocessors performed numeric computations that were not natively available on the main processor. The main processor could perform the calculation, but the coprocessors were designed for numeric functions and performed the work much faster.

(Intel did not invent this idea. Coprocessors were available on minicomputers before PCs existed, and on mainframes before minicomputers existed.)

A common augmentation to processors is the GPU. Today's GPUs are in a combination of video adapter and numeric processor. They drive a video display, and they also perform graphic-oriented processing. They often use more power than the CPU, and perform more computations than the CPU, so one could argue that the GPU is the main processor, and the CPU is an auxiliary processor that handles input and output for the GPU.

Let's consider a different augmentation to our PC. We can keep the CPU, memory, and input-output devices, but let's replace the GPU with a different processor. Instead of a graphics-oriented processor that drives a video display, let's imagine a numeric-oriented processor.

This numeric-oriented processor (let's call it a NOP*) is different from the regular GPU. A GPU is designed, in part, to display images, and our NOP does not need to do that. The NOP waits for a request from the CPU, acts on it, and provides a result. No display is involved. The request that we send to the NOP is a program, but to avoid confusion with our main program, let's call it a 'subprogram'.

A GPU does the same, but also displays images, and therefore has to operate in real-time. Therefore, we can relax the constraints on our NOP. It has to be fast (faster at computations than the CPU) but it does not have to be as fast as a GPU.

And as a NOP does not connect to a display, it does not need to have a port for the display, nor does it need to be positioned in a PC slot for external access. It can be completely in the PC, much like memory modules are attached to the motherboard.

Also, our NOP can contain multiple processors. A GPU contains a single processor with multiple cores. Our NOP could have a single processor with multiple cores, or it could have multiple processors, each with multiple cores.

A program with multiple threads runs on a single processor with multiple cores, so a NOP with one processor can one run 'subprogram' that we assign to it. A NOP with multiple processors (each with multiple cores) could run multiple 'subprograms' at a time. A simple NOP could have one processor, and a high-end NOP could have multiple processors.

Such a device is quite possible with our current technology. The question is, what do we do with it?

The use of a GPU is obvious: driving a video card.

The use of a NOP is... less obvious.

It's less obvious because a NOP is a form of computing that is different from our usual form of computing. Our typical program is a linear thing, a collection of instructions that are processed in sequence, starting with the first and ending with the last. (Our programs can have loops and conditional branches, but the idea is still linear.)

Our NOP is capable of performing multiple calculations at the same time (multiple cores) and performing those calculations quickly. To use a NOP, one must have a set of calculations that can run in parallel (not dependent on each other) and with a large set of data. That's a different type of computing, and we're not accustomed to thinking in those terms. That's why the use of a NOP is not obvious.

There are several specialized applications that could use a NOP. We could analyze new designs for automobiles or airplanes, simulate protein folding, explore new drugs, and analyze buildings for structural integrity. But these are all specialized applications.

To justify a NOP as part of a regular PC, we need an application for the average person. Just as the spreadsheet was the compelling application for early PCs, and GPS and online maps were the compelling app for cell phones, we need a compelling app for a NOP.

I don't know what such an application be, but I know something of what it would look like. A NOP, like a GPU, has a processor with many cores. Today's GPUs can have in excess of 6000 cores (which exceed today's CPUs that have a puny dozen or two). But cores don't automatically make your program run faster. Cores allow a program with multiple threads to run faster.

Therefore, a program that takes advantage of a NOP would use multiple threads -- lots of them. It would perform numerical processing (of course) and it would operate on lots of data. The CPU would act as a dispatcher, sending "jobs" to the NOP and coordinating the results.

If our PCs had NOPs built in, then creative users would make programs to use them. But our PCs don't have NOPs built in, and NOPs cannot be added, either. The best we can do is use a GPU to perform some calculations. Many PCs do have GPUs, and some are used for numeric-oriented programming, but the compelling application has not emerged.

The problem is not one of technology but one of vision and imagination.

- - - - -

* I am quite aware that the term NOP is used, in assembly language, for the "no operation" instruction, an instruction that literally does nothing.

Thursday, May 5, 2022

C but for Intel X86

Let's step away from current events in technology, and indulge in a small reverie. Let's play a game of "what if" with past technology. Specifically the Intel 8086 processor.

I will start with the C programming language. C was designed for the DEC PDP-7 and PDP-11 processors. Those processors had some interesting features, and the C language reflects that. One example is the increment and decrement operators (the '++' and '--' operators) which map closely to addressing modes on the DEC processors.

Suppose someone had developed a programming language for the Intel 8086, just as Kernighan and Ritchie developed C for the PDP-11. What would it look like?

Let's also suppose that this programming language was developed just as the 8086 was designed, or shortly thereafter. It was released in 1978. We're looking at the 8086 (or the 8088, which has the identical instruction set) and not the later processors.

The computing world in 1978 was quite different from today. Personal computers were just entering the market. Apple and Commodore had computers that used the 6502 processor; Radio Shack had computers that used the Z-80 and the 68000.

Today's popular programming languages didn't exist. There was no Python, no Ruby, no Perl, no C#, and no Java. The common languages were COBOL, FORTRAN, BASIC, and assembler. Pascal was available, for some systems. Those would be the reference point for a new programming language. (C did exist, but only in the limited Unix community.)

Just as C leveraged features of the PDP-7 and PDP-11 processors, our hypothetical language would leverage features of the 8086. What are those features?

One feature that jumps out is text strings. The 8086 has instructions to handle null-terminated text. It seems reasonable that an 8086-centric language would support them. They might even be a built-in type for the language. (Strings do require memory management, but that is a feature of the run-time library, not the programming language itself.)

The 8086 supports BCD (binary-converted decimal) arithmetic. BCD math is rare today, but it was common on IBM mainframes and a common way to encode data for exchange with other computers.

The 8086 had a segmented architecture, with four different segments (code, data, stack, and "extra"). Those four segments map well to Pascal's organization of code, static data, stack, and heap. (C and C-derivatives use the same organization.) A language could support dynamic allocation of memory and recursive functions (two things that were not available in COBOL, FORTRAN, or BASIC). And it could also support a "flat" organization like those used in COBOL and FORTRAN, in which all variables and functions are laid out at link time and fixed in position.

There would be no increment or decrement operators.

Who would build such a language? I suppose a natural choice would be Intel, as they knew the processor best. But then, maybe not, as they were busy with hardware design, and had no operating system on which to run a compiler or interpreter.

The two big software houses for small systems (at the time) were Microsoft and Digital Research. Both had experience with programming languages. Microsoft provided BASIC for many different computer systems, and also had FORTRAN and COBOL. Digital Research provided CBASIC (a compiled BASIC) and PL/M (a derivative of IBM's PL/I).

IBM would probably not create a language for the 8086. They had no offering that used that processor. The IBM PC would arrive in 1981, and IBM didn't consider it a serious computer -- at least not until people started buying them in large quantities.

DEC, at the time successful with minicomputers, also had no offering that used the 8086. DEC offered many languages, but used their own processors.

Our language may have been developed by a hardware vendor, such as Apple or Radio Shack, but they like Intel were busy with hardware and did very little in terms of software.

So it may have been either Microsoft or Digital Research. Both companies were oriented for business, so a language developed by either of them would be oriented for business. A new language for business might be modelled on COBOL, but COBOL didn't allow for variable-length strings. FORTRAN was oriented for numeric processing, and it didn't handle strings either. Even Pascal had difficulty with variable-length strings.

My guess is that our new language would mix elements of each of the popular languages. It would be close to Pascal, but with more flexibility for text strings. It would support BCD numeric values, not only in calculations but also in input-output operations. The language would be influenced by COBOL's verbose approach to a language.

We might see something like this:

PROGRAM EXAMPLE
DECLARE
  FILE DIRECT CUSTFILE = "CUST.DAT";
  RECORD CUSTREC
    BCD ACCTNUM PIC 9999,
    BCD BALANCE PIC 9999.99;
    STRING NAME PIC X(20);
    STRING ADDRESS PIC X(20);
  FILE SEQUENTIAL TRANSFILE = "TRANS.DAT";
  RECORD TRANSREC
    BCD ACCTNUM PIC 9999,
    BCD AMOUNT PIC 999.99;
  STRING NAME;
  BCD PAYMENT,TAXRATE;
PROCEDURE INIT
  OPEN CUSTFILE, TRANSFILE;
PROCEDURE MAINLINE
  WHILE NOT END(TRANSFILE) BEGIN
    READ TRANSFILE TO TRANSREC;
  END;
CALL INIT;
CALL MAINLINE;

and so forth. This borrows heavily from COBOL; it could equally borrow from Pascal.

It may have been a popular language. Less verbose than COBOL, but still able to process transactions efficiently. Structured programming from Pascal, but with better input-output. BCD data for efficient storage and data transfer to other systems.

It could have been a contender. In an alternate world, we could be using programming languages derived not from C but from this hybrid language. That might solve some problems (such as buffer overflows) but maybe given us others. (What problems, you ask? I don't know. I just now invented the language, I'll need some time to find the problems.)


Sunday, May 1, 2022

Apple wants only professional developers

Apple got itself some news this past week: It sent intimidating letters to the developers of older applications. Specifically, Apple threatened to expel old apps -- apps that had not been updated in three years -- from the iTunes App Store. (Or is it the Apple App Store?)

On the surface, this seems a reasonable approach. Apple has received complaints about the organization of the App Store, and the ability (or lack thereof) to find specific apps. By eliminating older apps, Apple can reduce the number of apps in the store and improve the user experience.

But Apple showed a bit of its thinking when it sent out the notice. It specified a grace period of 30 days. If the developers of an app submitted a new version, the app could remain in the App Store.

The period of 30 days calls my attention. I think it shows a lack of understanding on Apple's part. It shows that Apple thinks anyone can rebuild and resubmit their app in less than one month.

For professional teams, this seems a reasonable limit. Companies that develop apps should be familiar with the latest app requirements, have the latest tools, and have processes to release a new version of their app. Building apps is a full-time job, and they should be ready to go.

Individuals who build apps "for fun" are in a different situation. For them, building apps is not a full-time job. They probably have a different full-time job, and building apps is a side job. They don't spend all day working on app development, and they probably don't have the latest tools. (They may not even have the necessary equipment to run the compilers and packager necessary to meet Apple's requirements.) For them, the 30-day period is an impossible constraint.

Apple, in specifying that limit, showed that it does not understand the situation of casual developers. (Or, more ominously, deliberately chose to make life difficult for casual developers. I see no evidence of hostility, so I will credit this limit to ignorance.)

In either case (ignorance or malice) Apple thinks -- apparently -- that developers can spin out new versions of their apps quickly. In the long term, this will become true. Casual developers will give up on Apple and stop developing their apps. (They may also drop Apple's products. Why buy a phone that won't run their app?)

As casual developers leave the field, only the serious developers will remain. Those will be the commercial developers, or the professional developers who are paid by corporations.

That sets the Apple environment as a commercial platform, one that serves commercially-developed apps for commercial purposes. The Apple platform will have online banking, email, commercial games, video streaming, location tracking for auto insurance, and other apps in the realm of commerce. But it will have very few fun apps, very few apps built by individuals for enjoyment. Every app will have a purpose, and that purpose will be to make money, either directly or indirectly.

Yet it doesn't have to be this way. Apple has an alternative, if they want it.

Right now, the Apple App Store is a single store. Apple could change that, splitting the App Store into multiple stores, or a single store with sections. One section could be for the commercial apps and another section for the amateur apps. The commercial section will have the tighter restrictions that Apple wants to ensure a good experience for users (updated apps, recent APIs, etc.) and the amateur section will hold the casually-built apps. But the two sections are not equal: apps in the commercial section are allowed to use API calls for payments, and apps in the amateur section are not. (Apple could limit other APIs too, such as biometrics or advertising.)

A two-tiered approach to the App Store gives the developers of iOS apps a choice: play in the pro league, or play in the amateur league. It may be an approach worth considering.

Wednesday, April 20, 2022

Advances in programming come from restraints

Advances in programming come from, to a large extent, advances in programming languages. And those advances in programming languages, unlikely as it seems, are mostly not expanded features but restrictions.

That advances come from restrictions seems counter-intuitive. How does fewer choices make us better programmers?

Let's look at some selected changes in programming languages, and how they enabled better programming.

The first set of restrictions was structured programming. Structured programming introduced the concepts of the IF/THEN/ELSE statement and the WHILE loop. More importantly, structured programming banished the GOTO statement (and its cousin, the IF/GOTO statement). This restriction was an important advancement for programming.

A GOTO statement allows for arbitrary flows of control within programs. Structured programming's IF/THEN/ELSE and WHILE statements (and WHILE's cousin, the FOR statement) force structure onto programs. Arbitrary flows of control were not possible.

The result was programs that were harder to write but easier to understand, easier to debug, and easier to modify. Structured programming -- the loss of GOTO -- was an advancement in programming.

A similar advance occurred with object-oriented programming. Like structured programming, object-oriented programming was a set of restrictions coupled with a set of new features. In object oriented programming, those restrictions were encapsulation (hiding data within a class) and the limiting of functions (requiring an instance of the class to execute). Data encapsulation protected data from arbitrary changes; one had to go through functions (in well-designed systems) to change the data. Instance functions were limited to executing on instances of the class, which meant that one had to *have* an instance of the class to call the function. Functions could not be called at arbitrary points in the code.

Both structured programming and object-oriented programming advanced the state of the art for programming. They did it by restricting the choices that programmers could make.

I'm going to guess that future advancements in programming will also come from restrictions in new programming languages. What could those restrictions be?

I have a few ideas.

One idea is immutable objects. This idea has been tested in the functional programming languages. Those languages often have immutable objects, objects which, once instantiated, cannot change their state.

In today's object-oriented programming languages, objects are often mutable. They can change their state, either through functions or direct access of member data.

Functional programming languages take a different view. Objects are immutable: once formed they cannot be changed. Immutable objects enforce discipline in programming: you must provide all of the ingredients when instantiating an object; you cannot partially initialize an object and add things later.

I would like to see a programming language that implements immutable objects. But not perfectly -- I want to allow for some objects that are not immutable. Why? Because the shift to "all objects are immutable" is too much, too fast. My preference is for a programming language to encourage immutable designs and require extra effort to design mutable objects.

A second idea is a limit to the complexity of expressions.

Today's programming languages allow for any amount of complexity in an expression. Expressions can be simple (such as A + 1) or complex (such as A + B/C - sqr(B + 7) / 2), or worse.

I want expressions to be short and simple. This means breaking a complex expression into multiple statements. The only language that I know that placed restrictions on expressions was early FORTRAN, and then only for the index to an array variable. (The required form was I*J+K, where I, J, and K were optional.)

Perhaps we could design a language that limited the number of operations in an expression. Simpler expressions are, well, simpler, and easier to understand and modify. Any expression that contained more than a specific number of operations would be an error, forcing the programmer to refactor the expression.

A third idea is limits on the size of functions and classes. Large functions and large classes are harder to understand than small functions and small classes. Most programming languages have a style-checker, and most style-checkers issue warnings for long functions or classes with lots of functions.

I want to strengthen those warnings and change them to errors. A function that is too long (I'm not sure how long is too long, but that's another topic) is an error -- and the compiler or interpreter rejects it. The same applies to a class: too many data members, or too many functions, and you get an error.

But like immutable objects, I will allow for some functions to be larger than the limit, and some classes to be more complex than the limit. I recognize that some classes and functions must break the rules. (But the mechanism to allow a function or class to break the rules must be a nuisance, more than a simple '@allowcomplex' attribute.)

Those are the restrictions that I think will help us advance the art of programming. Immutable objects, simple expressions, and small functions and classes.

Of these ideas, I think the immutable objects will be the first to enter mainstream programming. The concept has been implemented, some people have experience with it, and the experience has been positive. New languages that combine object-oriented programming with functional programming (much like Microsoft's F#, which is not so new) will allow more programmers to see the benefits of immutable objects.

I think programming will be better for it.

Tuesday, March 22, 2022

Apple has a software problem

Apple has a problem. Specifically, Apple has a software problem. More specifically, Apple has a problem between its hardware and its software. The problem is that Apple's hardware is getting bigger and more powerful at a much faster rate than its software.

Why is better hardware a problem? By itself, better hardware isn't a problem. But hardware doesn't exist by itself -- we use hardware with software. Faster, more powerful hardware requires bigger, more capable software.

One might think that fast hardware is a good thing, regardless of software. Faster hardware runs software faster, right? And faster is always a good thing, right? Well, not always.

For software that operates on a large set of data, such that the user is waiting for the result, yes, faster hardware is better. But faster hardware is only better if the user is waiting. Software that operates in "batch mode" or with limited interaction with the user is improved with better hardware. But software that interacts with the user, software that must wait for the user to do something, isn't necessarily improved.

Consider the word processor, a venerable tool that has been with us since the introduction of the personal computer. Word processors spend most of their time waiting for the user to press a key. This was true even with computers from prior to the IBM PC. In the forty-odd years since, hardware has gotten much, much faster but word processors have not gotten much more complicated. (There was a significant increase in complexity when we shifted from DOS and its character-based display and printing to Windows and graphics-based display and printing, but very little otherwise.)

The user experience for word processors has changed little in that time. Faster hardware has not improved the experience. If we limited computers to word processors, there would be no need for a processor more powerful than the Intel 80386. By extension, if you needed a computer for word processing (and nothing else) today's bottom-of-the-line, cheap, minimal computer would be more than enough for you. There is no point in spending on a premium computer (or even a mediocre one) because the minimal computer can do the job adequately.

The same logic applies to spreadsheets. And e-mail. And web browsers. Computers have gotten better faster than these programs and their data have gotten bigger.

The computers I use for my day-to-day and even unusual tasks are old PCs, ranging from five to twenty years in age. All of them are fast enough for what I need to do. An aged Dell Inspiron N5010 runs Windows 10 and lets me use Zoom and Teams to join virtual meetings. I could replace it with a modern laptop, but the experience would be the same! Why should I bother?

A premium computer is needed only for those tasks that perform complex operations on  large sets of data. And this is where Apple fails to provide the tools to justify its powerful (and expensive) hardware.

Apple is focussed on hardware, and it does a terrific job of designing and manufacturing powerful computers. But software is another story. Apple develops applications and then seems to lose interest in them. It built Pages, Numbers, and Keynote, and has made precious few improvements -- other than recompiling for ARM processors, or adding support for things like AirPlay. It hasn't added features.

The same goes for applications such as GarageBand, iTunes, and FaceTime. Even Xcode.

Apple has even let utilities such as grep and sed in MacOS (excuse me, "mac os". Or is it "macos"?) are aging with no updates. The corresponding GNU utilities have been modified and improved in various ways, to the point that developers now recommend the installation of the GNU utilities on Apple computers.

Apple may be waiting for others to build the applications that will take advantage of the latest Mac computers. I'm not sure that many will want to do that.

Building applications to leverage the new Apple processors may seem a no-brainer. But there are a number of disincentives.

First, Apple may build their own version of the application, and compete with the vendor. Independent vendors may be reluctant to enter a market when Apple is a possible competitor.

Second, developing applications to take advantage of the M1 architecture requires a lot of time and effort. The application must be multithreaded -- single-threaded applications cannot fully leverage the multiple cores on the M1. Designing, coding, and testing such an application is a lot of work.

Third, the market is limited. Applications developed to take advantage of the M1 processor are, well, developed for the M1 processor. They won't run on Windows PCs. You can't cross-build to run on Windows PCs, because PC processors are much slower than the Apple processors. The set of potential customers is limited to those who have the upper-end Apple computers. That's a small market (compared to Windows) and the potential revenue may not cover the development costs.

That is an intimidating set of disincentives.

So if Apple isn't building applications to leverage the upper-end Macs, and third-party developers aren't building applications to leverage upper-end Macs, then ... no one is building them! The result being that there are no applications (or very few) to take advantage of the higher-end processors.

I expect sales of the M1-based Macs to be robust, for a short time. But as people realize that their experience has not improved (except, perhaps for "buttery smooth" graphics) they will hesitate for the next round of new Macs (and iPads, and iPhones). As customers weigh the benefits and costs of new hardware, some will decide that their current hardware is good enough. (Just as my 15-year-old PCs are good enough for my simple word processing and spreadsheet needs.) If Apple introduces newer systems with even faster processors, more people will look at the price tags and decide to wait before upgrading.

Apple is set up to learn an important lesson: High-performance hardware is not enough. One needs the software to offer solutions to customers. Apple must work on its software.


Monday, March 14, 2022

Developer productivity is not linear

The internet has recently castigated an anonymous CEO who wanted his developers to work extra hours (without an increase in pay, presumably). Most of the reactions to the post have focussed on the issue of fairness. (And a not insignificant number of responses have been... less than polite.)

I want to look at a few other aspects of this issue.

I suspect that the CEO thinks he wants employees to have the same enthusiasm for the company that he himself has. He may want employees to put in extra hours and constantly think about improvements and new ideas, just as he does. But while the CEO (who is probably the founder) may be intrinsically motivated to work hard, employees may not share that same intrinsic motivation. And the CEO may be financially motivated to make the company as successful as possible (due to his compensation and stock holdings), but employees are typically compensated through wages and nothing else. (Some companies do offer bonuses; we have no information about compensation in this internet meme.) A salary alone is not enough to make employees work longer hours.

But its not really motivation, or enthusiasm, or a positive attitude that the CEO wants.

What the CEO wants, I think, is an increase in productivity. Making developers work extra, uncompensated hours is, in one sense, an increase in productivity. The developers will contribute more to the project, at no additional cost to the company. Thus, the company sees an increase in productivity (an increase in output with no increase in inputs).

Economists will point out that the extra work does have a cost, and that cost is borne by the employees. Thus, while the company doesn't pay for it, the cost does exist. It is an "externality" in the language of economists.

But these are small mistakes. The CEO is making bigger mistakes.

One big mistake is the thinking that developer productivity is linear. That is, thinking that if a developer can do so much (let's call it N) in one hour, then that same developer can do 2N in 2 hours, 4N in 4 hours, and so forth. This leads to the conclusion that by working an extra 2 hours each day (from 8 hours to 10 hours) then the developer provides 10N units of productivity instead of 8N units. This is not true; developers get tired like anyone else and their productivity wanes as they tire. Even if all of the hours are paid, developer productivity can vary.

Beyond simply tiring, the productivity of a developer will vary throughout a normal workday, and good developers recognize the times that are best for the different tasks of analysis, coding, and debugging.

A second big mistake is thinking that the quality of a developer's work is constant, and unaffected by the number of hours worked. This is similar to the first mistake, but somewhat different. The first mistake is about quantity; this mistake is about quality. The act of writing (or fixing) a computer program is a creative one, requiring a programmer to draw on knowledge and experience to devise correct, workable, and efficient solutions. Programmers who are tired make mistakes. Programmers who are under stress from personal issues make mistakes. (Programmers who are under stress from company-generated issues also make mistakes.) Asking programmers to work longer hours increases mistakes and reduces quality.

If one wants to increase the productivity of developers, there are multiple ways to do it. Big gains in productivity can come from automated tests, good tools (including compilers, version control, and debuggers), clear and testable requirements, and respect in the office. But these changes require time to implement, some require expenditures, and most have delayed returns on the investments.

Which brings us to the third big mistake: That gains in productivity can occur rapidly and for little to no cost. The techniques and tools that are effective at improving productivity require time and sometimes money.

Asking programmers to work longer hours is easy to implement, can be implemented immediately, and requires no expenditure (assuming you do not pay for the extra time). It requires no additional tools, no change to process, and no investment. On the surface, it is free. But it does have costs -- it costs you the goodwill of your team, it can cause an increase in errors in the code, and it can encourage employees to seek employment elsewhere.

There is little to be gained, I think, by saying impolite things to the CEO who wants longer hours from his employees. Better to look to our own houses, and our own practices and procedures. Are we using good tools? How can we improve productivity? What changes will it require?

Improving our productivity is a big task -- as big as we choose to make it. Let's use proven techniques and respect our employees and colleagues. I think that will give us better results.