   "Apply cmd to text. Return text as is if cmd isn't this cmd"
   [cmd text]
   (if-let [[_ fr to] (re-find (re-matcher #"^move position (\d+) to position (\d+)$" cmd))]
-    (move-position text (parse-int fr) (parse-int to))))
+    (list move-position text (parse-int fr) (parse-int to))))
 
 ;; swap position X with position Y means that the letters at indexes X
 ;; and Y (counting from 0) should be swapped.

  "Apply cmd to text. Return text as is if cmd isn't this cmd"
  [cmd text]
  (if-let [[_ fr to] (re-find (re-matcher #"^swap position (\d+) with position (\d+)$" cmd))]
    (swap-position text (parse-int fr) (parse-int to))))

;; reverse positions X through Y means that the span of letters at
;; indexes X through Y (including the letters at X and Y) should be

  "Apply cmd to text. Return text as is if cmd isn't this cmd"
  [cmd text]
  (if-let [[_ fr to] (re-find (re-matcher #"^swap letter ([a-z]+) with letter ([a-z]+)$" cmd))]
    (list swap-letter text fr to)))

(defn mycall
  "form is a list where first arg is a function and rest is args. Execute it if non-nil.
   Not using eval, since eval is much more general, like handles macros etc."
  [form]
  (if form (apply (first form)(rest form))))

(defn call-cmd
  [cmd text]
  (let [ret (or (mycall (parse-rotate-left cmd text))
                (mycall (parse-rotate-right cmd text))
                (mycall (parse-move-position cmd text))
                (mycall (parse-reverse-positions cmd text))
                (mycall (parse-rotate-based-on cmd text))
                (mycall (parse-swap-letter cmd text))
                (mycall (parse-swap-position cmd text)))]
    (if (nil? ret){:error :not-a-command :data cmd}
        ret)))

