Up to this point I have not followed through on my promise to offend everyone in general, and in particular, functional-programming-in-imperative-languages advocates. Everything’s been pretty positive about functional programming.
This is where the tide is going to start to turn, but I’m going to lead into it a bit before getting really offensive.
“Programmable Semicolons” Let’s talk about monads, and in particular, monads in their capacity as “programmable semi-colons”.
If you understand why monads are “programmable semicolons” it’s a reasonably good sign you have a good understanding of them.
Functional programming languages see types not just as buckets of things that can contain values, but as assertions, e.g., this is not just a string that I vaguely hope is a Username, but this is a validated, certain-to-exist Username for a user, and anything that receives an input parameter to some function that is a Username need not run its own validation code on the Username to ensure it is valid, and thus also doesn’t need an error path for invalid Usernames.
At the beginning of this series, I said I was going to annoy every programmer in the world in some way or other. So hang on, here comes one of those super hot takes that I was promising:
Global variables… are bad.
Alright, for those of you who were not so offended that you instantly snapped your browser window shut, obviously I am aware that this is not news. The higher-skill end of the programming world was well aware that global variables are dangerous since before functional programming1 was even conceived of.
This is another lesson that does not require functional programming to notice, but it is a lesson that functional programming puts front and center whereas independently discovering it from imperative programming may take a long time.
Functional programming derives (pun intended) a lot of benefit from its typeclasses, despite them in some sense being second-class citizens in the expression problem to sum types. Much code is written against small interfaces like “functors” or “monads”, which can then be applied to any value that fits into those interfaces.
Functional programming languages of the type I’m talking about have immutable objects1.
For this particular section I’m just going to be talking about “immutability”, so in addition to Haskell, I also include Erlang and any other language with immutable values only. This does not includes languages that merely encourage them, but permit mutability; this discussion is about 100% immutable langauges, where mutation is held not just at arm’s length, no matter how “long” that arm may be (Rust), but outright eliminated.
There is a common metaphor for hyperspace travel in science fiction, where some scientist type explains how the FTL works by taking a piece of paper, drawing a line on it to demonstrate “normal” travel, then folding the paper to bring the origin and destination together.
Imperative code affords straight line approaches to problem. I have some code. It does 73 things. I need it to do a 74th thing, in the middle of one of the things it currently does, which is itself a complicated mixture of the other 72 things going on.
One of the distinguishing features of functional programming is an emphasis on pure functions. I will start with an initial sloppy definition of purity to get us started, and will refine it into a range of definitions later. If you don’t like this first one, bear with me.
For now we’ll go with, a pure function is a function that considers only its inputs or immutable external values, makes no changes to any other values, and returns the same result given the same parameters every time.
I recommend to any professional programmer that they spend some time with a very strict functional language, enough to get to the point they can write non-trivial programs in it.
For the purposes of these posts, you can read functional programming as Haskell. There is an earlier definition of functional programming that just involves having closures, but as all modern1 languages have closures now that is no longer a relevant definition.
Programming languages seem to have somewhat stagnated to me. A lot of shuffling around ideas that already exist, not a lot of new ones.
This is not necessarily bad. Shuffling around ideas that already exist is a natural part of refining them. Shuffling around ideas that already exist is safer than a radical rewrite of existing convention. Even taking a language that already exists and giving it a new standard library can be worthwhile.
To set expectations, this is not a sweeping review of the entire industry; indeed, quite the contrary. This is just one guy’s story about his limited experiences with VR gaming.
About five years ago, the office I work at allowed some interested employees to host a “VR Gaming” event in the main conference room. It wasn’t sponsored by the company, so it was put on just by the enthusiasts that happened to work there.