This blog post was originally posted on my blogpost blog at this URL, and was later migrated to this place. There may be some comments at the original URL.
This is my first programming blog post. So please be gentle in your criticism. :-)
default keyword in Scala:
In generic classes and methods, one issue that arises is how to assign a default value to a type parameter
A when you do not know in advance whether
A is a reference type, a numeric type, or something else. To handle such a situation, C# provides a keyword
default, which returns
null for reference types, and zero for numeric types. For
structs, which are CLR’s value types, default returns an object with all members initialized to their respective
default values using the same mechanism.
Following example shows the
default keyword in action:
Scala has a similar feature to get a default value for the given type parameter. Just declare a variable at the class level, annotate it with a type, and put an undescore after the assignment operator. The variable will then be assigned the appropriate default according to its type. (Note: All Scala snippets in this post are typed at REPL.)
However for some reason that I do not know of, this feature is only available for class fields. It doesn’t work for local variables.
This can easily be work around:
Thus we have successfully emulated the behavior of C#’s
default keyword in Scala (Except for the structs’ case, which do not exist on JVM anyway).
Putting it on steroids:
Now what do I mean by putting
default on steroids? Think how we could improve the behavior of the defaulting mechanism we built above. Wouldn’t it make more sense for a string to default to an empty string i.e.
""? Wouldn’t it make more sense for an
Option[_] variable to default to
None? Similarly your custom classes could have more appropriate defaults than
null. For example,
0.0 + 0.0j would be a suitable default for a
Complex object. In the remaining part of this post, we are going to see how Scala’s typeclasses let us build such a default-on-steroids.
Here is the required machinery for this little utility:
Default is a typeclass, which is invariant on A for obvious reasons. Its companion object
Default contains implicits and implicit suppliers for a few common types. The method
forAnyRef is put in a separate trait
LowPriorityImplicitsForDefault so that it has a lower precedence than other more specific implicit supplier methods such as
forNumeric (We do this to hack around Scala’s implicit lookup rules. Don’t bother if you do not understand this, as it’s beyond the point of this post).
Now all we need to do is define a no-arg method
default that picks an appropriate
Default implicit from the scope and returns its value.
And we are done! :-)
Here is our new
default, in action:
Say, later on at some point we define a class
Complex. How do you supply a
Default implicit for it? Easy. Put it in
Cool, isn’t it? :-)
What happens when there’s no implicit defined for a certain type? Well, in such a case, the method
forAnyRef acts as a fallback method, and default returns
This example shows how Scala’s typeclasses can be immensely useful in the cases requiring post hoc polymorphism.
Well, that’s it. I hope this was good enough an attempt for a first blog post. :-) All suggestions and criticism is welcome.