Tuesday, December 29, 2020

For readability, BASIC was the best

One language stands alone in terms of readability.

That language is BASIC.

BASIC -- the old, pre-Visual Basic of the 1980s -- has a unique characteristic: a single line can be read and understood.

One may think that a line from any programming language can be read and understood. After all, we read and understand programs all the time, don't we? That's true, but we read entire programs, or large sections of programs. Those large fragments of programs contain information that defines the classes, functions, and variables in the programs, and we use that information to understand the code. But if we strip away that extra information, if we limit ourselves to a single line, then we cannot read and completely understand the code.

Let's look at an example line of code:

a = b * 5

Can you tell what this code does? For certain? I cannot.

A naive assessment is that the code retrieves the value of variable 'b', multiplies it by 5, and stores the result in the variable 'a'. It is easy to assume that the variables 'a' and 'b' are numeric. Yet we don't know that -- we only assume it.

If I tell you that the code is Python code, and that 'b' refers to a string object, then our understanding of this code changes. The code still performs a 'multiply' operation, but 'multiply' for a string object is very different from 'multiply' for a numeric object.

Instead, if I tell you that the code is C++, then we must identify the type for 'b' (which is not provided in the single line of code) and we must know if the class for 'b' defines the '*' operator. That operation could do anything, from casting b's contents to a number and multiplying 5 to sending some text to 'cout'.

We like to think we understand the code, but instead we are constantly making assumptions about the code and building an interpretation that is consistent with those assumptions.

But the language BASIC is different.

In BASIC, the line

a = b * 5

or, if you prefer

100 LET A = B * 5

is completely defined. We know that the variable B contains a numeric value. (The syntax and grammar rules for BASIC require that a variable with no trailing sigil is a numeric variable.) We also know that the value of B is defined. (Variables are always defined. If not initialized in our code, that have the value 0.) We know the behavior of the '*' operator -- it cannot be overridden or changed. We know that the variable 'A' is numeric, and that it can receive the results of the multiply operation.

We know these things. We do not need other parts of the program to identify the type for a variable, or a possible redefinition of an operator.

This property of BASIC means that BASIC is readable in a way that other programming languages are not. Other programming languages require knowledge of declarations. All of the C-based languages (C, Objective-C, C++, C#, and even Java) require this. Perl, Python, and Ruby don't have variables; they have names that can refer to any type of object. The only other programming language that comes close is FORTRAN II. It might have had the same readability; it had rules for names of variables and functions.

BASIC's readability is possible because it requires the data type of a variable to be encoded in the name of the variable. This is completely at odds with every modern language, which allow variables to be named with no special markings for type. BASIC used static typing; not only static typing, but overt typing -- the type was expressed in the name.

Static, overt typing was possible in BASIC because BASIC used a limited number of types (numeric, integer, single-precision floating point, double-precision floating point, and string) each of which could be represented by a single punctuation character. Each variable name had a sigil for the type. (Or no sigil, in which case the type was numeric.)

Those sigils were so useful that programmers who switched to Visual Basic kept the idea, through the use of programming style conventions that asked for prefixes for each variable. That effort become unwieldy, as there were many types (Visual Basic used many libraries for Windows functions and classes) and there was no all-encompassing standard and no was to enforce a standard.

Overt typing is possible with a language that has a limited number of types. It won't work (or it hasn't worked) for object-oriented languages. Those languages are designed for large systems with large code bases. They have built-in types and allow for user-defined types, with no support to indicate the type in the name of the variable. And as we saw with Visual Basic, expressing the different types is complicated.

But that doesn't mean the idea is useless. Overt typing worked for BASIC, a language that was designed for small programs. (BASIC was meant to be a language for teaching the skills of programming. The name was an acronym: Beginner's All-Purpose Symbolic Instruction Code.) Overt typing might be helpful for a small language, one designed for small programs.

It strikes me that cloud computing is the place for small languages. Cloud computing uses multiple processors to perform calculations, and split code bases. A well-designed cloud application consists of lots of small programs. Those small programs don't have to be built with object-oriented programming languages. I expect to see new programming languages for cloud-based computing, programming languages that are designed for small programs.

I'm not recommending that we switch from our current set of programming languages to BASIC. But I do think that the readability of BASIC deserves some attention.

Because programs, large or small, are easier to understand when they are readable.

Monday, December 21, 2020

Measuring the success of .NET

Microsoft released .NET (and the language C#) in the early 2000s. With almost 20 years of experience, can we say that NET has been a success?

Microsoft, I am certain, will claim that .NET has been a success and continues to be a success. But they have a vested interest in the success of .NET, so their opinion is possibly biased.

It strikes me that Apple's move to ARM processors has provided us with a measure for the success of .NET. How can that be? Well, let's look at programming languages.

Programming languages come in three flavors: compiled, interpreted, and byte-code. Each has a different way of executing instructions to perform the desired calculations.

Compiled languages convert source code into machine code, and that machine code is directly executable by the processor. In today's world, that means (usually) that the compiler produces code for the Intel x86 processor, although other processors can be the "target". Once compiled, the executable form of the program is usable only on a system with appropriate processor. Code compiled for the Intel x86 runs only on the Intel x86 (or a compatible processor such as one from AMD). Notably, the compiled code cannot be used on a different processor, such as the ARM processors. (Apple can run Intel code on its new ARM processors because it emulates the Intel processor. The emulator pretends to be an Intel processor, and the code doesn't know that it is running on an emulator.)

Interpreted languages take a different approach. Instead of converting the source code to executable code, the interpreter parses each line of source code and executes it directly. The importance of this is that a program written in an interpreted language can be run on any processor, provided you have the interpreter.

BASIC, one of the earliest interpreted languages, ran on different processors, including mainframes, minicomputers, and microcomputers. All of them could run the same program, without changes, thus a BASIC program was quite "portable".

In between compiled languages and interpreted languages are the byte-code languages, which are a little bit of interpreter and little bit compiler. Byte-code languages are compiled, but not to a specific processors. Or rather, they are compiled to an imaginary processor, one that does not exist. The code produced by the compiler (often called "byte code") is interpreted by a small run-time system. The idea is that the run-time system can be created for various processors, and the same byte-code can run on any of them.

Java uses the byte-code approach, as does C#, VB.NET (all the .NET languages, actually), and the languages Python, Ruby, Perl, and Raku (and a bunch more).

The languages C, C++, Objective-C, Go, and Swift are compiled to executable code.

I can think of no programming languages that use the pure interpreted approach, at least not nowadays. The two languages that used an interpreted approach were BASIC and FORTH, and there were some implementations of BASIC that were byte-code and some even were fully compiled. But that's not important in 2020.

What is important in 2020 is that Apple is moving from Intel processors to ARM processors, and Microsoft may be considering a similar move. Of the two companies, Microsoft may be in the better position.

Apple uses the languages Objective-C and Swift for its applications, and encourages third-party developers to use those languages. Both of those languages are compiled, so moving from Intel processors to ARM processors means that programs, originally compiled for Intel processors must recompiled to run on the ARM processors.

Unless, of course, you run the Intel code on an ARM processor with an emulator. Not every application is ready to be recompiled, and not every third-party developer is ready to recompile their applications, so the emulator is an easy way to move applications to the ARM processors. The emulator is important to Apple, and I'm sure that they have spent a lot of time and effort on it. (And probably will spend more time and effort in the next year or two.)

Microsoft, in contrast, uses a large set of languages and encourages third-party developers to use its .NET framework. That puts it in a different position than Apple. While Apple's applications must be recompiled, Microsoft's applications do not. Microsoft can provide an ARM-based Windows and and ARM-based .NET framework, and all of the applications written in .NET will run. (And they will run without an emulator.)

Microsoft has a nice, simple path to move from Intel to ARM. Alas, the world is not so simple, and Microsoft's situation is not so simple.

The migration from Intel to ARM is easy (and low-risk) only for applications that are written completely in .NET. But applications are not always written completely in .NET. Sometimes, applications are written partially in .NET and partially in "native code" (code for the underlying processor). There are two reasons for such an approach: performance and legacy code. Native code tends to run faster than .NET byte-code, so applications that require high performance tend to be written in native code.

The other reason for native code is legacy applications. Large applications written prior to the introduction of .NET (and yes, that is twenty years ago) were written in a language that compiled to Intel code, typically C or C++. Converting that code from C or C++ to a .NET languages (C#, VB.NET, or the not-quite-C++ that was "managed C++") was a large effort, and entailed a large risk. Better to avoid the effort and avoid the risk, and maintain the application in its original language.

With all of that as a prelude (and I admit it is a long prelude), we can now look at the success of .NET.

If Microsoft releases a version of Windows for the ARM processor, we can see how many applications can migrate from Intel-based Windows to ARM-based Windows, and how many applications cannot. The applications that can move will be those applications written completely in .NET. The applications that cannot migrate (or that need an emulator) are those applications that are written all or partially in native code.

The degree of total (or pure) .NET applications can be a measure of the success of .NET. The more applications that use .NET (and no native code), the more success we can attribute to .NET.

The degree of native-code applications (partial or total), on the other hand, indicates a failure of .NET. It indicates choices made to not use .NET and use a different platform (Windows API, MFC, etc.) instead.

That is my measurement of the success of .NET: How many applications can move from Intel to ARM without recompiling. If Microsoft announces Windows for ARM, let's see which applications can move immediately and without the assistance of an emulator.


Tuesday, December 1, 2020

A few minor thoughts on Apple's new M1 processor

Apple has released their new M1 processor and their new Mac and Macbook computer which use the new processor. Apple is quite proud of this achievement (and they have every right to be) and users are impressed with the performance of the M1.

Yet I have some concerns about the new processors.

First, with the new processors and the new Macs, Apple has consistently emphasized performance, but little beyond that. Their demos have featured games and video editing, to show off the performance. The advertising is far from the presentations of yore which listed features and boasted MIPS ratings. (Perhaps video games are the new way to boast processor performance.) Apple's announcement was designed for consumers, not corporate buyers and not technologists and especially not developers. Apple has made their computers faster (and more efficient, so longer battery life) but not necessarily more capable.

Second, Apple's change to proprietary ARM processors (and let's be real, the design is proprietary) fractures the hardware market. Apple equipment is now different from "regular" personal computers. This is not new; Apple used PowerPC processors prior to using Intel processors in 2006. But the new Macs are different enough (and designed with enough security) that other operating systems cannot (and probably will never) be installed on them. Linus Torvalds has commented on the new Macs, and indicated that without Apple's support, Linux will not run on the M1 Macs.

Third, Apple made no announcement of cloud computing. This is not a surprise; Apple has not offered cloud computing and I see nothing to change that in the near future. It is telling that Amazon, not Apple, has announced new offerings of Apple M1 Mac minis in the cloud. Apple seems content to limit their use of cloud computing to iCloud storage, online documents, and Siri. I'm not expecting Apple to offer cloud computing for some time.

Moving beyond Apple, what will other manufacturers (Dell, Lenovo, etc) do? Will they switch to ARM processors?

I expect that they will not -- at least not on their own. Their situation is different. Apple has control over hardware and software. Apple designs the computer (and now, the processor). Apple designs and writes the operating system. Apple builds many of the applications for the Mac. This vertical integration lets Apple switch to a proprietary processor.

Manufacturers for "regular" personal computers rely on Windows, which is designed and written by Microsoft. Microsoft sells some applications, but encourages a large ecosystem of applications. A corresponding shift in the "regular" PC market requires the cooperation Microsoft, hardware manufacturers, and application developers. Such a change is possible, but I think Microsoft has to lead the effort.

Microsoft does provide a hardware specification for running Windows, and they could issue a specification that uses an ARM processor. Such a specification would exist along side the current Intel-based specification, expanding the space for Windows PCs. Microsoft could even design and build their own hardware, much as they did with Surface tablets and laptops.

I expect that Microsoft will support ARM processors (although not Apple's M1 processors) and offer cloud compute services for those processors. They may design a custom ARM processor, as Apple has done, or use a "standard" ARM processor design.

Getting back to Apple, I can see that the new M1 processor gives Apple more control over its market. The "expansion" market of running non-Apple operating systems is, as I see it, terminated with the M1 Macs. Boot Camp is out, Parallels works (but not with virtual machines), and non-Apple operating systems cannot be installed. (Technically that's not quite true. A clever engineer did get the ARM version of Windows to run on an M1 Mac, but only by using QEMU as an intermediary. It wasn't native ARM Windows on the M1 Mac.)

More control may sound good, but it does alienate some folks.

The Linux crowd will move to other hardware. Linux is a small presence in the desktop market, and Apple may not care or notice even. But Linux is a large presence in the developer market, and a decline in developers using Macs may affect Apple.

The Windows crowd has plenty of options for hardware, with more as Microsoft expands Windows to ARM processors. Windows laptops are just as good as Macbooks, and better in some ways, with options for non-glare displays and finger-friendly keyboards. My experience has shown that PC hardware tends to last longer than Apple hardware (especially equipment built after 2010).

I think, in the long run, Apple's move will fragment the market, aligning Apple hardware with Apple operating systems and Apple applications. It will push developers away from Apple hardware, and therefore Apple operating systems and the entire Apple ecosystem. Apple won't die from this, but it will give up some market share. The more noticeable effect will be the separation of processing on Apple and non-Apple platforms. Apple will be in their own world, their own garden of hardware, operating systems, and applications, and they will gradually drift away from mainstream computing.


Wednesday, November 25, 2020

Ideas for Windows

Where should Windows go? What improvements should Microsoft make?

I have some ideas.

First, Microsoft should drop the '10' designation of Windows. Yes, Windows 10 is different from Windows 8.1 and Windows 8 (and Windows 7, and Windows Vista, and...) but that's not important. What's important is how people talk about Windows, and how Microsoft wants people to talk about Windows.

People don't talk about "Windows 10"; they call it "Windows 1809" or "Windows 20H2". And those names are good enough to identify a version of Windows. The "10" is superfluous.

There is another benefit to dropping the '10'. It means that Windows doesn't get embroiled in marketing battles with Apple's macOS. Apple just updated macOS from version 10 to version 11. Is Apple now "ahead" in the operating system race because they have version 11? Is Microsoft behind because they have version 10? (Fans of the old movie "This is Spinal Tap" can make jokes about "our amplifiers go up to 11".)

By dropping the '10' and referring to release numbers, Microsoft avoids all of the comparisons. Or at least the meaningless comparisons of '10' and '11'.

Looking beyond version numbers, Microsoft is moving into a position which will let it reduce the number of configurations for Windows.

Today, Windows has multiple families: "Windows Server", "Windows Professional", and "Windows Home".  When Windows was sold in a box, these divisions made sense.

As Windows moves to a subscription service, the notion of different Windows versions makes less sense. The subscription model changes the idea of the purchase. Instead of "I'm buying this Windows product today and I will use it for a few years, getting free updates in that time" the idea becomes "I have subscribed to Windows, I pay a monthly fee, and this month I want this configuration of Windows". The difference is that one can change the product during the subscription (much like changing a Netflix account to allow more or fewer screens at the same time).

With a Windows subscription, one could start with Windows Home, then "dial up" the configuration to Windows Professional for a few months.

Maybe the designations of "Home" and "Professional" don't make sense anymore. Perhaps a subscription to Windows gives one access to a set of features (more granular that "Home" or "Professional"), and you can activate (or deactivate) new features as you want. Instead of choosing one of three options, one chooses from a large menu of services, enabling those that make sense.

I think we will see a number of changes as Microsoft moves from the "sale in a box" concept to the subscription concept of software.

Tuesday, November 17, 2020

The joy of a small programming language

I recently had the pleasure of reading the reference manual for Dibol (a programming language from the 1970s). And reading the manual was a pleasure. What made it so was the brevity and directness of the manual, the simplicity of the concepts, and the feeling of confidence in my ability to start programming it the language.

Dibol is a language from the minicomputer era, a short period of computing that occurred prior to the PC revolution. Made by DEC, it was an alternative for COBOL that ran on small systems and operated on simple files. It's syntax was influenced by COBOL, but much simpler.

The entire reference manual ran about 30 pages.

Dibol, I think, would have fit well in the Unix environment. Unix systems tended to use text files with flexible formats and varying line lengths, and Dibol was built for text files with fixed-length formats, so the match is not perfect. But Dibol is a language that follows the Unix philosophy: a simple tool to perform a simple task.

I could see it as a companion to AWK, a small language which handles text files and variable-length lines.

Dibol didn't "make it" as a programming language. It lives today, in the form of "Synergy/DE" which is a large superset of the original Dibol. So large, in fact, that it perhaps no longer follows the Unix idea of a simple tool. (I suspect the reference manual is longer than 30 pages.) But Dibol and its successors DBL and Synergy/DE have no significant presence in the popularity lists from Tiobe or PYPL or RedMonk.

We have no small languages today -- at least no small languages that enjoy any amount of popularity. AWK may be the most famous of the small languages, and even it is in the lower ranks on popularity lists. The popular languages are big (C++, Java, Python, C#, R, Visual Basic...).

We should be careful with the popularity indices. The methods used by them may skew the results. Tiobe and PYPL count queries about the languages -- people asking questions. I think we can safely assume that people will ask more questions about large languages than small languages, so complex languages have an advantage in the popularity metrics.

RedMonk also looks at Github and the code posted there. It's not clear if RedMonk is counting number of projects, number of files, or lines of code. (A complex language would probably have more lines of code.) But Dibol and other small languages do not show in RedMonk's list.

So we can conclude that there is no significant use of small programming languages. As a programming language, you're either big or you're unknown.

Which, I think, is a shame. The big language are hard to learn and easy to create large, complicated systems. Small languages have the advantage of doing one job and doing it well. We as an industry may be missing out on a lot.

It also means that large programming languages are the "go to" solution for programmers; that programmers prefer large languages. There is some sense in this. A large programming language (C#, Java, take your pick) can handle just about any task. Therefore, a programmer who knows a large programming language is capable (in one sense) of handling any task. Large programming languages give the programmer flexibility, and more opportunity. (I say "in one sense" because knowledge of a programming language is, while necessary, not sufficient for the design of large or specialized applications. System architecture, user requirements, performance analysis, and deployment practices are also required.)

The consistent use of large programming languages means that our solutions will tend to be large. I know of no small Java applications, no small C++ applications, and no small C# applications. There may be small utility programs written in large languages, but I suspect that those utility programs grow over time and become large utility programs.

Large code bases require more effort to maintain than small code bases, so our bias towards large programming languages is, in the long run, costing our customers time and money.

Of course, the alternative (lots of small programs written in small programming languages) can have the problem of multiple languages and not enough people to maintain them. A shop with hundreds of programs written in a dozen or so different programming languages also faces maintenance efforts. Should every programmer in the shop know every programming language used in that shop? That also requires time and effort.

So what should a programmer do? Learn one large language? Learn lots of small languages?

My recommendation is to learn multiple languages, some large and some small. For large languages, pick two of the popular languages C, C++, C#, Java, JavaScript, and Python. Also learn some small languages such as Awk, Lua, and bash.

But don't spend time on Dibol.

Wednesday, November 11, 2020

Flipping bits

Apple has introduced a new line of Mac computers which use Apple's new M1 system-on-a-chip. Apple made several claims about the performance, but those claims were vague -- at least in terms of measured performance. (Claims were in the form of "up to 2 times faster", "up to five times faster", "the fastest Macbook yet".)

Apple's M1 chip contains a processor that is based on ARM architecture, which is quite different from Intel's x86 architecture. How does one compare them?

One of the oldest comparisons of processors is MIPS (millions of instructions per second). Dating back to the mainframe age, it is simple in concept: count the number of instructions in each second of processing. But when comparing different architectures, a comparison of instruction to instruction is not useful. The instructions sets are different, and a computation on one processor might use one instruction, and the same computation on a different processor might take three or four instructions.

A later metric, FLOPS (floating-point operations per second) is somewhat better when the two systems are performing tasks that use a lot of numeric processing. This metric focusses on the instructions used for processing numeric values, specifically floating-point values, and looks at operations and not necessarily discrete instructions. But its focus is its weakness: Tasks that use integer arithmetic and fixed-point data representations aren't usefully measured with FLOPS metrics.

Thinking about the differences between Intel and ARM processors, perhaps we need a different metric, one that is robust for different architectures and different types of processing. And I have thought of one, although it may not be practical.

My idea for measuring performance is to execute a task or function and count the number of bits that are changed (or "flipped") during the process.

The advantage of this metric is that it is neutral to architectures and also neutral to the type of processing.  MIPS doesn't measure different instruction sets well and FLOPS omits integer operations. Bit-flipping, in contrast, works with all architectures and all data types. (I'll get to the downside of the bit-flipping metric later.)

The idea of bit flipping is simple: count each bit that changes state, either from 0 to 1 or from 1 to 0. If a register holds 0x0001 and is cleared, then one bit is changed (from 1 to 0). If a register holds 0x001f and is cleared, then five bits are changed. (If a register holds 0x0000 and it is cleared, then no bits are changed.)

Such a measure has the advantage of working with any type of data. We can use this measure with floating-point data and with integer data. We can even use it with BCD (binary converted decimal) data. We can use it with text data and with objects.

Notice that this measure does not measure time. A comparison of the number of bits changed during a process is a count, not a time. One processor might be flipping more bits but running faster. A higher flip count does not necessarily mean slower performance.

One might think that such a limitation makes the bit-flip metric useless for performance comparisons. If one is interested in speed, and only speed, then the point is valid. Bit-flipping measures the efficiency of the processor: the same task with a lower bit-flip count is more efficient -- and therefore uses less energy. That may be useful to system designers.

One challenge with the bit-flip metric is deciding which bits count. Even though bits are all the same (a single value of either 1 or 0) different bits are stored in different locations and used for different purposes.

One simple difference is memory and registers. Processors store values in memory ("RAM") and also store values in registers, a small set of locations that are part of the processor. Registers are used for computations and change often; memory is used for storage and changes less frequently. Should the bit-flips for memory count the same as bit-flips in registers?

If we agree to count registers and memory differently, then we open the door to other distinctions in bits. Modern processors have caches, usually three layers, which store values too. Caches exist between registers and memory. If registers and memory have different "weights" for bit-flipping, caches should probably have different weight too.

We've been looking at data, but processors also use addresses. In order to read or write a value in memory, the processor must put an address on the buss to tell memory which cell it wants. Those bits change; should we count those changes too?

Addresses have more complications. Modern processors use an advanced form of memory management, which allows for multiple processes. Memory management changes the address that the process requests (a "logical" address) to the real address that holds the value (the "physical" address). Should those bit-flips count? (Keep in mind that physical memory pages are assigned at random, so two separate runs could have different physical pages and therefore different memory addresses and therefore different bit-flip counts.)

After careful consideration, I think the best solution is to count all of the bits. ("All the bits!") Categorize them if you want, report them in groups if you want, assign different weights to the different groups if you want, but count all of them.

We could compare similar tasks on Windows and Mac, on Intel and ARM, even Microsoft Word and Office Libre.

Which brings me to the one drawback to bit-flip counts.

It's hard to do.

Counting bit-flips requires access to memory, registers, and all sorts of innards of the processor. It's not something an application can do, or even a device driver or kernel extension. This kind of observation must occur in the processor; nothing else will do.

To effectively use bit-flipping, we need the cooperation of Intel and ARM (and Apple, who designs the M1 off of the ARM design). We also need clear and precise descriptions of the data we want to collect, so that the counts on Intel processors count the same things as counts on ARM processors.

We also need an answer to the meta-question about data collection: Counting bit-flips in itself changes data values (the counters for bit-flip operations). Do we count those bit-flips too? (For the record, I am against counting those bit flips. Because if we count the bit-flip counter flips, then we have to count the counters for those bit flips, and the count the bit flips for those counters, and on and on. Enough is enough!)

Bit-flipping is a nice thought experiment. Implementation requires changes to processors and the cooperation of manufacturers, which is a tall order. I suspect it will remain a thought experiment.

Unless!

Unless... we limit bit-flips to something simple (such as only the CPU registers, and nothing else) and we leverage virtual modes, letting the "real" processor count the bit flips in the "virtual" processor. (Bit-flipping is a simple operation: XOR the "before" and "after" values, and then count the bits in the result.)

Such an arrangement might just be possible. It still needs cooperation from the processor designers, but such a scaled-down version might be possible.

Thursday, November 5, 2020

Big is the new big

For PCs, big is the new big. It wasn't always this way.

When the PC revolution started, small was big. The advantage of PCs was smallness, in size, in cost, and in effort. PCs were small enough to fit on a desktop, cheap enough to be purchased as "word processors" (to avoid the data processing bureaucracy), and easy enough that one person could operate them.

The programmers of the PC revolution took pride in the smallness of hardware and of programming languages. BASIC, the original language of the PC revolution, could fit on a computer with 8K of RAM. (That's 8192 bytes.) Other programming languages were also small. Even the names emphasized smallness: Tiny-C, Tiny-Pascal.

We rebels of IT considered "big" an aspect of mainframe systems, and associated "big" with slow, lumbering processes that hindered productivity. The Agile movement was defined as the opposite of "BDUF" (Big Design Up Front). Big was what we did not want our systems to be.

Yet something has changed. We no longer want to be small. Now, we want to be big.

Notice the (now decade-old) desire for "big data". That was a full embrace of bigness. There was also "big analytics" which analyzes large datasets.

Other things have become big. Databases have become big. Spreadsheets have become big. Word processors have become big. Our PCs are not stand-alone systems, but nodes in a larger system and reliant on that system for authentication, updates, and basic processing.

Programming languages have become big, with C++, Java, Python, C#, and Visual Basic in the top slots of the Tiobe index for October 2020. The top position is held by C. While some consider C a small programming language, I have my doubts. C uses a small set of keywords, but has a large standard library. It may not be large, but it isn't small.

We have lost our desire for small systems. Our smart phones are physically small, yet their operating systems are complex and app development is for professionals. Even small hardware systems such as the Raspberry Pi run a full Linux distro, which requires a fair amount of administration.

The only small systems are the Arduino and similar systems, which run a slim monitor operating system and are designed for hardware control, not general-purpose computing.

Perhaps we were deluding ourselves. Perhaps we wanted large systems all along. We craved the power of fast processors, ample memory, and disk space that was not limiting -- that much is certain. Perhaps the cost of faster processors, more memory, large disk space, and interconnected systems is bigness. Perhaps it is not possible (or not cost-effective) to operate small systems loosely coupled.

Perhaps.

But perhaps the desire for small, simple systems remains, and perhaps, one day, it will resurface.


Wednesday, October 7, 2020

Platforms are not neutral

We like to think that our platforms (processor, operating system and operating environment) are neutral, at least when it comes to programming languages. After all, why should a processor care if the code that it executes (machine code) was generated by a compiler for C#, or Java, or Fortran, or Cobol? Ditto for the operating system. Does Windows care of the code was from a C++ program? Does Linux care of the code came from Go?

And if processors and operating systems don't care about code, why should a platform such as .NET or the JVM care about code?

One could argue that the JVM was designed for Java, and that it has the data types and operations that are needed for Java programs and not other languages. That argument is correct: the JVM was built for Java. Yet people have built compilers that convert other languages to the JVM bytecode. That list includes Clojure, Lisp, Kotlin, Groovy, JRuby, and Jython. All of those languages run on the JVM. All of those languages use the same data types as Java.

The argument for .NET is somewhat different. The .NET platform was designed for multiple languages. When announced, Microsoft supplied not only the C# compiler but also compilers for C++, VB, and Visual J++. Other companies have added compilers for many other languages.

But those experiences do not mean that the platforms are unbiased.

The .NET platform, and specifically the Common Language Runtime (CLR) was about interoperability. The goal was to allow programs written in different languages to work together. For example, to call a function in Visual Basic from a function in C++.

To achieve this interoperability, the CLR requires languages to use a common set of data types. These common types include 32-bit integers, 64-bit floating-point numbers, and strings. Prior to .NET, the different language compilers from Microsoft all had different ideas about numeric types and string types. C and C++ user null-terminated strings, but Visual Basic used counter-in-front strings. (Thus, a string in Visual Basic could contain NUL characters, but a string in C or C++ could not.) There were differences with floating-point numeric values also.

Notice that these types are aligned with the C data types. The CLR, and the agreement on data types, works for languages that use data types that match C's data types. The .NET version of Visual Basic (VB.NET) had to change its data types in order to comply with the rules of the CLR. Thus, VB.NET was quite a bit different from the previous Visual Basic.

The CLR works for languages that use C-style data types. The CLR supports custom data types, which is nice, and necessary for languages that do not use C-style data types, but then one loses interoperability, and interoperability was the major benefit of .NET.

The .NET platform favors C-style data types. (Namely integers, floating point, and NUL-terminated strings.)

The JVM also favors C-style data types.

Many languages use C-style data types.

What languages don't use C-style data types?

Cobol, for one. Cobol was developed prior to C, and it has its own ideas about data. It allows numeric values with PICTURE clauses, which can define limits and also formatting. Some examples:

   05  AMOUNT1          PIC 999.99.
   05  AMOUNT2          PIC 99999.99.
   05  AMOUNT3          PIC 999999.99.
   05  AMOUNT4          PIC 99.99.

(The '05' at the front of each line is not a part of the variable, but indicates how the variable is part of a larger structure.)

These four different values are numeric, but they do not align well with any of the CLR types. Thus, they cannot be exchanged with other programs in .NET.

There are compilers for Cobol that emit .NET modules. I don't know how they work, but I suspect that they either use custom types (which are not easily exchanged with modules from other languages) or they convert the Cobol-style data to a C-style value (which would incur a performance penalty).

Pascal has a similar problem with data types. Strings in Pascal are length-count strings, not NUL-terminated strings. Pascal has "sets" which can contain a set of values. The notion of a set translates poorly to other languages. C, C++, Java, and C# can use enums to do some of the work, but sets in Pascal are not quite enums.

Pascal also has definite ideas about memory management and pointers, and those ideas do not quite align with memory management in C (or .NET). With care, one can make it work, but Pascal is not a native .NET language any more than Cobol.

Fortran is another language that predates the .NET platform, and doesn't work well on it. Fortran is a simpler language that Cobol or Pascal, and concentrates on numeric values. The numeric types can convert to the CLR numeric types, so compiling and exchanging data is possible.

Fortran's strength was speed. It was (and still is) one of the fastest languages for numeric processing. Its speed is due to its static memory layout, something that I have not seen in compilers for Fortran to .NET modules. Thus, Fortran on .NET loses its advantage. Fortran on .NET is not fast, and I fear it never will be.

Processors, too, are biased. Intel processors handle binary numeric values for integers and floating-point values, but not BCD values. IBM S/360 processors (and their descendants) can handle BCD data. (BCD data is useful for financial transactions because it avoids many issues with floating-point representations.)

Our platforms are biased. We often don't see that bias, most likely because with use only a single platform. (A single processor type, a single operating system, a single programming language.) The JVM and .NET platforms are biased towards C-style data types.

There are different approaches to data and to computation, and we're limiting ourselves by limiting our expertise. I suspect that in the future, developers will rediscover the utility of data types that are not C-style types, especially the PICTURE-specified numeric types of Cobol. As C and its descendants are ill-equipped to handle such data, we will see new languages with the new (old) data types.


Wednesday, September 30, 2020

The future of Firefox

Use of Mozilla's Firefox browser is declining (at least as a percentage of market share), and people are concerned.

Some are concerned that we will lose an option in the browser market. Others are concerned that the demise of Firefox signals a forthcoming decline of open-source software. Mozilla, of course, is concerned about its business.

I'm not sure what Mozilla should do in this situation. I do have some observations:

First, people select browsers (and other things) for one of two reasons.

1) They want to use the specific product (in this case, the Firefox browser)

2) They don't want to use the alternatives (in this case, Internet Explorer, Edge, Chrome, Safari, etc.)

To improve its market share, Mozilla will have to either provide a product or service that people want to use, or be an alternative to a product that people don't want to use. Mozilla must either make a better browser, one that people look at and think to themselves "yeah!", or wait for people to dislike the other browsers on the market.

When Chrome appeared on the market, people used it, I think, for the latter reason. At the time, Internet Explorer (IE) was the most commonly used browser (sometimes by corporate dictat) and people did not like it. Chrome was not Internet Explorer, and by using Chrome, one could "poke Microsoft in the eye".

But that was then. Now, people use Chrome because they want to. People might have chosen Chrome after using Gmail, and may have had favorable opinions of Google due to the 1GB space for mailboxes, which was quite large at the time. And Gmail was free!

Whatever the reasons, people like Chrome. Mozilla does not have the tailwind of people disliking their current browser.

Waiting for potential customers to dislike their current product is not a viable strategy. People may be unhappy with some of Google's practices, and that may drive some away from Chrome (and some of those to Firefox) and Mozilla has been advertising along those lines.

But dislike of Google is probably not enough. Mozilla needs "a better mousetrap".

And I'm not sure how they can build one.

Wednesday, September 16, 2020

Technical debt is similar to new features

If we accept the premise that technical debt is the difference between what we want the code to be and what the code actually is, we can treat technical debt like new requirements.

Most development shops have a process for new requirements. That process usually involves describing the new feature, estimating the benefits (additional revenue, reduced expenses), estimating the effort, scheduling the work, testing, and deploying the new requirements in a new version.

An organization can use a similar process for technical debt. Technical debt must be described ("module X fails to meet code style rules 12, 14, and 17" or "library Y is obsolete"), estimated for benefits, estimated for effort, scheduled, tested, and deployed.

Technical debt does vary from new requirements in two ways. First, new features are often about revenue or cost reduction, and technical debt is about the reduction of risk. This difference often makes new requirements more desirable; revenue is often better than less risk, especially for a working system.

The second difference is the sponsors for changes. New features often have organizational sponsors. They may have titles such as "product owner", "VP of marketing", or "user representative". These sponsors make the case for the new feature, presenting the benefits to the managers who control the project budget.

In contrast, the sponsors for technical debt are (almost always) developers. It is the developers who see the problems in the code, the developers who want to improve things.

But "improving the code" is not a goal that makes sense for the business. Managers are concerned with four general topics: money, time, risk, and politics. "Improving the code" is not one of them. To get managers to "buy in" to the effort to reduce technical debt, developers must make the case in management terms. They have to convert "improvement to the code" into one of money, time, risk, and politics.

A change to eliminate technical debt may, on occasion, offer a reduction in cost, but usually the benefit is a reduction in risk. To get time and resources to reduce technical debt, developers must present a clear case about the risk caused by the current code, and possible costs (money, time, delayed releases) in the future.

If developers can make their case, then the process for technical debt is quite similar to the process for a new feature. Changes for technical debt can be identified, described, tracked, prioritized, estimated, scheduled, implemented, and deployed.

Technical debt is not a mysterious aspect of software development. It can be described and measured, and the effort to reduce it can be estimated, prioritized, scheduled, and implemented -- just like the efforts for  new features. The big difference between technical debt and new features is that technical debt is about risk, and new features are about money. Any organization must balance the needs of money, time, risk, and politics -- that's management.

Monday, September 14, 2020

Technical debt is what we want it to be

We like to think that technical debt is an attribute of software.

Wikipedia provides a definition: A concept in software development that reflects the implied cost of additional rework caused by choosing an easy (limited) solution now instead of using a better approach that would take longer.

I believe that technical debt is not derived from software, but is instead derived from our expectation of the software.

Or more specifically, technical debt is code that violates a coding style or architectural guideline.

If we accept this definition of technical debt, something interesting happens.

Technical debt becomes not an aspect of software, but an aspect of our desire for the software.

Moreover, it can change over time.

Consider a hypothetical project with code written in Python. There is a substantial code base, and there are no rules for code style. The development team is unaware of the generally accepted rules for Python code, nor do they use pycodestyle.

The code performs as expected with no defects. (I did say that this was a hypothetical project.)

Yet the code itself is a jumbled mess of classes and functions, with poor names for variables and lines that exceed Python's recommend 80 characters. The development team is okay with the state of the code. (After all the code does run and it does produce the correct results.)

The code in the project has no technical debt. There is nothing in the code that developers or managers want to change.

Now we change the scene: The team becomes aware of code style rules and the pycodestyle package. They discuss the idea of code standards and agree to use the pycodestyle package to review their code.

Now the code has technical debt.

We did not change the code. The code is exactly the same as before the introduction of code style rules.

Yet now it has technical debt.

Not because the code changed. Because the expectations of the developers changed. Simply changing the rules made technical debt appear.

Technical debt does not follow the rules of accounting. One does not use double-entry bookkeeping to track it. There is no "law of conservation of technical debt".

Technical debt is what we say it is. Or more precisely, technical debt is what we want the code to be that it is not. The key phrase is "what we want".

Technical debt is not an absolute attribute of the code. It depends on the expectation of the developers.

Wednesday, August 26, 2020

Apple's upcoming challenge

Up to now, Apple's business has been simple: sell hardware. Software such as macOS, GarageBand, and even iTunes was made to sell hardware.

Up to now. Or some time in the recent past.

Apple now has two major lines of business: hardware and services. At some point, conflicts between the two will arise. How will Apple navigate those conflicts?

Here is how this affects consumers and developers -- and Apple.

In the past, developers were reluctant to build certain types of apps. The fear was that Apple could build their own version of an app and include it in iOS or macOS, and that such an inclusion would reduce sales of the independent app to near zero. (Apple includes lots of apps for its phones and for its laptops. macOS includes a word processor, a spreadsheet, an e-mail client, and sound editing software, among other things.)

But now, with income from the sale of apps (or subscriptions to online apps) Apple faces a choice: Do they build an app or let someone else build it?

If Apple builds the app, their hardware/software offering is more complete, which makes it more appealing to customers. On the other hand, Apple must invest in the app and maintain the app over time.

Suppose Apple doesn't build the app. Odds are high that someone else will build the app, and submit it to Apple for inclusion in the Apple App Store.

And charge for it. Either a one-time charge or a subscription fee. Both of which provide income to Apple.

Notice what has happened. The app, when developed by Apple, is an expense. When developed by a third party, it is revenue. But the differences are more than financial.

Removing the financial aspect, the big difference of the two modes is control. When Apple builds the app it has complete control over the appearance, functionality, performance, and reliability. Apple can ensure that data is stored only on Apple devices or Apple-approved cloud servers. When Apple lets third parties build the app, it cedes some control to those third parties.

I can see two trends in the future.

One is that Apple will cease adding apps to its macOS and iOS operating systems. (It will add utilities that control and configure hardware, like the AirPort utility for AirPort devices. But it will add few games or office tools.)

Another is that Apple will increase (or attempt to increase) its control over apps that run on macOS and iOS. Apple will issue stronger and more detailed guidelines for user interfaces, security, privacy, and reliability. In this case, Apple is trying to have its cake (maintain control) and eat it too (farm out development to third parties and gain revenue).

I think this strategy just might work for Apple. They sell lots of hardware, and third-party developers want access to that market. Apple customers are loyal, replacing their old Apple laptops and phones with new Apple laptops and phones.

There are some risks.

Such a strategy will mean a difficult time for third-party developers, who will have to jump through more and more hoops to get their apps published in Apple's App Store. Some developers may give up on the Apple market, and this is the risk that Apple must manage. If too many developers abandon the Apple ecosystem, then Apple loses apps and income, and could lose customers for hardware.

Another risk is that Apple loses its ability to develop apps. If it relies on third parties to create apps for iPhones and Macbooks, will it shift its internal resources from app development to something else? Will it lose the ability to create regular, non-system apps? If it does, then returning to a strategy in which Apple creates apps (user apps, not just system apps) will require the re-development of that development experience.

But if Apple avoids those problems, they can succeed and reap the rewards.

Tuesday, August 25, 2020

Developers for open source

Infoworld makes the case that open source is constrained not by money but by developers -- people.

This seems a good time to recall some wisdom from the late 1990s. Christine Comaford, a technology pundit of the times, listed four things that techies want:

Lavish, genuine praise
Fun projects to work on and fun tools to work with
Free beer and pizza
Some money
(And look where money is in this list.)

I've taken the liberty of expanding Ms. Comaford's first item with the adjective "genuine".

Open source can learn from this list, and use it to attract and retain developers.

The money is ready. Infoworld admits that funding is available.

Fun projects and fun tools are also available. Open source has plenty of projects. Today's tools are much better than those of 1997.

Keep in mind, in 1997, open source didn't exist like it does today. It was a tiny corner of the IT realm, obscure and unknown to many. The vast majority of development was in corporations or government agencies, with development tied to employment and tools specified by corporate committees.

If open source projects want to attract developers, the two remaining aspects are the place. Free beer and pizza -- substitute soda, juice, fruit, and sandwiches if you want -- and lavish praise.

Praise. Recognition. Credit (as in movie-style credit).

These are mechanisms to entice developers.


Wednesday, August 19, 2020

Apple and cloud computing

 Apple's tussle with Epic (the creators of Fortnite) shows a deeper problem for Apple. That problem is cloud computing.

Apple has avoided cloud computing, at least from its customers' perspectives. Apple is the last company to use the "run locally" model for its application. Apps for iPhones and iPads run on those devices, applications for Macbooks run on them. (Apple does use servers and possible cloud computing for iCloud storage and Siri, but those are accessories to macOS, not a front-and-center service.)

In contrast, Google's cloud-based Documents and Sheets apps let one build documents and spreadsheets in the cloud, with data stored on Google's servers and available from any device. I can create a document on a Chromebook, then open it on my Android phone, and later update it on a desktop PC with a Chrome browser. This works because the data is stored on Google's servers, and each device pulls the latest version when it is needed.

Microsoft is moving in this direction with its online version of Office tools. Even Oracle is moving to cloud-based computing.

Apple is staying with the old "local data, local execution" model, in which computing and data is on the local device. Bur Apple does let one move from one device to another (such as from an iPad to a Macbook) by synchronizing the data onto Apple's servers.

The difference is the location of processing. In Google's model (and in Microsoft's new model), processing occurs on the server. Apple keeps processing on the local device.

For simple tasks such as word processing and spreadsheets, the difference is negligible. One might even claim that local processing is better as it offers more options for documents and spreadsheets. (More fonts, more chart options, more functions in spreadsheets.) The counter-argument is that the simpler cloud-based apps are better because they are simpler and easier to use.

Regardless of your preference for simple or complex word processors, cloud computing is also used by games, and games are a significant market. More and more games are shifting from a model of "local processing with come communication to other users" to a model of "some local processing to communications with servers for more processing". In other words, games are using a hybrid model of local processing and cloud processing.

This shift is a problem for Apple, because it breaks from the "all processing is local" model that Apple uses.

What is Apple to do? They have two choices. They can stay with the "all processing is local" model (and ignore cloud computing) or they can adopt cloud computing (most likely as a hybrid form, with some processing in the cloud and some processing remaining on the local computer).

Ignoring cloud computing seems risky. Everyone is moving to cloud computing, and Apple would be left out of a lot of innovations (and markets). So let's assume that Apple adopts some form of cloud computing, and enables developers of applications for Apple devices to run some functions in the cloud.

How will Apple host their cloud platform? Here again there are two choices. Apple can build their own cloud platform, or they can use someone else's.

Building their own cloud infrastructure is not easy. Apple comes late to cloud computing, and will have a lot of work to build their infrastructure. Apple probably has the time to do it, and most definitely has the cash to build data centers and hire the engineers and system administrators.

But the alternative -- using someone else's cloud -- is also not easy. Apple is not friends with the major cloud providers (Amazon.com, Microsoft, Google) but it may form alliances with one of the smaller providers (Oracle, Dell, IBM) or it might purchase a small cloud provider (Linode, Digital Ocean, OVH). Apple has the cash to make such a purchase. While possible, a purchase may not be what Apple wants.

My guess is that Apple will build their own cloud platform, and will make it different from the existing cloud platforms. Apple will need some way to distinguish their cloud platform and make it appealing to app developers.

Perhaps Apple will focus on security, and build a self-contained cloud platform, one that offers services to Apple devices but not others, and one that is isolated from other cloud platforms and services. An "Apple only" cloud platform with no connection to the outside world would allow Apple to ensure the security of customer data -- with no connection to the outside world, data would have no way to escape or be extracted.

Apple may go so far as to mandate the use of their cloud platform, prohibiting apps from communicating with other cloud platforms. iPhone apps and Macbook applications could use Apple's cloud, but not AWS or Azure. This would be a significant restriction, but would guarantee revenue to Apple.

(Assuming that Apple charges for cloud services, which seems a reasonable assumption. Exactly how to charge for cloud services is a challenge, and may be the only thing preventing Apple from offering cloud services today.)

The outcome of the dispute between Apple and Epic may foreshadow such a strategy. If Apple prevails, they may go on to create a locked cloud platform, one that does not allow competition but does ensure security of data. (Or perhaps a milder strategy of offering the Apple cloud, but only on the condition that the Apple cloud is the only cloud used by an app. Classic apps that use other clouds may continue to run, but they could use Apple cloud. Moving any services to the Apple cloud would mean moving all services to the Apple cloud.)

I don't know how things will play out. I don't know what discussions are being held in Apple's headquarters. These ideas seem reasonable to me, so they may come to pass. Of course, Apple has surprised us in the past, and they may surprise us again!

Thursday, August 13, 2020

Apple and Fortnite

Events in the Apple vs. Fortnite dispute are unfolding rapidly. In less than a week, Fortnite modified their web page to allow payments outside of Apple's payments API (which meant that Apple could not extract a 30% toll), Apple removed Fortnite's app from the Apple App Store (which meant that customers can no longer install it on Apple devices), and Fortnite ran an advertisement video that parodies Apple's "1984" ad for the original Macintosh computer. Fortnite has also filed a lawsuit against Apple.

A few thoughts on this dispute:

First, Apple will probably win the lawsuit. It seems to be a contract dispute, and I think Apple's terms and conditions are strong enough to defend its actions. (Although I am not a lawyer and I am not offering legal advice.)

Second, Apple is probably surprised at the tactics used by Fortnite. I'm sure Apple is frequently involved in lawsuits, ranging from patent disputes to wrongful termination by employees. Most of these are handled quietly. Fortnite is running a very public campaign, and wants to make as much noise as possible. I'm not sure that Apple is prepared for a public dispute.

Third, Fortnite is prepared for this fight. The parody of Apple's "1984" advertisement shows that -- such a parody was not assembled in an afternoon hack session.

Fourth, Apple is the larger of the companies, and is therefore "punching down" against the smaller Fortnite. Apple faces the risk of looking bad, and must tread carefully. Carelessly worded statements by Apple will be received poorly.

Fifth, it seems that Fortnite is ready to walk away from the Apple platform. A public spat such as this one leaves little room for reconciliation.

Sixth, Apple is most likely ready for Fortnite to walk away. Apple recognizes that the revenue from Fortnite is a small portion of its overall income. Apple probably assumes that it can get other companies to provide games for Apple devices.

Finally, while Fortnite will probably lose in a court of law, they may win in the court of public opinion. This may be damaging to Apple. Apple has fans and followers, but I don't know that Apple has many friends. The fans and followers will stay with Apple, but partners and suppliers may become more cautious in their dealings with Apple. Small developers may delay releases for Apple devices, or may defer them indefinitely. For Apple to win, it needs more than lawyers -- it needs a good public relations campaign.


Add Functional Programming to Object-oriented Programming, not the other way round

The programming world has multiple paradigms, or styles of programming. The reigning champion is Object-oriented Programming, embodied in C++, Java, and C# and oriented around, well, objects. The prior champion was Structured Programming (or Procedural Programming) represented by C and Pascal and oriented around control structures (and avoiding GOTOs). The challenger is Functional Programming oriented around functions, and in the languages Haskell and F#, among others. An older paradigm is Unstructured Programming (USP), which does use GOTOs and lacks the modern IF/THEN/ELSE and DO/WHILE constructs of Structured Programming.

SP and USP operate in the same space: small and medium-side programs. Since they operate in the same space, one often picks one of them, but does not use both. (One can use both, but it is not easy.)

Object-oriented programming (OOP) operates in "the large" and helps us organize large systems. Structured Programming (SP) and Functional Programming (FP) operate in "the small" and help us build short blocks of code that are reliable and readable. In this view, SP complements OOP and they work well together. SP and FP, on the other hand, compete in the same space. We can build large systems with OOP and SP, or with OOP and FP. (We can build small programs with SP alone, or with FP alone. OOP is not useful with small programs.)

Structured Programming is demonstrably better than Unstructured Programming. Functional programming is arguably better then the older Structured Programming. One would think that we would use the best paradigm, and that we would use Functional Programming. But we don't. It takes time to learn a programming paradigm, and most programmers know the Structured Programming paradigm. Structured Programming is what we have, buried inside many modern systems.

The mix of Object-oriented Programming and Structured Programming makes sense. To use a programming paradigm, or a mix of paradigms, one must have a language that supports the paradigms. C++, Java, and C# all support OOP and SP. Pascal supports only SP; Object Pascal and Delphi support both. Haskell supports FP.

The advocates of Functional Programming have noticed that their preferred languages have achieved modest acceptance, but none have become as popular as the most popular languages C++, Java, and C#, or even Python. That lack of acceptance makes some sense, as a Functional Programming language does not have the Object-oriented Programming concepts that help us organize large systems. (Conversations with practitioners have probably ended with project managers and OOP programmers saying something along the lines of "Functional Programming is nice, but we have a large code base in an Object-oriented Programming language, and we cannot give up that organization." 

I think these conversations have spurred the advocates of Functional Programming to merge OOP into FP languages, the hope that project managers and programmers will accept the new combination. The combination of object-oriented programming and functional programming is a nice trick, and it works.

But this approach is, in my view, the wrong approach.

When programmers and managers say that they want a programming language that supports OOP and FP, they don't really mean that they want an FP programming language that supports OOP.

What they want is a programming language that supports their current code base and allows them to add Functional Programming in small doses.

They want a compromise, much like C++ was a compromise for OOP. C++ offered classes to C programmers -- and was originally called "C with classes". It didn't mandate a pure OOP approach. Instead, it let programmers add OOP to an existing code base, and add OOP in a gradual manner.

The "FP plus OOP" approach fails because the existing code base is not OOP, but OOP with SP. A "FP plus OOP" language requires that all of the SP code blocks be re-written in FP. That can work for tiny programs and classroom exercises, but it doesn't work in the industry with large sets of code.

Yes, some companies have large, million-lines-of-code systems written in FP. But those systems were built in FP from the beginning.

Companies that have large, million-lines-of-code systems written in OOP (with procedural code too) don't want to stop everything and re-write that code. They want to add FP in small doses. They want the benefit of FP in a few key locations. Over time, they can expand FP to other parts of the system.

They don't want an FP language with OOP extensions. They want an "OOP and SP" language with FP extensions.

There is a language that may provide a path forward. Microsoft has its F# language, which is a Functional Programming language, but it also lives in .NET, which means one can combine F# modules with C# modules. If one has a system in C# and wants the advantages of Functional Programming, F# is worth investigating.

But beyond F#, I see no languages that offer a compromise between paradigms, and a way forward for managers and programmers. The current set of FP languages are too "pure" and don't allow the mixing of OOP, FP, and SP paradigms.

Perhaps we will see some new languages that bridge the worlds of Structured Programming, Object-oriented Programming, and Functional Programming.

Thursday, August 6, 2020

Apple's risky game

Apple's recent spat with Hey has shown a possible problem with Apple's strategy.

If I may oversimplify events: Hey.com built an app for e-mail, and submitted it to Apple for distribution in the Apple App Store. Apple approved it. Hey then submitted an upgrade, which Apple rejected, claiming that the Hey.com e-mail app did not conform to Apple's rules. Hey.com charges users $99 per year for the e-mail service, and Apple wanted 30% of it. Hey fought back, saying that the terms for apps were 30% of in-app purchases, and people could buy a subscription on the hey.com web site. Apple said that such an arrangement was not satisfactory, and stood firm on its rejection of the upgraded app.

Hey's complaint is mostly one of fairness: the terms and conditions said "in-app purchases". Hey thought that they conformed to that clause. Apple then explained that an app must allow for in-app purchases when a subscription is required. (And apparently when a customer subscribes on the web site, Apple still wanted 30%.)

To further muddy the waters, Apple allows "read only" apps such as Netflix to avoid the 30% fee. 

One can see the advantage of Apple's strategy: by forcing an app maker to pay the 30% fee, it increases income (for Apple).

But a side effect of this strategy is that it converts a partner in one's ecosystem into a customer. Were hey.com to accept the proposed terms, they would be paying Apple. (Which, last time I checked, makes them a customer.)

So is hey.com a partner, a competitor, or a customer?

They are a partner in that they provide an app for the Apple App Store.

They are a competitor in that their app (an e-mail app) competes with Apple's built-in e-mail app.

They are a customer in that they pay money to Apple.

It is one thing to irritate your competitors; it is another to irritate your customers. Competitors expect that you will compete. Customers expect that you deliver value. And the folks at Hey consider the services provided by Apple in exchange for the 30% fee to be insufficient.

For Apple, this is probably a business decision, governed by finances and not by emotions. Even if they lose some app providers (customers), they make more money overall.

Further muddying occurred with a recent announcement (true or otherwise) that Amazon paid less than 30% for its app. This will not sit well with developers, especially after Tim Cook (CEO of Apple) claimed that all app developers have the same arrangement.

"Ah," think the small developers, "I see how this works. The big companies have a nice little club with discounts, but I have to pay full price."

Apple must tread carefully here. Apple has its market, and its walled garden, and its App Store. Partners or partners-turned-customers may grumble and pay the 30% "Apple tax" -- for now.

Apple runs the risk of becoming the next Microsoft -- or more specifically, the next big company that people love to hate. Developers may play by Apple's rules, grudgingly, as captives in the market. But when an alternative appears on the horizon, they will remember Apple's behavior and many will flock to that new opportunity. Apple may gain in the short term and lose in the long.

Thursday, July 23, 2020

IBM and Apple innovate in different ways

Two of the most influential companies in the PC universe are IBM and Apple. There are others, including Microsoft. But I want to compare just IBM and Apple. These two companies have similarities, and differences.

IBM and Apple are both hardware companies. Apple is still a hardware company, although its main business is phones and not computers. IBM is more of a services company; it was a hardware company in 1981 when it introduced the IBM PC.

Both companies innovated and both companies created designs that influence the market today.

IBM introduced the detached keyboard (other systems were all-in-one designs or keyboard-and-CPU with a separate display). IBM also introduced the internal hard drive, the original 8-inch floppy disk, the 3.5-inch floppy disk, the ThinkPad TrackPoint (the "pointing stick"), and the VGA display and video card.

Apple introduced the mouse for personal computers (the original mouse was two decades earlier and for a system much larger than a PC), the PowerBook laptop (a year before the first ThinkPad), AppleTalk, touchscreen for iPhones, and (notably) iTunes which gave consumers a reliable, legal way to load music onto their devices.

Apple stands out in that it innovates not just by adding features, but by removing them. Apple was first in delivering a computer without a floppy drive, and then a computer without a CD drive. Apple famously removed the headphone jack from its phones. It also omitted the Home, End, PgUp, and PgDn keys on its laptops, going back as far as the first PowerBook. (As the PowerBook was not compatible with the IBM PC, it had no need of those keys.)

Apple, more than IBM or any other hardware supplier, has innovated by removing things. The makers of Windows PCs and laptops had typically followed Apple's lead. They have, over time, removed floppy drives, CD drives, and most laptops now require specific multi-key presses for Home, End, PgUp, and PgDn.

IBM innovated by adding features. Apple innovates by trimming away features. That's quite a difference.

Of course, one can remove only so much. Apple has trimmed the phone to a simple slab with a single port for charging and data transfer. It has trimmed the Macbook to a thin wedge that opens to a screen, keyboard, and trackpad. There is very little left to remove, which means that Apple has little room to innovate along its traditional methods.

But notice that Apple's innovation-by-reduction has been in hardware. Its operating systems are not the equivalent of a slim wedge. To the contrary, Apple's mac OS and iOS are somewhat bulky, which is something Apple shares with Windows and Linux.

Of the major operating systems, mac OS probably has the best chance of slimming. Apple has the "remove things to make it better" mindset, which helps to remove features. Apple also has close integration between operating system and hardware, and drops support for older hardware, which lets it remove drivers for older devices. Windows and Linux, in contrast, want to support as much hardware as they can, which means adding drivers and allowing for older devices.

Let's see if Apple's "less is more" approach works it way into mac OS and into Swift, Apple's favored language for development.

Thursday, July 16, 2020

Low code and no code still require thinking

One of the latest fads in tech is the "low code" (sometimes called "no code") approach to application development. This approach lets one construct an application without programming. The implication is that anyone can do it, and that one does not need to study programming or hire a programmer.

In a sense, all of this is true. And yet, it is not quite true.

Nor is it new.

Let's look at the "low code is really old" idea.

We have seen "low code" development for decades. It comes and goes, a cycle almost in sync with cicadas (which emerge from the ground every seventeen years).

It has been called different things in the past: "Report Program Generator", "Powerbase", "Fourth Generation Languages", and possibly even "COBOL" (which was hawked as a way for managers and non-programmers to read -- although not write -- code).

Each incarnation of low-code solutions uses contemporary technology, and always uses mid-grade, generally available hardware. The idea is to make these solutions available to everyone, or at least a large portion of the population, and not require expensive or specialized equipment. The 2020 version of "low code development" includes cloud-based, web-based, multiuser applications that run on servers and are accessed by a web browser.

There are multiple vendors offering different solutions. Some solutions are little more than multi-user spreadsheets with templates for data entry and charts. Others are more sophisticated. But all share a common trait, one that has been in all low-code solutions over time: they build what they build, with little room for expansion or customization. Low-code solutions offer a room with walls, and you can move anywhere in that room -- until you reach a wall.

(Tech-savvy folks will observe that *all* programming solutions, including the high-end hardware and sophisticated programming languages, are "rooms with constraining walls". Computers are not infinite, nor are compilers, processors, and databases. You can do only so much, and then you must stop. All programming methods, high-code and low-code, have limits. But the low-code methods have more restrictive limits.)

My complaint is not about the limits, though. My complaint is about the unstated assumption that anyone can quickly build an application.

Any programming solution, high-code or low-code, requires more than programming. It requires an understanding of the data, and that data is used within the organization. It requires that the person building the application know the range of data values, the properties of individual data elements, and the ways in which those elements can be combined.

In other words, you still have to know what you want to do, you have to understand your data, and you have to think. Even for a low-code solution. Building a solution without the proper analysis and thought can lead to the wrong solution.

Low-code solutions are good for simple tasks, when those tasks are well-defined, have few (or no) exceptions, and do not have high performance requirements.

The high-code solutions require more planning and more coding (of course!), but offer greater expansion capabilities and more customization. You can detect specific conditions and add special processing for unusual cases. High-code languages also offer support for performance analysis such as profiling. 

Another unstated assumption is that once you have built your solution (low-code or otherwise), you are done. Experienced programmers know that programs and systems are not static, that they grow over time as people think of new uses for them. Low-code solutions tend to have little headroom, little upward potential. (They do what they do, and no more.) High-code solutions can be built in ways that let them expand easily, but such expansion is not guaranteed. I have seen any number of custom, high-code solutions that could not expand to meet the growing demands of the business.

Low-code generating systems have a place in the world. One can argue that spreadsheets are the extreme in low-code solutions (if we omit the macros written in VBA). Yet even spreadsheets require us to understand the data.

Selecting a low-code solution over a high-code solution is about trade-offs: ease-of-use (for the low-code solutions) against expansion and tuning (in the high-code solution). Which is better for you will depend on the task at hand, the people you have and their skills, and the future uses of the data and the developed system.

I favor simplicity, and consider solutions in terms of their complexity. I try to use the simplest technology for the solution,

First, consider using a spreadsheet. If a spreadsheet will handle the data and do what you need, use it.

Second, consider a low-code solution. If a low-code app will handle the data and do what you need, use it.

Finally, consider a high-code solution. If the simpler solutions don't do what you need, use the high-code solution.

But think about what you need, about your data, and about the limits on different solutions.

Then decide.

Wednesday, July 8, 2020

Remote work was a perk, now it may be the norm

Before the 2020 COVID-19 pandemic, remote work was unusual, and office work was the norm. After the pandemic, which will be the perk and which the norm?

During the pandemic, for many companies -- especially those which develop software -- remote work has become the norm. But that is during the pandemic. I am thinking about the period after the pandemic.

I am quite certain that companies that have switched from the pre-pandemic configuration of a large office building full of analysts, programmers, testers, and system administrators to the pandemic configuration of a large empty office building with analysts, programmers, testers, and system administrators working at home have noticed that their large office building is ... empty. I am also certain that someone in those companies has "done the math" and calculated the savings in keeping those employees working from home and moving the necessary employees to a much smaller office building.

(I am also certain that most office buildings are leased, and the owners of said buildings have looked at the possibility that their clients will want to move to smaller quarters. But back to the client companies.)

It is clear that after the pandemic, at least some companies will switch to a permanent "work from home" strategy. Twitter and a few other notable companies have made such announcements. But will all companies do so?

The 2020 COVID-19 pandemic may bring about a change to corporate culture. The pre-pandemic mode of thought (employees work in the office except for a few favored individuals) could switch to a new mode of thought, namely "employees work from home except for a few favored individuals".

It is possible, although unlikely, that all companies will change to this new mindset of remote work as the norm. It is more likely that some companies will change and some companies will stay with the original idea of remote work as a perk.

And it is quite possible that some of the former will adopt a second mindset of "office work as a perk". That is, the mirror reflection of what we had prior to the pandemic. Instead of remote work considered a perk, granted to a few individuals, some companies may consider office work the perk, granted to a few individuals.

What's more, the job market may be fractured between companies that want remote workers and companies that want in-office workers. This may lead to additional details in job postings ("remote only", "remote but in same time zone", and "in-office only", or "in-office at least three days per week"). The one standard arrangement of working in an office five days a week may no longer apply.

In the long run, I think the "remote as norm" strategy will dominate. The advantages of "work in the office" seem to be informal conversations and better communication through body language, neither of which can be expressed in dollars. The advantages of remote work can, in contrast, be calculated in dollars (the cost of not leasing the office building with its desks and chairs, minus the cost of securing communications to remote office workers).

Looking at past performance, hard factors (dollars) win over soft factors (non-dollars). We can look to past labor movements and labor laws. Child labor was prevalent -- until outlawed. Work was 10-hour days and six days per week, until the forty-hour work-week was enforced (or at least strongly encouraged) by labor law. Discrimination by age, gender, and race were the practice, until outlawed.

Before anti-discrimination laws, one may have argued that it made sense to hire the person with the best qualifications regardless of race or gender, but companies somehow hired mostly white males for the better jobs. Practices that just "make sense" weren't -- and aren't -- necessarily adopted.

Work in the office may "make sense" for some things, but the economics are clear. I expect companies to take advantage of the economics, and switch workers to remote work. I also expect that remote work will be assigned by a person's position in the corporate hierarchy, with executives and managers working in offices and "worker bee" employees working from home.

Some companies may even offer work in the office as a perk for certain positions.

Thursday, July 2, 2020

Rough seas ahead for Intel

Apple's announced that it is switching processors from Intel to ARM. (For the MacBook. Apple has used ARM for iPhone and iPad for years.) This announcement indicates problems for Intel.

But first, some thoughts on "market leaders".

We like to think that markets have leaders, and those leaders set the direction and pace for the market, much as a squad leader in the military sets the direction and pace for the squad. Let's call this the "true leader".

There is another type of leader, one that instead of setting the direction and pace, looks at the crowd and runs out in front, and then claims leadership. Let's call this the "opportunistic leader".

So is Intel a true leader or an opportunistic leader? I think it is the latter.

One could argue that Intel lost its ability to lead the market in the mid-1980s, with the specific culprit being the IBM PC. Prior to the IBM PC, the market for personal computers was fractured, with different manufacturers using different processors. Apple and Commodore used the 6502, Tandy used the Zilog Z-80 in the TRS-80, and lots of others used Intel's 8080. Intel had the 8088 and 8086 processors, but very few manufacturers used them.

In the 1980s, Intel had a plan for the future of microprocessors - the iAPX line. It was a plan that built on the 16-bit 8086 but expanded to different architectures as the processors became more powerful. There were several specifications for processors, culminating with the iAPX 432 a 32-bit processor. (At the time, this was impressive.) The more powerful processors were not compatible with the 8-bit 8080, or (notably) the 16-bit 8086. It was a nice plan.

The IBM PC and the market for the IBM PC invalidated that plan. People wanted the IBM PC, which meant the Intel 8088. Later, it meant the IBM PC AT with the Intel 80286, which was not an iAPX processor.

This shows that Intel was not leading the market in the "true leader" sense.

Want another example? Let's look at "itanium", Intel's attempt at 64-bit architecture. (Also known as "IA-64".) It was a processor that was not compatible with the existing 32-bit software. Worse, it has a design that pushed work to the compiler, and some of that work was not determinable at compile time. AMD countered with x86_64, a design compatible with existing 32-bit code, and customers wanted that instead of Intel's offering. They wanted it so much that Intel eventually adopted the x86_64 design and abandoned IA-64.

I think these two examples show that Intel is more of the opportunistic leader than the true leader. Intel can design processors, and can design and manufacture the chips and build the support circuitry, but it's business strategy is to run out in front of the market.

Which brings us to Apple and ARM processors.

Apple has announced that it will switch from Intel processors to ARM processors for its Macbook laptops.

Is Apple a true market leader? Or are they opportunistic, running out in front of the crowd?

It doesn't matter.

It may be that Apple's decision will "move the market". It may be that Apple's "spidey sense" has detected a desire to shift to ARM processors, and Apple is first in the market to make the change. Whichever reason, Apple is doing it.

I think that not only Apple will shift from Intel to ARM, but the rest of the market will, too. For two reasons: cost and efficiency.

People will want computers with ARM processors because they (the computers) will have a lower price. 

People will want computers with ARM processors because they (the computers) will be more energy-efficient. (Which means a longer battery life.)

People who buy computers generally don't care about the processor. They care about running applications, and ARM can deliver that.

Windows is ready to move to ARM. Linux is ready to move to ARM. Apple is not only ready to move to ARM but is in fact moving to ARM.

What will happen to Intel?

Intel has a definite problem. They have lost the low-end market for processors. They are losing the mid-range market for processors.

One might think that Intel may find haven in high-end processors, running servers and other high-power computers. And there may be some space for them, but there is a problem: IBM.

IBM has staked out the top end of the market, with System/z processors (the successor to IBM's System/360, System/370, and System/390 processors) running the big servers that host virtual machines. IBM has a competent business there, one that will not be easily displaced by Intel's x86 processors.

Intel has a market that it being eaten by ARM at the bottom end and limited by IBM at the top end. Not an enviable position.

And certainly not a market leader, in any sense.

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.