Thursday, June 25, 2020

A new old web

One idea I have been pondering is a retro version of the world wide web. This "new old web" would be a world-wide web as it originally existed: a collection of static web pages with links to other web pages, either on the same site or on other sites.

The defining aspects of this new old web are what it doesn't have: HTTPS, certificates, cookies, and JavaScript. It would be a simpler version, and an unsecure version, of today's web.

Why do this? Why re-create the old web, one that does not have HTTPS and therefore security?

In a word, permanence.

The current web all but requires HTTPS, which in turn requires security certificates, which in turn expire and therefore require replacements. All of that means that a web site needs maintenance, every 12 months or whenever the certificates expire.

What I am considering is a web that lets one set up a web server and leave it running with no maintenance. Perhaps one could apply updates to the operating system and occasionally blow dust out of the box, but that's it. No annual dance for certificates. Maybe one does not even update the operating system.

Why do this? Mostly as a thought experiment, to see where it leads us. So let's start with these conditions and see where we go. 

This new old web could have web sites that exist for years, or even decades.

Of course, without certificates, one cannot support HTTPS.

Without HTTPS, one cannot transact business. No banking, no credit card statements, and no purchases.

Without HTTPS, one cannot securely log in to a web site, so no personalized web sites. No Facebook, no Twitter, no e-mail.

Such a web would need a new web browser. Current web browsers dislike HTTP connections, and warn that the page is insecure. (We may be a few years away from requiring HTTPS for all links and URLs.) So with current web browsers deprecating HTTP, perhaps we need a new HTTP-only browser.

A new HTTP-only browser would request and load pages over HTTP connections. It would not request an HTTPS connection. A link to HTTPS would be considered an ill-formed link and not valid.

If I'm building a new browser, I can make other changes.

I banish cookies. This prevents third-party cookies and tracking. Overall, this is an enhancement to privacy.

Scripts are also forbidden. No JavaScript or any scripts of any type. The HTML <script> tag must render as text. This eliminates the threat of cross-site scripting.

Web pages may contain text, HTML, and CSS.

One could use PHP, JSP, ASP or ASPX on the server side to render web pages, although the possible uses may be limited. (Remember, no logins and no user IDs.)

It seems that such a web would be mostly static web pages, serving documents and images. I suppose one could serve videos. One could, of course, link from one page to the next.

My idea is not to replace the existing web. The existing web, while it started as this earlier, static web, has evolved into a different thing, one that is quite useful.

My idea is to create a second web, one that exists in parallel to the current web. I would like to try it, just to see what people would do with it. Instead of a web with private areas for private data (e-mail, Facebook, online banking, music that has been purchased, etc.) we would have a web where everything is available to everyone.

How would we act in such a space? What would we create?

That is what I have been pondering.

Thursday, June 18, 2020

Apple is stuck in its own revenue trap

The "Hey" e-mail app got a bit of attention this week. Made by BaseCamp, and published on iOS (and therefore subject to the terms and conditions of the iOS App Store), Apple rejected version 1.0.1, claiming that the app did not meet its guidelines. Two aspects made this rejection notable: version 1.0 was approved (and version 1.0.1 is minimally different), and Apple decided to "clarify" its terms and conditions after many people complained that the app was, in fact, in compliance with the published terms and conditions. (Apple's clarification was that certain rules apply to "business apps" and different rules apply to "consumer apps", and that the "Hey" e-mail app was out of compliance because it did not provide Apple with 30% of its revenue.)

Lost in the noise about the "Apple tax" and clarity of terms and conditions and consistency of rulings on said terms and conditions is an aspect of Apple that we may want to ponder.

Apple justifies its 30% cut of in-app revenue by offering the platform and services.

iOS is a capable platform. It does a lot. One can argue that the 30% rate is too high (or too low). One can argue that Apple holds a monopoly on apps for iOS.

I want to think about something else: Apple's model of computing, which allows it to justify the "tax".

Those services assume a specific model of computing. Not cloud computing, not web services, not distributed computing. A model of computing that was dominant in the 1970s (when Apple was founded) and the early 1980s. The model of local computing, of personal computing.

In this model, apps run on phones and applications run on laptops and desktops (and the Mac Pro tower). Apps and applications communicate with the user through the user interface. Everything happens on the local device. For Apple iPhones and MacBooks, computing occurs on those devices.

Compare that model to the model used by Google's Chromebook. In that model, the Chromebook is a simple device that sends requests to servers (the cloud) and simply presents the results. (IT professionals of a certain age will recognize this model as a variant of the 1960s timesharing, or IBM's terminals to mainframes. Both used simple terminals to invoke actions on the remote system.)

Back to Apple.

Apple must keep this model of local computing, to justify their take of revenue. They cannot move to a Chromebook model. If they did, they would lose their reason for the 30% tax. Developers are angry enough now at Apple, and while some decline to write for the iOS platform, many others "pay the tax" albeit grudgingly.

But what happens when computing moves to the cloud? A cloud-based app does little on the phone. The computing is on the servers. The app, at best, presents a UI and sends requests to the servers. Is the UI and an HTTP stack enough to justify the 30% "tax"? It's my opinion that such a simple system does not, and therefore Apple must keep apps in the older model of local computing, in which an app uses many services.

Apple has built a nice operating system and platform with its iOS, and it has built a trap with its App Store and 30% revenue cut. Apple is loath to give up that revenue. To keep that revenue, it needs to provide the services that it proudly hawks.

So, as I see it, Apple is stuck. Stuck with local computing, and stuck with a relatively complex platform. I expect Apple, for at least the short to middle term, to stay with this model. That means that apps on iPhone and iPad will stay in the local computing model, when means that they will be complex -- and difficult to support.

In the long run, I think Apple will move to a cloud-based model of computing, but only after everyone else, and only when Apple starts losing business. It will be a difficult transition, and one that may require new management of Apple. Look for a run of quarters with disappointing earnings, and a change in leadership, before Apple changes its App Store policies.

Thursday, June 11, 2020

The computer of Linus Torvalds

My experience as developer ranges from solo artist to member of large, enterprise projects. That experience has given me various insights about hardware, operating systems, programming languages, teamwork, and management.

One observation is about a combination of those aspects, specifically hardware and development teams: The minimum hardware requirements for a system are (most likely) the hardware that the developers are using. If you equip developers with top-of-the-line hardware, the system when delivered will require top-of-the-line hardware to run acceptably. As a corollary, if you equip developers with mid-line hardware, the delivered system will run acceptably on that level of hardware.

Developers may often complain about slow hardware, and point out that top-level hardware is not that expensive, and may actually reduce expenses once you factor in the time to pay developers to wait for slow compiles and tests. That is a valid point, but it loses sight of the larger point of a system that performs for a user with hardware that is less than top-of-the-line.

With fast hardware, developers do not see the performance problems. With slower hardware, developers are aware of performance issues, and build a better system. (Or at least one that runs faster.)

Which brings us to Linux Torvalds, the chief developer for the Linux kernel. More specifically, his computer.

A recent article on slashdot lists the specifications of his new computer. It sounds really nice. Fast. Powerful. And just what will lead Torvalds (and Linux) into the "performance trap". Such a computer will hide performance issues from Linus. That may send Linux into a direction that lets it run well on high-end hardware, and not so well on lower-end hardware or older systems.

With a high-end system to run and test on, Torvalds will miss the feedback when some changes have negative affects on performance on slower hardware. Those changes may work "just fine" on his computer, but not so well on other computers.

I recognize that the development effort of the Linux kernel has a lot of contributors, not all of whom have top-level hardware. Those developers may see performance issues. They may even raise them. But do they have a voice? Will their concerns be heard, and addressed? Or will Torvalds reject the issues as complaints and arrogantly tell those developers get "real computers and stop whining". His reputation suggests the latter.

If Torvalds does fall into the "performance trap" it may have significant effects on the future success of Linux. Linux may become "tuned" to high-performance hardware, running acceptably on expensive systems but slow and laggy on cheaper hardware. It may run well on new equipment but poorly on older systems.

That, in turn, may force users of older, slower hardware to re-think their decision to use Linux.


Thursday, May 28, 2020

After the quarantine, think

The 2020 quarantine, with its spate of "stay at home" orders and closure of offices, has enabled (forced?) may companies to implement "work from home" procedures that allow employees to, well, work from home. For some companies, this was a small change, as they already had procedures and infrastructure in place to allow employees to work from remote locations. For other companies, it was a big change.

As various parts of the country rescind the "stay at home" orders, companies are free to resume work as normal. It is my position that, instead of simply requiring employees to report to the office as before, companies (and their managers) think about what is best for the company.

Companies now have experience with remote work. In the past, one reason to stay with "work at the office" (the traditional arrangement of everyone working in a single office) was that managers could not be sure that "work from home" (or, more generally, "work from anywhere") would work for the company. The lack of experience made such a change risky. That excuse is no longer valid. Companies now have several weeks of experience with remote work.

But I am not suggesting that companies blindly adopt "work from home" for all employees. Nor I am suggesting that companies abandon remote work and require employees to work in the office.

Instead, I recommend that managers review the performance of the past few weeks, identify the strengths and weaknesses of remote work, and agree on a plan for the future. Some companies may be happy with remote work and decide to continue with it. Other companies may revert to "work at the office". A third group will choose a middle ground, with some employees remote and others in the office, or remote work for a portion of the week.

I am sure that managers are aware of the costs of maintaining an office building, and will view the path of remote work as a way to reduce those costs. Remote work also allows for expansion of the workforce without a corresponding expansion (and cost) of office space.

"Work in the office" on the other hand allows for all work to be done in a single location, which may make it easier to interact with people. Face-to-face communication is more effective than e-mail, voice phone, and video calls. A single office building also keeps the IT infrastructure in one place, with no need (or cost) for remote access and the accompanying security.

The 2020 pandemic and quarantine gave us information about remote work. It would be foolish for managers to ignore that information when deciding how to run their company.

Thursday, May 21, 2020

The lessons we programmers learn

We in the programming industry learn from our mistakes, and we create languages to correct our mistakes. Each "generation" of programming language takes the good aspects of previous languages, drops the bad aspects, and adds new improved aspects. (Although we should recognize that "good", "bad", and "improved" are subjective.) Over time, our "programming best practices" are baked into our programming languages.

We learned that assembly language was specific to hardware and forced us to think too much about memory layouts, so we invented high-level languages. COBOL and FORTRAN allowed us to write programs that were portable across computers from different vendors and let us specify variables easily. (I won't say "memory management" here, as early high-level languages did not allow for dynamic allocation of memory the way C and C++ do.)

COBOL, FORTRAN, and BASIC (another high-level language) used GOTO statements and rudimentary IF statements for flow control. We learned that those statements lead to tangled code (some say "spaghetti code"), so we invented structured programming with its "if-then-else" and "do-while" statements. Pascal was one of the first languages to implement structured programming. (It retained the GOTO statement, but it was rarely needed.)

Structured programming was better than non-structured programming, but it was not sufficient for large systems. We learned that large system need more than if-then-else and do-while to organize the code, so we invented object-oriented programming. The programming languages C++, Java, and C# became popular.

Designing new languages seems like a built-in feature of the human brain. And designing new languages that use the best parts of the old languages while replacing the mistakes of the old languages seems like a good thing.

But this arrangement bothers me.

Programmers who learn the whole trail of languages, from assembly to BASIC to C++ to Java, understand the weaknesses of the early languages and the strengths of later languages. But these programmers are few. Most programmers do not learn the whole sequence; they learn only the current languages which have pruned away all of the mistakes.

We programmers often look forward. We want the latest language, the newest database, the most recent operating system. In looking forward, we don't look back. We don't look at the older systems, and the capabilities that they had.

Those old systems (and languages) had interesting features. Their designers had to be creative to solve certain problems. Many of those solutions were discarded as hardware became more powerful and languages became more structured.

Is it possible that we have, in our enthusiasm to improve programming languages, discarded some ideas that are worthy? Have we thrown out a baby (or two) with the bathwater of poor language features?

If we don't look back, if we leave those abandoned features in the dust heap, how would we know?

Thursday, May 7, 2020

COBOL all the way down

Programming languages have changed over time. That's not a surprise. But what surprised me was one particular way in which languages have changed: the importance of libraries.

The first programming languages were designed to be complete. That is, a program or application built in that language would use only that language, and nothing else.

Programs built in COBOL (usually financial applications) use COBOL and nothing else. COBOL was built to handle everything. A COBOL program is COBOL, all the way down. (COBOL programs can use SQL, which was fitted into COBOL in the 1970s, but SQL is an exception.)

We saw a change in later languages. FORTRAN, BASIC, Pascal, and C provided functions in their run-time libraries. Most of the application was written in the top-level language, with calls to functions to perform low-level tasks such as trigonometric calculations or string operations.

The introduction of IBM's OS/2 and Microsoft's Windows also changed programming. The graphical operating systems provided a plethora of functions. There were functions for graphical output (to displays or printers), input devices (keyboards and mice), memory management, process management, and network functions. It was no longer sufficient to learn the language and its keywords; one had to learn the extra functions too.

Programming languages such as Java and C# provided more libraries and packages, and some of the libraries and packages handled nontrivial tasks. Libraries allowed for a collection of classes and functions, and packages allowed for a collection of libraries in a form that was easily deployed and updated. These additional packages required the programmer to know even more functions.

The trend has been not only an increase in the number of functions, but also the capabilities and sophistication of library functions and classes. Programming is, more and more, about selecting libraries, instantiating classes, and invoking functions, and less and less about writing the functions that perform the work.

We can see this trend continue in recent languages. Many applications in Python and R are use libraries for a majority of the work. In Python and R, the libraries do the work, and the code in Python and R act more like plumbing, connecting classes and functions.

To put this succinctly:

Early programming languages assume that the processing of the application will occur in those languages. Libraries provide low-level operations, such as input-output operations. A COBOL application is a COBOL program with assistance from some libraries.

Recent programming languages assume that the processing will occur in libraries and not user-written code. The expectation is that libraries will handle the heavy lifting. A Python application is one or more libraries with some Python code to coordinate activities.

This change has profound impacts for the future of programming, from system architecture to hiring decisions. It won't be enough to ask a candidate to write code for a linked list or a bubble sort; instead one will ask about library capabilities. System design will depend more on libraries and less on programming languages.

Wednesday, April 22, 2020

Three levels of Python programming

Python programming is not always what we think it is. I now think of Python programming as having three levels, three distinct forms of programming.

The first level is what we typically think of as programming in Python. It is writing Python code. This is the impression one gets when one has an "introduction to Python" class. The first program of "Hello, World" is written in Python, as are the successive programs in the class. Programs become more complex, with the addition of functions and later classes to organize larger and larger programs.

In this level, all of the code is Python. It is Python from top to bottom. And it works, for simple applications.

For some applications, it is not "Python all the way down". Some applications are complex. They must manage large quantities of data, and perform a significant number of calculations, and they must do it quickly. A Python-only solution is not a satisfactory solution, because Python is interpreted and slow.

At this point, programmers include carefully-constructed modules that perform calculations quickly. The modules "numpy" and "scipy" are the common modules, but there are many.

This is the second level of programming in Python. It is not often thought of as "programming in Python" or even "programming". It is more often though of as "importing modules and using the classes and functions in those modules".

That mindset makes sense. This work is less about Python and more about knowing which modules are available and which functions they provide. The task of programming is different; instead of writing all of the code, one assembles a solution from pre-packaged modules and uses Python to connect the various pieces.

That is why I think of it as a second level of programming. It is a different type of programming, a different type of thinking. It is not "how can I write code?" but instead "what existing code will perform this computation?".

Which brings us to the third level.

The third level of Python programming is building your own module. The existing Python modules, if they do what you need, are fast and effective. But if they do not do what you need, then they are not helpful.

Writing your own solution in Python will result is a slow program -- perhaps unacceptably slow. Therefore, as a last resort, one writes one's own module (in C or C++) and imports it into the main Python program.

This is, purists will argue, programming not in Python but in C or C++. They have a point -- it is writing C or C++ code.

But when the objective is to build a system to perform a specific task, and the top layer of the application is written in Python, then one can argue that the C code is merely an extension of the same application.

Or, one can think of the task as creating a system in multiple modules and multiple languages, not a single program in a single programming language, and using the best language for each piece of the system.

Python programming (or systems development) is often less about coding in a particular language and more about solving problems. With Python, we have three levels at which we can solve those problems.