Every programmer knows the feeling. You’ve written a few lines, tested them, and checked them into some repository. Now is the time to stop, take a breather, maybe reflect upon the majesty of it all, and then get back to obsessing about your latest programmer cult.
It doesn’t matter if you started your first programming class this fall or if you’ve been writing bit-banging code since it had to be toggled into the front panel of an Altair. There’s only so much fun to be had talking about mundane things like correctness or accuracy. Only the client prattles on about whether the code meets the specs.
The real adrenaline rushes come from wandering the moors like a poet, tormented and bedeviled by some finer nuance of the art of writing code. Gluing together variables and functions is boring. Life is only worth living when you jump on some bandwagon, fall in line behind some charismatic genius, and join some strident debate about the details of telling computers what to do.
Here are 10 of the most intoxicating pitchers of Kool-Aid you can chug.
Magical white space
Let’s start with one of the most intense debates, the question over how we structure the white space in our code. It’s a debate that’s literally about something you can’t see and often has no effect whatsoever. But the utter irrelevance doesn’t matter, because programmers can argue for hours about using tabs or spaces in their code or, even worse, how to include spaces inside the lines.
But let’s not get too caught up in the fact that most parsing algorithms don’t care about the white space and blip over the spaces and tabs without pausing. Calling them “white space supremacists” will only anger them. Let’s call them purists and celebrate their attention to detail because that’s all too rare today.
Curly brackets or tabs
The C language has given us many amazing ideas, but the most controversial may be using curly brackets to indicate the beginning and end of the block of code. Some people find it easy to unpack the nested blocks and figure out how the curly brackets match up. They understand that it was a great leap forward from the era of line numbers and GOTO statements.
There are others, though, who find the counting and matching to be a mess and not much of an advance over the old spaghetti code. For them, there’s a lot to like about the newer languages like Python and the data formats like YAML that use the indentation to indicate where the nested blocks begin and end. Sure, they’re constantly counting spaces or tabs instead of curly brackets, but that’s a step up for them.
You could choose to fly above this maelstrom and think that blocks of expressions are just blocks of expressions, but then you couldn’t join into the arguments. Choose your poison: curly brackets or tabs and never look back.
Coders love to write out their instructions to the computers in simple, clean, and concise lines and they like to issue these orders whenever it’s convenient and expedient. The trouble is that someone figured out it’s much easier to analyze and optimize software where the instructions are arranged in nice functions structured as black boxes with clearly defined inputs and outputs. Seemingly random instructions to increment some other variable or turn off some feature—what functional programmers call “side effects”—only complicate the matter.
The cult of functional programming believes that we should all aspire to this clean structure of functions that aren’t tossing side effects at random times. This makes creating bug-free, highly threaded code much simpler. Or so they believe.
There are now dozens of languages for true believers in the functional approach. And many of them bow to the reality that side effects sometimes make the code easier to create and maintain. Functional languages like Scala and Frege live within the world supported by the ubiquitous Java Virtual Machine, while Rust is the latest option for those who must write system code.
The devotees to functional programming tend to be academics who write complicated algorithms that tackle abstract mathematical topics—in other words some of the easiest algorithms to write in a functional way. The rest of the world deals with messier user interfaces for humans that don’t tend to think in nicely nested functional abstractions.
There are few functional options on the lists of the most popular programming languages, largely because programmers have grown tired of building the most common applications with a functional straightjacket on. The alternatives have taken names like imperative, declarative, and object-oriented programming. These aren’t so much counter-movements as much as collections or programmers who never got sucked into the functional cult and steadfastly refuse to join.
The first generation of languages liberated programmers from the need to keep track of the registers inside the CPU and refer to data with variable names like x. The programmers immediately abused this freedom and started jamming all kinds of data into variables everywhere. When this became too confusing, the smart programming language designers proposed asking the programmers to add just a few more characters next to the initial declaration of a variable—characters that would spell out the type of data that was going to be jammed into the variable. The computer could then double-check the computations and make sure that at least all of the data going into a function is the right type.
A group of mathematically minded programmers have created elaborate theories of typed data that imagine elegant and sophisticated hierarchies of types that converge on the one true and bug-free truth that will be returned at the end of the computation. The typed language cult aspires to create programs that approximate this beautiful ideal. They want rigorously defined types that allow the compiler to offer belts-and-suspenders assurance that there won’t be any bugs left by mistaken types.
As soon as the typed language lovers started getting traction, a counter-movement started to declare that much of the work of typing your data was sort of a waste of time. It’s not like programmers are going to try to add a string and an integer on purpose and then the program will immediately crash with an exception when it runs. It’s not like the compiler saves much time by flagging this problem a few minutes in advance.
The non-typed lovers imagine that it’s not worth the trouble to spell out a type each and every time it’s defined. Not only that, but the typing adds tight limitations on creating flexible data structures that adapt and improve as more data becomes available during the computation.
Not only that, but some of the automated compilers are becoming much better at reading our minds and inferring the right type of the variable. If the computers can just figure it out, shouldn’t we leave the housekeeping to them?
Low code / no code
Writing software is hard. So it’s no surprise that programmers will be inspired to create any automation that will save them the trouble of writing more code. When this automation gets sophisticated enough, the developers start to brag that anyone can create something sophisticated with little or no code.
The rub is that the work still requires thinking like a programmer about hidden abstractions and elaborate data structures. This thinking needs to be codified and set down some way or another like a JSON file or maybe some XML. The automators usually dismiss this work as mere configuration, but sometimes we can spend just as many hours fiddling with configuration files as we do with instructions written in official programming languages.
These details don’t matter too much. Programmers will always be drawn to automation because they hate doing the same thing twice. Even more important, the suits will always dream that the automation will cut their costs and lift the bottom line. This dream will sustain the low code or no code cult through months and months of twiddling with non-code options.
For the last 30 or 40 years, programming oracles have predicted that we would be clicking on icons, dragging around flowcharts, or waving our hands to tell the machines what to do. Anything but typing and adding keystrokes to some text file. Despite the predictions, the command line and the text-based programming languages just won’t die. If anything, programmers seem to love typing more than ever and the latest crazes seem to be all text.
Champions of privacy
People love their privacy and programmers are no different. If anything, programmers know just how invasive computers can be. The problem is that many business models involve using sophisticated software to anticipate what customers want. Sure, we could ask people directly, but most people are too busy to fill out another form. So the only way to make these business models work is to push aside the concerns about privacy… but just for this instance. When it’s a choice between a job and someone else’s privacy, it’s often no contest.
There are some interesting compromises. Privacy-preserving mathematics can work in some cases and there are some sophisticated ways of ensuring that we can provide some semblance of privacy while also offering cool new mind-reading features.
Champions of openness
Everyone loves the idea of open source and open standards—until it conflicts with their own business model by allowing competitors to thrive. Some of the biggest proponents of open source software are also the ones sustaining themselves with the most proprietary secret sauce. Google, for instance, has supported wonderful open source projects and publicly campaigned against digital rights management software that gives content creators the power to make some money. But if you ask about their search engine’s ranking algorithms, they draw the line. That’s not open.
They’re not alone. Most companies follow a flexible approach on openness. Openness is always good if it applies to someone else’s business model but not your own.
All of the above
While all of these cults sound absolute and the true believers act like the rules are laws handed down by an angry God ready to deploy lightning bolts, the reality is that the programming world is full of clever tricks that allow us to stretch definitions. It’s often possible to join two cults that seem in opposition—if you’re a bit clever in how you do it.
Some of the functional languages, for instance, are flexible enough to let you do some non-functional tricks if you feel the need. Meanwhile others will argue that even venerable bit-banging tools like C are ultimately functional programming languages. Some of the type haters undermine the type checking languages by just defining all functions to take the most generic objects in the type hierarchy.
There’s no reason why you can’t be just as clever and create your own combination of cults that mix together these different philosophies, no matter how much they seem to be in conflict. You’re the one writing the code. You’re the one giving orders around here.