Typical Types of Typing and the Types They Typify, Part 1
Note: This is the first of a two-part entry in my ongoing “Road to Wheeler” series.
In the C language, where I was first introduced to the concept of “type”, types are metadata associated with some bytes. Here’s some C code:
int x = 5; int z = x + 3;
Here x, z, 5, and 3 are all understood to be ‘int’s. What’s an int? The computer doesn’t really care. It just knows that an int is going to be a certain number of bytes in memory.
If She’s Lucky, I’ll Show Her My OO Face
In a common OO language like C++ or Java, we start to think of types in more abstract terms. We’re no longer thinking solely in terms of memory footprint. Now we’re thinking in terms of interface. Also, the concept of “type” becomes very closely bound with the notion of polymorphism: We expect that a function with two different implementations will “automagically” catch the proper value that gets thrown at it:
// Imagine a few classes, which I won't bother to fill out: class Person; class Customer : Person; class Vendor : Person; public void Display(Customer thingy) { // Do something customer-specific here. } public void Display(Vendor thingy) { // Do something vendor-specific here. }
That’s about as far as a lot of programmers in the Java, C# and C++ worlds seem to go in terms of thinking about types. That’s too bad, because there’s more going on.
Quack Quack
Duck typing is the big thing outside of most of the static typing world. Essentially duck typing depends purely on behavior – if an implicit interface is available, things work. By “implicit interface”, I mean if the functions and properties on a class which are expected actually exist. “If it walks like a duck and quacks like a duck, it must be a duck.”
Duck typing doesn’t require a lot of formality, but it’s still a type strategy. You’ll find duck typing in languages like Python, Ruby, and Perl.
Btw, not to be outdone, C# 4.0 offers “dynamic types” – essentially some syntax and internal support to allow duck typing in C# code. It ain’t pretty, but it is equivalent. (Accordingly, look for it in Java in 5 years and C++ in about 14. /snark)
Hey! Here’s some code to ponder:
# More hand-waving classes. You get the idea. class Person def show class Robot def show class Customer < Person class Vendor < Robot def display(whatever) #do something with a Customer or Vendor. Or Robot or Person. Or whatever has a show method. whatever.show end
This works because both classes, though unrelated, have the same method which is expected (show). So duck typing is still interface typing, but without any guarantee. “Jump and the net will appear” it one way to look at it. (Most of the time it does!)
Pattern Matching and Awesomesauce
Here’s where I’m going to take a detour from the norm and talk about pattern matching. Pattern matching is a nifty feature in a number of different languages which lets you capture data and use it polymophically. Most often this is used to isolate a specific piece of data or to differentiate partial functions. It is in that last sense that I’m most interested in pattern matching as a typing scheme. Here’s an example in Erlang:
display({customer, FirstName, LastName}) -> show_customer(FirstName, LastName); display({vendor, FirstName, LastName}) -> show_vendor(FirstName, LastName).
Just as in the OO example, here we have two overloaded functions and one of them will be selected based on the first argument. What is different here is that we’re not switching on types, we’re switching on values. The “customer” atom is a value that is being matched. If I had passed in some other atom, like “vendor”, that wouldn’t have matched “customer” in the first function signature, so the computer would look at the next function to see if that matches. Luckily in this case I’ve defined my second function to match “vendor”, so it finds a match. Note that I could also have used an underscore (wildcard) in place of “vendor”, and matched on anything that had made it that far. Effectively that would have meant “not a customer”.
Like with duck typing, we’re not dealing with an explicit type, but we still have typing behavior. It’s a different kind of type.
This has turned into a two-parter. I’ll recap: I’ve reviewed some common type schemes and bent the concept of “type” a little bit. In the next installment I’m going to bend the idea of “type” just a little more. Be sure to come back and see if I break anything.