Scala Intricacies

I ran into a couple of little syntax bits today that all added up to a bunch of wasted time. First was a call by name argument:

def passByName( t: => Long) = {}

This results in t essentially becoming Unit => Long that gets implicitly called each time t is used. This was not immediately obvious, and like other similar bits of syntax, it was difficult to search for. The name of the feature, pass by name, doesn’t help since it doesn’t immediately explain what’s going on.

The second piece of syntax was the ability to have multiple parameter lists to enable a special kind of currying:

def currying(a:Long)(b:Int):String = {(a + b).toString}

This is equivalent to:

def currying(a:Long):Int=>String = {(x:Int) => (x + a).toString}

This syntax is more compact and clearer. It also gets better as you add more items. It also interoperates well with implicit parameters since you can attach the implicits to the last parameter list and have them fill in but you get a clean function signature for everything else.

The third piece of syntax was an inheritance issue that happens when a trait extends a class. Normally a trait is mixed in using the `with` keyword and classes are extended using the `extends` keyword. At first I didn’t realize you could extend a class with a trait, having seen the self trait syntax:

trait Bar { self: Foo =>}

But I did so unknowingly and when I attempted to mixin that trait in a way that was illegal, I got a great error message which helped resolve what to do next, but didn’t explain why what I did was wrong.

Having two different syntaxes that allow for very similar but slightly different behavior seemed confusing. I found this post describing the slight differences between the two different syntaxes and what they mean. It mostly seems to be a style thing, the self trait syntax lets you extend whatever class you want but it needs to eventually have the self class. This may have some consequences regarding linearization although it didn’t come up in the referenced post or what I was doing. The trait extending class syntax requires that you extend from it directly. It also does give some additional options for overriding methods since they can call the super implementations.

The last piece was how context bounds work on ClassTag types. When you define a method like:

def myMethod[T:ClassTag]

it implicitly creates an additional argument changing the signature to:

def myMethod[T](implicit tag: ClassTag[T])

This argument propagates through to any other usages of T and enables the usage of tag. Figuring this out from the codebase itself didn’t work out well. Searching for associated phrases was unhelpful since it isn’t really inheritance and most of the documentation is listed under TypeTag and not ClassTag since the two work similarly. The other issue was that the majority of the documentation I saw during my initial readings referenced manifests, which were deprecated in favor of the ClassTag and TypeTag. I managed to get some assistance from some of my coworkers to figure this one out, but it wasn’t an easily searchable or understandable concept since it took inheritance syntax to create implicit arguments.

All four of these syntax bits are useful but have some very specific nuances. Like a lot of Scala language features, they are all useful and well implemented individually. As a group though, there is a lot of unique and quirky  syntax to learn. I’ll keep chronicling all of the various bits and pieces that I find that warrant more thought.  

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