diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,12 +4,12 @@
 This is the Madlang DSL for generating text. You specify a template, and Madlang
 will create randomized text from the template.
 
-It is an interpreted language, written in Haskell. It runs from the command line, but it is also a Haskell library that can be integrated into [other projects](https://github.com/vmchale/toboggan).
+Madlang is an interpreted language, written in Haskell. It runs from the command line, but also provides a Haskell library that can be integrated into [other projects](https://github.com/vmchale/toboggan), compiled to a [web app](https://github.com/vmchale/madlang-reflex), or used as an EDSL.
 
 There is also a vim plugin for syntax highlighting, available [here](https://github.com/vmchale/madlang-vim).
 
-It can be used for twitter bots (among other things) and provides human-readable syntax for the Markov
-chains that are often used to generate text.
+It can be used for twitter bots (among other things) and provides human-readable
+syntax for generating text.
 
 ## Examples
 
@@ -36,24 +36,11 @@
 
 ### Syntax
 
-There are two keywords in madlang: `:define` and `:return`. `:return` is the main string we'll be spitting back, so there can be only one per file. `:define` on the other hand can be used to make multiple templates. These templates are combinations of strings (enclosed in quotes) and names of other templates.
-
-Of course, you can't have a circular reference with names - if `goodfortune` depends on `fortune` while `fortune` depends on `goodfortune`, we end up with either no fortune or an infinite fortune. So we throw an error.
+There are two keywords in madlang you'll use most: `:define` and `:return`. `:return` is the main string we'll be spitting back; there can be only one per file. `:define` on the other hand can be used to make functions. These functions are combinations of templates, organizing pairs of weights and strings.
 
-There is also a Shakespearean insult generator demo available in
+There is a Shakespearean insult generator demo available in
 `demo/shakespeare.mad`
 
-## Using the library
-
-The main function you'll want to use is probably `runFile`; it reads a file and generates randomized text:
-
-```
- λ:> runFile [] "demo/shakespeare.mad"
- "Thou hasty-witted gleeking puttock!"
-```
-
-Haddock documentation of all library functionality is located [here](https://hackage.haskell.org/package/madlang#readme).
-
 ## Installation
 
 ### Releases
@@ -81,7 +68,7 @@
 curl -sSL http://haskellstack.org | sh
 ```
 
-Then run `stack install madlang --resolver nightly` and you'll get the `madlang` executable installed on your path. This may take a bit of time, as it will build *all* dependencies of `madlang` first. 
+Then run `stack install madlang --resolver nightly` and you'll get the `madlang` executable installed on your path. This may take a bit of time, as it will build *all* dependencies of `madlang` first.
 
 ### Use
 
@@ -93,6 +80,33 @@
 
 You can do `madlang --help` if you want a couple other options for debugging.
 
+## Using the library
+
+One function you might want to use is `runFile`; it reads a file and generates randomized text:
+
+```
+ λ:> runFile [] "demo/shakespeare.mad"
+ "Thou hasty-witted gleeking puttock!"
+```
+
+To use the library as an EDSL, there are two options: splicing in a file or
+using a quasi-quoter, viz.
+
+```haskell
+demo :: IO T.Text
+demo = run
+    $(madFile "demo/shakespeare.mad")
+
+demo :: IO T.Text
+demo = run [|madlang
+:define f
+    1.0 "heads"
+    1.0 "tails"
+:return
+    1.0 f|]
+```
+
+Haddock documentation of all library functionality is located [here](https://hackage.haskell.org/package/madlang#readme).
 ## Syntax Highlighting
 
 Syntax highlighting for the DSL is provided in the vim plugin [here](http://github.com/vmchale/madlang-vim). It includes integration with [syntastic](https://github.com/vim-syntastic/syntastic).
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -1,16 +1,18 @@
 { mkDerivation, ansi-wl-pprint, base, composition, containers
-, directory, hspec, hspec-megaparsec, megaparsec, microlens, mtl
-, mwc-random, optparse-applicative, random-shuffle, stdenv, text
+, directory, file-embed-poly, hspec, hspec-megaparsec, megaparsec
+, microlens, MonadRandom, mtl, optparse-applicative, random-shuffle
+, stdenv, template-haskell, text
 }:
 mkDerivation {
   pname = "madlang";
-  version = "2.2.0.0";
+  version = "2.3.0.3";
   src = ./.;
   isLibrary = true;
   isExecutable = true;
   libraryHaskellDepends = [
-    ansi-wl-pprint base composition containers directory megaparsec
-    microlens mtl mwc-random optparse-applicative random-shuffle text
+    ansi-wl-pprint base composition containers directory
+    file-embed-poly megaparsec microlens MonadRandom mtl
+    optparse-applicative random-shuffle template-haskell text
   ];
   executableHaskellDepends = [ base ];
   testHaskellDepends = [
diff --git a/demo/example.mad b/demo/example.mad
new file mode 100644
--- /dev/null
+++ b/demo/example.mad
@@ -0,0 +1,42 @@
+:define mainCharacter
+    1.0 "mechanic"
+    1.0 "professor"
+    1.0 "madonna"
+    1.0 "miner"
+    1.0 "mercenary"
+    1.0 "pilot"
+
+:define mainCharacterTrait
+    1.0 "prolix "
+    1.0 "maudlin "
+    1.0 "pompous "
+    1.0 "prevaricating "
+    1.0 "miniscule "
+    1.0 "preening "
+
+:define superlative
+    1.0 "grandiose "
+    1.0 "accomplished "
+    1.0 "saturnine "
+    1.0 "beautiful "
+    1.0 "gracious "
+    1.0 "lithe "
+
+:define predicate
+    1.0 "fell asleep."
+    1.0 "wishes she could journey around the world."
+    1.0 "falls down on the subway escalator."
+    1.0 "meets a handsome dark stranger."
+    1.0 "suffers because mercury is in powerade."
+    1.0 "charms a prince."
+
+:define subject
+    3.0 "A " mainCharacterTrait mainCharacter " "
+    1.0 "The most " superlative "of " mainCharacterTrait mainCharacter "s "
+
+:define final
+    1.0 subject.to_upper predicate
+    6.0 subject predicate
+:return
+    1.0 final
+    0.02 final.oulipo
diff --git a/madlang.cabal b/madlang.cabal
--- a/madlang.cabal
+++ b/madlang.cabal
@@ -1,5 +1,5 @@
 name:                madlang
-version:             2.3.0.3
+version:             2.3.0.4
 synopsis:            Randomized templating language DSL
 description:         Please see README.md
 homepage:            https://github.com/vmchale/madlang#readme
@@ -39,6 +39,7 @@
                      , Text.Madlibs.Cata.SemErr
                      , Text.Madlibs.Cata.Display
                      , Text.Madlibs.Exec.Main
+                     , Paths_madlang
   build-depends:       base >= 4.7 && < 5
                      , megaparsec
                      , text
@@ -47,7 +48,7 @@
                      , MonadRandom
                      , composition
                      , directory
-                     , file-embed-poly
+                     , file-embed
                      , random-shuffle
                      , microlens
                      , mtl
@@ -63,14 +64,15 @@
   hs-source-dirs:      app
   main-is:             Main.hs
   if flag(llvm-fast)
-    ghc-options:       -threaded -rtsopts -with-rtsopts=-N -fllvm -optlo-O3 -O3
+    ghc-options:       -threaded -static -fllvm -optlo-O3 -O3
+---optc-static -optl-static 
   else
     ghc-options:       -threaded -rtsopts -with-rtsopts=-N 
   build-depends:       base
                      , madlang
   default-language:    Haskell2010
 
-benchmark tweeths-bench
+benchmark madlang-bench
   type:             exitcode-stdio-1.0
   hs-source-dirs:   bench
   main-is:          Bench.hs
@@ -80,7 +82,7 @@
                   , megaparsec
                   , text
   if flag(llvm-fast)
-    ghc-options:       -threaded -rtsopts -with-rtsopts=-N -fllvm -optlo-O3 -O3
+    ghc-options:       -threaded -fllvm -optlo-O3 -O3
   else
     ghc-options:       -threaded -rtsopts -with-rtsopts=-N -O3
   default-language: Haskell2010
diff --git a/src/Text/Madlibs/Ana/Parse.hs b/src/Text/Madlibs/Ana/Parse.hs
--- a/src/Text/Madlibs/Ana/Parse.hs
+++ b/src/Text/Madlibs/Ana/Parse.hs
@@ -81,7 +81,7 @@
 modifier :: Parser (T.Text -> T.Text)
 modifier = do
     char '.'
-    str <- (try $ string "to_upper") <|> (string "to_lower")
+    str <- foldr (<|>) (pure "") $ map (try . string) ["to_upper", "to_lower", "reverse", "reverse_words", "oulipo"]
     pure (fromMaybe id (M.lookup str modifierList)) <?> "modifier"
 
 -- | Parse template into a `PreTok` of referents and strings
diff --git a/src/Text/Madlibs/Ana/ParseUtils.hs b/src/Text/Madlibs/Ana/ParseUtils.hs
--- a/src/Text/Madlibs/Ana/ParseUtils.hs
+++ b/src/Text/Madlibs/Ana/ParseUtils.hs
@@ -13,15 +13,24 @@
 import System.Random.Shuffle
 import qualified Data.Map as M
 import Data.Char
+import Control.Monad.Random.Class
 
 --TODO consider moving Ana.ParseUtils to Cata.Sorting
 
+-- | A map with all the modifiers we 
 modifierList :: M.Map String (T.Text -> T.Text)
-modifierList = M.fromList [("to_upper", T.map toUpper), ("to_lower", T.map toLower)]
+modifierList = M.fromList [("to_upper", T.map toUpper)
+    , ("to_lower", T.map toLower)
+    , ("reverse", T.reverse)
+    , ("reverse_words", T.unwords . reverse . T.words)
+    , ("oulipo", T.filter (/='e'))]
 
-jumble :: T.Text -> IO T.Text
+-- | Jumble the words in a string
+jumble :: (MonadRandom m) => T.Text -> m T.Text
 jumble = (fmap (T.pack . unwords)) . shuffleM . words . T.unpack
 
+-- | Strip file extension
+strip :: String -> T.Text
 strip = T.pack . reverse . drop 4 . reverse
 
 -- | Get the :return value
diff --git a/src/Text/Madlibs/Cata/Display.hs b/src/Text/Madlibs/Cata/Display.hs
--- a/src/Text/Madlibs/Cata/Display.hs
+++ b/src/Text/Madlibs/Cata/Display.hs
@@ -1,3 +1,4 @@
+-- | Module with helper functions for displaying the parsed tree
 module Text.Madlibs.Cata.Display where
 
 import Data.Tree
diff --git a/src/Text/Madlibs/Cata/Run.hs b/src/Text/Madlibs/Cata/Run.hs
--- a/src/Text/Madlibs/Cata/Run.hs
+++ b/src/Text/Madlibs/Cata/Run.hs
@@ -16,7 +16,7 @@
 -- @ 
 run :: (MonadRandom m) => RandTok -> m T.Text
 run tok@(List rs) = do
-    value <- getRandomR (0,1) --(withSystemRandom . asGenST $ \gen -> uniform gen)
+    value <- getRandomR (0,1)
     let ret = ((snd . head) . filter ((>=value) . fst)) $ mkCdf tok
     case ret of
         (Value txt) -> pure txt
diff --git a/src/Text/Madlibs/Exec/Main.hs b/src/Text/Madlibs/Exec/Main.hs
--- a/src/Text/Madlibs/Exec/Main.hs
+++ b/src/Text/Madlibs/Exec/Main.hs
@@ -14,6 +14,8 @@
 import Data.Maybe
 import Data.Composition
 import System.Directory
+import Paths_madlang
+import Data.Version
 
 -- | datatype for the program
 data Program = Program { sub :: Subcommand 
@@ -21,7 +23,7 @@
                        }
 
 -- | datatype for the subcommands
-data Subcommand = Debug { version :: Bool }
+data Subcommand = Debug
                 | Run { rep :: Maybe Int , clInputs :: [String] }
                 | Lint { clInputs :: [String] }
 
@@ -30,20 +32,12 @@
 orders = Program
     <$> (hsubparser
         (command "run" (info temp (progDesc "Generate text from a .mad file"))
-        <> command "debug" (info debug (progDesc "Debug a template"))
+        <> command "debug" (info (pure Debug) (progDesc "Debug a template"))
         <> command "lint" (info lint (progDesc "Lint a file"))))
     <*> (argument str
         (metavar "FILEPATH"
         <> help "File path to madlang template"))
 
--- | Parser for debug subcommand
-debug :: Parser Subcommand
-debug = Debug
-    <$> switch
-        (long "version"
-        <> short 'v'
-        <> help "Show version information")
-
 -- | Parser for the run subcommand
 temp :: Parser Subcommand
 temp = Run
@@ -74,11 +68,13 @@
 runMadlang :: IO ()
 runMadlang = execParser wrapper >>= template 
 
+versionInfo = infoOption ("madlang version: " ++ showVersion version) (short 'v' <> long "version" <> help "Show version")
+
 -- | Wraps parser with help parser
-wrapper = info (helper <*> orders)
+wrapper = info (helper <*> versionInfo <*> orders)
     (fullDesc
     <> progDesc "Madlang templating language"
-    <> header "Madlang - markov chains made easy")
+    <> header ("Madlang - templating text made easy"))
 
 -- | given a parsed record perform the appropriate IO action
 template :: Program -> IO ()
@@ -91,8 +87,7 @@
         (Run reps _) -> do
             parsed <- parseFile ins "" filepath
             replicateM_ (fromMaybe 1 reps) $ runFile ins filepath >>= TIO.putStrLn 
-        (Debug _) -> do
-            putStr . (either show displayTree) =<< makeTree ins "" filepath 
+        Debug -> putStr . (either show displayTree) =<< makeTree ins "" filepath 
         (Lint _) -> do
             parsed <- parseFile ins "" filepath
             putStrLn $ either parseErrorPretty (const "No syntax errors found.") parsed
diff --git a/src/Text/Madlibs/Generate/TH.hs b/src/Text/Madlibs/Generate/TH.hs
--- a/src/Text/Madlibs/Generate/TH.hs
+++ b/src/Text/Madlibs/Generate/TH.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE TemplateHaskell #-}
 
+-- | Module containing Quasi-Quoter and Template Haskell splice for use as an EDSL.
 module Text.Madlibs.Generate.TH 
     ( textToExpression
     , madFile
@@ -14,6 +15,7 @@
 import Language.Haskell.TH.Quote
 import Data.FileEmbed
 import Text.Megaparsec
+import Data.Text.Encoding
 
 -- | `QuasiQuoter` for an EDSL, e.g.
 -- 
@@ -35,13 +37,15 @@
                       , quotePat = error "quasi-quoter does not support patterns"
                       , quoteType = error "quasi-quoter does not support types"
                       , quoteDec = error "quasi-quoter does not support top-level quotes"
-                      } -- TODO add quasiQuoter w/context etc.
+                      } -- TODO add quasiQuoter w/inclusions or context
 
+-- | Convert a `String` containing  to a `Q Exp` with the parsed syntax tree.
 textToExpression :: String -> Q Exp
 textToExpression txt = do
     parse <- [|parseTok "source" [] []|]
     pure $ (VarE 'errorgen) `AppE` (parse `AppE` ((VarE 'T.pack) `AppE` (LitE (StringL (txt)))))
 
+-- | Turn a parse error into an error that will be caught when Template Haskell compiles at runtime.
 errorgen :: Either (ParseError Char Dec) a -> a
 errorgen = either (error . T.unpack . show') id
 
@@ -56,6 +60,6 @@
 -- Note that the embedded code cannot have any inclusions.
 madFile :: FilePath -> Q Exp
 madFile path = do
-    file <- embedFile path
-    parse <- [|parseTok "source" [] []|] -- TODO make this recurse but still work!
+    file <- (embedFile path)
+    parse <- [|(parseTok "source" [] []) . decodeUtf8|] -- TODO make this recurse but still work!
     pure $ (VarE 'errorgen) `AppE` (parse `AppE` file)
diff --git a/src/Text/Madlibs/Internal/Utils.hs b/src/Text/Madlibs/Internal/Utils.hs
--- a/src/Text/Madlibs/Internal/Utils.hs
+++ b/src/Text/Madlibs/Internal/Utils.hs
@@ -27,9 +27,9 @@
 
 -- | Add a PR for this? Could be useful in Megaparsec idk
 -- Allows us to use monoidal addition on parsers
-instance (Monoid a) => Monoid (Parser a) where
-    mempty = pure mempty
-    mappend x y = mappend <$> x <*> y
+--instance (Monoid a) => Monoid (Parser a) where
+--    mempty = pure mempty
+--    mappend x y = mappend <$> x <*> y
 
 -- | Normalize pre-tokens/corresponding probabilities
 normalize :: [(Prob, [PreTok])] -> [(Prob, [PreTok])]
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -3,5 +3,4 @@
 packages:
 - '.'
 extra-deps:
-- file-embed-poly-0.1.0
-resolver: lts-8.11
+resolver: lts-8.12
