diff --git a/Text/Hamlet/Parse.hs b/Text/Hamlet/Parse.hs
--- a/Text/Hamlet/Parse.hs
+++ b/Text/Hamlet/Parse.hs
@@ -31,7 +31,8 @@
     pure = return
     (<*>) = ap
 
-newtype Deref = Deref [Ident] -- ^ is monadic, ident
+data Deref = DerefLeaf Ident
+           | DerefBranch Deref Deref
     deriving (Show, Eq, Read, Data, Typeable)
 newtype Ident = Ident String
     deriving (Show, Eq, Read, Data, Typeable)
@@ -192,13 +193,15 @@
     tag'' (TagIdent s) (x, y, z) = (x, (Nothing, "id", s) : y, z)
     tag'' (TagClass s) (x, y, z) = (x, y, s : z)
     tag'' (TagAttrib s) (x, y, z) = (x, s : y, z)
+    derefParens = between (char '(') (char ')') $ deref True
+    derefSingle = derefParens <|> fmap DerefLeaf ident
     deref spaceAllowed = do
         let delim = if spaceAllowed
                         then (char '.' <|> (many1 (char ' ') >> return ' '))
                         else char '.'
-        x <- ident
-        xs <- many $ delim >> ident
-        return $ Deref $ x : xs
+        x <- derefSingle
+        xs <- many $ delim >> derefSingle
+        return $ foldr1 DerefBranch $ x : xs
     ident = Ident <$> many1 (alphaNum <|> char '_' <|> char '\'')
 
 data TagPiece = TagName String
diff --git a/Text/Hamlet/Quasi.hs b/Text/Hamlet/Quasi.hs
--- a/Text/Hamlet/Quasi.hs
+++ b/Text/Hamlet/Quasi.hs
@@ -150,15 +150,15 @@
       "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
 
 deref :: Scope -> Deref -> Exp
-deref _ (Deref []) = error "Invalid empty deref"
-deref scope (Deref d) =
-    let z' = case lookup z scope of
-                Nothing -> varName zName
-                Just zExp -> zExp
-     in foldr go z' y
+deref scope (DerefBranch x y) =
+    let x' = deref scope x
+        y' = deref scope y
+     in x' `AppE` y'
+deref scope (DerefLeaf d@(Ident dName)) =
+    case lookup d scope of
+        Nothing -> varName dName
+        Just exp' -> exp'
   where
-    z@(Ident zName) = last d
-    y = init d
     varName "" = error "Illegal empty varName"
     varName v@(s:_) =
         case lookup (Ident v) scope of
@@ -167,7 +167,6 @@
                 if isUpper s
                     then ConE $ mkName v
                     else VarE $ mkName v
-    go (Ident func) z' = varName func `AppE` z'
 
 -- | Checks for truth in the left value in each pair in the first argument. If
 -- a true exists, then the corresponding right action is performed. Only the
diff --git a/hamlet.cabal b/hamlet.cabal
--- a/hamlet.cabal
+++ b/hamlet.cabal
@@ -1,5 +1,5 @@
 name:            hamlet
-version:         0.4.0
+version:         0.4.1
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
diff --git a/runtests.hs b/runtests.hs
--- a/runtests.hs
+++ b/runtests.hs
@@ -55,6 +55,7 @@
     , testCase "trailing space" caseTrailingSpace
     , testCase "currency symbols" caseCurrency
     , testCase "external" caseExternal
+    , testCase "parens" caseParens
     ]
 
 data Url = Home | Sub SubUrl
@@ -374,3 +375,17 @@
     helper "foo<br/>" $ $(xhamletFile "external.hamlet")
   where
     foo = "foo"
+
+caseParens :: Assertion
+caseParens = do
+    let plus = (++)
+        x = "x"
+        y = "y"
+    helper "xy" [$hamlet|$(plus x) y$|]
+    helper "xy" [$hamlet|$(plus.x).y$|]
+    helper "xxy" [$hamlet|$(plus (plus x).x).y$|]
+    let list = ["1", "2", "3"]
+    helper "123" [$hamlet|
+$forall (id id.id id.list) x
+    $x$
+|]
