Sunday, December 26, 2010

Pointer to Member Functions in C++

Pointers to member functions in C++ are quite useful when you need to store behavior. A pointer to a member function doesn't store the address of one function implementation - it allows you to call overriden member funtions in subclasses. For example:
#include <iostream>

using namespace std;

struct View
{
    virtual void mouseMove() { cout << "View.mouseMove()" << endl; }
};

struct Button : public View
{
    virtual void mouseMove() { cout << "Button.mouseMove()" << endl; }
};

typedef void (View::*EventType)();

struct MouseEvent
{
    EventType _eventType;

    MouseEvent( EventType eventType ) : _eventType( eventType ) { }

    void dispatch( View* view ) { (view->*_eventType)(); }
};

int main( int argc, char* argv[] )
{
    MouseEvent* event = new MouseEvent( &View::mouseMove );

    event->dispatch( new Button() );
}
This is somewhat similar to using generic functions in Dylan - there's a level of indirection between the reference and the function implementation.  In very dynamic languages like Ruby, you can use symbols to achieve the same behavior:
class View
  MOUSE_MOVE = :mouse_move

  def mouse_move()
    puts "View.mouse_move()"
  end
end

class Button < View
  def mouse_move()
    puts "View.mouse_move()"
  end
end

class MouseEvent
  def initialize( event_type )
      @event_type = event_type
  end

  def dispatch( view )
    view.send( @event_type )
  end
end

event = MouseEvent.new( View::MOUSE_MOVE )
event.dispatch( View.new() )

Liberate Me Ex Null

Not sure if I got the Latin perfect, but please, future language designers, save us from null!
Even bright new languages like Scala can't help us from the land of null:
def foo( string: Some[String] ) = {
  string.get
}

foo( null )
java.lang.NullPointerException at Main$$anon$1.foo(test.scala:2)
"Some" (and "None") are from the "Option" type, which is a way of letting you say you have something or nothing, while still preserving type safety.  But because of null compatibility with the JVM, Some[] is nullable!  A more dynamic language, Dylan, can type check this pattern:
define method foo (string :: <string>) end;
This method takes a string - and does not accept a null value.  If you want to allow nulls (or false, in Dylan's case), you write:
define method foo (string :: false-or(<string>)) end;
which is ultimately shorthand for a type union:
define method foo (string :: type-union(<string>, singleton(#f))) end;
 

Anonymous function syntax across languages

One of my favorite references is the "Syntax Across Languages" site:
Anonymous function syntax across languages

It's amazing how many different (although some very similar) ways you can write an anonymous function.  I have to confess, even in the development of my own language, Impulse, I have added yet another variation: |a, b| a + b, which is essentially Ruby without the braces { }.

Static + Dynamic Typing

Sometimes you want the strictness of static type checking, but also want the flexibility of dynamic binding. C# expression trees, for example:
http://msdn.microsoft.com/en-us/library/bb397951.aspx

This is basically a LISP embedded in C#, or rather, the .NET runtime. The flip side to this is to add static type checking (with type inference) to a dynamic language. Examples of this would be Dylan and Dr Scheme. In the end, does it matter which direction you start from?

http://lambda-the-ultimate.org/node/1311
http://axisofeval.blogspot.com/2010/07/c-40-industrial-response-to-lisp.html
http://c2.com/cgi/wiki?SoftTyping

Welcome to Structura

Welcome to Structura, a blog about programming languages and patterns. I'm a language enthusiast, so topics will range from old and new languages, to new patterns and ideas, to rants about why a language took a particular direction. I will be biased, of course, but I will be fair. Enjoy!

Regards,
Mike