1

I wanted to write a function that "auto-corrects" a string, based on a list of regular expressions and their respective replacements.

I've come up with this, and it works:

(setq auto-corrections-dictionary
  [
   [ "cat" "lion"]
   [ "horse" "zebra" ]
  ])

(defun auto-correct (string)
  (interactive)
  (car (last (mapcar
               (lambda (regexp-replacement-pair)
                 (setq string
                   (replace-regexp-in-string
                     (aref regexp-replacement-pair 0)
                     (aref regexp-replacement-pair 1)
                     string)))
                 auto-corrections-dictionary))))

(auto-correct "The cat chased the horse.")
    => "The lion chased the zebra."

Since I'm brand new to Emacs and Lisp, I have a couple of questions:

  • string is the function's argument. Within mapcar's lambda function I repeatedly set the value of string to the latest auto-corrected string, so that I don't lose any previous replacements. Is that the correct pattern? Is there a more "Lisp-y" way to do that?
  • mapcar returns a list of strings, with one element for each consecutive replacement. I'm only interested in the last element, which is the final result of the function. However, this seems wasteful when I think of memory use and (possibly) performance. Should I be concerned? Should I have used something else instead of mapcar?
  • Any other comments along the lines of "nah, here's how to do it properly..."?
  • Finally: is there a builtin function I could have used instead of writing my function? ;)
  • If you don't want to accumulate a list of results, use mapc (see which) instead of mapcar. – phils Nov 28 '17 at 3:49
1

I would use a list of conses for the dictionary, and reduce to apply to the corrections:

(setq auto-corrections-dictionary
      '(("cat" . "lion")
        ("horse" . "zebra" )))

(defun auto-correct (string)
  (seq-reduce
   (lambda (string regexp-replacement-pair)
     (replace-regexp-in-string
      (car regexp-replacement-pair)
      (cdr regexp-replacement-pair)
      string))
   auto-corrections-dictionary
   string))

Also, I see no point in making the function interactive.

  • Thanks, Omar. Correct, no need for (interactive) ... that's what you get with blindly copy-pasting ... ;-) – Torben Dec 12 '17 at 2:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.