Sunday, November 26, 2017

Exploring Type class in Scala: A knowledge pack

This series of blog post seeks to provide an exhaustive exploration of the Type-class pattern in Scala.

Aptly described as a "knowledge pack", it won't only touch on the actual mechanism of encoding the type-class pattern in Scala, but it will also explore a bit of the underlining idea behind the pattern and the various language features that come together to make it possible to encode it the way it is done in Scala.

The reason for taking this approach is borne out of my own experience while trying to grok the concept.

I quickly discovered, as anybody new to Scala will do, that the idea of Type classes is widely used in Scala: both in the standard library and in popular third-party libraries. Thus it is imperative to have a good working knowledge of how it works, to be able to effectively use/read code/libraries that make use of the pattern.

My own attempt to get acquainted with the pattern was not straightforward as I would have expected.

Yes, there are lots of articles out there on the topic, and yes, I made sure to read as many as I could, but even with that, I did not get the feeling I was grokking the concept.

Most of the articles I read left me feeling that the whole pattern is just too verbose, with so many moving parts with no apparent benefit to all the ceremony required to get it working. I also had to deal with various arcane Scala syntax that usually gets thrown into the picture while explaining the pattern.

It was not until I encountered Type classes in Haskell that the pieces started falling into place. Which is not surprising because Type class originated from Haskell, and in Haskell, it is a feature of the language, not just another pattern, as it is, in Scala.

After my experience with Type classes in Haskell and spending some time reflecting on the whole idea, I was able to pinpoint the reasons why the Type class pattern initially seemed inaccessible.

Two broad reasons were largely responsible:

The first was my previous knowledge of OOP in Java (especially how polymorphism is achieved via inheritance). This was a huge stumbling mental block to fully appreciating what the Type-class pattern was all about and I had to Unlearn the narrow worldview that has been formed via using Java to embracing a more generalized appreciation of the concept of polymorphism and how it relates to Type classes.

The other hindrance was the fact that Type class is not native language feature in Scala, but a pattern that is encoded in Scala. This encoding requires various language features of Scala to come together.

Thus to fully grok how the pattern is implemented, an understanding of the other various language features is required. And this ranges from implicit and how implicit resolution works to the syntax for expressing type constraints, to variance. This adds some cognitive load, especially if you are not familiar with these parts of Scala required to encode the Type class pattern.

So, if at any point in time, in your attempt to learn about Type-classes in Scala, you have felt frustrated and shared thoughts similar to the hindrances I mentioned above, then I believe this series of blog posts should help. I have taken some time to address the various knowledge gap that I had to fill in other to come to a full appreciation of the pattern.

The following posts make up this series:

1. Revisiting Polymorphism. Tip: It is more than inheritance
2. Review of Implicit and Implicit resolution
3. Exploring Type Annotations in Scala
4. Encoding Type class in Scala
5. Common patterns of Type class
6. Three Real-World Examples of Type class Pattern in Scala
7. Exploring Type class in Scala: Conclusion

With all these said, let us tackle the first issue: Rethinking what you know about Polymorphism .

No comments: