#403 . vs -> method operators

codeodor Fri 21 Nov 2008

When I ready the WhyFan? page, I got excited about using -> to conditionally call the method dynamically.

One thing I'd like to see is that if a method of the same name exists, and the number of arguments is the same as the defined method, call that one, but ignore the argument type and let the method run. Then, if the interface in use by the incorrectly typed object happens to match, it will run just fine.

I'm not sure if there's some other design decision that would make that extremely difficult or impossible, but it sure would be neat to be able to use the dynamic call operator if you know the 2nd object matches the part of the interface needed, but not the whole interface.

Example:

class Hammer {}
class Rock {}
class Murderer
{
  Void swingHammer(Hammer whichOne)
  {
    echo("Murderer swings his " + whichOne.type);
  }


}

class Kill
{
  static Void main()
  {
    echo("\n\n\n");
    killer := Murderer.make
    killer.swingHammer(Hammer.make)

    //but what if the hammer isn't handy?
    // too bad, it won't compile!
    // killer.swingHammer(Rock.make)

    // use whatever's handy damnit!
    killer->swingHammer(Rock.make)
  }
}

brian Fri 21 Nov 2008

but ignore the argument type and let the method run. Then, if the interface in use by the incorrectly typed object happens to match, it will run just fine.

The problem really has to do with the JVM and CLR. In order to make that work we can't treat the dot operator as an efficient strongly typed call. In your example if you attempted to call a method on Hammer the JVM verifier would fail if the object on the stack wasn't actually a Hammer (even if we have a duck typed version of that method available).

So in order to make that work we'd have to give up statically bound calls and use dynamic calls for everything. That is basically how JPython and JRuby work, and as such they don't get native Java performance.

In this case if you wanted to allow dynamic/duck typing you could just have swingHammer take a generic Obj and use -> instead of . operators. This is kind of the crux of the design - there is a performance penalty when using -> so ideally you want to design for statically bound calls when you can.

My personal experience is that the design actually works out really well. We get Java like speeds for most of our code, but Ruby/Python/Groovy flexibility when you need it (such as when writing tests).

Login or Signup to reply.