如何根据elisp中的一个条件设置一组变量?

时间:2016-11-13 11:01:15

标签: lisp elisp

假设我想根据一个条件设置barbaz的值,这两个条件都相同,比如foo的值。使用let特殊表单,我会做这样的事情

(let ((bar (if foo 1 2))
      (baz (if foo 3 4)))
  ... )

虽然上面的程序是正确的,但它似乎有点奇怪,因为它检查foo两次的值。在这种情况下是否可以使用惯用表达式以避免重复检查?

3 个答案:

答案 0 :(得分:1)

您可以使用cl-lib.el提供的多个值, Emacs的Common Lisp扩展

(multiple-value-bind (bar baz) 
    (if foo (values 1 3) (values 2 4))
  ...)

您可能希望在单独的函数中提取这两种情况。

答案 1 :(得分:1)

我在elisp中可以想到的唯一答案(没有多重值)是一件非常可怕的事情:

(apply (lambda (bar baz)
         ...)
       (if foo
           (list 1 2)
         (list 3 4)))

一般情况下这很简单,但显然不需要提供文字列表的好情况。

你可以将它包装在一个宏中:以下是这样的,虽然它迫切需要一些错误检查(elisp太烦人了,不能写我想花更多的时间在它上面 - 至少现在有反引号)。

(defmacro plet (vars-vals &rest forms)
  `(apply (lambda ,(car vars-vals)
            ,@forms)
          ,(cadr vars-vals)))

然后你的表达式会变成(这次使用文字列表)

(plet ((bar baz) (if foo '(1 2) '(3 4)))
  ...)

答案 2 :(得分:1)

您无需在let表单中设置值。 let表单创建本地绑定,之后您可以根据需要设置值。

(let (bar baz)
  (if foo
      (setq bar 1
            baz 2)
    (setq bar 3
          baz 4))
  ...)