As We Think, We Do
The purpose of abstracting is not to be vague, but to create a new semantic level in which one can be absolutely precise. - Edsger W. Dijkstra
I owe you the second part to "Writing a Transpiler", and that will be delivered next week
This weekend I wrote a tweet I thought was straightforward.
It ended up being controversial.
The purpose of the tweet was to encourage those who are hesitant in learning C to simply do so. There are programmers that don't believe it's a good language to start with, or a relevant to learn at all.
The former part, they are semi-correct.
It can be difficult, and there aren't many great resources out there on building with C.
The latter part, however, are simply incorrect.
The world around you is powered by C/C++ code.
Most people take for granted the devices that use these languages to this day.
Our vehicles, TVs, smart home devices.
Anything with a tiny computer in it, you can bet its powered by C/C++ code.
Not to mention all the legacy codebases that are still relevant and in use today.
If you've been following me for a bit, you know I've been on the hunt for the "best" first programming language to learn.
The current contenders are C, C#, and OCaml.
OCaml is interesting and new to me. I picked it up a few months ago and still find myself learning new things everyday. It's a static, strongly typed functional language with high level syntax that compiles natively. Its a blast to write, and a top contender for a programming language to recommend to beginners.
C# is a language I am familiar enough with to be dangerous. It's an static, strongly typed imperative language used across the developer world. It's also a compiled language, and can be straightforward to understand for most.
The common thread between these two is they're both static, strongly typed languages. These kind of languages need you to be explicit in your code; you need to know what you're passing around and why.
C, however, is a static, weakly typed language. It has a lot of loopholes, footguns, and is notorious for being difficult to learn. The bane of many programmers, the reason many beginners quit, and the harbinger of security issues.
Yet, it still takes the top spot of my most recommended language to start with.
Why?
When you learn C, you reap immense benefits.
These benefits come in the form of learning mental models that allow you to reason about your code.
Mental models are an internal representation of external reality.
They rely on a small set of fundamental assumptions (axioms).
We depend on mental models to help us navigate through the world.
Mental models allow us to create abstractions, ways to reason about information rooted in first principles.
These mental models, however, have to be rooted in something that can be described precisely, or they do not work.
They also have to start simple, avoiding complexity to keep the model clear and understandable.
We understand how cars work without getting into the details. As drivers this is great; few of us are mechanics, and cars don't need us to be.
The same goes for computers.
As developers, though, we are the mechanics. We do need to know how the car works beyond conception. We want to build to our hearts content, and we want to be self sufficient in that endeavor.
So we build our mental models. Cars have engines, those connect to transmissions, that connect to the wheels...so on and so forth.
Engines are pistons creating combustible chambers to generate power, and thus need oil.
Understanding the inner workings allows us to harness and improve the machine.
Understanding the inner workings of a computer grounds our code and orient ourselves.
When I first started coding, I learned Python. I struggled with lists. They have elements and items, they contain them, but what are they used for? Why use them over a dict, tuple, or set?
I felt like I was swimming in dark water, not knowing which way was up or down.
I was drowning.
Then I started learning C because I had an interest in systems programming.
Within a few weeks of learning C, all my confused Python concepts began to make sense.
Lists represent sequences of values between two memory addresses.
Python's list is a C object, which is extremely complex and not how arrays work in C.
Gaps in my understanding began to disappear.
Finally, I had a way I could orient myself, and I stopped drowning.
Thats why I've decided Im going to write a series on building with C.
It will be beyond learning C syntax, focusing on building mental models for understanding how computers work.
I don't know what it looks like yet, but I do know it'll go over:
- Memory and managing it
- C syntax and semantics
- Demystifying pointers
- CPU instructions
- Developing mental models and abstractions that make sense
Of course, diagrams and visual aids will be apart of it, along with code blocks.
C++ will not be apart of it, as its a completely separate beast.
C is a small language that gets out of your way, and it gives you nothing. Thats why it can be difficult to use.
The end goal is to build a library of mental models you can pull from.
A lot of us have knowledge, but fewer of us know how to apply our knowledge
I want to leave you with this quote from the very famous, Richard Feynman:
You have to keep a dozen of your favorite problems constantly present in your mind, although by and large they will lay in a dormant state. Every time you hear or read a new trick or a new result, test it against each of your 12 problems to see whether it helps. Every once in a while there will be a hit, and people will say: "How did he do it? He must be a genius!"
- Richard Feynman
Hope you have a fantastic week!
Glitchbyte