Type Erasure Is Stupid

How a leaked implementation detail wrongfully became a feature

·
·

This is going to be a bit of a technical rant about something most programmers won’t have the misfortune of dealing with.

But goddamnit it matters to me.

If you’re not using cringe languages with type erasure * Like Java. , let me clue you in on what it is first. It is a “necessary feature” where generic type information is simply forgotten by the compiler. What this means is that List<int> and List<double> both become List.

This might not seem like a biggie, but this has a big ramification on method signatures * A method signature is unique if either the method’s name or its type parameters are different. , making this code uncompilable.

// Before type erasure
public void method(List<int> list) { ... }

public void method(List<double> list) { ... }

// After type erasure
public void method(List list) { ... }

public void method(List list) { ... } // signature conflict

Now, you might say this example is contrived because you can just change the method name to resolve the signature conflict—and it might even add clarity—but here is a different example that doesn’t involve method signatures.

class JsonReader<T>
{
	public T fromJson(String json)
	{
		return new ObjectMapper().readValue(json, T.class);
	}
}
var fruitReader = new JsonReader<Fruit>();

Fruit fruit = fruitReader.fromJson(json);

After type erasure, T.class becomes invalid because there is no type to retrieve the class from!

Is this an impossible problem? No, and that’s the infuriating part.

Because you can manually include the type information by passing it as a parameter.

public T fromJson(String json, Class<T> clazz)
{
	return new ObjectMapper().readValue(json, clazz);
}
Fruit fruit = fruitReader.fromJson(json, Fruit.class);

But I don’t want to do this!! It’s ugly!

More importantly, if I can solve it, why can’t the language devs do it?

The Implementation Detail Is Leaking

In the world of programming design, you first lay out what it is you want to accomplish, e.g. creating a List class. What a design doesn’t dictate is how it is implemented; in fact, it shouldn’t care at all how something is implemented. These technical concerns are for the developers, and they are called implementation details.

Taking our List class example, the two primary ways you can implement a List is either using arrays or linked lists. Regardless of how they’re implemented, they should be functionally identical * If you need to eek out every last bit of performance, you can choose one of the two to best suit your case. , and most of the times you’ll just ask for a List and not care if it is an ArrayList or a LinkedList.

The thing about implementation details, is that they are undocumented and can change on a whim, so it is risky to depend on their internal behavior. These should always be hidden from the end-user.

While exposing internal behavior is largely benign—as the fault lies upon any programmers who try to exploit it—leaking internal behaviors such that you must take it into account is a huge no-no. Think unsafe in Rust; functions that use unsafe code must not let it bubble beyond its braces.

So what does that make type erasure?

A leaked implementation detail.

It is a two-decade old solution to generics for Java that should have been shelved long ago for modern solutions. A teenager solved part of the problem that Java devs claimed was impossible. C# is basically Microsoft Java * According to Kett :3 , and it doesn’t have type erasure; in fact it can pull off sick tricks like this.

public class Factory<T> where T:new()
{
	public T create()
	{
		return new T();
	}
}

What is Java’s excuse?

“b-but types don’t exist in the machine code—”
Don’t care, they exist in dev space.

The whole point of types is to enforce cohesion. The compiler already has access to the type information to fill in the blanks, it just erroneously throws it away early.

I should not have to work around someone else’s mediocre solution. Programming is about expressing what you want; it is the language’s job to execute it.

every day I come across the curse of type erasure my eyes bleed black viscous ichor

Chai

signature that says "Chai"

Comment via Bluesky!
Kett and Bobbu/Snowy reposted this.
TheNathannator

thought this referred to the programming technique (thinking C++), instead learned about language design decisions that were absolutely inconceivable to me lol