Is It 1998 Again?

Set the Dial to 1998

Let’s power up the time machine and take a quick trip back to the wide world of tech around 1998. Microsoft was the Khaleesi of software and controlled a vast empire through Windows, Office, and Internet Explorer. Microsoft marched its conquering army of apps over the desktop and through the Internet with innovations like XMLHttpRequest, USB peripherals, and intelligent assistants.

All three of these innovations would go on to fashion the world we live in today with websites that look and feel like apps, devices that plug and play with our computers and phones, and helpful voices that do our bidding.

But back in 1998 these groundbreaking technologies were siloed, incompatible, and unintuitive!

  • You’d find that fancy web apps were usually tied to a specific browser (Walled Garden).
  • You’d buy a USB mouse and often find that it couldn’t wiggle your pointer around the screen (Standard Conformance).
  • You’d grow frustrated with Clippy (aka Clippit the Office assistant) because the only job it could reliably do was “Don’t show me this tip again.” (Poor UX).

And this is exactly where we are in 2018! Still siloed, incompatible, and unintuitive!

  • Do you want to run that cool app? You have to make sure you subscribe to the wall garden where it lives!
  • Do you want your toaster to talk to your doorbell? Hopefully they both conform to the same standard in the same way!
  • Do you want a super intelligent assistant who anticipates your every need, and understands the spirit, if not the meaning, of your commands? Well, you have to know exactly what to say and how to say it.

Digital Mass Extinction

The difference between 1998 and 2018 is that the stakes are higher and the world is more deeply connected. Products and platforms like Apple’s iOS, Google’s Cloud IoT Core, and Amazon’s Alexa existed in 1998–they just couldn’t do as much and they cost a lot more to build and operate.

In between 1998 and 2018 we had a digital mass extinction event—The dot com bubble burst. I was personally involved with two companies that didn’t survive the bubble, FlashPoint (digital camera operating system) and BitLocker (online database application kit). Don’t even try to find these startups in Wikipedia. But there are a few remains of each on the Internet: here and here.

Today, FlashPoint would be reincarnated as a camera-based IoT platform and BitLocker would sit somewhere between iCloud and MongoDB. Yet the core problems of silos, incompatibility, and lack of intuitive control remain. If our modern day apps, IoT, and assistants don’t tackle these problems head-on there will be another mass extinction event. This time in the cloud.

How To Avoid Busting Bubbles

Let’s take a look at the post-dot com bubble burst world for some clues on how to prevent the next extinction. After the startups of the late 1990s died-off in the catastrophe of the early 2000s the designers, developers, and entrepreneurs moved away from silos, proprietary standards, and complicated user experiences. The modern open standards, open source, and simplicity movements picked up steam. It became mission critical that your cool app could run inside any web browser, that it was built on battle tested open source, and that no user manuals were required.

Users found they could buy any computer, use any web browser, and transfer skills between hardware, software, and services. This dedication to openness and interoperability gave great results for the top and bottom lines. Tech companies competed on a level playing field and focused on who could be the most reliable and provide the highest performance and quality. Google and Netflix were born. Apple and Amazon blossomed.

Contrast that with the pre-bubble burst world of 1998 (and 2018) where tech companies competed on being first to market and building high walls around their proprietary gardens.

If we want to avoid the next tech bubble burst (around 2020?) we need Apple, Google, Amazon, and even Netflix to embrace openness and compatibility.

  • Users should be able to talk to Google, Siri, and Alexa in exactly the same way and get similar results (UX transferability).
  • Users should be able to use iOS apps on their Android phones (App compatibility).
  • Users should be able to share connected and virtual worlds such that smart speakers, smart thermostats, and augmented reality work together without tears (Universal IoT bus).

Google and Apple and Standards

At Google I/O last week the Alphabet subsidiary announced a few of examples of bubble avoidance features…

  • Flutter and Material Design improvements that that work as well on Android as they do on iOS.
  • AR “cloud anchors” that create shared virtual spaces between Android and iOS devices.

But sadly Google mostly announced improvements to its silos and proprietary IP.  I’m sure at the WWDC next month Apple announce the same sorts of incremental upgrade that only iPhone and Mac users will benefit from.

Common wisdom is that Apple’s success is build on its proprietary technology from custom chips to custom software. This is simply not true. When I was at Apple in the 1990s success (and failure) built on a foundation of standards, like CD-ROM, USB, and Unicode. Where Apple failed, in the long run, was where it went its own incompatible, inoperable, way.

In the 1998 the macOS was a walled garden failure. In 2018 macOS is a open source BSD Unix-based success. More than Windows, more than ChromeOS, and almost as much as Linux, macOS is an open, extensible, plug and play operating system compatible with most software.

The Ferris Wheel of Replatforming

Ask any tech pundit if the current tech bubble is going to burst and they will reply in all caps: “YES! ANY MOMENT NOW!!! IT’S GONNA BLOW!!!”

Maybe… or rather eventually. Every up has its down. It’s one of the laws of thermodynamics. I remember reading an magazine article in 2000 which argued that the dot com boom would never bust, that we had, through web technology, reached escape velocity. By mid-2000 we were wondering if the tech good times would ever return.

Of course the good times returned. I’m not worried about the FAANG companies surviving these bubbles. Boom and bust is how capitalism works. Creative destruction as been around as long as Shiva, Noah, and Adam Smith. However, it can be tiresome.

I want us to get off the ferris wheel of tech bubbles inflating and deflating. I want, and need, progress. I want my apps to be written once and run everywhere. I want my smart speaker of choice, Siri, to be as smart as Google and have access to all the skills that Alexa enjoys. I want to move my algorithms and data from cloud to cloud the same way I can rent any car and drive it across any road. Mostly, I don’t want to have to go back and “replatform.”

When you take an app, say a banking app or a blog, and rewrite it to work on a new or different platform we call that replatforming. It can be fun if the new platform is modern with cool bells and whistles. But we’ve been replaforming for decades now. I bet Microsoft Word has been replatformed a dozen times now. Or maybe not. Maybe Microsoft is smart, or experienced, enough to realize that just beyond the next bubble is Google’s new mobile operating system Fuchsia and Apple’s iOS 12, 13, and 14 ad infinitum…

The secret to avoid replatforming is to build on top of open standards and open source. To use adaptors and interpreters to integrate into the next Big Future Gamble (BFG). macOS is built this way. It can run on RISC or CISC processors and store data on spinning disk or solid state drives. It doesn’t care and it doesn’t know where the data is going or what type of processor is doing the processing. macOS is continuously adapted but is seldom replatformed.

To make progress, to truly move from stone, to iron, to whatever comes after silicon, we need to stop reinventing the same wheels and instead, use what we have built as building blocks upon which to solve new, richer problems, to progress.


Swift Programming: Filtering vs For Loops

The current version 3.1 has come a long way from the Yet-Another-C-Based-Syntax of the 1.0 version of Swift.

One of the best features of Swift is how functional programming idioms are integrated into the core of the language. Like JavaScript, you can code in Swift in several methodologies, including procedural, declarative, object-oriented, and functional. I find it’s best to use all of them all simultaneously! It’s easy to become a victim of the law of diminishing returns if you try to stick to one programming idiom. Swift is a very expressive coding language and it’s economical to use different styles for different tasks in your program.

This might be hard for non-coders to understand but coding style is critical for creating software that functions well because a good coding style makes the source easy to read and easy to work with. Sometimes you have to write obscure code for optimization purposes but most of the time you should err of the side of clarity.

Apple has made a few changes to Swift that help with readability in the long term but remove traditional C-based programming language syntax that old-time developers like me have become very attached to.

The most famous example was the increment operator:

In modern Swift you have to write:

As much as I loved to type ++ to increment the value of a variable there was a big problem with x++! Most coders, including me, were using it the wrong way! The correct way for most use cases is:

Most of the time the difference in side effects between ++x and x++ were immaterial, except when it wasn’t and it created hard to track down bugs in code that looked perfectly ok.

So now I’m used to typing += to increment values even in programming languages where ++ is legal. (Also, C++ should rebrand itself as C+=1.)

Another big change for me was giving up for-loops for functional expressions like map, reduce, and filter. As a young man when I wanted to find a particular object in an array of objects I would loop through the array and test for a key I was interested in:

Nothing is wrong with this code—it works. Well, actually there is a lot wrong with it:

  • It’s not very concise
  • I should probably have used a dictionary and not an array
  • What if I accidentally try to change o or objects inside this loop?
  • If objects is a lengthy array it might take some time to get to 12345
  • What if there is more than one o with the id of 12345?
  • This for-loop works but like x++: it can be the source of subtle, hard to kill bugs while looking so innocent.

But I’ve learned a new trick! In Swift I let the filter expression do all this work for me!

In that single line of code o will be the first object that satisfies the test id == 12345. Pretty short and sweet!

At first, I found the functional idiom of Swift to be a little weird looking. By weird I mean it looks a lot like the Perl programming language to me! But I learned to stop being too idiomatic and to allow myself to express functional syntax as needed.

For you JavaScript or C programmers out there here is a cheat sheet to understanding how this functional filtering works:

  • let means o is a constant, not a mutable variable. Functional programing prefers constants because you can’t change them accidentally!
  • The { } represents a closure that contains a function and Swift has special syntactic sugar that allows you to omit a whole bunch of typing if the function in the closure is the last or only parameter of the calling function. (Remember in functional programming functions are first class citizen and can be pass around like variables!)
  • $0 is a shortcut for the first parameter passed to your closure. So you don’t have to bother with throw away names like temp or i,j,k,x, or y.
  • .first! is a neat way to get [0], the first element of an array. The ! means you know it can’t fail to find at least one element. (Don’t use the ! after .first unless you are 100% sure your array contains what you are looking for!)

I’m working on a new project, a game that I hope to share with you soon. The game itself won’t be very interesting. I find that I enjoy creating games more than I enjoy playing them so I’m not going to put too much effort in creating the next Candy Crush or Minecraft. But I will blog about it as I work thought the problems I’ve set for my self.

The Rise and Fall of Autocorrect

I’ve turned off “auto correction” on my iPhone and it’s a godsend. I still get predictive suggestions and spelling correction. But I no longer have to fight with autocorrect and end up with wrong but similar words in my emails and texts.

When the iPhone first arrived in eight years ago we needed autocorrect because we lost the keyboard. We were nervous anout the loss of physical targets for our thumbs to hit. Many early iPhone reviewers complained about the perils of “typing on glass” and I still see email signatures asking my forgiveness for the author’s use of a phone without buttons. 

After nearly a decade of glass typing my thumbs are well trained. I type almost as fast with two thumbs as I do with 10 fingers. Every once in a while I try one of these smart mini keyboard attachments and I’ve discovered I can’t type on a phone with real keys. Physical buttons sized to fit a modern smart phone form factor are just too cramped for my thumbs to fly like a virtuoso pianist.

Autocorrect has been slowing me down and embarrassing me for ages. It transforms “can’t” into “can” and non-western European names into insults. Autocorrect wants me to spell the name of my company, Viacom, in ALL-CAPS. I don’t understand that one. Maybe in world where Apple’s autocorrect text engine gets its data VIACOM is the correct way to type it. But not in my world. 

And that is the big issue with autocorrect. We each have our own style of spelling and grammar. These stylistic variation enrage the grammar police but give our text personality and nuance. Autocorrect enforces uniformity and hurts out ability to express our ideas in an idiomatic fashion that allows us to create personal and community languages. 

Humans are born as language creation machines. We develop new words that express our POV on both new ideas. We repurpose old words to express new concepts while referencing tradition. Autocorrect messes with our ability to say what we mean and mean what we say. 

I’ve been communicating without the mediation of Autocorrect for about a week now. I’m typing at about the same speed. I’m making less causal mistakes and “speaking” in my true voice. I’m not fighting with an annoying helpful AI trying guess at what I mean. The only downside so far is that my “I” are longer capitalized by magic. I had to relearn to tap the shift-key. 

— Typed without regrets on an iPhone with autocorrect disabled. All mistakes are my own. 

The Secret to Swift is Enums

I’ve found the CS193P (Developing iOS 8 Apps with Swift) iTuneU class really helpful in wrapping my old Objective-C head around Apple’s new Swift programming language. Yes, I know we’re at iOS9 but the fundamentals of the class are still relevant and coaxing the code to compile in iOS 9/Swift 2.0 is a fun little last in and of itself.

The big revelation for me is how core Swift’s enums are to understanding and using the language properly. When Apple decided to improve it’s development environment it could have done so in a million different directions. Apple could have just patched up Objective-C. Apple could have moved over to Java or Scala or even JavaScript. (I was hoping for  JavaScript as Node.js and ECMAScript 6 have proved that JavaScript is an industrial strength language with a real future.)

So when I learned that Apple created a new language for iOS and Mac OS X (and now WatchOS and tvOS) application development I was intrigued and disappointed and hopeful all at the same time. Many parts of Swift seems easy and cool but some parts were down right intellectually challenging: Classes and Structs? Super fancy Enums? Optionals? Strings with out a simple function to get their length? What the heck is going on here?

Swift seemed promising. But it was also changing rapidly over the last year. I fooled around with it but when I hit optionals and weak references I realized the language was not going to sugarcoat the problems of null pointers and memory management–it was trying to make them more tractable.

Optionals were especially vexing. var amount: Double? was not a Double. It was a potential Double. Amount! had better be a Double or it would crash my program. If it was’t for Xcode’s automated static code analysis I never would have been able to put the ? and ! in the right places after the right variable names. And I didn’t like that feeling.

But then I found CS193P and Professor Paul Hergarty’s remarkable ability to explain things simply.

Enums in Swift are amazing little machines. They have little in common with C Enum other than you can use them to define collections of related constants. Enums are types with values that evaluate to themselves. But  you can associate a “raw value”, like a number or a string, or more a advanced value, like Tuples or Arrays or Dictionaries. And with advanced types come functions and closures.

Yikes. These are not your father’s Enums. As Professor Hergarty’s says, Swift Enums are types used for when you want to switch between values. And, point of fact, Swift Enums are defined like a Switch structure with case statements. Each of the cases, except with raw values, can be of different types.

And boom! That explains Optionals. When you have a value that could be nonexistent or of some type, an Optional is just an Enum that wraps up it safely so you can pass it around without crashing. ? and ! are just syntactic shortcuts for accessing the different states an Optional variable might be in. Imagining that Optionals are Enums gave me the handle my mind needed to process the whole concept.

In CS193P Professor Paul Hergarty uses an Enum to power his “Calculator Brain”. In any other programming language an Enum would be used to make the code more readable. But in Swift you can use an Enum as the glue to associate states with types with functions. I have a feeling that this Enum-driven mechanism is the cleanest way to write a Swift state machine. It’s still a little rough around the edges and verbose. But it’s a super reusable pattern good not only for the mathematical operations of a calculator but for managing the states of a web server, business application, or game.

You should watch all the videos in CS193P to get the full picture. But in the meantime I’ve created a simplified version of Professor Hergarty’s CalculatorBrain suitable for a Swift Playground (above). As you fool around with the code keep in mind the following points:

  • CalculatorBain is a class and when it’s instantiated it’s initializer creates a dictionary of operations that it knows about based on type. You can add more known operations by writing a little code in one place. In the sample code the operations for addition, subtraction, division, and multiplication are written very concisely using Swift’s shortcut syntax for closures with default parameter names. (This reminds me of the best features Perl.)
  • The custom type Op is an Enum that is self documenting and has values associated with either a Double (for operands) or a Dictionary (for operations indexed by name). So simple lookups via a case statement are all that is needed to process input and output a result.
  • The two Evaluate functions are recursive, calling each other until every operand or operation needed in the Ops stack is consumed. Evaluate basically does this:
    • Until the Ops stack is empty pull an item off the end of the stack.
    • If that item is an Operand return it and the remainder of the Ops stack.
    • If that item is an operation dig into the Ops stack until you can get two operands and then execute the function associated with the operation using the operands.
    • The return the result with the remaining Ops stack.
  • If I had to write this code without using recursion and without Swift’s muscular Enums, well, there would be a lot more code and it would be more “hard coded”.

The only improvement I can think of would be to declare the known operations as a literal Dictionary. But the Swift compiler isn’t ready for that and complains: “Expression was too complex to be solved in reasonable time”. I guess if Swift can’t do something swiftly it doesn’t want to do it at all!