A new Swift video series exploring functional programming and more.
#28 • Monday Sep 3, 2018 • Subscriber-only

An HTML DSL

This week we apply domain specific languages to a very real-world problem: representing and rendering HTML. We code up a simple but powerful solution that forms the foundation of what we use to build the Point-Free website.

#28 • Monday Sep 3, 2018 • Subscriber-only

An HTML DSL

This week we apply domain specific languages to a very real-world problem: representing and rendering HTML. We code up a simple but powerful solution that forms the foundation of what we use to build the Point-Free website.


Subscribe to Point‑Free

This episode is for subscribers only. To access it, and all past and future episodes, become a subscriber today!

See subscription optionsorLog in

Sign up for our weekly newsletter to be notified of new episodes, and unlock access to any subscriber-only episode of your choosing!

Sign up for free episode

Introduction

In a couple recent episodes, we introduced the idea of domain specific languages, often abbreviated DSLs, which are languages that are highly tuned to a specific task. We then introduced the idea of embedded DSLs (or EDSLs), which are domain specific languages that are hosted, or written, in a more general purpose language, like Swift.

To get comfortable with the idea, we embedded some basic arithmetic in the Swift type system. Using a DSL helped us separate the pure, data-driven description of a domain problem from the impure, run-time interpretation of that data.

But arithmetic was a bit of a toy example, though, so today we’re going to embed a more real-world domain problem in Swift, HTML, by building the same DSL that we use to power the Point-Free web site!

Subscribe to Point-Free

👋 Hey there! Does this episode sound interesting? Well, then you may want to subscribe so that you get access to this episodes and more!


Exercises

  1. Our render function currently prints an extra space when attributes aren’t present: "<header ></header>". Fix the render function so that render(header([])) == "<header></header>".

  2. HTML specifies a number of “void elements” (elements that have no closing tag). This includes the img element in our example. Update the render function to omit the closing tag on void elements.

  3. Our render function is currently unsafe: text node content isn’t escaped, which means it could be susceptible to cross-site scripting attacks. Ensure that text nodes are properly escaped during rendering.

  4. Ensure that attribute nodes are properly escaped during rendering.

  5. Write a function redacted, which transforms a Node and its children, replacing all non-whitespace characters with a redacted character: .

  6. Write a function removingStyles, which removes all style nodes and attributes.

  7. Write a function removingScripts, which removes all script nodes and attributes with the on prefix (like onclick).

  8. Write a function plainText, which transforms HTML into human-readable text, which might be useful for rendering plain-text emails from HTML content.

  9. One of the most popular way of rendering HTML is to use a templating language (Swift, for example, has Stencil). What are some of the pros and cons of using a templating language over a DSL.


References

Chapters
Introduction
00:05
HTML in types
01:13
HTML in functions
04:19
HTML interpreted
10:42
HTML transformed
15:04
What's the point?
19:04