Thinking About the Meaning Types Carry

Thinking About the Meaning Types Carry

Because I have spent so much time with Python, I had never truly reflected on programming language types.

My mental model of a “type” so far was:

That was it.

In dynamic languages you can get away without paying much attention to types, so you can initialize something as an Int and later assign a String.

x = 10
x = "abc"
print(x)

Statically typed languages generally forbid this.

When initialization and later assignments change the type, accidental behavior becomes more likely.

Imagine a large codebase where repeated assignments make a variable’s type oscillate. You now need to constantly keep its type in mind. Branches that alter types make it even more complex.

That is effectively like running a type-inference interpreter inside the programmer’s head.

So even in dynamic languages we usually avoid code like this. Languages such as JavaScript even allow const, so the language can provide safety by preventing reassignment.

In practice, dynamic languages like Python often treat numeric strings and integers the same in many situations, so this kind of code slips in surprisingly often. At the same time, behavior can differ because of type distinctions, and those cases are very hard to spot.

So is making types explicit only about reducing bugs?

I do not think so. I feel that types carry meaning.

Primitive types provided by the language are abstract and make it hard to capture meaning.

At best you can say a variable or property is an integer, or that a function returns a string.

It may be more accurate to say that capturing meaning is hard rather than saying that you can imbue meaning.

You can also define your own types.

Using classes or interfaces you can define types that encapsulate meaning.

This, to me, is the true strength of a type system.

Consider a backend API.

Suppose there is an endpoint that returns product information.

To keep things simple, a product has id, name, and price.

If we only use primitive types we might end up with:

Now define your own types: Id, Name, and Price.

Then you can restrict the range of valid values for each type:

With these constraints, each type now has meaning.

Primitive types merely enforce the generic constraints defined by the language (Long, String, Int), but custom types let you encode domain-specific rules.

I believe this is the true power that types possess.

Defining types and weaving them into the design yields many benefits:

This way the system sheds complexity while gaining expressive power.

In Closing

Today I focused on types and reflected on the meaning and strength they bring.

Types often stay out of sight unless you consciously think about design.

Recently I feel there has been a shift back toward statically typed languages from dynamically typed ones. As I mentioned in the previous article, you do get rapid early velocity, but things become tough in large systems.

Domain-driven design gaining adoption may also be part of the backdrop.