Как выйти из функции в любой произвольной точке, в elisp

Это простой вопрос, но почему-то я не смог найти ответ по googling:

Как вы выходите из функции в любой произвольной точке выполнения, если какое-либо условие не выполняется. Например (я использую "(exit)" в качестве замены здесь):

(defun foo ()
  (progn (if (/= a1 a2)
             (exit) ; if a1!=a2, exit the function somehow
           t)
         (blahblah...)))

Ответ 1

В elisp вы можете использовать catch и throw вместо cl block и return-from.

(defun foo ()
  (catch 'my-tag
    (when (not (/= a1 a2))
      (throw 'my-tag "non-local exit value"))
    "normal exit value"))

См. C-h i g (elisp) Nonlocal Exits RET

Ответ 2

Поместите блок вокруг тела и верните его:

(require 'cl-macs)
(defun foo ()
  (block foo
    (if (/= a1 a2)
        (return-from foo)
        reture-value))))

Ответ 3

Просто используйте defun* вместо defun (поставляется с пакетом cl). Этот макрос уже действует как Common Lisp defun (обертывает тело функции в блок try-catch и псевдонимы return-from до throw и т.д.).

Например:

(require 'cl)

(defun* get-out-early ()
  "Get out early from this silly example."
  (when (not (boundp some-unbound-symbol))
    (return-from get-out-early))
  ;;
  ;; Get on with the func...
  ;;
  (do-such-and-such with-some-stuff))

Ответ 4

Функция возвращает значение последней обработанной формы. Если вам все равно, что такое значение, тогда nil будет вероятным кандидатом. В этом случае функция возвращает значение функции if.

например:.

(defun foo ()
  (if (/= a1 a2)
      nil
    "return-value"))

В этом тривиальном примере они также были бы эквивалентны:

(defun foo ()
  (if (not (/= a1 a2))
      "return-value"))

(defun foo ()
  (when (not (/= a1 a2))
    "return-value"))