I am mediocre at writing and mediocre at composing music. Yet I still publish what I make.
I don't believe what I make to be good, and I'm aware of the shortcomings. Still I put in my best effort when I make stuff, and make it as good as I possibly can.
Because, how could I ever become better if I don't dare to be bad? I'm not afraid to show the struggle, and I welcome the criticism.
Sure I must still read and study. Refining, exploring, and sharpening my skills by myself. But if none is ever shown, it makes me the only lonely critic, blind to my own failures.
The goal is the struggle and challenge. I know that being wrong and making mistakes is one of the best way to improve. I want to get criticism, and want to embrace and learn from it even if it is painful. I don't want to outsource my thinking, but struggle through the process. Improvement for its own sake.
Maybe that shows it value at some point. Virtue is the goal for now, and that is good enough for me.
I love strong types. They solve a frustrating group of issues where a variable's type is too general, potentially causing very subtle bugs.
In simple terms, strong types prevent accidental mixing of types. If I just told you a number like "5.5", you would have no idea what that number actually represents (is it kilograms? meters? something else?). What strong typing gives is akin to me saying "5.5 meters" instead.
It is generally easy and very cheap to implement in pretty much any language with typing, and the value it brings is immediate.
I'll mostly use TypeScript in the examples below, but the principles are true in most strongly typed languages. At the end is a list of implementations and "further reading".
Motivating example
Let's say you stumble upon the following function:
functionfindItemById(itemId:number){// ...}
findItemById takes one number parameter. Any number can be passed in here, regardless of whether it is actually an item ID or not. It is therefore very easy to accidentally write something like this:
const itemId:number= model.itemIndex;// An index is not an ID!const item =findItemById(itemId);// Or this:const itemId:number= model.categoryId;// This is not the right type of ID!const item =findItemById(itemId);
The compiler would not give any warning or error. The code is correct, after all!
Although this is a very synthetic example, real code might not be as straightforward.
The solution
What we really want is a way to separate types, that have the same underlying primitive, from each other. So that we can write functions like this instead:
functionfindItemById(id: ItemId){// ...}// Now, the code would raise a compile-time error:const itemId:number= model.itemIndex;const item =findItemById(itemId);// Causes: error TS2345: Argument of type 'number' is not assignable to parameter of type 'ItemId'.
Suddenly the compiler is your friend, and tells you that something is wrong.
The solution is to force the type to be of a specific branded type:
interfaceBrandedType<BrandT>{
type: BrandT;// Replace the above line with this for a more lenient version that avoids// strict "as" coercion.// type?: BrandT;}typeIdType<T, BrandT>=T& BrandedType<BrandT>;typeItemId= IdType<number,"ItemId">;// Will cause an error like this: Type 'number' is not assignable to type 'ItemId'const itemId: ItemId = model.itemIndex;
Note that it is still possible to coerce it to be the right type, and with branding this is necessary:
Once a type has been coerced into the right type it will typically stay that way forever, so this significantly reduces the possible locations where the bug arises.
The most typical bug that happens, in my experience, is trying to use the wrong ID type in the wrong location. As the compiler now raises an error, the risk of that bug disappears.
const itemId: CategoryId = model.categoryId;findItemById(itemId);// Error: Argument of type 'CategoryId' is not assignable to parameter of type 'ItemId'.
Different languages have different ways to implement strong types. This is not really a tutorial about how to implement it (see instead the various implementations below), but a very strong encouragement to use it!
Although the gravityScale parameter is weakly typed, it is impossible to accidentally swap the parameters.
// This won't compileb2Body_SetGravityScale(2.0, bodyId);
But imagine the function was defined like this:
b2Body_SetGravityScale(int bodyId,float gravityScale);// This would then compile, possibly with a warning about casting float to int:b2Body_SetGravityScale(2.0, bodyId);
Again, because Box2D uses strong typing, a whole host of issues is removed, and the function itself quite clearly documents what it does.
Personal thoughts
In addition to reducing bugs, I find that using strong types makes code much easier to read and reason about.
Code is, after all, documentation. It tells us exactly what a piece of software will do. The clearer the code is, the easier it is to understand and the easier it is to modify. This is true whether it is humans or coding assistants that are working on a codebase. Both need a good foundation to be able to comprehend the logic.
By adding strong types, one can more strictly document what a parameter intends to do, in a way that is enforced by the compiler. This is much better than having just the parameter name documenting the purpose. Anything that isn't strictly enforced by the compiler will quickly drift as the code changes. This is why code comments often are misleading, they don't actually couple to the logic in any way!
Over my career I have moved more and more in the direction of stricter conventions. The more the compiler can help enforcing correct code, the easier it becomes to develop software. This is similar as to why I am increasingly averse to weakly typed languages, and why I virtually never generate code with assistants (they tend to reduce code clarity).
The codebase I use at work, for example, has been converted from JavaScript to TypeScript for this very reason. Before it was converted, it was quite difficult to know what all the members of a type were, or what parameters a function really took. But after the conversion, everything has become so much easier to work with.
Libraries / Implementations
See the Wikipedia page for an overview, including demonstrations in several languages.
I don't know what to call this genre, but I love it so much. The contrast between the playful and light, with existential horror just beyond safe comfort. I find too few explore this, and I wish it was more popular.
Wholesome innocence
My favourite books of all time are "Alice's Adventures in Wonderland", and "Through the Looking-Glass".
The narrative is simple, elegant, whimsical, and wanders from topic to topic. I find it is like a series of short stories sewn together. Each story exploring absurd situations through the eyes of the semi-reasonable Alice.
It is always silly and light-hearted. Like the caucus-race with no clear rules, where Alice is forced to give prizes even though everybody won. Or being asked by the caterpillar to eat the other side of a mushroom to grow larger (mushrooms of course famous for having two sides).
The world might be absurd, but it isn't scary or dangerous. Even when Alice is under the imminent threat of losing her head.
I love the joyous playful nature of it. A world with no real danger, just weird and strange things happening.
Dark abyss
But what lies just beyond the horizon? Just beyond the comfort of this silly playground?
Just like the paper thin atmosphere of Earth, our safe blanket under which we can live and breathe. Past it lies a world so incompatible with life you'd lose consciousness in seconds, and die in mere moments more. A place where, even if you're in a ship shielded from radiation, you'd still be bombarded by all manner of particles and waves.
And even beyond our own local playground lies things so incomprehensibly powerful they might as well be Lovecraftian beings: Black holes the size of our solar system, extremely powerful cosmic gamma-ray bursts, enormous supernovae, and all manner of lesser and greater threats to life.
The immense power of a supernova would light up as a beacon in the sky. Utterly terrifying if you were close to it, but if you were many light years away it would just be a pretty light in the sky. The same thing having two vastly distinct experiences, one of beauty, one of terror.
A black hole could be heading towards our solar system right now, nearly invisible. If large enough, or it hits the right location, it could completely mix up the solar system and cause indescribable chaos. Ending all life in the process. Being afraid of it doesn't help, because we're entirely powerless to stop it.
An aimless universe, with no ill intent, that it could destroy so much so fast. The terror of seeing something ever threatening in the distance makes the fertile Earth look so much more safe and comfortable.
Wholesome innocence, dark abyss
When I write fiction I find this combination, and contrast, so interesting.
The planet my fictional world is set on (which I for historical reasons call the Danmaku universe) has a serious and grounded character, with all manner of playful and whimsical locations and creatures.
Like the forest clearing with a patch of talking grass. They act as a chorus of voices speaking like an entire civilization, yet completely oblivious to their own lack of ability to do anything but rustle in the wind.
Or Siorei the treetop girl, a lesser god who is responsible for leaves falling from trees in autumn. She is furious at her believers for creating such a pointless god, but can't do anything about it as it would threaten her own existence.
All of this harmless and fun.
But there is a cosmic backdrop that makes the entire world bathe in a sea of otherworldly features. The horrible creatures from the realm of organics. A realm purely consisting of living flesh, indescribable in form and purpose. When someone looks at something from this realm they can't really understand what they're seeing, as if their vision gets blurred when looking at it.
Locations such as the vast void, where a flat membrane lines an infinite ground. In the sky are pitch black floating islands, only visible as they obscure the starry sky beyond. A place seemingly safe, unless one accidentally ends up on the islands by thinking the wrong thing.
But not everything is dangerous, just foreign and unknown. Like the Skotadi, a creature who appears extremely terrifying. It seemingly makes clones of itself, enlarges itself to appear like a terrifying monster, and attacks with immense power. Yet its only goal is to escape, and its illusions are just a defense mechanism. Someone attacked by it would only realize afterwards that their injuries are superficial.
All of this is an ever present threat. Being at the wrong place at the wrong time can force you to deal with something very foreign, and potentially very dangerous. But for most of the time it is something just beyond the lived world, that makes one appreciate the comfort of safety.
I really enjoy exploring this through the role-playing campaign I'm running. I want to write more posts about this universe in the future, as I've grown very fond of what it has become. And whatever this combination of genres could be called, lies at the heart of it.
What has happened in so few years? I feel I can hardly think anymore.
My mind is a mess, constantly bombarded by opinions about everything.
I can no longer act or express any thought, without a contrary suggestion.
I try to cancel it out. Block news, block opinions, block everything.
I want to focus on what I can see, feel, hear, touch. I want something real.
But no matter what I do, wherever I go, the mind gets forced to think. The marionette tugged by invisible
threads. I want less, but must endure more.
It is not that I don't care about the world, or that I don't care about us all.
I just can't care anymore. I am only capable of acting on what is close to me, on firm ground.
It is not that I don't want to learn and explore. But what is left to find, when
everything is a corruption of something else. No longer is anything connected to the
source, to terra firma. The truth so much laundered, no cloth remains.
I want to give, create, shape the clay I've been given. But what's the point?
What's the purpose? Is another thread tugging what we need?
The world ran ahead, leaving its heart and soul behind. I stand still, waiting for sunrise.