Some language designs, most notably Java, conflate classes and types. They even go further by conflating subclassing and subtyping. This might be convenient but it causes a lot of pain.
Without a clear line for how they’re distinct it becomes hard to understand how either one really works. It makes certain language features and design tradeoffs opaque. For instance, it is key for understanding “type erasure”. It lies at the basis for why Scala’s
TypeTags are different from Java’s
ClassTags. It can also be an underlying thing that makes variance more difficult to understand.
Finally, certain design advice like the Liskov Substitution Principle actually apply to types and not classes. When using a language which conflates these ideas you still have to design your classes to respect LSP, but there’s a subtle sleight of hand occurring.
Continue reading “Classes and types are different”
The type checker isn’t your enemy at first. When you write hello world in your new typed language and you try to pull a fast one. You pass a number in where it’s expecting a string and just double check the checker. Is it really paying attention? Then a little later you legitimately make a silly mistake and it catches you still—good one you!
No, you hate the type checker when you’re trying to get work done and it just won’t damn shut up already! This is perfectly good code! Or maybe you’ve made a little typo. Do you really need 8 pages of compiler errors telling you how a module you haven’t touched in 4 days isn’t happy either? Really?
In most languages (a few lovely ones excepted) the errors are just awful, too. Sure, you can pick through them. Maybe 50% of the time figure out what they’re really whining about, but it’s a mess.
Is this really anything anyone recommends? Is something so miserable really worth the high praise?
Well, no. There’s a different way that experts use type systems.
Continue reading “Learning to love the type checker”
You don’t really need to know what a type is in order to make great use of them. That said, not knowing what they are can be disconcerting. If you want to be able to communicate fluently with the type system then you should understand the major noun. More to the point, knowing what they are can help you to think in types.
It can be a little confusing to understand what a type is, though. It’s easy to at first say that they’re “sets of objects or values”, but that doesn’t necessarily part the fog of mystery. Fortunately, there’s a good way to understand types using one simple diagram.
Continue reading “What even is a type?”
One of the downsides of improving your craft as a programmer is that to do so you must wade into a vast ocean of opinion. At it’s simplest, you’re going to have to consume and manage conflicting ideas. It’d be nice if there was just one right answer, but those are very rare and hard won. At its worst, though, you get into religious wars.
Religious wars can be validating. On each side are people arguing passionately that the other side is wrong. You’re encouraged to find yourself on one side of the line or the other and once you do it feels right. We’re all tribal creatures and it feels good to find your side.
They can also be terrifically painful. People may call out beliefs that you hold deeply. You may struggle to at once understand someone as successful and smart but also so deeply wrong about something important to you.
You might even just find it painful for prosaic reasons. Unending debates are annoying and waste time. They fill important channels full of the same old noise.
Continue reading “You don’t have to choose a side”
Edit: I changed some wording to avoid potential bad connotations.
You don’t have to wander far into the functional programming world before you run into references to “purity”. Worse, you often hear it as an admonishment:
You should factor your code to use pure functions. Or, this function is complicated because it is impure. At the very edges there are even ways to write entire programs as “pure functions”. Those familiar with that practice have a tendency to lay blame for every fault at the feet of impurity.
Even the word is pretty polarizing. It suggests that your impure, dirty code is full of lurking issues and sits far away from some important ideal. But that’s a tragic point of view. Plenty of “impure” code is still simple, clear, and extremely valuable. The implied judgement is misguided at best.
But before we can talk about the tradeoffs of using pure functional style, we need to understand it. What does it mean for a function to be pure anyway?
Continue reading “A pure function does no funny business”
It’s likely that you’ve encountered functional programming as a way of describing certain kinds of programs, techniques, libraries, or programming languages, but if you haven’t already dug in and seriously attempted to understand these things then you might feel a lot of hesitation.
In some communities—for instance, the React community in frontend development—functional ideas are taking center stage and shaping expectations of what someone in that community ought to know. In others, functional techniques are available, but suggested only for special circumstances such as the
funtools module in Python. Finally, there are today rapidly growing groups which are heavily invested in these techniques such as the Scala, Haskell, Swift, and Elixir communities.
It’s perfectly plausible to write great programs and create great products without ever learning functional techniques, but as these techniques become more popular and widespread it’s easy to feel like you should be learning more about them. Is it really worth the investment?
Continue reading “You should study functional programming to become a better programmer”