Sunday, 1 November 2009

The future of programming

Over the last couple of months I've been ruminating about what an ideal next-stage programming language would look like.

For starters it would be strongly-typed compiled language (non of this fail at runtime, impossible to debug nonsense masquerading as easy-to-write code. I spend my time modifying and debugging code written by others and that's where you need to be efficient).

Also, for ease of adoption, it would have to be a Java-based language so that you could use the existing compilers and Java libraries.

The main thrust would be to avoid focussing too much on technical language features, but to instead move towards eliminating the current need to interpret between what's in my head and what's written on the screen. That is, not to concentrate on how fantastic closures may or may-not be, but to look forward to what we want code to look like. And to know what to avoid, look at C++ template magic!! The cannonical example of what we want is the leap forward of the for-each loop.

So here's my brain dump of the things currently getting in the way when transferring either way between brain and screen:

1. Auto-immutable versions of classes (i.e. a version of "const"). E.g. you can only call accessors, not modifiers on a const reference.

2. Value-types that are as good as built-in-types. (Pass by value, operator overloading, no inheritance).

3. Return multiple values (might be specialisation of automatic n-tuples, e.g. given classes C and D, {C,D} defines a new class containing a C & a D).

4. Expressive syntax as per Linq/Groovy e.g. for(x:set).where(x.isAble)... ("where" is user-definable external to X)

5. Named parameters when calling functions e.g. setPos(x:10,y:20) rather than setPos(10,20)

6. Optional parameters, i.e. possibly null parameters, can be omitted.

7. References are not null unless marked so (to be enforced by compiler) - i.e. remove almost all checks for null.

8. Preconditions / postconditions / invariants supported e.g. by annotation (to be enforced by compiler where possible).

9. Scope of variables inside try{} extends past end of try{} to remove horrendous split of declare and initialisation.

10. Implicit try{} - i.e. declare a catch/finally and it auto-generates a try{} for the preceeding code - no more nested try blocks.

11. Auto resource-cleanup. Probably achievable by previous two points+ making close() etc. throw no exceptions, but I like the auto-pointer resource-is-initialisation pattern which declares at creation that it will be closed rather than having to remember to put it in a finally block.

12. Implicit implementation of I/F - no need to implement void fns or fns that can return null, and ability to declare default implementation in I/F.

13. Fns not virtual by default (you need to design for a function to be overridable, and currently you cannot tell which are).

14. Built in support for "copy on modify" - value-types (which can't have references to external classes, only internal value-types) must be efficient, which they wouldn't be without this.

All these points would make the code I work with on a daily basis simpler and easier to understand / work with, more explicit, with less brain/screen translation.

I'm sure that I've forgotten some points, but that's a good enough brain dump for now.