Statically Typed

because Hindley-Milner rocks

C++ Templates and Relations to Scala (part 1)


It feels like I haven’t posted in forever.  Actually I’ve got a bunch of posts sitting in “edit” stage that just aren’t mature enough to post.  This is what happens when you make one post that really should be more posts but have trouble developing an individual story line for each.  However, today I think I’ve got a pretty good story to tell.

For those that have had the great fortune/misfortune of working with C++ templates you’ve discovered that they are both powerful and versatile.  Attesting to their power are libraries like Boost::MPL (template meta-programming at compile time.)  For versatility look no further than the STL (with libraries mimicking functional constructs like the foldLeft or map functions.)

Personally I love them.  To figure out why, consider the implications of the following declaration.  It yields some surprising results:

template<typename T, typename V>
class Foo{
public:
    Foo(V _func) : m_Func( _func ){}
    void operator()( T _val ){
        m_Func.bar( _val );
        m_Func.baz( _val );
    }
private:
    V m_Func;
};

First of all I do not need to declare the return type of either of the functions “bar” or “baz.”  Second, I don’t even need to declare their argument types either.  As long as templated parameter “T” can be understood to be the type expected by the functions or is implicitly convertible to that type I’m fine.  This almost extends to function declarations too:

template<typename T, typename R>
R foo( T _val ){ /*stuff*/ }

but here I’ve got to declare not only the argument type but also the return type.

Contrast this with Java before contrasting this with Scala.  In Java, due to some of the limitations imposed upon us by type eraser I can’t even think of stating

public <T,R> R foo(T _val){ return _val.bar(); }

I have to make sure that “T” derives explicitly from either a class or an interface which contains a “bar” method.  I could never even think of passing in a function (which conveniently can’t be done anyways.)

In Scala I have slightly more freedom.  I don’t have to specify a class or even a trait from which it inherits.  In a structure which is more akin to the way templates are checked at compile time in C++ I’m allowed to declare my parameters as:

def foo( x:{def bar():Unit} ) = //stuff
def foo[T<:{def bar():Unit}]( x:T ) = //stuff
class Baz[T<:{def bar():Unit}]{ //stuff 
}

Here I’m only stating that whatever object or function is passed in has some method “foo” with the given signature.  I’m not even stating that I’ll use that function nor am I stating what super type “T” is.

That is the big difference between C++ and Scala (as far as we’re concerned here.)  In C++ I get a free ride on both the return type and argument of the functions as long as they either agree or have an implicit conversion to the proper type.  In Scala, the function’s signature must be explicitly declared as above but I am not required to need it.  It could be abused to aggravate your co-workers by requiring a “<your name here>Rocks” function.

Now who would do that?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on November 17, 2010 by in C++, Java, Scala.
%d bloggers like this: