diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+shell-monad (0.6.1) unstable; urgency=medium
+
+  * Always render comments using : , not #
+    This ensures that some oddball constuctions, eg making a pipe
+    to a comment, always generate valid shell code.
+
+ -- Joey Hess <id@joeyh.name>  Tue, 06 Jan 2015 19:13:58 -0400
+
 shell-monad (0.6.0) unstable; urgency=medium
 
   * Added a nice interface to the test command. Test is a GADT,
diff --git a/Control/Monad/Shell.hs b/Control/Monad/Shell.hs
--- a/Control/Monad/Shell.hs
+++ b/Control/Monad/Shell.hs
@@ -90,15 +90,13 @@
 import Control.Monad.Shell.Quote
 
 -- | A term that can be expanded in a shell command line.
---
--- Mostly, this is used for shell variables: 'Term Var a'
---
--- It can also be used for static values: 'Term Static a'
 data Term t a where
 	VarTerm :: UntypedVar -> Term Var a
 	StaticTerm :: (Quotable (Val a)) => a -> Term Static a
 
+-- | Used to represent a shell variable.
 data Var
+-- | Used for a static value.
 data Static
 
 data UntypedVar = V
@@ -247,11 +245,12 @@
 fmt multiline = go
   where
 	go (Cmd t) = t
-	go (Comment t)
-		| multiline = "# " <> L.filter (/= '\n') t
-		-- Comments go to end of line, so instead
-		-- use : as a no-op command, and pass the comment to it.
-		| otherwise = ": " <> getQ (quote (L.filter (/= '\n') t))
+	-- Comments are represented using : for two reasons:
+	-- 1. To support single line rendering.
+	-- 2. So that it's a valid shell expression; any
+	-- Expr, including Comment can be combined with any other.
+	-- For example, Pipe Comment Comment.
+	go (Comment t) = ": " <> getQ (quote (L.filter (/= '\n') t))
 	go (Subshell i l) =
 		let (wrap, sep) = if multiline then ("\n", "\n") else ("", ";")
 		in i <> "(" <> wrap <> L.intercalate sep (map (go . indent) l) <> wrap <> i <> ")"
@@ -362,8 +361,6 @@
 instance Param UntypedVar where
 	toTextParam v = \env -> "\"" <> getQ (expandVar v env (varName v)) <> "\""
 
--- | Var arguments cause the (quoted) value of a shell variable to be
--- passed to the command.
 instance Param (Term Var a) where
 	toTextParam (VarTerm v) = toTextParam v
 
@@ -389,7 +386,7 @@
 instance Param Arith where
 	toTextParam a = \env -> 
 		let t = fmtArith env a
-		in "\"$((" <> t <> "))\""
+		in "\"" <> t <> "\""
 
 -- | Allows a function to take any number of Params.
 class CmdParams t where
@@ -977,10 +974,6 @@
 -- Bool, such as ANot and AEqual instead evaluate to 1 for True and 0 for
 -- False.
 -- 
--- Arith is an instance of Num, which allows you to write expressions
--- like this with shell variables:
---
--- > val x * (100 + val y)
 data Arith
 	= ANum Integer
 	| AVar (Term Var Integer)
@@ -1006,10 +999,9 @@
 	| AShiftLeft Arith Arith -- ^ shift left (first argument's bits are shifted by the value of the second argument)
 	| AShiftRight Arith Arith -- ^ shift right
 	| AIf Arith (Arith, Arith) -- ^ if the first argument is non-zero, the result is the second, else the result is the third
-	deriving (Eq, Ord)
 
 fmtArith :: Env -> Arith -> L.Text
-fmtArith env = go
+fmtArith env arith = "$(( " <> go arith <> " ))"
   where
 	go (ANum i) = L.pack (show i)
 	-- shell variable must be expanded without quotes
@@ -1042,6 +1034,10 @@
 	binop a o b = paren $ go a <> " " <> o <> " " <> go b
 	unop o v = paren $ o <> " " <> go v
 
+-- | Arith is an instance of Num, which allows you to write expressions
+-- like this with shell variables, that generate Arithmetic Expressions.
+--
+-- > val x * (100 + val y)
 instance Num Arith where
 	fromInteger = ANum
 	(+) = APlus
@@ -1072,21 +1068,3 @@
 	fromEnum = error "fromEnum not implemented for Arith"
 	enumFromTo = error "enumFromTo not implemented for Arith"
 	enumFromThenTo = error "enumFromToThen not implemented for Arith"
-
-instance Eq a => Eq (Term Var a) where
-	VarTerm a == VarTerm b = a == b
-
-instance Eq a => Eq (Term Static a) where
-	StaticTerm a == StaticTerm b = a == b
-
-instance Eq UntypedVar where
-	a == b = varName a == varName b
-
-instance Ord a => Ord (Term Var a) where
-	VarTerm a <= VarTerm b = a <= b
-
-instance Ord a => Ord (Term Static a) where
-	StaticTerm a <= StaticTerm b = a <= b
-
-instance Ord UntypedVar where
-	a <= b = varName a <= varName b
diff --git a/shell-monad.cabal b/shell-monad.cabal
--- a/shell-monad.cabal
+++ b/shell-monad.cabal
@@ -1,5 +1,5 @@
 Name: shell-monad
-Version: 0.6.0
+Version: 0.6.1
 Cabal-Version: >= 1.8
 License: BSD3
 Maintainer: Joey Hess <id@joeyh.name>
