dark mode light mode Search Menu

Adding Types to Untyped Languages

Mary Kreul on Flickr

We’ve talked a lot about typed languages lately, like Rust or Idris. These are languages that have a way to classify, or type, the data that’s in them. These types can be checked by the language to prevent errors or even help you write code. What about all those untyped languages? The Pythons, Rubys, and JavasScripts of the world? Are they left out in the cold, no types to cover them in the darkness of winter?

Well, no, actually!

Enterprising programmers have invented methods to add types to untyped languages, and they do it in a few different ways! In this rest of this article, we’ll talk a little bit about some of them and give examples of how types are added to the three languages we named above! Namely, we’ll be talking about Sorbet for Ruby, TypeScript for JavaScript, and pytype for Python.

First, there’s a neat little observation that makes adding types to untyped languages a lot easier: every untyped language can be seen as a typed language with only one type. We can call this lone type Any like TypeScript does, or Untyped like Sorbet does, or any number of other names but the point is the same: if you give everything in the language the type Untyped then everything type checks. After all, you’re always checking that Untyped equals Untyped. That can’t fail!

Once we know we can give every term in an untyped language a dummy type that always passes type checking, this means that we can gradually add in more informative types like “boolean” or “integer” to bits of code. We can start expressing ideas like “the address argument to the web server response function needs to be a string” or “collision code for the hit boxes needs to take only integers” in the code bit by bit. This is, no surprise, called gradual typing. It’s really useful for programmers working in big teams with bigger code bases because gradually adding types works like adding comments to the code that can be checked to see if the code is being used correctly.

Sorbet is a gradual type system for Ruby and TypeScript is basically a gradual type system for JavaScript. The reason why I say “basically” is because, technically speaking, TypeScript is a gradually typed language that compiles to JavaScript but isn’t JavaScript.

Python has a cool project that’s a little different than the gradual typing approach: pytype, which uses type inference. Type inference is related to type checking, but it’s a two-step process: first the type checker tries to figure out the types of everything not explicitly labeled with a type, and then checks them. What does “figure out the types” mean? For example:

aVariable + anotherVar

If you see something like this, assuming that this is Python code, what do you know about the kinds of data in the variables? You know that they have either numbers or strings. If you instead see:

aVariable + str(anotherVar)

Then you know that aVariable must be a string but anotherVar could have literally anything in it. Type inference is this process of looking at how data is used to figure out exactly what it is, but the inference phase of type checking is way more complicated than just the simple rules we thought about here. Once types have been inferred then the typechecker tests to see if the inferences it made combine together to make a sensible program.

This is exactly what pytype does. It looks at your code to figure out what the types are and whether they make sense. You can also add “annotations” of what the types of functions should be to help the type inference algorithm along.

So that’s just a little taste of the ways that the power of typed languages can be combined with the flexibility of untyped languages. If you have a favorite untyped language, try searching for “[your fave language here] gradual typing” or “[your fave language here] optional type system” and see what you can find. There’s just so many cool things language nerds do!

Learn More

Untyped and dynamically typed languages




type checker for Ruby




speedy python checker




Typescript: the basics


Into to Typescript