diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+# Version 1.2
+
+* COMPILER ASSISTED BREAKING CHANGE: Renaming logging functions again.
+  For example, `info` is the name we give to the `ToMessage`-polymorphic
+  logging functions, `info_` to their `Message`-monomorphic version, and
+  `info'` to the `STM` version. The previous `STM` suffix in `infoSTM`
+  is gone, so as to mimick the naming conventions of `di-core`.
+
+* Export `attr_`.
+
 # Version 1.1
 
 * COMPILER ASSISTED BREAKING CHANGE: The `STM` compatible logging functions
diff --git a/di-df1.cabal b/di-df1.cabal
--- a/di-df1.cabal
+++ b/di-df1.cabal
@@ -1,5 +1,5 @@
 name: di-df1
-version: 1.1
+version: 1.2
 author: Renzo Carbonara
 maintainer: renλren.zone
 copyright: Renzo Carbonara 2018
diff --git a/lib/Di/Df1.hs b/lib/Di/Df1.hs
--- a/lib/Di/Df1.hs
+++ b/lib/Di/Df1.hs
@@ -21,6 +21,7 @@
  , push
    -- * Metadata
  , attr
+ , attr_
    -- * Logging from @IO@
  , debug
  , info
@@ -31,6 +32,15 @@
  , critical
  , emergency
    -- ** Type-inference helpers
+ , debug_
+ , info_
+ , notice_
+ , warning_
+ , error_
+ , alert_
+ , critical_
+ , emergency_
+   -- ** Logging from @STM@
  , debug'
  , info'
  , notice'
@@ -39,15 +49,6 @@
  , alert'
  , critical'
  , emergency'
-   -- ** Logging from @STM@
- , debugSTM
- , infoSTM
- , noticeSTM
- , warningSTM
- , errorSTM
- , alertSTM
- , criticalSTM
- , emergencySTM
 
    -- * Support for @Di.Handle@
  , df1
@@ -110,9 +111,21 @@
   -> value
   -> Di.Di level Df1.Path msg
   -> Di.Di level Df1.Path msg   -- ^
-attr k v = Di.push (Df1.Attr k (Df1.value v))
+attr k v = attr_ k (Df1.value v)
 {-# INLINE attr #-}
 
+-- | Like 'attr', but takes a 'Df1.Value' rather than any 'Df1.ToValue'.
+--
+-- This helps with type inference in case you are trying to
+-- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
+attr_
+  :: Df1.Key
+  -> Df1.Value
+  -> Di.Di level Df1.Path msg
+  -> Di.Di level Df1.Path msg   -- ^
+attr_ k v = Di.push (Df1.Attr k v)
+{-# INLINE attr_ #-}
+
 --------------------------------------------------------------------------------
 -- MonadIO variants.
 
@@ -122,7 +135,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-emergency di = emergency' di . Df1.message
+emergency di = emergency_ di . Df1.message
 {-# INLINE emergency #-}
 
 -- | Log a condition that should be corrected immediately, such as a corrupted
@@ -132,7 +145,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-alert di = alert' di . Df1.message
+alert di = alert_ di . Df1.message
 {-# INLINE alert #-}
 
 -- | Log a critical condition that could result in system failure, such as a
@@ -142,7 +155,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-critical di = critical' di . Df1.message
+critical di = critical_ di . Df1.message
 {-# INLINE critical #-}
 
 -- | Log an error condition, such as an unhandled exception.
@@ -151,7 +164,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-error di = error' di . Df1.message
+error di = error_ di . Df1.message
 {-# INLINE error #-}
 
 -- | Log a warning condition, such as an exception being gracefully handled or
@@ -161,7 +174,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-warning di = warning' di . Df1.message
+warning di = warning_ di . Df1.message
 {-# INLINE warning #-}
 
 -- | Log a condition that is not an error, but should possibly be handled
@@ -171,7 +184,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-notice di = notice' di . Df1.message
+notice di = notice_ di . Df1.message
 {-# INLINE notice #-}
 
 -- | Log an informational message.
@@ -180,7 +193,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-info di = info' di . Df1.message
+info di = info_ di . Df1.message
 {-# INLINE info #-}
 
 -- | Log a message intended to be useful only when deliberately debugging a
@@ -190,7 +203,7 @@
   => Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-debug di = debug' di . Df1.message
+debug di = debug_ di . Df1.message
 {-# INLINE debug #-}
 
 --------------------------------------------------------------------------------
@@ -200,180 +213,180 @@
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-emergency'
+emergency_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-emergency' di = Di.log di Df1.Emergency
-{-# INLINE emergency' #-}
+emergency_ di = Di.log di Df1.Emergency
+{-# INLINE emergency_ #-}
 
 -- | Like 'critical', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-critical'
+critical_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-critical' di = Di.log di Df1.Critical
-{-# INLINE critical' #-}
+critical_ di = Di.log di Df1.Critical
+{-# INLINE critical_ #-}
 
 -- | Like 'alert', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-alert'
+alert_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-alert' di = Di.log di Df1.Alert
-{-# INLINE alert' #-}
+alert_ di = Di.log di Df1.Alert
+{-# INLINE alert_ #-}
 
 -- | Like 'error', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-error'
+error_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-error' di = Di.log di Df1.Error
-{-# INLINE error' #-}
+error_ di = Di.log di Df1.Error
+{-# INLINE error_ #-}
 
 -- | Like 'warning', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-warning'
+warning_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-warning' di = Di.log di Df1.Warning
-{-# INLINE warning' #-}
+warning_ di = Di.log di Df1.Warning
+{-# INLINE warning_ #-}
 
 -- | Like 'notice', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-notice'
+notice_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-notice' di = Di.log di Df1.Notice
-{-# INLINE notice' #-}
+notice_ di = Di.log di Df1.Notice
+{-# INLINE notice_ #-}
 
 -- | Like 'info', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-info'
+info_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-info' di = Di.log di Df1.Info
-{-# INLINE info' #-}
+info_ di = Di.log di Df1.Info
+{-# INLINE info_ #-}
 
 -- | Like 'debug', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-debug'
+debug_
   :: MonadIO m
   => Di.Di Df1.Level path Df1.Message
   -> Df1.Message
   -> m ()
-debug' di = Di.log di Df1.Debug
-{-# INLINE debug' #-}
+debug_ di = Di.log di Df1.Debug
+{-# INLINE debug_ #-}
 
 --------------------------------------------------------------------------------
 -- STM variants
 
 -- | Like 'emergency', but can be used from any 'Monad' supporting 'STM'.
-emergencySTM
+emergency'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-emergencySTM natSTM di = Di.log' natSTM di Df1.Emergency . Df1.message
-{-# INLINE emergencySTM #-}
+emergency' natSTM di = Di.log' natSTM di Df1.Emergency . Df1.message
+{-# INLINE emergency' #-}
 
 -- | Like 'critical', but can be used from any 'Monad' supporting 'STM'.
-criticalSTM
+critical'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-criticalSTM natSTM di = Di.log' natSTM di Df1.Critical . Df1.message
-{-# INLINE criticalSTM #-}
+critical' natSTM di = Di.log' natSTM di Df1.Critical . Df1.message
+{-# INLINE critical' #-}
 
 -- | Like 'alert', but can be used from any 'Monad' supporting 'STM'.
-alertSTM
+alert'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-alertSTM natSTM di = Di.log' natSTM di Df1.Alert . Df1.message
-{-# INLINE alertSTM #-}
+alert' natSTM di = Di.log' natSTM di Df1.Alert . Df1.message
+{-# INLINE alert' #-}
 
 -- | Like 'error', but can be used from any 'Monad' supporting 'STM'.
-errorSTM
+error'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-errorSTM natSTM di = Di.log' natSTM di Df1.Error . Df1.message
-{-# INLINE errorSTM #-}
+error' natSTM di = Di.log' natSTM di Df1.Error . Df1.message
+{-# INLINE error' #-}
 
 -- | Like 'warning', but can be used from any 'Monad' supporting 'STM'.
-warningSTM
+warning'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-warningSTM natSTM di = Di.log' natSTM di Df1.Warning . Df1.message
-{-# INLINE warningSTM #-}
+warning' natSTM di = Di.log' natSTM di Df1.Warning . Df1.message
+{-# INLINE warning' #-}
 
 -- | Like 'notice', but can be used from any 'Monad' supporting 'STM'.
-noticeSTM
+notice'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-noticeSTM natSTM di = Di.log' natSTM di Df1.Notice . Df1.message
-{-# INLINE noticeSTM #-}
+notice' natSTM di = Di.log' natSTM di Df1.Notice . Df1.message
+{-# INLINE notice' #-}
 
 -- | Like 'info', but can be used from any 'Monad' supporting 'STM'.
-infoSTM
+info'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-infoSTM natSTM di = Di.log' natSTM di Df1.Info . Df1.message
-{-# INLINE infoSTM #-}
+info' natSTM di = Di.log' natSTM di Df1.Info . Df1.message
+{-# INLINE info' #-}
 
 -- | Like 'debug', but can be used from any 'Monad' supporting 'STM'.
-debugSTM
+debug'
   :: (Monad m, Df1.ToMessage msg)
   => (forall x. STM x -> m x)
   -> Di.Di Df1.Level path Df1.Message
   -> msg
   -> m ()
-debugSTM natSTM di = Di.log' natSTM di Df1.Debug . Df1.message
-{-# INLINE debugSTM #-}
+debug' natSTM di = Di.log' natSTM di Df1.Debug . Df1.message
+{-# INLINE debug' #-}
 
 --------------------------------------------------------------------------------
 
diff --git a/lib/Di/Df1/Monad.hs b/lib/Di/Df1/Monad.hs
--- a/lib/Di/Df1/Monad.hs
+++ b/lib/Di/Df1/Monad.hs
@@ -9,6 +9,7 @@
  , push
    -- * Metadata
  , attr
+ , attr_
    -- * Logging
  , debug
  , info
@@ -19,14 +20,14 @@
  , critical
  , emergency
    -- ** Type-inference helpers
- , debug'
- , info'
- , notice'
- , warning'
- , error'
- , alert'
- , critical'
- , emergency'
+ , debug_
+ , info_
+ , notice_
+ , warning_
+ , error_
+ , alert_
+ , critical_
+ , emergency_
  ) where
 
 import Prelude hiding (error)
@@ -91,9 +92,22 @@
   -> value
   -> m a
   -> m a -- ^
-attr k v = Di.push (Df1.Attr k (Df1.value v))
+attr k v = attr_ k (Df1.value v)
 {-# INLINE attr #-}
 
+-- | Like 'attr', but takes a 'Df1.Value' rather than any 'Df1.ToValue'.
+--
+-- This helps with type inference in case you are trying to
+-- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
+attr_
+  :: Di.MonadDi level Df1.Path msg m
+  => Df1.Key
+  -> Df1.Value
+  -> m a
+  -> m a -- ^
+attr_ k v = Di.push (Df1.Attr k v)
+{-# INLINE attr_ #-}
+
 --------------------------------------------------------------------------------
 -- MonadIO variants.
 
@@ -102,7 +116,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-emergency = emergency' . Df1.message
+emergency = emergency_ . Df1.message
 {-# INLINE emergency #-}
 
 -- | Log a condition that should be corrected immediately, such as a corrupted
@@ -111,7 +125,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-alert = alert' . Df1.message
+alert = alert_ . Df1.message
 {-# INLINE alert #-}
 
 -- | Log a critical condition that could result in system failure, such as a
@@ -120,7 +134,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-critical = critical' . Df1.message
+critical = critical_ . Df1.message
 {-# INLINE critical #-}
 
 -- | Log an error condition, such as an unhandled exception.
@@ -128,7 +142,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-error = error' . Df1.message
+error = error_ . Df1.message
 {-# INLINE error #-}
 
 -- | Log a warning condition, such as an exception being gracefully handled or
@@ -137,7 +151,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-warning = warning' . Df1.message
+warning = warning_ . Df1.message
 {-# INLINE warning #-}
 
 -- | Log a condition that is not an error, but should possibly be handled
@@ -146,7 +160,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-notice = notice' . Df1.message
+notice = notice_ . Df1.message
 {-# INLINE notice #-}
 
 -- | Log an informational message.
@@ -154,7 +168,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-info = info' . Df1.message
+info = info_ . Df1.message
 {-# INLINE info #-}
 
 -- | Log a message intended to be useful only when deliberately debugging a
@@ -163,7 +177,7 @@
   :: (Di.MonadDi Df1.Level path Df1.Message m, Df1.ToMessage msg)
   => msg
   -> m ()
-debug = debug' . Df1.message
+debug = debug_ . Df1.message
 {-# INLINE debug #-}
 
 --------------------------------------------------------------------------------
@@ -173,86 +187,86 @@
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-emergency'
+emergency_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-emergency' = Di.log Df1.Emergency
-{-# INLINE emergency' #-}
+emergency_ = Di.log Df1.Emergency
+{-# INLINE emergency_ #-}
 
 -- | Like 'critical', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-critical'
+critical_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-critical' = Di.log Df1.Critical
-{-# INLINE critical' #-}
+critical_ = Di.log Df1.Critical
+{-# INLINE critical_ #-}
 
 -- | Like 'alert', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-alert'
+alert_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-alert' = Di.log Df1.Alert
-{-# INLINE alert' #-}
+alert_ = Di.log Df1.Alert
+{-# INLINE alert_ #-}
 
 -- | Like 'error', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-error'
+error_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-error' = Di.log Df1.Error
-{-# INLINE error' #-}
+error_ = Di.log Df1.Error
+{-# INLINE error_ #-}
 
 -- | Like 'warning', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-warning'
+warning_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-warning' = Di.log Df1.Warning
-{-# INLINE warning' #-}
+warning_ = Di.log Df1.Warning
+{-# INLINE warning_ #-}
 
 -- | Like 'notice', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-notice'
+notice_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-notice' = Di.log Df1.Notice
-{-# INLINE notice' #-}
+notice_ = Di.log Df1.Notice
+{-# INLINE notice_ #-}
 
 -- | Like 'info', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-info'
+info_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-info' = Di.log Df1.Info
-{-# INLINE info' #-}
+info_ = Di.log Df1.Info
+{-# INLINE info_ #-}
 
 -- | Like 'debug', but takes a 'Df1.Message' rather than any 'Df1.ToMessage'.
 --
 -- This helps with type inference in case you are trying to
 -- log a literal string and have the @OverloadedStrings@ GHC extension enabled.
-debug'
+debug_
   :: Di.MonadDi Df1.Level path Df1.Message m
   => Df1.Message
   -> m ()
-debug' = Di.log Df1.Debug
-{-# INLINE debug' #-}
+debug_ = Di.log Df1.Debug
+{-# INLINE debug_ #-}
