Sunday, August 31, 2008

Multiple Dispatch can be neat

I was looking at this paper regarding multiple dispatch.

Coming from a java point of view, I still remember the disappointment the first time I realized that Java didn't have multiple dispatch. You know, the first time you realize that:

public static void a(Object o)
{
  System.out.print("1");
}

public static void a(Number n)
{
  System.out.print("2");
}

public static void main(String... args)
{
  Object o = new Integer(3);
  a(o);
  a((Number) o);
}

...would write "12" instead of "22".  (Of course, in functional languages this is taken even further with pattern matching)

I found more examples when looking at Slate, a Smalltalk-ish langage with this type of multiple dispatch (apparently development on the language is pretty much abandoned now though). 

The advantages with multiple dispatch is discussed in the paper I linked to, but as a quick recap it allows you to push variant behaviour into different methods instead of using something like "instance of" or its variants.

Sure, it is possible to push back behaviour to the target object, but it is not always possible. Here is a standard "equals" method in java:

public boolean equals(Object otherKey) 
{
   if (this == otherKey) 
   {
      return true;
   }
   if (otherKey instanceof Key) 
   {
      Key key = (Key) otherKey;
      return m_id == key.getId();
   }
   return false;
}

If java had multiple dispatch we could simplify this to:

public boolean equals(Key otherKey) 
{
   return m_id == key.getId();
}
public boolean equals(Object otherObject) 
{
   return false;
}

Which one is better should be pretty obvious.

There has been work on multiple dispatch for C++ that almost made it to C++0x, but apparently it came a bit too late to be included. CLOS and Dylan are the two languages usually mentioned in regards to multiple dispatch, but there is also support for it in Nice, the previously mentioned Slate, Cecil, Perl 6 and Groovy.

 

Tuesday, August 26, 2008

My Own Language Wish List

I am working on a programming language idea, it's just for fun and nothing will probably come out of it, but the research itself is proving incredibly rewarding.

Here is my wish list:
  • OO with C-like syntax
  • Both implicitly and explicitly defined protocols (interfaces)
  • Mixins for shared implementation.
  • Categories (add methods but not ivars to existing classes)
  • Dynamically typed with optional static typing with both static and runtime checks.
  • Unambiguous grammar (Compare with Ruby where you can shadow methods with local variables and vice-versa)
  • All statements return a value ("self" is default)
  • Compiles to C
  • Should work seamlessly with C-code (may include .h files, call C directly without implicit type conversion)
  • Module system similar to that of D.
  • Real hygienic macros.
  • Coroutines
  • Closures
  • Invariants
  • First class functions.
  • Metaprogramming (including directly working with the current context, replacing Closure bindings etc)
  • Arrows

I'm also considering no direct thread access, but to provide other ways to easily parallelize things across multiple threads.

Basically I think that raw multithreading usually is more of a problem than a solution.

Asynchronous communication should be built in and be the default. I am looking at Io as a good example here.

Sunday, August 24, 2008

The Compiler Puzzle

I've been playing with the idea to create a programming language, mostly for fun - to learn something about writing programming languages. 

Now I almost regret it, it's like an addiction, reading about different languages, compile-time optimization, fast message dispatch, garbage collection algorithms and the list goes on. It's really a fascinating subject, as addictive as any puzzler game.

This is, by the way, why I even started to look at D in depth (unfortunately for me, D 2.0 has no mac compiler so I can't really play around with it), and today I stumbled over Factor while looking for ways to optimize simple calls like +, -, *, % and /. 

One problem in dynamically typed languages without primitives is that a simple a + 1 is as expensive as the call a.doSomething(1).

So the code that looks like this in C:

int someFunction(int a, int b, int c)
{
a = 10 * b + c;
b = a % 37;
c += (a + c) % 3;
return a + b + c;
}

would in a dynamically typed language with a naive compiler translate to:

someFunction(a, b, c)
{
a = b.mult(10).add(c);
b = a.mod(37);
c = c.add(a.add(c).mod(3));
return a.add(b).add(c);
}

If this was C++ and the methods non-virtual, then it would be a simple thing for the compiler to inline them, with dynamic dispatch on the other hand, it's not that simple, and when you have dynamic typing the situation is even worse, because at compile time there is no way to even know what type a, b and c will have. It gets worse because dynamic message passing is a lot slower than than normal dynamic dispatch in statically typed languages.

One of the ways to alleviate this problem somewhat is by using type inference, which is one thing that Factor does.

It's like a game... how do you make the computer work as fast when you feed it objects it has to figure how to use, as when it is given clear instructions? If "as fast" is impossible, then how do you get it really, really close? Oh, it's a very nice puzzler indeed.

Saturday, August 23, 2008

I like Ruby - but big projects suck.

I like Ruby, I like it a lot, but I keep running into some issues. 

But first off let me say that for small programs, Ruby is absolutely wonderful. It is sad to see people struggle to write x10 or x100 the amount of code trying to do the same thing in Java because they don't know anything easier to use.

But then there are the huge projects. The ones with 50.000+ lines of code if written in Java and a fraction of that if written in Ruby. That is where the problems show up. Because even at 50.000 lines of code, a project is quite manageable in Java with a good IDE. With Ruby, 5000 is frickin bad.

I think some of the reason is because Ruby doesn't provide an easy way to maintain a project structure. Where a hierarchy is almost required in Java, it is actually outright hard to get it to work in Ruby. I don't particularly enjoy adding a header to every ruby file just to make sure it both can run stand-alone and compile properly with the rest of the project. Unit tests need even more path-magic to work.

The problem is compounded by the fact that you really would like to have well encapsulated libraries of code within a single project. In Ruby you sometimes write fiendishly clever and hard-to-understand code to simplify development in the rest of the code. Normally you'd then hide that implementation either as a separate jar/library/module, or at least in some (in Java terms) sub-package to insulate you from the implementation.

Unfortunately there are few ways to achieve that aside from building a full-fledged gem. And since there are no interfaces/protocols in Ruby, nor is it immediately clear from a class definition what public functions and methods your code actually provides, you probably are going try to read that code many times again, trying to understand exactly what it did, losing something like half an hour of productive work every time.

This problem could have been made smaller if rdoc was better, but when comparing it to say Javadoc, it is laughingly bad. Add to this the fact that rdoc is really lacking everywhere, both for ruby core classes and as for ruby gems, you should count yourself lucky if you find one with rdocs. So... again you are forced to read the actual code to understand how to properly use it.

Speaking of gems... this is yet another sad point compared to other languages. Jars and classpaths with Java suck, but at least you have your dependencies bundled up in a few files, whereas with gems you have them installed somewhere on your computer. This might be convenient for development, but not as good if you are writing something as a stand-alone program. Even c headers bundled with a library is a lot easier to get the hang of.

When I look at Python, which seems to have a sane module system and even docs bundled with the classes. I can't help but to wonder why Ruby hasn't borrowed these things already. 

Could it really be that most people still are only using Ruby for small projects?

Tuesday, August 19, 2008

D' nice kitchen sink

I have been looking a bit at D, without playing around with it any. That, of course, means I know nothing about the language whatsoever. It looks like it has pretty much everything in it.

C-style programming - check, type inferrence - check, contracts - check, modules - check, classes - check ...and so on.

(Which actually makes me pretty reluctant to use it for anything. Kitchen-sink programming languages always worry me for some reason.)

Anyway, the really cool thing about it is all those articles that keep popping up where people extend it to do neat things.

I only have two articles on the top of my head:
www.digitalmars.com/d/2.0/accu-functional.pdf
bartoszmilewski.wordpress.com/2008/08/16/thin-lock-implementation/

...but there are a lot more of them, and they're not just interesting from a D-programmer perspective, but the articles actually feel relevant to other imperative languages as well.

Very nice indeed.

Starting a blog

So, after getting addicted to reading programmer blogs, I'm going to try my hand at keeping one of my own. We'll see how it works out.