Software Development

Strong Typing without Types

In 1974, Liskov and Zilles defined a strongly-typed language as one in which “whenever an object is passed from a calling function to a called function, its type must be compatible with the type declared in the called function.” Strong type checking, without doubt, decreases the amount of type errors, which leads to higher quality. However, the question is: do we really need types in order to strongly enforce typing?

For example, this is a place where we expect an instance of Java interface Book to arrive:

1
2
3
4
5
void print(Book b) {
  System.out.printf(
    "The ISBN is: %s%n", b.isbn()
  );
}

The type Book may look like this:

1
2
3
interface Book {
  String isbn();
}

If an object that doesn’t implement the interface Book is passed to the method print(), the compiler will complain with the “type mismatch” error. It will be hard for a programmer to make a mistake and pass an object of type, say, Car to the method print(). However, it will still be possible, via dynamic type casting:

1
2
Car car = new Car("Mercedes-Benz G63");
print(Book.class.cast(car)); // Here!

This code will compile without issues, but at runtime the ClassCastException will be thrown, since it won’t be possible to cast Car to Book.

The beauty of strong typing is that it prevents errors. However, it increases the complexity of code: you need to create types first, you need to declare them in all your functions, you need type casting, which is hard to debug, and so on. Weak typing proponents complain about this a lot and create languages like Ruby, which don’t have types at all, for example:

1
2
3
def print(b)
  puts(format("This is ISBN: %s", b.isbn))
end

Here, the function print() doesn’t expect b to be of any particular type. Whatever comes in—is fine. Later, when it’s time to call .isbn the runtime checks whether the incoming b has such a method. If it does, everything works just fine, if it doesn’t, a runtime error NoMethodError is raised.

So far so good.

However, here is the idea: what if we combine the simplicity and brevity of dynamic typing with the safety of strong typing by getting rid of types all together and letting the compiler infer type information from the code that works with the objects? Here is our code again:

1
2
3
4
5
void print(Book b) {
  System.out.printf(
    "The ISBN is: %s%n", b.isbn()
  );
}

Think about this: at compile time it’s already obvious that b must have at least one method isbn(). No need to force programmers to define the type Book explicitly and mention in the signature of the method print() that only books are welcome: this knowledge can easily be inferred from the body of the method print()! The compiler may look at all statements in the method print() and clearly understand what exactly will be done with the object b. This information should be enough to visualize the “type” of the incoming object. No need to ask the programmer to do this explicitly and spend another five lines of code in a new file to declare the type Book. The compiler can do this job for us.

Of course, to make this work we must prohibit type casting of any kind, which is not possible in Java, C++, C# and other pseudo-object-oriented languages. But it is possible in EO!

WDYT?

Published on Java Code Geeks with permission by Yegor Bugayenko, partner at our JCG program. See the original article here: Strong Typing without Types

Opinions expressed by Java Code Geeks contributors are their own.

Yegor Bugayenko

Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button