  Aliasing, or sharing, is prominent in many domains, denoting that two
differently-named objects are in fact identical: a change in one object (memory
cell, circuit terminal, disk block) is instantly reflected in the other.
Languages for modelling such domains should let the programmer explicitly
define the sharing among objects or expressions. A DSL compiler may find other
identical expressions and share them, implicitly. Such common subexpression
elimination is crucial to the efficient implementation of DSLs. Sharing is
tricky in embedded DSL, since host aliasing may correspond to copying of the
underlying objects rather than their sharing.
  This tutorial summarizes discussions of implementing sharing in Haskell DSLs
for automotive embedded systems and hardware description languages. The
technique has since been used in a Haskell SAT solver and the DSL for music
synthesis. We demonstrate the embedding in pure Haskell of a simple DSL with a
language form for explicit sharing. The DSL also has implicit sharing,
implemented via hash-consing. Explicit sharing greatly speeds up hash-consing.
The seemingly imperative nature of hash-consing is hidden beneath a simple
combinator language. The overall implementation remains pure functional and
easy to reason about.
