diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,17 @@
-# Revision history for FormatStringLiteral
+# Revision history for PyF
 
+- Bump dependencies to megaparsec 7
+- Error message are now tested
+- Name in template haskell splices are stable. This increases readability of error messages
+- Better error message for badly formated expression
+
+# Formatting removal
+
+- All monomorphic quasiquoters (`f`, `fString`, `fText`, `fIO`, `fLazyText`) are removed
+- Polymophic quasiquoter `f'` is renamed `f` and is the only entry point. Monomorphic users are encouraged to use the polymorphic quasiquoter with type annotation.
+- `Formatting` dependency is removed.
+- Previously named `f` quasiquoters which was exporting to `Formatting.Format` is removed. User of this behavior should use `Formatting.now` instead.
+
 ## 0.6.1.0 -- 2018-08-03
 
 - Custom delimiters, you can use whatever delimiters you want in place of `{` and `}`.
@@ -7,7 +19,6 @@
 ## 0.6.0.0 -- 2018-08-02
 
 - Fix the espace parsing of `{{` and `}}` as `{` and `}`
-
 
 ## 0.5.0.0 -- 2018-04-16
 
diff --git a/PyF.cabal b/PyF.cabal
--- a/PyF.cabal
+++ b/PyF.cabal
@@ -1,5 +1,5 @@
 name:                PyF
-version:             0.6.1.1
+version:             0.7.0.0
 synopsis: Quasiquotations for a python like interpolated string formater
 description: Quasiquotations for a python like interpolated string formater.
 license:             BSD3
@@ -19,18 +19,16 @@
                   PyF.Formatters
 
   build-depends:       base >= 4.9 && < 5.0
-                     , template-haskell >= 2.11 && < 2.14
+                     , template-haskell >= 2.11 && < 2.15
 
                      -- Parsec and some transitive deps
-                     , megaparsec >= 6.0 && < 6.6
+                     , megaparsec >= 7.0 && < 8.0
                      , text >= 0.11 && < 1.3
-                     , containers >= 0.5 && < 0.6
-
-                     -- Formatting and some transitive deps
-                     , formatting >= 6.2 && < 6.4
+                     , containers >= 0.5 && < 0.7
 
                      --
                      , haskell-src-meta
+                     , haskell-src-exts
   hs-source-dirs: src
   ghc-options: -Wall
   default-language:    Haskell2010
@@ -41,9 +39,18 @@
   main-is:             Spec.hs
   other-modules: SpecUtils SpecCustomDelimiters
   build-tools:  python3
-  build-depends:       base, PyF, hspec, text, template-haskell, formatting, process
+  build-depends:       base, PyF, hspec, text, template-haskell, process
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
+
+-- test-suite pyf-failure
+--   type:                exitcode-stdio-1.0
+--   hs-source-dirs:      test
+--   main-is:             SpecFail.hs
+--   build-tools:  python3
+--   build-depends:       base, hspec, text, template-haskell, process, hspec-golden, hspec, temporary, hashable
+--   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
+--   default-language:    Haskell2010
 
 source-repository head
   type:     git
diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -1,31 +1,20 @@
-*PyF* is a Haskell library for string interpolation and formatting.
-
-*PyF* exposes a quasiquoter `f` for the [Formatting](https://hackage.haskell.org/package/formatting) library. The quasiquotation introduces string interpolation and formatting with a mini language inspired from printf and Python.
-
-# Quick Start
-
-The following *Formatting* example:
+# PyF
 
-```haskell
->>> import Formatting
+[![CircleCI](https://circleci.com/gh/guibou/PyF.svg?style=svg)](https://circleci.com/gh/guibou/PyF)
 
->>> name = "Dave"
->>> age = 54
+*PyF* is a Haskell library for string interpolation and formatting.
 
->>> format ("Person's name is " % text % ", age is " % hex) name age
-"Person's name is Dave, age is 36"
-```
+*PyF* exposes a quasiquoter `f` which introduces string interpolation and formatting with a mini language inspired from printf and Python.
 
-can be written as:
+# Quick Start
 
 ```haskell
->>> import Formatting
 >>> import PyF
 
 >>> name = "Dave"
 >>> age = 54
 
->>> format [f|Person's name is {name}, age is {age:x}|]
+>>> [f|Person's name is {name}, age is {age:x}|]
 "Person's name is Dave, age is 36"
 ```
 
@@ -38,7 +27,7 @@
 - Floating point representation
 - The interpolated value can be any Haskell expression
 
-You will need the extension `QuasiQuotes`, enable it with `{-# LANGUAGE QuasiQuotes #-}` in top of your source file or with `:set -XQuasiQuotes` in your `ghci` session.
+You will need the extension `QuasiQuotes`, enable it with `{-# LANGUAGE QuasiQuotes #-}` in top of your source file or with `:set -XQuasiQuotes` in your `ghci` session. `ExtendedDefaultRules` and `OverloadedStrings` may be more convenient.
 
 Expression to be formatted are referenced by `{expression:formatingOptions}` where `formatingOptions` follows the [Python format mini-language](https://docs.python.org/3/library/string.html#formatspec). It is recommended to read the python documentation, but the [Test file](https://github.com/guibou/PyF/blob/master/test/Spec.hs) as well as this readme contain many examples.
 
@@ -50,25 +39,25 @@
 
 ```haskell
 >>> name = "Guillaume"
->>> format [f|{name:<11}|]
+>>> [f|{name:<11}|]
 "Guillaume  "
->>> format [f|{name:>11}|]
+>>> [f|{name:>11}|]
 "  Guillaume"
->>> format [f|{name:|^13}|]
+>>> [f|{name:|^13}|]
 "||Guillaume||"
 ```
 
 Padding inside `=` the sign:
 
 ```haskell
->>> [fString|{-pi:=10.3}|]
+>>> [f|{-pi:=10.3}|]
 "-    3.142"
 ```
 
 ## Float rounding
 
 ```haskell
->>> format [f|{pi:.2}|]
+>>> [f|{pi:.2}|]
 "3.14"
 ```
 
@@ -76,11 +65,11 @@
 
 ```haskell
 >>> v = 31
->>> format [f|Binary: {v:#b}|]
+>>> [f|Binary: {v:#b}|]
 "Binary: 0b11111"
->>> format [f|Octal (no prefix): {age:o}|]
+>>> [f|Octal (no prefix): {age:o}|]
 "Octal (no prefix): 37"
->>> format [f|Hexa (caps and prefix): {age:#X}|]
+>>> [f|Hexa (caps and prefix): {age:#X}|]
 "Hexa (caps and prefix): 0x1F"
 ```
 
@@ -89,9 +78,9 @@
 Using `,` or `_`.
 
 ```haskell
->>> [fString|{10 ^ 9 - 1:,}|]
+>>> [f|{10 ^ 9 - 1:,}|]
 "999,999,999"
->>> [fString|{2 ^ 32  -1:_b}|]
+>>> [f|{2 ^ 32  -1:_b}|]
 "1111_1111_1111_1111_1111_1111_1111_1111"
 ```
 
@@ -100,9 +89,9 @@
 Using `+` to display the positive sign (if any) or ` ` to display a space instead:
 
 ```haskell
->>> [fString|{pi:+.3}|]
+>>> [f|{pi:+.3}|]
 "+3.142"
->>> [fString|{pi: .3}|]
+>>> [f|{pi: .3}|]
 " 3.142"
 ```
 
@@ -111,7 +100,7 @@
 Preceding the width with a `0` enables sign-aware zero-padding, this is equivalent to inside `=` padding with a fill char of `0`.
 
 ```haskell
->>> [fString{-10:010}|]
+>>> [f{-10:010}|]
 -000000010
 ```
 
@@ -120,9 +109,9 @@
 First argument inside the curly braces can be a valid Haskell expression, for example:
 
 ```haskell
->>> format [f|2pi = {2* pi:.2}|]
+>>> [f|2pi = {2* pi:.2}|]
 6.28
->>> format [f|tail "hello" = {tail "hello":->6}|]
+>>> [f|tail "hello" = {tail "hello":->6}|]
 "tail \"hello\" = --ello"
 ```
 
@@ -133,28 +122,24 @@
 Most options can be combined. This generally leads to totally unreadable format string ;)
 
 ```haskell
->>> format [f|{pi:~>5.2}|]
+>>> [f|{pi:~>5.2}|]
 "~~3.14"
 ```
 
-# Other quasiquoters
-
-*PyF* main entry point is `f` but for convenience some other quasiquoters are provided:
-
-- `f(StrictText|LazyText|String|Builder|IO)` directly call the underlying `Formatting` runner and produce the specified type.
-- `f'` use type inference to deduce the type.
+# Output type
 
-`PyF` reexport most of `Formatting` runners, such as `format`, `sformat`, `formatToString`, ...
+*PyF* main entry point `f` is polymorphic and can represents `Text`, lazy `Text`, `String`, lazy text `Builder` or `IO` operations. Most of the time, type inference will do the right thing for you, but you may need to add type annotations.
 
 For example:
 
 ```haskell
->>> [f'|hello {pi.2}|] :: String
+>>> [f|hello {pi.2}|] :: String
 "hello 3.14"
->>> :type [fString|hello|]
-[Char]
 ```
 
+Note: it works in ghci without any type annotation if the extensions
+`OverloadedStrings` and `ExtendedDefaultRules` are enabled.
+
 # Caveats
 
 ## Type inference
@@ -199,7 +184,7 @@
   too polymorphic), you will get an awful error:
 
 ```haskell
->>*> [fString|{True:d}|]
+>>*> [f|{True:d}|]
 
 <interactive>:80:10: error:
     • No instance for (Integral Bool)
@@ -210,21 +195,21 @@
 - There is also one class of error related to alignement which can be triggered, when using alignement inside sign (i.e. `=`) with string. This can fail in two flavors:
 
 ```haskell
->>> [fString|{"hello":=10s}|]
+>>> [f|{"hello":=10s}|]
 
 <interactive>:88:1: error:
     • Exception when trying to run compile-time code:
         String Cannot be aligned with the inside `=` mode
 CallStack (from HasCallStack):
   error, called at src/PyF/Internal/QQ.hs:143:18 in PyF-0.4.0.0-inplace:PyF.Internal.QQ
-      Code: quoteExp fString "{\"hello\":=10s}"
-    • In the quasi-quotation: [fString|{"hello":=10s}|]
+      Code: quoteExp f "{\"hello\":=10s}"
+    • In the quasi-quotation: [f|{"hello":=10s}|]
 ```
 
 And
 
 ```haskell
-*PyF PyF.Internal.QQ> [fString|{"hello":=10}|]
+*PyF PyF.Internal.QQ> [f|{"hello":=10}|]
 
 <interactive>:89:10: error:
     • String Cannot be aligned with the inside `=` mode
@@ -234,7 +219,7 @@
 - Finally, if you make any type error inside the expression field, you are on your own:
 
 ```haskell
->>> [fString|{3 + pi + "hello":10}|]
+>>> [f|{3 + pi + "hello":10}|]
 
 <interactive>:99:10: error:
     • No instance for (Floating [Char]) arising from a use of ‘pi’
@@ -255,7 +240,7 @@
 import PyF
 
 myCustomFormatter :: QuasiQuoter
-myCustomFormatter = fStringWithDelimiters ('@','!')
+myCustomFormatter = fWithDelimiters ('@','!')
 ```
 
 Later, in another module:
diff --git a/src/PyF.hs b/src/PyF.hs
--- a/src/PyF.hs
+++ b/src/PyF.hs
@@ -4,46 +4,25 @@
 {- | A lot of quasiquoters to format and interpolate string expression
 -}
 module PyF
-  (f,
-   f',
-   fIO,
-   fString,
-   fBuilder,
-   fLazyText,
-   fStrictText,
-
+  ( f
    -- * With custom delimiters
-   fWithDelimiters,
-   f'WithDelimiters,
-   fIOWithDelimiters,
-   fStringWithDelimiters,
-   fBuilderWithDelimiters,
-   fLazyTextWithDelimiters,
-   fStrictTextWithDelimiters,
-
-   -- * Formatting re-export
-   runFormat,
-   format,
-   sformat,
-   bprint,
-   fprint,
-   hprint)
+  , fWithDelimiters
+  )
 where
 
 import           Language.Haskell.TH.Quote (QuasiQuoter(..))
 import qualified PyF.Internal.QQ as QQ
 
-import Formatting (runFormat, format, sformat, bprint, fprint, hprint)
-import qualified Formatting as F
 import           Language.Haskell.TH
 
 import qualified Data.Text.Lazy as LText
+import qualified Data.Text.Lazy.IO as LText
 import qualified Data.Text as SText
 import qualified Data.Text.Lazy.Builder as Builder
 
 templateF :: (Char, Char) -> String -> QuasiQuoter
 templateF delimiters fName = QuasiQuoter {
-    quoteExp = QQ.toExp delimiters
+    quoteExp = \s -> (AppE (VarE 'magicFormat)) <$> (QQ.toExp delimiters s)
   , quotePat = err "pattern"
   , quoteType = err "type"
   , quoteDec = err "declaration"
@@ -51,69 +30,30 @@
   where
     err name = error (fName ++ ": This QuasiQuoter can not be used as a " ++ name ++ "!")
 
--- | Returns an expression usable with Formatting.format (and similar functions)
+-- | Generic formatter, can format an expression to (lazy) Text, String, Builder and IO () depending on type inference
 f :: QuasiQuoter
 f = templateF pythonDelimiters "f"
 
 fWithDelimiters :: (Char, Char) -> QuasiQuoter
 fWithDelimiters delimiters = templateF delimiters "fWithDelimiters"
 
--- | Generic formatter, can format an expression to (lazy) Text, String, Builder and IO () depending on type inference
-f' :: QuasiQuoter
-f' = wrapQQ (templateF pythonDelimiters "f'") (VarE 'magicFormat)
-
-f'WithDelimiters :: (Char, Char) -> QuasiQuoter
-f'WithDelimiters delimiters = templateF delimiters "f'WithDelimiters"
-
-wrapQQ :: QuasiQuoter -> Exp -> QuasiQuoter
-wrapQQ qq wrap = qq {
-  quoteExp = \s -> do
-      e <- quoteExp qq s
-      pure (AppE wrap e)
-  }
-
 class MagicFormat t where
-  magicFormat :: F.Format t t -> t
+  magicFormat :: Builder.Builder -> t
 
 instance MagicFormat (IO ()) where
-  magicFormat = F.fprint
+  magicFormat = LText.putStrLn . Builder.toLazyText
 
 instance MagicFormat [Char] where
-  magicFormat = F.formatToString
+  magicFormat = LText.unpack . Builder.toLazyText
 
 instance MagicFormat SText.Text where
-  magicFormat = F.sformat
+  magicFormat = LText.toStrict . Builder.toLazyText
 
 instance MagicFormat LText.Text where
-  magicFormat = F.format
+  magicFormat = Builder.toLazyText
 
 instance MagicFormat Builder.Builder where
-  magicFormat = F.bprint
-
--- Monomorphic formatters
-fIO, fString, fStrictText, fLazyText, fBuilder :: QuasiQuoter
-fIOWithDelimiters, fStringWithDelimiters, fStrictTextWithDelimiters, fLazyTextWithDelimiters, fBuilderWithDelimiters :: (Char, Char) -> QuasiQuoter
-
-fIO = fIOWithDelimiters pythonDelimiters
-fString = fStringWithDelimiters pythonDelimiters
-fStrictText = fStrictTextWithDelimiters pythonDelimiters
-fLazyText = fLazyTextWithDelimiters pythonDelimiters
-fBuilder = fBuilderWithDelimiters pythonDelimiters
+  magicFormat = id
 
 pythonDelimiters :: (Char, Char)
 pythonDelimiters = ('{', '}')
-
--- | Format the format string and directly print it to stdout
-fIOWithDelimiters delimiters = wrapQQ (templateF delimiters "fIO") (VarE 'F.fprint)
-
--- | Format the format string as a 'String'
-fStringWithDelimiters delimiters = wrapQQ (templateF delimiters "fString") (VarE 'F.formatToString)
-
--- | Format the format string as a strict 'SText.Text'
-fStrictTextWithDelimiters delimiters = wrapQQ (templateF delimiters "fStrictTeext") (VarE 'F.sformat)
-
--- | Format the format string as a Lazy 'LText.Text'
-fLazyTextWithDelimiters delimiters = wrapQQ (templateF delimiters "fLazy") (VarE 'F.sformat)
-
--- | Format the format string as a 'Builder.Builder'
-fBuilderWithDelimiters delimiters = wrapQQ (templateF delimiters "fBuilder") (VarE 'F.bprint)
diff --git a/src/PyF/Internal/PythonSyntax.hs b/src/PyF/Internal/PythonSyntax.hs
--- a/src/PyF/Internal/PythonSyntax.hs
+++ b/src/PyF/Internal/PythonSyntax.hs
@@ -33,6 +33,9 @@
 import Data.Maybe (fromMaybe)
 
 import qualified Data.Set as Set -- For fancyFailure
+import qualified Language.Haskell.Meta.Syntax.Translate as SyntaxTranslate
+import qualified Language.Haskell.Exts.Parser as ParseExp
+import qualified Language.Haskell.Exts.SrcLoc as SrcLoc
 import PyF.Formatters
 
 type Parser t = Parsec Void String t
@@ -60,7 +63,7 @@
 
 -- | A format string is composed of many chunks of raw string or replacement
 data Item = Raw String -- ^ A raw string
-           | Replacement String (Maybe FormatMode) -- ^ A replacement string, composed of an arbitrary Haskell expression followed by an optional formatter
+           | Replacement Exp (Maybe FormatMode) -- ^ A replacement string, composed of an arbitrary Haskell expression followed by an optional formatter
            deriving (Show)
 
 {- |
@@ -103,7 +106,7 @@
 replacementField :: (Char, Char) -> Parser Item
 replacementField (charOpening, charClosing) = do
   _ <- char charOpening
-  expr <- many (noneOf (charClosing:":"))
+  expr <- evalExpr (many (noneOf (charClosing:":" :: [Char])))
   fmt <- optional $ do
     _ <- char ':'
     format_spec
@@ -170,12 +173,25 @@
 
 lastCharFailed :: String -> Parser t
 lastCharFailed err = do
-  (SourcePos name line col) <- getPosition
+  offset <- getOffset
+  setOffset (offset - 1)
 
-  -- This is right as long as there is not line break in the string
-  setPosition (SourcePos name line (mkPos (unPos col - 1)))
   fancyFailure (Set.singleton (ErrorFail err))
 
+evalExpr :: Parser String -> Parser Exp
+evalExpr exprParser = do
+  offset <- getOffset
+  s <- exprParser
+  case SyntaxTranslate.toExp <$> ParseExp.parseExp s of
+    ParseExp.ParseOk expr -> pure expr
+    ParseExp.ParseFailed (SrcLoc.SrcLoc _name' line col) err -> do
+      let
+        linesBefore = take (line - 1) (lines s)
+        currentOffset = length (unlines linesBefore) + col - 1
+
+      setOffset (offset + currentOffset)
+      fancyFailure (Set.singleton (ErrorFail err))
+
 overrideAlignmentIfZero :: Bool -> Maybe (Maybe Char, AnyAlign) -> Maybe (Maybe Char, AnyAlign)
 overrideAlignmentIfZero True Nothing = Just (Just '0', AnyAlign AlignInside)
 overrideAlignmentIfZero True (Just (Nothing, al)) = Just (Just '0', al)
@@ -263,7 +279,7 @@
     ]
 
 fill :: Parser Char
-fill = anyChar
+fill = anySingle
 
 align :: Parser AnyAlign
 align = choice [
diff --git a/src/PyF/Internal/QQ.hs b/src/PyF/Internal/QQ.hs
--- a/src/PyF/Internal/QQ.hs
+++ b/src/PyF/Internal/QQ.hs
@@ -10,7 +10,9 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE UndecidableInstances #-}
 
-{- | This module uses the python mini language detailed in 'PyF.Internal.PythonSyntax' to build an template haskell expression which represents a 'Formatting.Format'.
+{- | This module uses the python mini language detailed in
+'PyF.Internal.PythonSyntax' to build an template haskell expression
+representing a formatted string ('String', 'Text' or 'Builder').
 
 -}
 module PyF.Internal.QQ (
@@ -20,8 +22,6 @@
 
 import Text.Megaparsec
 
-import qualified Formatting as F
-
 import           Language.Haskell.TH
 
 import Data.Maybe (fromMaybe)
@@ -30,13 +30,11 @@
 
 import qualified Data.Text.Lazy as LText
 import qualified Data.Text as SText
-import qualified Data.List.NonEmpty as NonEmpty
 
 import qualified Data.Word as Word
 import qualified Data.Int as Int
 import Numeric.Natural
 
-import Language.Haskell.Meta.Parse (parseExp)
 
 import PyF.Internal.PythonSyntax
 import qualified PyF.Formatters as Formatters
@@ -49,23 +47,40 @@
 toExp:: (Char, Char) -> String -> Q Exp
 toExp delimiters s = do
   filename <- loc_filename <$> location
+  case parse (parseGenericFormatString delimiters) filename s of
+    Left err -> do
+      err' <- overrideErrorForFile filename err
+      fail (errorBundlePretty err')
+    Right items -> goFormat items
+
+-- Megaparsec displays error relative to what they parsed
+-- However the formatting string is part of a more complex file and we
+-- want error reporting relative to that file
+overrideErrorForFile :: FilePath -> ParseErrorBundle String e -> Q (ParseErrorBundle String e)
+-- We have no may to recover interactive content
+-- So we won't do better than displaying the megaparsec
+-- error relative to the quasi quote content
+overrideErrorForFile "<interactive>" err = pure err
+-- We know the content of the file here
+overrideErrorForFile filename err = do
   (line, col) <- loc_start <$> location
+  fileContent <- runIO (readFile filename)
 
-  let change_log "<interactive>" currentState = currentState
-      change_log _ currentState = let
-        (SourcePos sName _ _) NonEmpty.:| xs = statePos currentState
-        in currentState {statePos = (SourcePos sName (mkPos line) (mkPos col)) NonEmpty.:| xs}
+  let
+    -- drop the first lines of the file up to the line containing the quasiquote
+    -- then, split in what is before the QQ and what is after.
+    -- e.g.  blablabla [f|hello|] will split to
+    -- "blablabla [f|" and "hello|]"
+    (prefix, postfix) = splitAt (col - 1) $ unlines $ drop (line - 1) (lines fileContent)
 
-  case parse (updateParserState (change_log filename) >> parseGenericFormatString delimiters) filename s of
-    Left err -> do
 
-      if filename == "<interactive>"
-        then do
-          fail (parseErrorPretty' s err)
-        else do
-          fileContent <- runIO (readFile filename)
-          fail (parseErrorPretty' fileContent err)
-    Right items -> goFormat items
+  pure $ err {
+    bundlePosState = (bundlePosState err) {
+        pstateInput = postfix,
+        pstateSourcePos = SourcePos filename (mkPos line) (mkPos col),
+        pstateOffset = 0,
+        pstateLinePrefix = prefix
+        }}
 
 toExpPython :: String -> Q Exp
 toExpPython = toExp ('{', '}')
@@ -74,18 +89,15 @@
 goFormat items = foldl1 fofo <$> (mapM toFormat items)
 
 fofo :: Exp -> Exp -> Exp
-fofo s0 s1 = InfixE (Just s0) (VarE '(F.%)) (Just s1)
+fofo s0 s1 = InfixE (Just s0) (VarE '(<>)) (Just s1)
 
 -- Real formatting is here
 
 toFormat :: Item -> Q Exp
-toFormat (Raw x) = [| F.now (Builder.fromString x) |]
-toFormat (Replacement x y) = do
+toFormat (Raw x) = [| Builder.fromString x |]
+toFormat (Replacement expr y) = do
   formatExpr <- padAndFormat (fromMaybe DefaultFormatMode y)
-
-  case parseExp x of
-    Right expr -> pure (AppE (VarE 'F.now) (VarE 'Builder.fromString `AppE` (formatExpr `AppE` expr)))
-    Left err -> fail err
+  pure (VarE 'Builder.fromString `AppE` (formatExpr `AppE` expr))
 
 changePrec :: Precision -> Maybe Int
 changePrec PrecisionDefault = Just 6
@@ -123,11 +135,13 @@
   PercentF prec alt s -> [| formatAnyFractional $(withAlt alt Formatters.Percent) s (newPadding padding) (toGrp grouping 3) (changePrec prec) |]
 
   -- Default / String
-  DefaultF prec s -> [| \v ->
-      case categorise (Proxy :: Proxy $(typeAllowed)) v of
-        Integral i -> formatAnyIntegral Formatters.Decimal s (newPadding padding) (toGrp grouping 3) i
-        Fractional f -> formatAnyFractional Formatters.Generic s (newPadding padding) (toGrp grouping 3) (changePrec' prec) f
-        StringType f -> Formatters.formatString (newPaddingForString padding) (changePrec' prec) f
+
+  -- Note: v / i / f uses pat and var to ensure stable name in error message
+  DefaultF prec s -> [| \($(pat "v")) ->
+      case categorise (Proxy :: Proxy $(typeAllowed)) $(var "v") of
+        Integral $(pat "i") -> formatAnyIntegral Formatters.Decimal s (newPadding padding) (toGrp grouping 3) $(var "i")
+        Fractional $(pat "f") -> formatAnyFractional Formatters.Generic s (newPadding padding) (toGrp grouping 3) (changePrec' prec) $(var "f")
+        StringType $(pat "f") -> Formatters.formatString (newPaddingForString padding) (changePrec' prec) $(var "f")
                          |]
    where
      typeAllowed :: Q Type
@@ -140,6 +154,15 @@
 
   StringF prec -> [| Formatters.formatString pad (changePrec' prec) |]
     where pad = newPaddingForString padding
+
+-- Generate stable name in TH slices
+-- The name are postfixed by _PyF to limit the risk of shadowing
+
+pat :: String -> Q Pat
+pat name = pure (VarP (mkName (name ++ "_PyF")))
+
+var :: String -> Q Exp
+var name = pure (VarE (mkName (name ++ "_PyF")))
 
 newPaddingForString :: Padding -> Maybe (Int, Formatters.AlignMode 'Formatters.AlignAll, Char)
 newPaddingForString padding = case padding of
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -11,7 +11,7 @@
 import SpecCustomDelimiters
 
 {-
-   - Normal tests are done using the recommanded API: [fString|.....|]
+   - Normal tests are done using the recommanded API: [f|.....|]
    - Test with $(checkExample formatString result) are checked against the python reference implementation. Result is provided as documentation.
    - Test with $(checkExampleDiff formatString result) are not checked against the python reference implementation. This is known (and documented) differences.
    - Test with $(check formatString) are only tested against the python reference implementation.
@@ -27,9 +27,9 @@
       anInt = 123
       aFloat = 0.234
       aString = "hello"
-    it "int" $ [fString|{anInt}|] `shouldBe` "123"
-    it "float" $ [fString|{aFloat}|] `shouldBe` "0.234"
-    it "string" $ [fString|{aString}|] `shouldBe` "hello"
+    it "int" $ [f|{anInt}|] `shouldBe` "123"
+    it "float" $ [f|{aFloat}|] `shouldBe` "0.234"
+    it "string" $ [f|{aString}|] `shouldBe` "hello"
   describe "only expression" $ do
     describe "default" $ do
       it "int" $(checkExample "{123}" "123")
@@ -90,6 +90,10 @@
     describe "percent" $ do
       it "simple" $(checkExample "{0.234:%}" "23.400000%")
       it "precision" $(checkExample "{0.234:.2%}" "23.40%")
+
+    describe "string truncating" $ do
+      it "works" $ $(checkExample "{\"hello\":.3}" "hel")
+
     describe "padding" $ do
       describe "default char" $ do
         it "left" $(checkExample "{\"hello\":<10}" "hello     ")
@@ -172,7 +176,7 @@
         age = 31
         euroToFrancs = 6.55957
       in
-        [fString|hello {name} you are {age} years old and the conversion rate of euro is {euroToFrancs:.2}|] `shouldBe` ("hello Guillaume you are 31 years old and the conversion rate of euro is 6.56")
+        [f|hello {name} you are {age} years old and the conversion rate of euro is {euroToFrancs:.2}|] `shouldBe` ("hello Guillaume you are 31 years old and the conversion rate of euro is 6.56")
 
 
   describe "error reporting" $ do
@@ -180,14 +184,14 @@
 
   describe "sub expressions" $ do
     it "works" $ do
-      [fString|2pi = {2 * pi:.2}|] `shouldBe` "2pi = 6.28"
+      [f|2pi = {2 * pi:.2}|] `shouldBe` "2pi = 6.28"
 
   describe "escape strings" $ do
     it "works" $ do
-      [fString|hello \n\b|] `shouldBe` "hello \n\b"
+      [f|hello \n\b|] `shouldBe` "hello \n\b"
 
   it "escape chars" $ do
-     [fString|}}{{}}{{|] `shouldBe` "}{}{"
+     [f|}}{{}}{{|] `shouldBe` "}{}{"
 
   describe "custom delimiters" $ do
     it "works" $ do
diff --git a/test/SpecCustomDelimiters.hs b/test/SpecCustomDelimiters.hs
--- a/test/SpecCustomDelimiters.hs
+++ b/test/SpecCustomDelimiters.hs
@@ -5,4 +5,4 @@
 import PyF
 
 myCustomFormatter :: QuasiQuoter
-myCustomFormatter = fStringWithDelimiters ('@','!')
+myCustomFormatter = fWithDelimiters ('@','!')
diff --git a/test/SpecUtils.hs b/test/SpecUtils.hs
--- a/test/SpecUtils.hs
+++ b/test/SpecUtils.hs
@@ -12,7 +12,6 @@
 import Language.Haskell.TH
 import Language.Haskell.TH.Syntax
 
-import Formatting
 import System.Process
 import System.Exit
 
@@ -51,7 +50,7 @@
   case pythonRes of
     Nothing -> [| expectationFailure $ "Expression: `" ++ s ++ "` fails in python" |]
     Just res -> do
-      let qexp = [| formatToString $(toExpPython s)  `shouldBe` res |]
+      let qexp = [| $(toExpPython s)  `shouldBe` res |]
       case exampleStr of
         Nothing -> qexp
         Just e -> if res == e
@@ -72,7 +71,7 @@
      against the python implementation
 -}
 checkExampleDiff :: String -> String -> Q Exp
-checkExampleDiff s res = [| formatToString $(toExpPython s) `shouldBe` res |]
+checkExampleDiff s res = [| $(toExpPython s) `shouldBe` res |]
 
 {- | `check formatString` checks only with the python implementation
 -}
