diff --git a/LambdaShell.cabal b/LambdaShell.cabal
--- a/LambdaShell.cabal
+++ b/LambdaShell.cabal
@@ -1,7 +1,7 @@
 Name:            LambdaShell
 Cabal-Version:   >= 1.2
 Build-Type:	 Simple
-Version:         0.9.1
+Version:         0.9.3
 License:         GPL
 License-file:    LICENSE
 Author:          Robert Dockins
@@ -9,7 +9,7 @@
 Stability:       Beta
 Category:        Compilers/Interpreters
 Synopsis:        Simple shell for evaluating lambda expressions
-Homepage:        http://www.cs.princeton.edu/~rdockins/lambda/home/
+Homepage:        http://rwd.rdockins.name/lambda/home/
 Description:
   The lambda shell is a feature-rich shell environment and command-line tool for
   evaluating terms of the pure, untyped lambda calculus.  The Lambda
@@ -27,15 +27,14 @@
      LambdaParser
      LambdaShell
      Version
+     Paths_LambdaShell
   Extensions:
      MultiParamTypeClasses
-  Extra-libraries:
-     readline
-  GHC-Options: -O
+  GHC-Options: -W -fno-warn-unused-binds -fno-warn-unused-matches
   Build-Depends:
-     base, haskell98, parsec,
-     mtl, readline,
+     base >= 2, base < 5,
+     parsec, mtl,
      Shellac >= 0.9,
-     Shellac-readline >= 0.9
+     Shellac-compatline >= 0.9
   if impl( ghc >= 6.8 )
      Build-Depends: containers
diff --git a/src/CPS.hs b/src/CPS.hs
--- a/src/CPS.hs
+++ b/src/CPS.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -45,7 +45,9 @@
 do_simple_cps :: Monad m => CPS m
 
 do_simple_cps b (Binding _ name) =
-    lookupBindingM name b >>= \t -> do_simple_cps b t
+    lookupBindingM name b >>=
+       maybe (return (Lam () "k" $ App () (Var () 0) $ (Binding () name)))
+             (do_simple_cps b)
 
 do_simple_cps b (Var _ i) =
     return (Lam () "k" $ App () (Var () 0) $ (Var () (i+1)))
@@ -76,7 +78,9 @@
 do_eta_cps :: Monad m => CPS m
 
 do_eta_cps b (Binding _ name) =
-    lookupBindingM name b >>= \t -> do_simple_cps b t
+    lookupBindingM name b >>=
+      maybe (return (Lam () "k" $ App () (Var () 0) $ (Binding () name)))
+            (do_simple_cps b)
 
 do_eta_cps b (Var _ i) =
     return (Lam () "k" $ App () (Var () 0) $ (Var () (i+1)))
@@ -146,7 +150,9 @@
     -> m (PureLambda Bool String)
 
 do_onepass_cps b (Binding _ name) =
-     lookupBindingM name b >>= \t -> do_onepass_cps b t
+     lookupBindingM name b >>= 
+        maybe (return (Lam True "k" $ App True (Var True 0) $ (Binding False name)))
+              (do_onepass_cps b)
 
 do_onepass_cps b (Var _ i) =
      return (Lam True "k" $ App True (Var True 0) $ (Var False (i+1)))
@@ -175,6 +181,11 @@
     => Bindings () String
     -> PureLambda () String
     -> m (PureLambda Bool String)
+
+do_onepass_cps_tail b (Binding _ name) =
+     lookupBindingM name b >>=
+       maybe (return (Lam True "k0" (App False (Var True 0) (Binding False name))))
+             (do_onepass_cps_tail b)
 
 do_onepass_cps_tail b (Var _ i) =
     return (Lam True "k0" (App False (Var True 0) (Var False (i+1))))
diff --git a/src/Env.hs b/src/Env.hs
--- a/src/Env.hs
+++ b/src/Env.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -29,8 +29,8 @@
 
 data Env = Env !Int ![String] !(Set.Set String)
 
-empty :: Env
-empty = Env 0 [] (Set.empty)
+empty :: Set.Set String -> Env
+empty = Env 0 []
 
 insert :: String -> Env -> Env
 insert label (Env z labels set)
diff --git a/src/Lambda.hs b/src/Lambda.hs
--- a/src/Lambda.hs
+++ b/src/Lambda.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -68,21 +68,19 @@
 import Data.List
 import qualified Env as Env
 import qualified Data.Map as Map
-import Control.Monad (MonadPlus (..))
 import Control.Monad.Identity
 
-type Bindings a l = Map.Map String (PureLambda a l)
+type Bindings a l = Map.Map String (Maybe (PureLambda a l))
 
-lookupBinding :: String -> Bindings a l -> PureLambda a l
+lookupBinding :: String -> Bindings a l -> Maybe (PureLambda a l)
 lookupBinding name b  = runIdentity (lookupBindingM name b)
 
-lookupBindingM :: Monad m => String -> Bindings a l -> m (PureLambda a l)
+lookupBindingM :: Monad m => String -> Bindings a l -> m (Maybe (PureLambda a l))
 lookupBindingM name b =
    case Map.lookup name b of
-      Just x  -> return x
+      Just x -> return x
       Nothing -> fail (concat ["'",name,"' not bound"])
 
-
 ----------------------------------------------------------------
 -- | The type of lambda terms;
 --   they are polymorphic in an annotation type \'a\' and the type
@@ -129,11 +127,11 @@
 -- | Show a lambda term, minimizing parenthises and disambiguating
 --   variables in nested scopes with identical labels.
 
-printLam :: PureLambda a String -> String
-printLam lam = showLam lam []
+printLam :: Bindings a String -> PureLambda a String -> String
+printLam binds lam = showLam binds lam []
 
-showLam :: PureLambda a String -> ShowS
-showLam = showLam_ Env.empty TopContext 0
+showLam :: Bindings a String -> PureLambda a String -> ShowS
+showLam binds = showLam_ (Env.empty (Map.keysSet binds)) TopContext 0
 
 
 data LamContext
@@ -250,7 +248,7 @@
 lamReduceWHNF b unfold (App a t1 t2)           = lamReduceWHNF b True t1   >>= \t1' -> return (App a t1' t2)
 lamReduceWHNF b unfold (Lam a l t)             = Nothing
 lamReduceWHNF b unfold (Var _ _)               = Nothing
-lamReduceWHNF b unfold (Binding a name)        = if unfold then Just (lookupBinding name b) else Nothing
+lamReduceWHNF b unfold (Binding a name)        = if unfold then lookupBinding name b else Nothing
 
 
 -------------------------------------------------------------------------------------
@@ -262,7 +260,7 @@
 lamReduceHNF b unfold (App a t1 t2)            = lamReduceHNF b True t1   >>= \t1' -> return (App a t1' t2)
 lamReduceHNF b unfold (Lam a l t)              = lamReduceHNF b unfold t  >>= \t'  -> return (Lam a l t')
 lamReduceHNF b unfold (Var _ _)                = Nothing
-lamReduceHNF b unfold (Binding a name)         = if unfold then Just (lookupBinding name b) else Nothing
+lamReduceHNF b unfold (Binding a name)         = if unfold then lookupBinding name b else Nothing
 
 
 
@@ -277,7 +275,7 @@
                                                  (lamReduceNF b unfold t2 >>= \t2' -> return (App a t1 t2'))
 lamReduceNF b unfold (Lam a l t)               = lamReduceNF b unfold t   >>= \t'  -> return (Lam a l t')
 lamReduceNF b unfold (Var _ _)                 = Nothing
-lamReduceNF b unfold (Binding a name)          = if unfold then Just (lookupBinding name b) else Nothing
+lamReduceNF b unfold (Binding a name)          = if unfold then lookupBinding name b else Nothing
 
 
 
@@ -294,7 +292,7 @@
                                                  (lamStrictNF b unfold t2 >>= \t2' -> return (App a t1 t2'))
 lamStrictNF b unfold (Lam a l t)               = lamStrictNF b unfold t   >>= \t'  -> return (Lam a l t')
 lamStrictNF b unfold (Var _ _)                 = Nothing
-lamStrictNF b unfold (Binding a name)          = if unfold then Just (lookupBinding name b) else Nothing
+lamStrictNF b unfold (Binding a name)          = if unfold then lookupBinding name b else Nothing
 
 
 
@@ -378,5 +376,6 @@
               -> PureLambda () String
               -> PureLambda () String
 
-unfoldTop binds (Binding a x) = Map.findWithDefault (error $ concat ["'",x,"' not bound"]) x binds
+unfoldTop binds (Binding a x) = maybe (Binding a x) id $
+                                  Map.findWithDefault (error $ concat ["'",x,"' not bound"]) x binds
 unfoldTop binds x             = x
diff --git a/src/LambdaCmdLine.hs b/src/LambdaCmdLine.hs
--- a/src/LambdaCmdLine.hs
+++ b/src/LambdaCmdLine.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
 
 import Data.IORef
 import Numeric
-import Maybe
+import Data.Maybe
 import Data.List
 import Data.Char
 import qualified Data.Map as Map
@@ -145,7 +145,7 @@
 
 -----------------------------------------------------------------
 -- Parser for the command line
--- yeah, I know its ugly
+-- Yeah, I know it's ugly.
 
 parseCmdLine :: [String] -> IO LambdaCmdLineState
 parseCmdLine argv =
@@ -208,8 +208,6 @@
 
 runShell :: LambdaCmdLineState -> IO ()
 runShell st = do
---   putStrLn versionInfo
---   putStrLn shellMessage
    lambdaShell (mapToShellState st)
    return ()
 
@@ -240,7 +238,8 @@
 evalStmt :: IORef ExitCode -> LambdaCmdLineState -> Statement -> IO LambdaCmdLineState
 evalStmt ec st (Stmt_eval t)     = evalTerm st t >> setSucc ec >> return st
 evalStmt ec st (Stmt_isEq t1 t2) = compareTerms ec st t1 t2 >> return st
-evalStmt ec st (Stmt_let name t) = setSucc ec >> return st{ cmd_binds = Map.insert name t (cmd_binds st) }
+evalStmt ec st (Stmt_let name t) = setSucc ec >> return st{ cmd_binds = Map.insert name (Just t) (cmd_binds st) }
+evalStmt ec st (Stmt_decl nms)   = setSucc ec >> return st{ cmd_binds = foldr (\x -> Map.insert x Nothing) (cmd_binds st) nms }
 evalStmt ec st (Stmt_empty)      = setSucc ec >> return st
 
 
@@ -248,11 +247,11 @@
 evalTerm st t = doEval (unfoldTop (cmd_binds st) t)
  where doEval t =
          case cmd_trace st of
-            Nothing       -> putStrLn (printLam (eval t))
+            Nothing       -> putStrLn (printLam (cmd_binds st) (eval t))
             Just Nothing  -> printTrace 50 t
             Just (Just x) -> printTrace x t
 
-       printTrace x t = putStr $ unlines $ map printLam $ take x $ trace t
+       printTrace x t = putStr $ unlines $ map (printLam (cmd_binds st)) $ take x $ trace t
 
        eval t  = lamEval      (cmd_binds st) (cmd_unfold st) (cmd_red st) t
        trace t = lamEvalTrace (cmd_binds st) (cmd_unfold st) (cmd_red st) t
diff --git a/src/LambdaParser.hs b/src/LambdaParser.hs
--- a/src/LambdaParser.hs
+++ b/src/LambdaParser.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -48,6 +48,7 @@
 
 data Statement
   = Stmt_eval (PureLambda () String)
+  | Stmt_decl [String]
   | Stmt_let String (PureLambda () String)
   | Stmt_isEq (PureLambda () String)
               (PureLambda () String)
@@ -99,7 +100,7 @@
 
  where p b = do x <- stmtParser b
                 let b' = case x of
-                          (Stmt_let name t) -> Map.insert name t b
+                          (Stmt_let name t) -> Map.insert name (Just t) b
                           _ -> b
                 spaces
                 ( do char ';'
@@ -130,6 +131,7 @@
 stmtParser :: Bindings () String -> LamParser Statement
 stmtParser b =
        try (letDefParser b     >>= return . uncurry Stmt_let)
+   <|> try (declParser b       >>= return . Stmt_decl)
    <|> try (compParser b       >>= return . uncurry Stmt_isEq)
    <|> (lambdaParser b         >>= return . Stmt_eval)
    <|> (return Stmt_empty)
@@ -144,6 +146,11 @@
     spaces
     return (x,y)
 
+declParser :: Bindings () String -> LamParser [String]
+declParser b = do
+    string "decl"
+    many1 space
+    sepBy1 nameParser (many1 space)
 
 letDefParser :: Bindings () String -> LamParser (String,PureLambda () String)
 letDefParser b = do
@@ -172,7 +179,7 @@
   (do spaces
       (n,t) <- definitionParser b
       spaces
-      let b' = Map.insert n t b
+      let b' = Map.insert n (Just t) b
       definitionFileParser b'
   )
   <|> (eof >> return b)
diff --git a/src/LambdaShell.hs b/src/LambdaShell.hs
--- a/src/LambdaShell.hs
+++ b/src/LambdaShell.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -41,11 +41,13 @@
 
 import System.Console.Shell
 import System.Console.Shell.ShellMonad
-import System.Console.Shell.Backend.Readline
---import System.Console.Shell.Backend.Basic
 
-defaultBackend = readlineBackend
+import System.Console.Shell.Backend.Compatline
+--import System.Console.Shell.Backend.Haskeline
 
+defaultBackend = compatlineBackend
+--defaultBackend = haskelineBackend
+
 type RS = ReductionStrategy () String
 
 
@@ -74,7 +76,7 @@
   LambdaShellState
   { trace       :: Bool      -- ^ Step through the reduction one redex at a time
   , traceNum    :: Int       -- ^ Number of reduction steps to display during tracing
-  , letBindings :: Map.Map String (PureLambda () String)
+  , letBindings :: Bindings () String
                              -- ^ All \"let\" bindings currently in scope
   , fullUnfold  :: Bool      -- ^ Should binding names be eagerly unfolded?
   , redStrategy :: RS        -- ^ The reduction strategy currently in use
@@ -165,9 +167,16 @@
   , cmd "version"    (shellPutInfo versionInfo) "Print version info"
   , cmd "simple_cps"  setCPSSimple   "Use the simple CPS strategy"
   , cmd "onepass_cps" setCPSOnepass  "Use the onepass optimizing CPS strategy"
+
+  , cmd "backend"    printBackend "Print the backend configuration"
   ]
 
 
+printBackend :: Sh LambdaShellState ()
+printBackend =
+  shellPutStrLn (show compatlineConfig)
+
+
 dumpTrace :: File -> Int -> Completable LetBinding -> Sh LambdaShellState ()
 dumpTrace (File f) steps (Completable termStr) = do
    st <- getShellSt
@@ -178,7 +187,7 @@
          let trace = lamEvalTrace (letBindings st) (fullUnfold st)
                                   (redStrategy st)
                                   (unfoldTop (letBindings st) term)
-         liftIO (writeFile f (unlines . map printLam . take steps $ trace))
+         liftIO (writeFile f (unlines . map (printLam (letBindings st)) . take steps $ trace))
 
 
 setTraceStep :: Int -> Sh LambdaShellState ()
@@ -189,14 +198,17 @@
     st <- getShellSt
     case Map.lookup name (letBindings st) of
         Nothing -> shellPutErrLn  $ concat ["'",name,"' not bound"]
-        Just t  -> shellPutInfoLn $ concat [name," = ",printLam t]
+        Just Nothing  -> shellPutInfoLn $ concat [name," << free variable >>"]
+        Just (Just t) -> shellPutInfoLn $ concat [name," = ",printLam (letBindings st) t]
 
 showBindings :: Sh LambdaShellState ()
 showBindings = do
    st <- getShellSt
    shellPutStrLn $
      Map.foldWithKey
-       (\name t x -> concat [name," = ",printLam t,"\n",x])
+       (\name t x -> case t of
+              Nothing -> concat [name," << free variable >>\n",x]
+              Just t  -> concat [name," = ",printLam (letBindings st) t,"\n",x])
        ""
        (letBindings st)
 
@@ -258,7 +270,8 @@
           case stmt of
            Stmt_eval expr      -> evalExpr expr
            Stmt_isEq x y       -> compareExpr x y
-           Stmt_let nm expr    -> modifyShellSt (\st -> st{ letBindings = Map.insert nm expr (letBindings st) })
+           Stmt_decl nms       -> modifyShellSt (\st -> st{ letBindings = foldr (\x -> Map.insert x Nothing) (letBindings st) nms })
+           Stmt_let nm expr    -> modifyShellSt (\st -> st{ letBindings = Map.insert nm (Just expr) (letBindings st) })
            Stmt_empty          -> return ()
 
 
@@ -277,12 +290,12 @@
 
    evalCount t st = do
       let (z,n) = lamEvalCount (letBindings st) (fullUnfold st) (redStrategy st) t
-      shellPutStrLn $ printLam z
+      shellPutStrLn $ printLam (letBindings st) z
       shellPutInfoLn $ concat ["<<",show n," reductions>>"]
 
    eval t st = do
       let z = lamEval (letBindings st) (fullUnfold st) (redStrategy st) t
-      shellPutStrLn $ printLam z
+      shellPutStrLn $ printLam (letBindings st) z
 
 
 compareExpr :: PureLambda () String
@@ -301,7 +314,8 @@
 
 data TraceShellState
    = TraceShellState
-     { tracePos  :: Int
+     { traceBindings :: Bindings () String
+     , tracePos  :: Int
      , traceStep :: Int
      , traceList :: [PureLambda () String]
      }
@@ -328,7 +342,7 @@
 printTrace :: Sh TraceShellState ()
 printTrace = do
   st <- getShellSt
-  shellPutStr $ unlines $ map (\(n,t) -> concat[show n,") ",printLam t]) $
+  shellPutStr $ unlines $ map (\(n,t) -> concat[show n,") ",printLam (traceBindings st) t]) $
         take (traceStep st) $ drop (tracePos st) $ zip [1..] (traceList st)
 
 tracePrev :: Sh TraceShellState ()
@@ -351,6 +365,7 @@
           { tracePos  = 0
           , traceStep = traceNum st
           , traceList = lamEvalTrace (letBindings st) (fullUnfold st) (redStrategy st) term
+          , traceBindings = letBindings st
           }
 
 traceSubshell :: PureLambda () String -> IO (Subshell LambdaShellState TraceShellState)
diff --git a/src/Version.hs b/src/Version.hs
--- a/src/Version.hs
+++ b/src/Version.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 versionInfo = unlines
   [ ""
   , "The Lambda Shell, version "++(showVersion version)
-  , "Copyright 2005-2007, Robert Dockins"
+  , "Copyright 2005-2011, Robert Dockins"
   , ""
   ]
 
@@ -35,8 +35,10 @@
 shellMessage = unlines
   [ "The Lambda Shell comes with ABSOLUTELY NO WARRANTY; for details"
   , "type ':nowarranty'.  This is free software, and you are welcome to"
-  , "redistribute it under certain conditions; type ':gpl'"
-  , "for details"
+  , "redistribute it under certain conditions; type ':gpl' for details."
+  , ""
+  , "Type ':help' for a listing of shell commands."
+  , ""
   ]
 
 noWarranty :: String  
diff --git a/src/main.hs b/src/main.hs
--- a/src/main.hs
+++ b/src/main.hs
@@ -1,6 +1,6 @@
 {-
  -   The Lambda Shell, an interactive environment for evaluating pure untyped lambda terms.
- -   Copyright (C) 2005-2007, Robert Dockins
+ -   Copyright (C) 2005-2011, Robert Dockins
  -
  -   This program is free software; you can redistribute it and/or modify
  -   it under the terms of the GNU General Public License as published by
