From 0243d72b6ad8124020cd7fd911ba3fb28b065ba1 Mon Sep 17 00:00:00 2001 From: Noel Welsh Date: Mon, 23 Oct 2023 15:18:42 +0100 Subject: [PATCH] Start on interpreters chapter --- build.sbt | 2 ++ src/pages/ads-interpreters/index.md | 7 +++++++ src/pages/ads-interpreters/regexp.md | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 src/pages/ads-interpreters/index.md create mode 100644 src/pages/ads-interpreters/regexp.md diff --git a/build.sbt b/build.sbt index f722d2bc..ea7ad625 100644 --- a/build.sbt +++ b/build.sbt @@ -48,6 +48,8 @@ lazy val pages = List( "adt/algebra.md", "adt/conclusions.md", + "adt-interpreters/index.md", + "type-classes/index.md", "type-classes/anatomy.md", "type-classes/implicits.md", diff --git a/src/pages/ads-interpreters/index.md b/src/pages/ads-interpreters/index.md new file mode 100644 index 00000000..06854d11 --- /dev/null +++ b/src/pages/ads-interpreters/index.md @@ -0,0 +1,7 @@ +# Reified Interpreters + +In the previous chapter we learned about algebraic data types. In this chapter we'll learn one of their major use cases, implementing interpreters. The interpreter strategy is perhaps the most important in all of functional programming. + +Before discussing the code, let's talk about why we might want to implement an interpreter. Implementing an interpreter sounds like a fairly esoteric thing to do, but it forms the core for building systems that maintain the desirable properties of functional programming---compositionality and reasoning---while allowing us to have effects in our code. The central idea is to **separate description from action**. For example, imagine we're implementing a graphics library using the interpreter strategy. A description simply says what we want to draw on the screen, but critically it does not actually draw anything. The interpreter takes this description and carries out the actions described by it. As the description doesn't do anything, we can freely compose descriptions. For example, if we have a description that describes a circle, and one for a square, we can compose them by saying we should draw the circle next to the square. This creates a new description that is the composition of the two base descriptions. + +It may be hard to see how this works from an abstract description. We'll make it concrete in just a moment, by building an interpreter for regular expressions. We've chosen this example because regular expressions are hopefully familiar to most you, so we can concentrate on the interpreter strategy and not on the details of regular expressions. We'll them extract the general strategy from this specific example, and finally give a few pointers to learn more. diff --git a/src/pages/ads-interpreters/regexp.md b/src/pages/ads-interpreters/regexp.md new file mode 100644 index 00000000..54449f78 --- /dev/null +++ b/src/pages/ads-interpreters/regexp.md @@ -0,0 +1,5 @@ +## Regular Expressions + +We'll start this case study by briefly describing the usual task for regular expressions---matching text---and then take a more theoretical view. We'll then move on to implementation. + +Programmers mostly commonly use regular expressions for matching text. For example, if we wanted to