diff --git a/src/Language/Lambda/Expression.hs b/src/Language/Lambda/Expression.hs
index 13e29b2ee6c9be55ed5fc4029d0e5dff2abfca3c..7ab2e4efae4d1d118c9148978954dea54b4ab2d6 100644
--- a/src/Language/Lambda/Expression.hs
+++ b/src/Language/Lambda/Expression.hs
@@ -9,6 +9,7 @@ data LambdaExpr name
   = Var name
   | App (LambdaExpr name) (LambdaExpr name)
   | Abs name (LambdaExpr name)
+  | Let name (LambdaExpr name)
   deriving (Eq, Show)
 
 -- Pretty printing
@@ -20,6 +21,7 @@ pprExpr :: PrettyPrint n => PDoc String -> LambdaExpr n -> PDoc String
 pprExpr pdoc (Var n)      = prettyPrint n `add` pdoc
 pprExpr pdoc (Abs n body) = pprAbs pdoc n body
 pprExpr pdoc (App e1 e2)  = pprApp pdoc e1 e2
+pprExpr pdoc (Let n expr) = pprLet pdoc n expr
 
 -- Pretty print an abstraction 
 pprAbs :: PrettyPrint n => PDoc String -> n -> LambdaExpr n -> PDoc String
@@ -45,6 +47,15 @@ pprApp pdoc e1@(Abs _ _) e2 = betweenParens (pprExpr pdoc e1) pdoc
 pprApp pdoc e1 e2
   = pprExpr pdoc e1 `mappend` addSpace (pprExpr pdoc e2)
 
+pprLet :: PrettyPrint n
+       => PDoc String
+       -> n
+       -> LambdaExpr n
+       -> PDoc String
+pprLet pdoc name expr
+  = intercalate ss " " pdoc
+  where ss = ["let", prettyPrint name, "=", prettyPrint expr]
+
 uncurry :: n -> LambdaExpr n -> ([n], LambdaExpr n)
 uncurry n = uncurry' [n]
   where uncurry' ns (Abs n' body') = uncurry' (n':ns) body'
diff --git a/src/Language/Lambda/Parser.hs b/src/Language/Lambda/Parser.hs
index 99fe676bc282ae2551ca2f305daca78f535a1340..a94964bd2c51d57a1da0325ddadcd041721af9f0 100644
--- a/src/Language/Lambda/Parser.hs
+++ b/src/Language/Lambda/Parser.hs
@@ -15,7 +15,7 @@ expr :: Parser (LambdaExpr String)
 expr = try app <|> term
 
 term :: Parser (LambdaExpr String)
-term = abs <|> var <|> parens
+term = let' <|> abs <|> var <|> parens
 
 var :: Parser (LambdaExpr String)
 var = Var <$> identifier
@@ -28,6 +28,10 @@ abs = curry <$> idents <*> expr
 app :: Parser (LambdaExpr String)
 app = chainl1 term (return App)
 
+let' :: Parser (LambdaExpr String)
+let' = Let <$> ident <*> expr
+  where ident = keyword "let" *> identifier <* symbol '='
+
 parens :: Parser (LambdaExpr String)
 parens = symbol '(' *> expr <* symbol ')'
 
@@ -44,3 +48,6 @@ identifier = lexeme ((:) <$> first <*> many rest)
 
 symbol :: Char -> Parser ()
 symbol = void . lexeme . char
+
+keyword :: String -> Parser ()
+keyword = void . lexeme . string
diff --git a/test/Language/Lambda/ExpressionSpec.hs b/test/Language/Lambda/ExpressionSpec.hs
index cb575a2dcaf3c603601e25a8e642ab796f330d03..2c7314b0b2de2e31f359f18ac5f378edf4d95297 100644
--- a/test/Language/Lambda/ExpressionSpec.hs
+++ b/test/Language/Lambda/ExpressionSpec.hs
@@ -17,6 +17,9 @@ spec = describe "prettyPrint" $ do
       prettyPrint (App (Var "a") (Var "b"))
         `shouldBe` "a b"
 
+    it "prints simple let expressions" $
+      prettyPrint (Let "x" (Var "y")) `shouldBe` "let x = y"
+
     it "prints nested abstractions" $
       prettyPrint (Abs "f" (Abs "x" (Var "x")))
         `shouldBe` "λf x. x"
@@ -37,3 +40,7 @@ spec = describe "prettyPrint" $ do
       
       prettyPrint (App (Abs "f" (Var "f")) (Abs "g" (Var "g")))
         `shouldBe` "(λf. f) (λg. g)"
+
+    it "prints complex let expressions" $
+      prettyPrint (Let "x" (Abs "a" (Abs "b" (App (Var "a") (Var "b")))))
+        `shouldBe` "let x = λa b. a b"
diff --git a/test/Language/Lambda/ParserSpec.hs b/test/Language/Lambda/ParserSpec.hs
index 8ceddc7d44fe2da01f7280ad07e69417b739eba1..9ccf36536e58f2cc14ab04a5913f7be8b4d697a2 100644
--- a/test/Language/Lambda/ParserSpec.hs
+++ b/test/Language/Lambda/ParserSpec.hs
@@ -27,13 +27,17 @@ spec = describe "parseExpr" $ do
   it "parses chained applications" $
     parseExpr "f x y" `shouldBe` Right (App (App (Var "f") (Var "x")) (Var "y"))
 
+  it "parses simple let expressions" $
+    parseExpr "let x = z" `shouldBe` Right (Let "x" (Var "z"))
+
   it "parses complex expressions" $ do
     let exprs = [
           "\\f x. f x",
           "(\\p x y. y) (\\p x y. x)",
           "f (\\x. x)",
           "(\\x . f x) g y",
-          "(\\f . (\\ x y. f x y) f x y) w x y"
+          "(\\f . (\\ x y. f x y) f x y) w x y",
+          "let x = \\f x. f x"
           ]
     
     mapM_ (flip shouldSatisfy isRight . parseExpr) exprs