Wednesday, September 12, 2012

Programming languages

Yesterday night, trying to sleep, I was thinking about next generation programming languages and how it would be nice to have a language that combined all kinds of features from C#, D, Intel Cilk, C++, support for both composition and inheritance architectures etc. etc.

Of course this magical new language would solve every single problem and bring about world peace. It wouldn't have garbage collection, but would require the user to manage memory manually like in C++, and wouldn't be managed to be able to get every bit of performance out of your computer. 

So this made me wonder, suppose you'd have this language and you'd have this standard library included with it like .Net does (but maybe a little more sparse) how would you handle situations like SomeContainer.ToArray()?

If you don't have garbage collection, and you allocate memory in this 'ToArray' method then the user would be responsible for freeing it later on. So this made me think is there a clever way to communicate this to the programmer beyond mere documentation?
This is what I came up with (syntax is just an example):
class SomeClass
{
  public allocator SomeOtherClass* MyMethod() 
    { return new SomeOtherClass(); }
}

void SomeOtherMethod()
{
  SomeOtherClass* myInstance = new SomeClassInstance.MyMethod();
  // ..
  delete myInstance;
}

The idea is that every method that returns allocated memory (which hasn't been stored somewhere else) MUST flag that method as an allocator. Then when an allocator method is used you MUST use the new keyword in front of it.

The advantage is that in the scope of 'SomeOtherMethod' you can clearly see that SomeClassInstance.MyMethod allocates memory and that the programmer is responsible to free this memory eventually. 

When a method isn't an allocator but still returns a pointer then the programmer can assume that this pointer doesn't need to be deleted and will be managed by some other piece of code somewhere else.

An additional advantage to this is that it should make it easier for the compiler to automatically detect certain types of memory leaks. The beauty about this is that it works hierarchically .. if a function calls an allocator and returns it's pointer it will need to be marked as an allocator as well (unless it stores the pointer somewhere).