eval
We could get around this problem by requiring the caller to quote every argument to limited-save-excursion:
(limited-save-excursion '(beginning-of-line) '(point))
This time limited-save-excursion is called with the two arguments (beginning-of-line) and (point). It could record the value of point, explicitly evaluate each subexpression in turn, then restore point and return. It would look like the following example.
(defun limited-save-excursion (&rest exprs) "Like save-excursion, but only restores point." (let ((saved-point (point))) ;memorize point (while exprs (eval (car exprs)) ;evaluate the next argument (setq exprs (cdr exprs))) (goto-char saved-point))) ;restore point
This function contains something new: a call to eval, which takes a Lisp expression as an argument and evaluates it. At first that may not seem like much since, after all, the Lisp interpreter is already evaluating Lisp expressions automatically, with no calls to eval needed. But sometimes the result of evaluation is another Lisp expression which you'd like to evaluate, and Lisp won't do the second one automatically. If we were to execute only (car exprs), we'd be extracting the first subexpression, then discarding it! We need eval to make that subexpression do something useful once we have it.
Here's an simple example to illustrate the difference between the evaluation that Emacs does normally and the need for eval:
(setq x '(+ 3 5)) x ⇒ (+ 3 5) ;evaluating x (eval x) ⇒ 8 ;evaluating the value of x
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access