In the previous chapter, we covered the core concepts of functional programming such as pure functions, immutability, and higher-order functions. We introduced some of the design patterns that are prevalent in large functional programs. Finally, we covered two popular functional programming libraries called Cats and Doobie and used them to write some interesting programs.
In this chapter, we will cover how Scala makes it possible to write powerful DSLs by providing a few interesting language features. We'll have a brief look at what DSLs are in general terms. We'll also cover a DSL that you'll very likely be using if you're going to work with Scala professionally. Finally, you will implement your own DSL.
This chapter demonstrates how Scala makes it possible to write powerful Domain Specific Languages (DSLs) by providing a few interesting language features.
By the end of this chapter, you will be able to:
ScalaTest
, a popular testing library for ScalaA domain specific language is, as the name suggests, a language that's specialized for a specific domain. Contrast that with a language like Scala, which is a general-purpose language in the sense that it's applicable across a broad range of domains.
By restricting the domain, you'd hope to make a language that's less comprehensive but better suited to solving a specific set of problems within a domain. A well-constructed DSL will make it easy to solve problems within a domain and make it hard for the user to make mistakes. DSLs come in many different shapes and sizes, but you can roughly separate them into two groups: external DSLs and internal DSLs.
External DSLs are written "outside" of the host language (the language that's used to implement the DSL is called the host language). That means you'll have to parse the text, evaluate it, and so on, just as if you were creating a general-purpose programming language. We won't be creating an external DSL, so we won't cover the topic much further.
One example of an external DSL is
DOT
, which is used to describe graphs. Here's an
example of a simple
DOT
program, which
produces the graph you see here:
Here is the code that can be written to implement the graph above:
graph graphname { a -- b -- c; b -- d; }
So,
DOT
is specialized for the domain of describing graphs.
For more information on
DOT
, please refer to
https://en.wikipedia.org/wiki/DOT_(graph_description_language).
Internal DSLs are embedded in the host language and can be separated into two groups:
We'll be writing an internal shallow DSL in this chapter, which is also, in my experience, the most common type of DSL you'll encounter when you're using various Scala libraries.
ScalaTest
is a
very popular testing library for Scala. It has a set of different DSLs for writing your test specifications. We'll look at
ScalaTest
in depth in the next section.
You now have a very basic understanding of what DSLs are and how they can be grouped into internal/external and shallow/deep. In the next section, we'll look at
ScalaTest
and how that library uses DSLs to make it easy to write test specifications.