Simplicity and Global Mutable Values

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.

Interface Normalization

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.

Half Constructed Objects Are Unnecessary

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.

Component Simplicity

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.

Applying Purity To The Imperative World

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.

Introduction to Applying Functional Programming Lessons in Imperative Code

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.

Some Programming Language Ideas

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.

VR Has Had A Phase Change And I Didn't Know It

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.

Go FAQ: The Pipe Operator In Generics Is Not A Sum Type

An increasingly-frequently asked question in the Go subreddit is some variant of: “I have this code but it isn’t doing what I expect it to do.” type MyStruct struct { // definition } type OtherStruct struct { // definition } type MySumType interface { MyStruct | OtherStruct } func main() { myStruct := MyStruct{...} printVal(myStruct) } func printVal[T MySumType](in T) { switch val := in.(type) { case MyStruct: fmt.Println("It's a MyStruct") case OtherStruct: fmt.

This Post Is Not About Python

Pure Python is generally a slow language. Written for performance, it will often be around 40-50 times slower than C, and Python “written for performance” is Python that is very straightforward and does not use many of its features. Python code that has a couple of methods on inherited classes, maybe a non-trivial decorator, and some __getattr__ or similar features can slow down multiplicative factors beyond the 40-50 slower very quickly.