            :username author
            :time time}])))])
 
-(def leo-tolstoy
-  [:leo-tolstoy
+(defn make-message-scanner [achievement-id message-predicate]
+  [achievement-id
    (fn [{:keys [message author time]}]
-     (when (>= (count (str/split-lines message)) 10)
+     (when (message-predicate message)
        {:username author
         :time time}))])
 
+(def leo-tolstoy
+  (make-message-scanner
+    :leo-tolstoy
+    #(>= (count (str/split-lines %)) 10)))
+
 (def man-of-few-words
-  [:man-of-few-words
-   (fn [{:keys [message author time]}]
-     (when (< (count message) 4)
-       {:username author
-        :time time}))])
+  (make-message-scanner
+    :man-of-few-words
+    #(< (count %) 4)))
 
 (def no-more-letters
-  [:no-more-letters
-   (fn [{:keys [message author time]}]
-     (when-not (some #(Character/isLetter (.charValue %)) message)
-       {:username author
-        :time time}))])
+  (make-message-scanner
+    :no-more-letters
+    (fn [message]
+      (some #(Character/isLetter (.charValue %)) message))))
 
 (def narcissist
   [:narcissist

         {:username author
          :time time}))])

; TODO commit-info achievements
(def borat
  [:borat

     nil)])
(def necromancer
  [:necromancer
   (fn [timeline]
     nil)])
(def collision
