Friday, November 21, 2014

Indirect Generics

I've been rethinking an old programming language idea I've had. I don't know if anyone else does things this way. (But probably, because Ecclesiastes 1:9.)

The goal is to allow generic code. Or said differently, to code in a domain dependent fashion. And to do it with as little pain as possible. Let's start with a commonly generified structure: arrays. And let's use standard templates/generics syntax:
class Array<Item> {
  Item get(Integer index) ...

// Declaring an instance.
Array<String> strings = ...;
With my idea, I could just treat them as different types:
class Item {}
class Array {
  Item get(Integer index) ...
I'm not getting too deep into syntax I might like to use for these examples. Instead, I'm staying approximately in Java land.

Here, Item is an abstract type (ignoring differences between classes, interfaces, and whatnot). And other types and functions in this module could use it just as easily. And it enforces no constraints, just as you might expect for the kinds of items you could put in an array.

In fact, this looks a lot like Lists in Java before generics came along, except that they reference the standard type Object. But how to make a specialization without explicit type parameters on Array? Easily enough:
Array<Item: String> strings = ...;
I'm usually a fan of named params anyway. Because this could get bulky, there might also be some syntax to allow positional arguments. And typedefs could also be handy for commonly used specializations.

Note also that we assume String can take the place of Item, so we're assuming structural typing or some such here, since String will not have been defined as a subtype of our domain-specific Item.

Of course, for more interesting situations (constrained generics), simply put other members in the types you want to use.

The overall idea is that when you are coding some module, just invent the types you need as you are going. Work in your own domain. Let the adaptation come later. (So, you might want to pay some attention to standard interface members, etc., but don't die over it.)