diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2011, Andreas Hammar
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Andreas Hammar nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,50 @@
+placeholders
+============
+
+While working on some Haskell code, it is often useful to develop
+incrementally by inserting `undefined` as a placeholder for missing code. 
+
+This approach has a couple of drawbacks.
+
+* If you have several occurrences of `undefined` in your code, it can be hard
+to track down the one reponsible for the error at run-time. 
+
+* It is too easy to forget to replace `undefined` with the proper code, which
+might cause unexpected errors.
+
+This library provides placeholders that produce better messages when
+evaluated at run-time and also generate compile-time warnings so that they do
+not get forgotten so easily.
+
+example
+=======
+ 
+    {-# LANGUAGE TemplateHaskell #-}
+    
+    import Development.Placeholders
+    
+    theUltimateAnswer :: Int
+    theUltimateAnswer = $notImplemented
+    
+    main = do
+        putStrLn "The ultimate answer:"
+        print theUltimateAnswer
+
+This will compile with a warning about the unimplemented function:
+
+    $ ghc --make Simple.hs
+    ...
+    Simple.hs:6:21: Unimplemented feature
+    ...
+
+At runtime, an exception will be thrown when the placeholder is evaluated,
+indicating the location of the placeholder.
+
+    $ ./Simple
+    The ultimate answer:
+    Simple: PlaceholderExcption "Unimplemented feature at Simple.hs:6:21"
+
+If compiled with the GHC flag `-Werror`, the warning will get turned into
+an error and compilation will fail. `-Werror` can therefore be used to
+verify that you haven't left any unintended placeholders behind.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/placeholders.cabal b/placeholders.cabal
new file mode 100644
--- /dev/null
+++ b/placeholders.cabal
@@ -0,0 +1,36 @@
+Name:                placeholders
+Version:             0.1
+Synopsis:            Placeholders for use while developing Haskell code
+Description:         While working on some Haskell code, it is often useful to
+                     work incrementally by inserting @undefined@ as a
+                     placeholder for missing code. 
+                     .
+                     This library provides placeholders that produce better
+                     messages when evaluated at run-time and also generate
+                     compile-time warnings so that they do not get forgotten
+                     so easily.
+
+                     For details, see <http://github.com/ahammar/placeholders>
+Homepage:            http://github.com/ahammar/placeholders
+License:             BSD3
+License-file:        LICENSE
+Author:              Andreas Hammar
+Maintainer:          Andreas Hammar <ahammar@gmail.com>
+Copyright:           (c) 2011 Andreas Hammar
+Category:            Development
+Build-type:          Simple
+Extra-source-files:  README.markdown
+Cabal-version:       >=1.6
+
+Source-repository head
+  Type:        git
+  Location:    git://github.com/ahammar/placeholders.git
+
+Library
+  Exposed-modules:     Development.Placeholders
+  
+  Build-depends:       base >= 4 && < 5,
+                       template-haskell
+  
+  Hs-source-dirs:      src
+  
diff --git a/src/Development/Placeholders.hs b/src/Development/Placeholders.hs
new file mode 100644
--- /dev/null
+++ b/src/Development/Placeholders.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-}
+
+-- | This module defines placeholders that you can use while coding to
+-- allow incomplete code to compile. They work just like 'undefined',
+-- but with improved error messages and compile-time warnings.
+module Development.Placeholders (
+    -- * Example
+    -- $example
+
+    -- * Placeholders
+    notImplemented,
+    todo,
+    placeholder,
+    placeholderNoWarning,
+
+    -- * Exceptions
+    PlaceholderException(..)
+) where
+
+import Control.Exception (Exception, throw)
+import Data.Typeable (Typeable)
+import Language.Haskell.TH (Q, Exp, Loc(..), litE, stringL, location, report)
+
+-- | Thrown when attempting to evaluate a placeholder at runtime.
+data PlaceholderException = PlaceholderException String
+    deriving (Show, Typeable)
+
+instance Exception PlaceholderException
+
+-- | Indicates that this piece of code has not yet been implemented.
+--
+-- @$notImplemented = $(placeholder \"Unimplemented feature\")@
+notImplemented :: Q Exp
+notImplemented = placeholder "Unimplemented feature"
+
+-- | Indicates unimplemented code or a known bug with a custom message.
+--
+-- @$(todo msg) = $(placeholder (\"TODO: \" ++ msg))@
+todo :: String -> Q Exp
+todo msg = placeholder $ "TODO: " ++ msg
+
+-- | Generates an expression of any type that, if evaluated at runtime will
+-- throw a 'PlaceholderException'. It is therefore similar to 'error', except
+-- that the source location is automatically included. Also, a warning is
+-- generated at compile time so you won't forget to replace placeholders
+-- before packaging your code.
+placeholder :: String -> Q Exp
+placeholder msg = do
+    emitWarning msg
+    placeholderNoWarning msg
+
+-- | Similar to 'placeholder', but does not generate a compiler warning. Use
+-- with care!
+placeholderNoWarning :: String -> Q Exp
+placeholderNoWarning msg = do
+    runtimeMsg <- formatMessage msg `fmap` location
+    [| throw $ PlaceholderException $(litE $ stringL runtimeMsg) |]
+
+emitWarning :: String -> Q ()
+emitWarning msg = report False $ msg
+
+formatMessage :: String -> Loc -> String
+formatMessage msg loc = msg ++ " at " ++ formatLoc loc
+
+formatLoc :: Loc -> String
+formatLoc loc = let file = loc_filename loc
+                    (line, col) = loc_start loc
+                in concat [file, ":", show line, ":", show col]
+
+-- $example
+-- 
+-- > {-# LANGUAGE TemplateHaskell #-}
+-- >
+-- > import Development.Placeholders
+-- >
+-- > theUltimateAnswer :: Int
+-- > theUltimateAnswer = $notImplemented
+-- >
+-- > main = do
+-- >     putStrLn "The ultimate answer:"
+-- >     print theUltimateAnswer
+--
+-- This will compile with a warning about the unimplemented function:
+--
+-- @
+-- $ ghc --make Simple.hs
+-- ...
+-- Simple.hs:6:21: Unimplemented feature
+-- ...
+-- @
+--
+-- At runtime, an exception will be thrown when the placeholder is evaluated,
+-- indicating the location of the placeholder.
+--
+-- @
+-- $ .\/Simple
+-- The ultimate answer:
+-- Simple: PlaceholderExcption \"Unimplemented feature at Simple.hs:6:21\"
+-- @
+--
+-- If compiled with the GHC flag @-Werror@, the warning will get turned into
+-- an error and compilation will fail. @-Werror@ can therefore be used to
+-- verify that you haven't left any unintended placeholders behind.
+
