diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 3.3.0.6
+
+  * Fix to allow nested dfns
+  * Allow `-Dval=VAR` on command-line
+
 # 3.3.0.5
 
   * Add `Ord` instance for tuples, etc.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -63,7 +63,6 @@
 
 ## Missing Features & Bugs
 
-  * No nested dfns
   * No list literal syntax
   * Postfix `:f` and `:i` are handled poorly
   * Streams of functions don't work
diff --git a/jacinda.cabal b/jacinda.cabal
--- a/jacinda.cabal
+++ b/jacinda.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               jacinda
-version:            3.3.0.5
+version:            3.3.0.6
 license:            AGPL-3.0-only
 license-file:       COPYING
 maintainer:         vamchale@gmail.com
diff --git a/src/A.hs b/src/A.hs
--- a/src/A.hs
+++ b/src/A.hs
@@ -128,7 +128,7 @@
           | Substr | Sub1 | Subs
           | Option
           | Captures | AllCaptures | Ixes
-          | Bookend | BookendG
+          | Bookend
 
 instance Pretty BTer where
     pretty ZipW        = ","
@@ -291,7 +291,6 @@
     ps _ (EApp _ (UB _ FParse) e')    = pretty e' <> ":f"
     ps _ (EApp _ (UB _ Parse) e')     = pretty e' <> ":"
     ps d (EApp _ (EApp _ (EApp _ (TB _ Bookend) e) e') e'')  = parensp (d>3) (ps 4 e <> ",," <> ps 4 e' <+> ps 5 e'')
-    ps d (EApp _ (EApp _ (EApp _ (TB _ BookendG) e) e') e'') = parensp (d>3) (ps 4 e <> "|," <> ps 4 e' <+> ps 5 e'')
     ps d (EApp _ (EApp _ (EApp _ (TB _ Fold) e) e') e'')     = parensp (d>5) (ps 6 e <> "|" <> ps 6 e' <+> ps 7 e'')
     ps d (EApp _ (EApp _ (EApp _ (TB _ Scan) e) e') e'')     = parensp (d>5) (ps 6 e <> "^" <> ps 6 e' <+> ps 7 e'')
     ps d (EApp _ (EApp _ (EApp _ (TB _ ScanList) e) e') e'') = parensp (d>5) (ps 6 e <> "^" <> ps 6 e' <+> ps 7 e'')
diff --git a/src/File.hs b/src/File.hs
--- a/src/File.hs
+++ b/src/File.hs
@@ -71,8 +71,8 @@
 
 -- | Parse + rename
 parsePWithMax :: [FilePath] -> Maybe FilePath -> T.Text -> [(T.Text, T.Text)] -> IO (Program AlexPosn, Int)
-parsePWithMax incls fn src vars = uncurry rP.swap.second fst3 <$> runStateT (parseP incls fn src vars) alexInitUserState
-    where fst3 (x,_,_) = x
+parsePWithMax incls fn src vars = uncurry rP.swap.second fst4 <$> runStateT (parseP incls fn src vars) alexInitUserState
+    where fst4 (x,_,_,_) = x
 
 parseWithMax' :: T.Text -> Either (ParseError AlexPosn) (Program AlexPosn, Int)
 parseWithMax' = fmap (uncurry rP . second (rwP.snd)) . parseWithMax
diff --git a/src/L.x b/src/L.x
--- a/src/L.x
+++ b/src/L.x
@@ -15,7 +15,6 @@
              , AlexUserState
              ) where
 
-import Control.Arrow ((&&&))
 import Data.Bifunctor (first)
 import qualified Data.ByteString.Lazy as BSL
 import Data.Functor (($>))
@@ -58,14 +57,27 @@
         y                        { res VarY }
     }
 
-    <0> "["                      { sym LSqBracket `andBegin` dfn } -- FIXME: this doesn't allow nested
+    <0> {
+        "#!".*                   ; -- shebang
 
+        asv                      { mkKw KwAsv }
+        usv                      { mkKw KwUsv }
+        csv                      { mkKw KwCsv }
+        header                   { mkKw KwHeader }
+        fs                       { mkKw KwFs }
+        rs                       { mkKw KwRs }
+        :set                     { mkKw KwSet }
+        :flush                   { mkKw KwFlush }
+        "@include"               { mkKw KwInclude }
+        fn                       { mkKw KwFn }
+
+    }
+
     <0,dfn> {
 
         $white+                  ;
 
         "{.".*                   ;
-        "#!".*                   ; -- shebang
 
         ":="                     { sym DefEq }
         "≔"                      { sym DefEq }
@@ -103,7 +115,7 @@
         "{%"                     { sym LBracePercent }
         "#{"                     { sym LBraceOctothorpe }
         "{|"                     { sym LBraceBar }
-        "]"                      { sym RSqBracket `andBegin` 0 }
+        "]"                      { tok (\p _ -> rsq (TokSym p RSqBracket)) }
         ".="                     { sym DotEq }
         "~"                      { sym Tilde }
         "!~"                     { sym NotMatchTok }
@@ -136,32 +148,23 @@
         "`$"                     { sym FieldListTok }
         \?                       { sym QuestionMark }
         "@@"                     { sym AmpAmp }
+        ¨                        { sym Quot }
 
-        in                       { mkKw KwIn }
+        "["                      { tok (\p _ -> lsq (TokSym p LSqBracket)) }
+
         let                      { mkKw KwLet }
         val                      { mkKw KwVal }
+        in                       { mkKw KwIn }
         end                      { mkKw KwEnd }
-        :set                     { mkKw KwSet }
-        :flush                   { mkKw KwFlush }
-        fn                       { mkKw KwFn }
-        "@include"               { mkKw KwInclude }
         if                       { mkKw KwIf }
         then                     { mkKw KwThen }
         else                     { mkKw KwElse }
-        asv                      { mkKw KwAsv }
-        usv                      { mkKw KwUsv }
-        csv                      { mkKw KwCsv }
-        header                   { mkKw KwHeader }
 
-        fs                       { res VarFs }
-        rs                       { res VarRs }
-        ix                       { res VarIx }
-        ⍳                        { res VarIx }
-        nf                       { res VarNf }
-        ¨                        { sym Quot }
-        min                      { res VarMin }
-        max                      { res VarMax }
-
+        ix                       { mkBuiltin BIx }
+        ⍳                        { mkBuiltin BIx }
+        nf                       { mkBuiltin BNf }
+        min                      { mkBuiltin BMin }
+        max                      { mkBuiltin BMax }
         substr                   { mkBuiltin BSubstr }
         split                    { mkBuiltin BSplit }
         splitc                   { mkBuiltin BSplitc }
@@ -211,7 +214,6 @@
 
         @string                  { tok (\p s -> alex $ TokStr p (escReplace $ T.init $ T.tail s)) }
 
-        -- TODO: allow chars to be escaped
         @rr                      { tok (\p s -> alex $ TokRR p (escRr $ T.init $ T.tail s)) }
 
         @name                    { tok (\p s -> TokName p <$> newIdentAlex p s) }
@@ -228,8 +230,10 @@
 
 constructor c t = tok (\p _ -> alex $ c p t)
 
-res = constructor TokResVar; mkKw      = constructor TokKeyword
-sym = constructor TokSym;    mkBuiltin = constructor TokBuiltin
+res = constructor TokVar
+mkKw = constructor TokKeyword
+sym = constructor TokSym
+mkBuiltin = constructor TokBuiltin
 
 data R = Z | B | EE | ES
 
@@ -252,16 +256,23 @@
 instance Pretty AlexPosn where
     pretty (AlexPn _ line col) = pretty line <> colon <> pretty col
 
-type AlexUserState = (Int, M.Map T.Text Int, IM.IntMap (Nm AlexPosn))
+type AlexUserState = (Int, M.Map T.Text Int, IM.IntMap (Nm AlexPosn), Int)
 
 alexInitUserState :: AlexUserState
-alexInitUserState = (0, mempty, mempty)
+alexInitUserState = (0, mempty, mempty, 0)
 
-gets_alex :: (AlexState -> a) -> Alex a
-gets_alex f = Alex (Right . (id &&& f))
+lsq, rsq :: a -> Alex a
+lsq ret = Alex $ \st ->
+    let (max', names, uniqs, db) = alex_ust st
+        db' = db+1
+    in Right (st { alex_ust = (max', names, uniqs, db'), alex_scd = dfn }, ret)
+rsq ret = Alex $ \st ->
+    let (max', names, uniqs, db) = alex_ust st
+        db' = db-1
+    in Right (st { alex_ust = (max', names, uniqs, db'), alex_scd = if db'==0 then 0 else dfn }, ret)
 
 get_pos :: Alex AlexPosn
-get_pos = gets_alex alex_pos
+get_pos = Alex $ \st -> Right (st, alex_pos st)
 
 alexEOF = EOF <$> get_pos
 
@@ -275,10 +286,9 @@
          | DefEq
          | Colon
          | LBrace | RBrace
-         | LParen
+         | LParen | RParen
          | LAnchor
          | DotEq
-         | RParen
          | LSqBracket | RSqBracket
          | Semicolon
          | Underscore
@@ -381,20 +391,13 @@
              | KwInclude
              | KwIf | KwThen | KwElse
              | KwAsv | KwUsv | KwCsv
+             | KwFs | KwRs
+             | KwOfs | KwOrs
 
--- | Reserved/special variables
 data Var = VarX | VarY
-         | VarFs | VarRs
-         | VarOfs | VarOrs
-         | VarIx | VarNf
-         | VarMin | VarMax
 
 instance Pretty Var where
     pretty VarX = "x"; pretty VarY = "y"
-    pretty VarFs = "fs"; pretty VarRs = "rs"
-    pretty VarOrs = "ors"; pretty VarOfs = "ofs"
-    pretty VarMin = "min"; pretty VarMax = "max"
-    pretty VarIx = "⍳"; pretty VarNf = "nf"
 
 instance Pretty Keyword where
     pretty KwLet     = "let"
@@ -411,7 +414,11 @@
     pretty KwUsv     = "usv"
     pretty KwAsv     = "asv"
     pretty KwCsv     = "csv"
-    pretty KwHeader = "header"
+    pretty KwHeader  = "header"
+    pretty KwFs      = "fs"
+    pretty KwRs      = "rs"
+    pretty KwOrs     = "ors"
+    pretty KwOfs     = "ofs"
 
 data Builtin = BIParse | BFParse
              | BSubstr
@@ -433,6 +440,8 @@
              | BInit | BLast
              | BDrop | BTake
              | BRein
+             | BMin | BMax
+             | BIx | BNf
 
 instance Pretty Builtin where
     pretty BIParse   = ":i"
@@ -465,6 +474,10 @@
     pretty BTake     = "take#"
     pretty BDrop     = "drop#"
     pretty BRein     = "reintercalate"
+    pretty BMin      = "min"
+    pretty BMax      = "max"
+    pretty BIx       = "⍳"
+    pretty BNf       = "nf"
 
 data Token a = EOF { loc :: a }
              | TokSym { loc :: a, _sym :: Sym }
@@ -472,7 +485,7 @@
              | TokTyName { loc :: a, _tyName :: TyName a }
              | TokBuiltin { loc :: a, _builtin :: Builtin }
              | TokKeyword { loc :: a, _kw :: Keyword }
-             | TokResVar { loc :: a, _var :: Var }
+             | TokVar { loc :: a, _var :: Var }
              | TokInt { loc :: a, int :: Integer }
              | TokFloat { loc :: a, float :: Double }
              | TokBool { loc :: a, boolTok :: Bool }
@@ -497,7 +510,7 @@
     pretty (TokStreamLit _ i) = "$" <> pretty i
     pretty (TokFieldLit _ i)  = "`" <> pretty i
     pretty (TokRR _ rr')      = "/" <> pretty rr' <> "/"
-    pretty (TokResVar _ v)    = "reserved variable" <+> squotes (pretty v)
+    pretty (TokVar _ v)       = "implicit variable" <+> squotes (pretty v)
     pretty (TokBool _ True)   = "#t"
     pretty (TokBool _ False)  = "#f"
     pretty (TokAccess _ i)    = "." <> pretty i
@@ -508,9 +521,9 @@
 freshName :: T.Text -> Alex (Nm AlexPosn)
 freshName t = do
     pos <- get_pos
-    (i, ns, us) <- alexGetUserState
+    (i, ns, us, db) <- alexGetUserState
     let (j, n) = freshIdent pos t i
-    alexSetUserState (j, ns, us) $> n
+    alexSetUserState (j, ns, us, db) $> n
 
 newVarAlex :: T.Text -> Alex (Nm AlexPosn)
 newVarAlex t = do {pos <- get_pos; newIdentAlex pos t}
@@ -522,17 +535,15 @@
     alexSetUserState st' $> n
 
 freshIdent :: AlexPosn -> T.Text -> Int -> (Int, Nm AlexPosn)
-freshIdent pos t max' =
-    let i=max'+1; nm=Nm t (U i) pos
-        in (i, nm)
+freshIdent pos t max' = let i=max'+1 in (i, Nm t (U i) pos)
 
 newIdent :: AlexPosn -> T.Text -> AlexUserState -> (AlexUserState, Nm AlexPosn)
-newIdent pos t pre@(max', names, uniqs) =
+newIdent pos t pre@(max', names, uniqs, depth') =
     case M.lookup t names of
         Just i -> (pre, Nm t (U i) pos)
         Nothing -> let i = max' + 1
             in let newName = Nm t (U i) pos
-                in ((i, M.insert t i names, IM.insert i newName uniqs), newName)
+                in ((i, M.insert t i names, IM.insert i newName uniqs, depth'), newName)
 
 runAlexSt :: T.Text -> Alex a -> Either String (AlexUserState, a)
 runAlexSt inp = withAlexSt inp alexInitUserState
diff --git a/src/Parser.y b/src/Parser.y
--- a/src/Parser.y
+++ b/src/Parser.y
@@ -10,7 +10,7 @@
                   ) where
 
 import Control.Exception (Exception, throw)
-import Control.Monad.Except (ExceptT, runExceptT, throwError)
+import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)
 import Control.Monad.Trans.Class (lift)
 import Data.Bifunctor (first, second)
 import Data.Functor (void)
@@ -130,19 +130,18 @@
     usv { TokKeyword $$ KwUsv }
     asv { TokKeyword $$ KwAsv }
     csv { TokKeyword $$ KwCsv }
-
-    x { TokResVar $$ VarX }
-    y { TokResVar $$ VarY }
+    fs { TokKeyword $$ KwFs }
+    rs { TokKeyword $$ KwRs }
+    ofs { TokKeyword $$ KwOfs }
+    ors { TokKeyword $$ KwOrs }
 
-    min { TokResVar $$ VarMin }
-    max { TokResVar $$ VarMax }
-    ix { TokResVar $$ VarIx }
-    nf { TokResVar $$ VarNf }
-    fs { TokResVar $$ VarFs }
-    rs { TokResVar $$ VarRs }
-    ofs { TokResVar $$ VarOfs }
-    ors { TokResVar $$ VarOrs }
+    x { TokVar $$ VarX }
+    y { TokVar $$ VarY }
 
+    min { TokBuiltin $$ BMin }
+    max { TokBuiltin $$ BMax }
+    ix { TokBuiltin $$ BIx }
+    nf { TokBuiltin $$ BNf }
     split { TokBuiltin $$ BSplit }
     splitc { TokBuiltin $$ BSplitc }
     substr { TokBuiltin $$ BSubstr }
@@ -386,7 +385,7 @@
 type Value = T.Text
 
 parseError :: Token AlexPosn -> [String] -> Parse a
-parseError tok = throwError . Unexpected tok
+parseError tok = throwE.Unexpected tok
 
 mkLet :: a -> [(Nm a, E a)] -> E a -> E a
 mkLet _ [] e     = e
@@ -416,8 +415,8 @@
 df t x = do {nm <- newVarAlex t; let l=Nm.loc nm in pure (Let l (nm, guess l x))}
 
 parseWithMax :: T.Text -> Either (ParseError AlexPosn) (Int, File)
-parseWithMax = fmap (first fst3) . runParse parseF
-    where fst3 (x, _, _) = x
+parseWithMax = fmap (first fst4) . runParse parseF
+    where fst4 (x, _, _, _) = x
 
 binds :: [(T.Text, Value)] -> Alex (E AlexPosn -> E AlexPosn)
 binds = fmap thread.traverse (uncurry df) where thread = foldr (.) id
diff --git a/src/R.hs b/src/R.hs
--- a/src/R.hs
+++ b/src/R.hs
@@ -6,9 +6,10 @@
 import           A
 import           C
 import           Control.Monad.State.Strict (MonadState, State, runState)
-import           Data.Bifunctor             (second)
+import           Data.Bifunctor             (bimap, first, second)
 import qualified Data.IntMap                as IM
 import qualified Data.Text                  as T
+import qualified Data.Vector                as V
 import           Lens.Micro                 (Lens', over)
 import           Lens.Micro.Mtl             (use, (%=), (.=))
 import           Nm
@@ -81,76 +82,6 @@
 mkLam :: [Nm a] -> E a -> E a
 mkLam ns e = foldr (\n -> Lam (loc n) n) e ns
 
-hasY :: E a -> Bool
-hasY = g where
-    g (ResVar _ Y)           = True
-    g (Tup _ es)             = g!|es
-    g (Rec _ es)             = (g.snd)!|es
-    g (OptionVal _ (Just e)) = g e
-    g (EApp _ e0 e1)         = g e0 || g e1
-    g Dfn{}                  = error "nested dfns not yet implemented"
-    g (Let _ (_, be) e)      = g e || g be
-    g (Lam _ _ e)            = g e
-    g (Paren _ e)            = g e
-    g (Guarded _ p e)        = g p || g e
-    g (Implicit _ e)         = g e
-    g (Arr _ es)             = g!|es
-    g (Anchor _ es)          = g!|es
-    g (Cond _ p e0 e1)       = g e0 || g e1 || g p
-    g _                      = False
-
-    infixr 6 !|
-
-    (!|) :: Foldable t => (a -> Bool) -> t a -> Bool
-    (!|) = any
-
-replaceXY :: (a -> Nm a) -- ^ @x@
-          -> (a -> Nm a) -- ^ @y@
-          -> E a
-          -> E a
-replaceXY nX nY = r where
-    r (ResVar l Y)      = Var l (nY l)
-    r (ResVar l X)      = Var l (nX l)
-    r e@Lit{}           = e
-    r e@RegexLit{}      = e
-    r e@RC{}            = e
-    r e@Var{}           = e
-    r e@NB{}            = e
-    r e@UB{}            = e
-    r e@BB{}            = e
-    r e@RwB{}           = e
-    r e@RwT{}           = e
-    r e@TB{}            = e
-    r (EApp l e0 e1)    = EApp l (r e0) (r e1)
-    r (Implicit l e)    = Implicit l (r e)
-    r (Guarded l p e)   = Guarded l (r p) (r e)
-    r (Let l (n, be) e) = Let l (n, r be) (r e)
-    r (Lam l n e)       = Lam l n (r e)
-    r (Cond l p e0 e1)  = Cond l (r p) (r e0) (r e1)
-    r (OptionVal l e)   = OptionVal l (r<$>e)
-    r (Tup l es)        = Tup l (r<$>es)
-    r (Rec l es)        = Rec l (second r<$>es)
-    r (Arr l es)        = Arr l (r<$>es)
-    r (Anchor l es)     = Anchor l (r<$>es)
-    r e@Column{}        = e
-    r e@AllColumn{}     = e
-    r e@Field{}         = e
-    r e@AllField{}      = e
-    r e@LastField{}     = e
-    r e@FieldList{}     = e
-    r e@FParseAllCol{}  = e
-    r e@IParseAllCol{}  = e
-    r e@ParseAllCol{}   = e
-    r e@FParseCol{}     = e
-    r e@IParseCol{}     = e
-    r e@ParseCol{}      = e
-    r (Paren l e)       = Paren l (r e)
-    r Dfn{}             = error "nested dfns not yet implemented"
-    r F{}               = error "Internal error."
-
-replaceX :: (a -> Nm a) -> E a -> E a
-replaceX n = replaceXY n (error "Internal error: 'y' not expected.")
-
 renameD :: D a -> RenameM (D a)
 renameD (FunDecl n ns e) = FunDecl n [] <$> rE (mkLam ns e)
 renameD d                = pure d
@@ -160,30 +91,59 @@
 
 {-# INLINABLE rE #-}
 rE :: (HasRenames s, MonadState s m) => E a -> m (E a)
-rE (EApp l e e')   = EApp l <$> rE e <*> rE e'
-rE (Tup l es)      = Tup l <$> traverse rE es
-rE (Rec l es)      = Rec l <$> traverse (secondM rE) es
-rE (Var l n)       = Var l <$> replaceVar n
-rE (Lam l n e)     = doLocal $ do
+rE = fmap fst.r undefined undefined
+
+{-# INLINABLE r #-}
+r :: (HasRenames s, MonadState s m) => (a -> Nm a) -> (a -> Nm a) -> E a -> m (E a, Bool)
+r _ _ (Var l n)      = (\n' -> (Var l n', False)) <$> replaceVar n
+r x y (EApp l e0 e1) = do
+    (e0',b0) <- r x y e0
+    (e1',b1) <- r x y e1
+    pure (EApp l e0' e1', b0||b1)
+r x y (Cond l p e0 e1) = do
+    (p',b0) <- r x y p
+    (e0',b1) <- r x y e0
+    (e1',b2) <- r x y e1
+    pure (Cond l p' e0' e1', b0||b1||b2)
+r x y (Lam l n e)   = doLocal $ do
     n' <- freshen n
-    Lam l n' <$> rE e
-rE (Dfn l e) | {-# SCC "hasY" #-} hasY e = do
+    first (Lam l n') <$> r x y e
+r x y (Let l (n, eb) e) = doLocal $ do
+    (eb', b) <- r x y eb
+    n' <- freshen n
+    bimap (Let l (n', eb')) (b||) <$> r x y e
+r _ _ (Dfn l e) = do
     x@(Nm nX uX _) <- dummyName l "x"
     y@(Nm nY uY _) <- dummyName l "y"
-    Lam l x . Lam l y <$> rE ({-# SCC "replaceXY" #-} replaceXY (Nm nX uX) (Nm nY uY) e)
-                  | otherwise = do
-    x@(Nm n u _) <- dummyName l "x"
-    Lam l x <$> rE ({-# SCC "replaceX" #-} replaceX (Nm n u) e)
-rE (Guarded l p e) = Guarded l <$> rE p <*> rE e
-rE (Implicit l e) = Implicit l <$> rE e
-rE ResVar{} = error "Bare reserved variable."
-rE (Let l (n, eϵ) e') = doLocal $ do
-    eϵ' <- rE eϵ
-    n' <- freshen n
-    Let l (n', eϵ') <$> rE e'
-rE (Paren _ e) = rE e
-rE (Arr l es) = Arr l <$> traverse rE es
-rE (Anchor l es) = Anchor l <$> traverse rE es
-rE (OptionVal l e) = OptionVal l <$> traverse rE e
-rE (Cond l p e e') = Cond l <$> rE p <*> rE e <*> rE e'
-rE e = pure e
+    (e',hasY) <- r (Nm nX uX) (Nm nY uY) e
+    pure $ if hasY
+        then (Lam l x (Lam l y e'), False)
+        else (Lam l x e', False)
+r x y (Implicit l e) = do
+    (e',b) <- r x y e
+    pure (Implicit l e', b)
+r x y (Guarded l p e) = do
+    (p',b0) <- r x y p
+    (e',b1) <- r x y e
+    pure (Guarded l p' e', b0||b1)
+r x _ (ResVar l X)   = pure (Var l (x l), False)
+r _ y (ResVar l Y)   = pure (Var l (y l), True)
+r x y (Tup l es) = do
+    (es',b) <- unzip <$> traverse (r x y) es
+    pure (Tup l es', or b)
+r x y (OptionVal l e) = do
+    v <- traverse (r x y) e
+    case v of
+        Nothing     -> pure (OptionVal l Nothing, False)
+        Just (e',b) -> pure (OptionVal l (Just e'), b)
+r x y (Rec l es) = do
+    (es',b) <- unzip . map (\(n,(eϵ,b)) -> ((n,eϵ),b)) <$> traverse (secondM (r x y)) es
+    pure (Rec l es', or b)
+r x y (Anchor l es) = do
+    (es',b) <- unzip <$> traverse (r x y) es
+    pure (Anchor l es', or b)
+r x y (Arr l es) = do
+    (es',b) <- V.unzip <$> traverse (r x y) es
+    pure (Arr l es', or b)
+r x y (Paren _ e') = r x y e'
+r _ _ e' = pure (e', False)
diff --git a/src/Ty.hs b/src/Ty.hs
--- a/src/Ty.hs
+++ b/src/Ty.hs
@@ -467,9 +467,6 @@
     addCM f (Foldable, l)
     pure (BB ((a ~> a ~> a) ~> ((f':$a) ~> a)) Fold1, s)
 tyES s (TB _ Bookend) = pure (TB (tyR ~> tyR ~> tyStream tyStr ~> tyStream tyStr) Bookend, s)
-tyES s (TB _ BookendG) = do
-    a <- freshTV "a"
-    pure (TB ((a~>tyB) ~> (a~>tyB) ~> tyStream a ~> tyStream a) BookendG, s)
 tyES s (TB _ Captures) = pure (TB (tyStr ~> tyI ~> tyR ~> tyOpt tyStr) Captures, s)
 tyES s (BB _ Prior) = do
     a <- freshTV "a"; b <- freshTV "b"
diff --git a/x/Opt.hs b/x/Opt.hs
--- a/x/Opt.hs
+++ b/x/Opt.hs
@@ -17,7 +17,7 @@
 
 data Cmd = TC !FilePath ![FilePath]
          | Run !FilePath !(Maybe T.Text) !(Maybe T.Text) !(Maybe FilePath) ![FilePath] ![(T.Text, Value)] Bool
-         | Expr !T.Text !(Maybe FilePath) !(Maybe T.Text) !Bool !Bool !Bool !(Maybe T.Text) ![FilePath] Bool
+         | Expr !T.Text !(Maybe FilePath) !(Maybe T.Text) !Bool !Bool !Bool !(Maybe T.Text) ![FilePath] ![(T.Text, Value)] Bool
          | Eval !T.Text
          | Install
 
@@ -93,7 +93,7 @@
     where
         tcP = TC <$> j'File <*> incls; eP = Eval <$> jacExpr
         runP = Run <$> j'File <*> jacFs <*> jacRs <*> inpFile <*> incls <*> defVar <*> begin
-        exprP = Expr <$> jacExpr <*> inpFile <*> jacFs <*> asv <*> usv <*> csv <*> jacRs <*> incls <*> begin
+        exprP = Expr <$> jacExpr <*> inpFile <*> jacFs <*> asv <*> usv <*> csv <*> jacRs <*> incls <*> defVar <*> begin
 
 incls :: Parser [FilePath]
 incls = many $ strOption
@@ -130,12 +130,12 @@
 
 run :: Cmd -> IO ()
 run (TC fp is)                         = tcIO is fp =<< TIO.readFile fp
-run (Run fp fs rs Nothing is vs h)    = do { contents <- TIO.readFile fp ; runStdin is (Just fp) contents vs (AWK fs rs h) }
-run (Run fp fs rs (Just dat) is vs h) = do { contents <- TIO.readFile fp ; runOnFile is (Just fp) contents vs (AWK fs rs h) dat stdout }
-run (Expr eb f fs a u c rs is h)      =
+run (Run fp fs rs Nothing is vs h)    = do {contents <- TIO.readFile fp ; runStdin is (Just fp) contents vs (AWK fs rs h)}
+run (Run fp fs rs (Just dat) is vs h) = do {contents <- TIO.readFile fp ; runOnFile is (Just fp) contents vs (AWK fs rs h) dat stdout}
+run (Expr eb f fs a u c rs is vs h)      =
     case f of
-        Nothing -> runStdin is Nothing eb [] (m h)
-        Just fp -> runOnFile is Nothing eb [] (m h) fp stdout
+        Nothing -> runStdin is Nothing eb vs (m h)
+        Just fp -> runOnFile is Nothing eb vs (m h) fp stdout
   where
     m = ap a u c fs rs
 run (Eval e)                          = print (exprEval e)
