diff --git a/libraries/prelude/prelude.purs b/libraries/prelude/prelude.purs
--- a/libraries/prelude/prelude.purs
+++ b/libraries/prelude/prelude.purs
@@ -495,6 +495,15 @@
                            \  };\
                            \}" :: forall s r. IORef s -> Eff (ref :: Ref | r) s
 
+
+  foreign import modifyIORef "function modifyIORef(ref) {\
+                             \  return function(f) {\
+                             \    return function() {\
+                             \      ref.value = f(ref.value);\
+                             \    };\
+                             \  };\
+                             \}" :: forall s r. IORef s -> (s -> s) -> Eff (ref :: Ref | r) {}
+
   foreign import writeIORef "function writeIORef(ref) {\
                             \  return function(val) {\
                             \    return function() {\
@@ -540,14 +549,22 @@
                            \  };\
                            \}" :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
 
-  foreign import modifySTRef "function modifySTRef(f) {\
-                             \  return function(ref) {\
+  foreign import modifySTRef "function modifySTRef(ref) {\
+                             \  return function(f) {\
                              \    return function() {\
                              \      ref.value = f(ref.value);\
                              \    };\
                              \  };\
-                             \}" :: forall a h r. (a -> a) -> STRef h a -> Eff (st :: ST h | r) {}
+                             \}" :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) {}
 
+  foreign import writeSTRef "function writeSTRef(ref) {\
+                            \  return function(a) {\
+                            \    return function() {\
+                            \      ref.value = a;\
+                            \    };\
+                            \  };\
+                            \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) {}
+  
   foreign import runST "function runST(f) {\
                        \  return f;\
                        \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
diff --git a/purescript.cabal b/purescript.cabal
--- a/purescript.cabal
+++ b/purescript.cabal
@@ -1,5 +1,5 @@
 name: purescript
-version: 0.3.4
+version: 0.3.5
 cabal-version: >=1.8
 build-type: Simple
 license: MIT
@@ -17,7 +17,7 @@
 library
     build-depends: base >=4 && <5, cmdtheline -any, containers -any,
                    directory -any, filepath -any, mtl -any, parsec -any, syb -any,
-                   transformers -any, utf8-string -any
+                   transformers -any, utf8-string -any, pattern-arrows -any
     exposed-modules: Data.Generics.Extras
                      Language.PureScript
                      Language.PureScript.Options
diff --git a/src/Language/PureScript/CodeGen/JS.hs b/src/Language/PureScript/CodeGen/JS.hs
--- a/src/Language/PureScript/CodeGen/JS.hs
+++ b/src/Language/PureScript/CodeGen/JS.hs
@@ -41,13 +41,13 @@
 import Language.PureScript.CodeGen.JS.AST as AST
 import Language.PureScript.Types
 import Language.PureScript.CodeGen.Optimize
+import Language.PureScript.TypeChecker.Monad (canonicalizeType)
 
 -- |
 -- Generate code in the simplified Javascript intermediate representation for all declarations in a module
 --
 moduleToJs :: Options -> Module -> Environment -> [JS]
 moduleToJs opts (Module pname@(ProperName name) decls) env =
-  mapMaybe filterRawDecls decls ++
   [ JSVariableIntroduction (Ident name) Nothing
   , JSApp (JSFunction Nothing [Ident name]
                       (JSBlock (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts (ModuleName pname) decl env) (sortBy typeClassesLast decls))))
@@ -55,8 +55,6 @@
                          (JSBinary Or (JSVar (Ident name)) (JSObjectLiteral []))]
   ]
   where
-  filterRawDecls (ExternDeclaration ForeignImport _ (Just js) _) = Just js
-  filterRawDecls _ = Nothing
   typeClassesLast (ExternDeclaration TypeClassDictionaryImport _ _ _) (ExternDeclaration TypeClassDictionaryImport _ _ _) = EQ
   typeClassesLast (ExternDeclaration TypeClassDictionaryImport _ _ _) _ = GT
   typeClassesLast _ (ExternDeclaration TypeClassDictionaryImport _ _ _) = LT
@@ -87,7 +85,7 @@
     in [ ctorJs, setProperty ctor (JSVar (Ident ctor)) mp ]
 declToJs opts mp (DataBindingGroupDeclaration ds) e =
   Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds
-declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ | importTy /= ForeignImport =
+declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ =
   Just [ js
        , setProperty (identToJs ident) (JSVar ident) mp ]
 declToJs _ _ _ _ = Nothing
@@ -201,7 +199,7 @@
   then
     return done
   else
-    return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar varName)) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ qualify m ctor)))) (JSBlock done) Nothing]
+    return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar varName)) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ canonicalizeType m e ctor)))) (JSBlock done) Nothing]
 binderToJs m e varName done (UnaryBinder ctor b) = do
   value <- fresh
   js <- binderToJs m e value done b
@@ -210,7 +208,7 @@
   then
     return [success]
   else
-    return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar varName)) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ qualify m ctor))))
+    return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar varName)) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ canonicalizeType m e ctor))))
                      success
                      Nothing]
 binderToJs m e varName done (ObjectBinder bs) = go done bs
diff --git a/src/Language/PureScript/CodeGen/JS/AST.hs b/src/Language/PureScript/CodeGen/JS/AST.hs
--- a/src/Language/PureScript/CodeGen/JS/AST.hs
+++ b/src/Language/PureScript/CodeGen/JS/AST.hs
@@ -129,7 +129,7 @@
   -- |
   -- Raw Javascript (generated when parsing fails for an inline foreign import declaration)
   --
-  | JSRaw String deriving (Show, Data, Typeable)
+  | JSRaw String deriving (Show, Eq, Data, Typeable)
 
 -- |
 -- Data type for expressions which can appear on the left hand side of an assignment
@@ -142,4 +142,4 @@
   -- |
   -- Assign an object property
   --
-  | JSAssignProperty String JSAssignment deriving (Show, Data, Typeable)
+  | JSAssignProperty String JSAssignment deriving (Show, Eq, Data, Typeable)
diff --git a/src/Language/PureScript/CodeGen/Optimize.hs b/src/Language/PureScript/CodeGen/Optimize.hs
--- a/src/Language/PureScript/CodeGen/Optimize.hs
+++ b/src/Language/PureScript/CodeGen/Optimize.hs
@@ -27,6 +27,8 @@
 --
 --  * Inlining variables
 --
+--  * Inline Prelude.($)
+--
 -----------------------------------------------------------------------------
 
 module Language.PureScript.CodeGen.Optimize (
@@ -49,15 +51,25 @@
 -- Apply a series of optimizer passes to simplified Javascript code
 --
 optimize :: Options -> JS -> JS
-optimize opts =
-  collapseNestedBlocks
-  . tco opts
-  . magicDo opts
-  . removeUnusedVariables
-  . unThunk
-  . etaConvert
-  . inlineVariables
+optimize opts = untilFixedPoint $ applyAll
+  [ collapseNestedBlocks
+  , tco opts
+  , magicDo opts
+  , removeUnusedVariables
+  , unThunk
+  , etaConvert
+  , inlineVariables
+  , inlineDollar ]
 
+applyAll :: [a -> a] -> a -> a
+applyAll = foldl1 (.)
+
+untilFixedPoint :: (Eq a) => (a -> a) -> a -> a
+untilFixedPoint f a = go a
+  where
+  go a' = let a'' = f a' in
+          if a'' == a' then a'' else go a''
+
 replaceIdent :: (Data d) => Ident -> JS -> d -> d
 replaceIdent var1 js = everywhere (mkT replace)
   where
@@ -279,3 +291,12 @@
   go :: JS -> [JS]
   go (JSBlock sts) = sts
   go s = [s]
+
+inlineDollar :: JS -> JS
+inlineDollar = everywhere (mkT convert)
+  where
+  convert :: JS -> JS
+  convert (JSApp (JSApp dollar [f]) [x]) | isDollar dollar = JSApp f [x]
+  convert other = other
+  isDollar (JSAccessor name (JSVar (Ident "Prelude"))) | name == identToJs (Op "$") = True
+  isDollar _ = False
diff --git a/src/Language/PureScript/Declarations.hs b/src/Language/PureScript/Declarations.hs
--- a/src/Language/PureScript/Declarations.hs
+++ b/src/Language/PureScript/Declarations.hs
@@ -53,6 +53,10 @@
   --
   = ForeignImport
   -- |
+  -- A foreign import which contains inline Javascript as a string literal
+  --
+  | InlineJavascript
+  -- |
   -- A type class dictionary import, generated during desugaring of type class declarations
   --
   | TypeClassDictionaryImport
diff --git a/src/Language/PureScript/Parser/Common.hs b/src/Language/PureScript/Parser/Common.hs
--- a/src/Language/PureScript/Parser/Common.hs
+++ b/src/Language/PureScript/Parser/Common.hs
@@ -78,7 +78,9 @@
                 , "let"
                 , "class"
                 , "instance"
-                , "where" ]
+                , "where"
+                , "null"
+                , "undefined" ]
 
 -- |
 -- A list of built-in operator names
@@ -265,6 +267,19 @@
 --
 parseIdent :: P.Parsec String ParseState Ident
 parseIdent = (Ident <$> identifier) <|> (Op <$> parens operatorOrBuiltIn)
+
+
+-- |
+-- Parse an identifier or parenthesized operator that is not a reserved keyword or operator
+--
+parseNonReservedIdent :: P.Parsec String ParseState Ident
+parseNonReservedIdent = do
+  ident <- parseIdent
+  when (isReserved ident) $ P.unexpected $ "reserved identifier " ++ show ident
+  return ident
+  where
+  isReserved (Ident ident) = ident `elem` reservedNames
+  isReserved (Op op) = op `elem` reservedOpNames
 
 -- |
 -- Parse a token inside square brackets
diff --git a/src/Language/PureScript/Parser/Declarations.hs b/src/Language/PureScript/Parser/Declarations.hs
--- a/src/Language/PureScript/Parser/Declarations.hs
+++ b/src/Language/PureScript/Parser/Declarations.hs
@@ -19,7 +19,8 @@
     parseModules
 ) where
 
-import Data.Maybe (fromMaybe)
+import Data.Maybe (isJust, fromMaybe)
+import Control.Monad (when)
 import Control.Applicative
 import qualified Text.Parsec as P
 
@@ -45,7 +46,7 @@
 
 parseTypeDeclaration :: P.Parsec String ParseState Declaration
 parseTypeDeclaration =
-  TypeDeclaration <$> P.try (parseIdent <* lexeme (indented *> P.string "::"))
+  TypeDeclaration <$> P.try (parseNonReservedIdent <* lexeme (indented *> P.string "::"))
                   <*> parsePolyType
 
 parseTypeSynonymDeclaration :: P.Parsec String ParseState Declaration
@@ -56,7 +57,7 @@
 
 parseValueDeclaration :: P.Parsec String ParseState Declaration
 parseValueDeclaration =
-  ValueDeclaration <$> parseIdent
+  ValueDeclaration <$> parseNonReservedIdent
                    <*> P.many parseTopLevelBinder
                    <*> P.optionMaybe parseGuard
                    <*> ((lexeme (indented *> P.char '=')) *> parseValue)
@@ -68,10 +69,10 @@
 parseExternDeclaration = P.try (reserved "foreign") *> indented *> (reserved "import") *> indented *>
    (ExternDataDeclaration <$> (P.try (reserved "data") *> indented *> properName)
                              <*> (lexeme (indented *> P.string "::") *> parseKind)
-   <|> ExternDeclaration ForeignImport <$> parseIdent
-                                       <*> P.optionMaybe (parseJSLiteral <$> stringLiteral)
-                                       <*> (lexeme (indented *> P.string "::") *> parsePolyType))
-
+   <|> do ident <- parseNonReservedIdent
+          js <- P.optionMaybe (parseJSLiteral <$> stringLiteral)
+          ty <- (lexeme (indented *> P.string "::") *> parsePolyType)
+          return $ ExternDeclaration (if isJust js then InlineJavascript else ForeignImport) ident js ty)
 parseJSLiteral :: String -> JS
 parseJSLiteral s = either (const $ JSRaw s) id $ P.runParser parseJS () "Javascript" s
 
diff --git a/src/Language/PureScript/Parser/Types.hs b/src/Language/PureScript/Parser/Types.hs
--- a/src/Language/PureScript/Parser/Types.hs
+++ b/src/Language/PureScript/Parser/Types.hs
@@ -24,7 +24,7 @@
 import Control.Applicative
 import qualified Text.Parsec as P
 import qualified Text.Parsec.Expr as P
-import Control.Monad (unless)
+import Control.Monad (when, unless)
 
 parseNumber :: P.Parsec String ParseState Type
 parseNumber = const Number <$> reserved "Number"
@@ -42,7 +42,7 @@
 parseArrayOf = squares $ TypeApp Array <$> parseType
 
 parseObject :: P.Parsec String ParseState Type
-parseObject = braces $ Object <$> parseRow
+parseObject = braces $ Object <$> parseRow False
 
 parseFunction :: P.Parsec String ParseState Type
 parseFunction = do
@@ -69,11 +69,10 @@
             , parseArray
             , parseArrayOf
             , parseObject
-            , parseFunction
             , parseTypeVariable
             , parseTypeConstructor
             , parseForAll
-            , parens parseRow
+            , parens (parseRow True)
             , parens parseType ])
 
 parseConstrainedType :: P.Parsec String ParseState Type
@@ -91,11 +90,10 @@
   return $ maybe ty (flip ConstrainedType ty) constraints
 
 parseAnyType :: P.Parsec String ParseState Type
-parseAnyType = (P.buildExpressionParser operators . buildPostfixParser postfixTable $ parseTypeAtom) P.<?> "type"
+parseAnyType = (P.buildExpressionParser operators $ parseTypeAtom) <|> parseFunction P.<?> "type"
   where
-  postfixTable :: [Type -> P.Parsec String ParseState Type]
-  postfixTable = [ \x -> TypeApp x <$> P.try (indented *> parseTypeAtom) ]
-  operators = [ [ P.Infix (lexeme (P.try (P.string "->")) >> return (\t1 t2 -> Function [t1] t2)) P.AssocRight ] ]
+  operators = [ [ P.Infix (return TypeApp) P.AssocLeft ]
+              , [ P.Infix (P.try (lexeme (P.string "->")) >> return (\t1 t2 -> Function [t1] t2)) P.AssocRight ] ]
 
 -- |
 -- Parse a monotype
@@ -121,9 +119,6 @@
 parseRowEnding :: P.Parsec String ParseState Type
 parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))
 
-parseRow :: P.Parsec String ParseState Type
-parseRow = (fromList <$> (commaSep $ parseNameAndType parsePolyType) <*> parseRowEnding) P.<?> "row"
-  where
-  fromList :: [(String, Type)] -> Type -> Type
-  fromList [] r = r
-  fromList ((name, t):ts) r = RCons name t (fromList ts r)
+parseRow :: Bool -> P.Parsec String ParseState Type
+parseRow nonEmpty = (curry rowFromList <$> (many $ parseNameAndType parsePolyType) <*> parseRowEnding) P.<?> "row"
+  where many = if nonEmpty then commaSep1 else commaSep
diff --git a/src/Language/PureScript/Pretty/Common.hs b/src/Language/PureScript/Pretty/Common.hs
--- a/src/Language/PureScript/Pretty/Common.hs
+++ b/src/Language/PureScript/Pretty/Common.hs
@@ -43,95 +43,7 @@
 identCharToString c = '$' : show (ord c)
 
 -- |
--- A first-order pattern match
---
--- A pattern is a Kleisli arrow for the @StateT Maybe@ monad. That is, patterns can fail, and can carry user-defined state.
---
-newtype Pattern u a b = Pattern { runPattern :: A.Kleisli (StateT u Maybe) a b } deriving (C.Category, A.Arrow, A.ArrowZero, A.ArrowPlus)
-
-instance Functor (Pattern u a) where
-  fmap f (Pattern p) = Pattern $ A.Kleisli $ fmap f . A.runKleisli p
-
--- |
--- Run a pattern with an input and initial user state
---
--- Returns Nothing if the pattern fails to match
---
-pattern :: Pattern u a b -> u -> a -> Maybe b
-pattern p u = flip evalStateT u . A.runKleisli (runPattern p)
-
--- |
--- Construct a pattern from a function
---
-mkPattern :: (a -> Maybe b) -> Pattern u a b
-mkPattern f = Pattern $ A.Kleisli (lift . f)
-
--- |
--- Construct a pattern from a stateful function
---
-mkPattern' :: (a -> StateT u Maybe b) -> Pattern u a b
-mkPattern' = Pattern . A.Kleisli
-
--- |
 -- Wrap a string in parentheses
 --
 parens :: String -> String
 parens s = ('(':s) ++ ")"
-
--- |
--- Construct a pattern which recursively matches on the left-hand-side
---
-chainl :: Pattern u a (a, a) -> (r -> r -> r) -> Pattern u a r -> Pattern u a r
-chainl g f p = fix $ \c -> g >>> ((c <+> p) *** p) >>> A.arr (uncurry f)
-
--- |
--- Construct a pattern which recursively matches on the right-hand side
---
-chainr :: Pattern u a (a, a) -> (r -> r -> r) -> Pattern u a r -> Pattern u a r
-chainr g f p = fix $ \c -> g >>> (p *** (c <+> p)) >>> A.arr (uncurry f)
-
--- |
--- Construct a pattern which recursively matches on one-side of a tuple
---
-wrap :: Pattern u a (s, a) -> (s -> r -> r) -> Pattern u a r -> Pattern u a r
-wrap g f p = fix $ \c -> g >>> (C.id *** (c <+> p)) >>> A.arr (uncurry f)
-
--- |
--- Construct a pattern which matches a part of a tuple
---
-split :: Pattern u a (s, t) -> (s -> t -> r) -> Pattern u a r
-split s f = s >>> A.arr (uncurry f)
-
--- |
--- A table of operators
---
-data OperatorTable u a r = OperatorTable { runOperatorTable :: [ [Operator u a r] ] }
-
--- |
--- An operator:
---
---  [@AssocL@] A left-associative operator
---
---  [@AssocR@] A right-associative operator
---
---  [@Wrap@] A prefix-like or postfix-like operator
---
---  [@Split@] A prefix-like or postfix-like operator which does not recurse into its operand
---
-data Operator u a r where
-  AssocL :: Pattern u a (a, a) -> (r -> r -> r) -> Operator u a r
-  AssocR :: Pattern u a (a, a) -> (r -> r -> r) -> Operator u a r
-  Wrap   :: Pattern u a (s, a) -> (s -> r -> r) -> Operator u a r
-  Split  :: Pattern u a (s, t) -> (s -> t -> r) -> Operator u a r
-
--- |
--- Build a pretty printer from an operator table and an indecomposable pattern
---
-buildPrettyPrinter :: OperatorTable u a r -> Pattern u a r -> Pattern u a r
-buildPrettyPrinter table p = foldl (\p' ops -> foldl1 (<+>) (flip map ops $ \op ->
-  case op of
-    AssocL pat g -> chainl pat g p'
-    AssocR pat g -> chainr pat g p'
-    Wrap pat g -> wrap pat g p'
-    Split pat g -> split pat g
-  ) <+> p') p $ runOperatorTable table
diff --git a/src/Language/PureScript/Pretty/JS.hs b/src/Language/PureScript/Pretty/JS.hs
--- a/src/Language/PureScript/Pretty/JS.hs
+++ b/src/Language/PureScript/Pretty/JS.hs
@@ -26,6 +26,7 @@
 import Data.Maybe (fromMaybe)
 import qualified Control.Arrow as A
 import Control.Arrow ((<+>))
+import Control.PatternArrows
 import Control.Applicative
 import Control.Monad.State
 
diff --git a/src/Language/PureScript/Pretty/Kinds.hs b/src/Language/PureScript/Pretty/Kinds.hs
--- a/src/Language/PureScript/Pretty/Kinds.hs
+++ b/src/Language/PureScript/Pretty/Kinds.hs
@@ -19,10 +19,12 @@
 
 import Data.Maybe (fromMaybe)
 
+import Control.Arrow (ArrowPlus(..))
+import Control.PatternArrows
+
 import Language.PureScript.Kinds
 import Language.PureScript.Pretty.Common
 import Language.PureScript.Unknown
-import Control.Arrow (ArrowPlus(..))
 
 typeLiterals :: Pattern () Kind String
 typeLiterals = mkPattern match
diff --git a/src/Language/PureScript/Pretty/Types.hs b/src/Language/PureScript/Pretty/Types.hs
--- a/src/Language/PureScript/Pretty/Types.hs
+++ b/src/Language/PureScript/Pretty/Types.hs
@@ -20,7 +20,9 @@
 
 import Data.Maybe (fromMaybe)
 import Data.List (intercalate)
+
 import Control.Arrow ((<+>))
+import Control.PatternArrows
 
 import Language.PureScript.Types
 import Language.PureScript.Pretty.Common
diff --git a/src/Language/PureScript/Pretty/Values.hs b/src/Language/PureScript/Pretty/Values.hs
--- a/src/Language/PureScript/Pretty/Values.hs
+++ b/src/Language/PureScript/Pretty/Values.hs
@@ -21,6 +21,7 @@
 import Data.Maybe (fromMaybe)
 import Data.List (intercalate)
 import Control.Arrow ((<+>))
+import Control.PatternArrows
 
 import Language.PureScript.Types
 import Language.PureScript.Values
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -19,12 +19,14 @@
 import qualified Language.PureScript as P
 
 import Data.List (isSuffixOf)
+import Data.Traversable (traverse)
 import Control.Applicative
 import Control.Monad
+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
 import System.Exit
 import System.Process
 import System.FilePath (pathSeparator)
-import System.Directory (getCurrentDirectory, getDirectoryContents)
+import System.Directory (getCurrentDirectory, getDirectoryContents, findExecutable)
 import System.Environment (getArgs)
 import Text.Parsec (ParseError)
 import qualified Paths_purescript as Paths
@@ -68,11 +70,17 @@
     args <- getArgs
     if "--run-js" `elem` args
     then do
-      (exitCode, out, err) <- readProcessWithExitCode "nodejs" [] js
-      case exitCode of
-        ExitSuccess -> putStrLn out >> return Nothing
-        ExitFailure code -> return $ Just err
+      process <- findNodeProcess
+      result <- traverse (\node -> readProcessWithExitCode node [] js) process
+      case result of
+        Just (ExitSuccess, out, _) -> putStrLn out >> return Nothing
+        Just (ExitFailure _, _, err) -> return $ Just err
+        Nothing -> return $ Just "Couldn't find node.js executable"
     else return Nothing
+
+findNodeProcess :: IO (Maybe String)
+findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
+    where names = ["nodejs", "node"]
 
 assertDoesNotCompile :: FilePath -> IO ()
 assertDoesNotCompile inputFile = do
