温馨提示:本文翻译自stackoverflow.com,查看原文请点击:lisp - How to format a nested multiple-value-bind the let way?
common-lisp let lisp multiple-value

lisp - 如何格式化嵌套的多值绑定让路?

发布于 2020-04-10 18:07:19

最近,我经常嵌套几个返回多个值的函数。但是,与let我允许将这些调用优雅地写入一个大语句不同,我总是以很多缩进结尾。

我的问题是:具有多个多值函数,例如

(defun return-1-and-2 ()
  (values 1 2))

(defun return-3-and-4 ()
  (values 3 4))

是否有可能达到与

(multiple-value-bind (one two)
    (return-1-and-2)
  (multiple-value-bind (three four)
      (return-3-and-4)
    (list one two three four)))

但写得更简洁let一点,例如

(multiple-let (((one two) (return-1-and-2))
               ((three four) (return-3-and-4)))
  (list one two three four))

查看更多

提问者
Dominik Mokriš
被浏览
67
Rainer Joswig 2020-02-03 01:55

库中可能有类似的构造。

请注意,由于作用域是嵌套的,因此它更类似于let*,而不是let

一个人可以写一个宏。例如:

(defmacro multiple-value-let* ((&rest bindings) &body body)

  "Sets the scope for several ((var-0 ... var-n) form)
  binding clauses, using the multiple return values of the form."

  (if (null bindings)
      `(progn ,@body)
    (destructuring-bind (((&rest vars) form) &rest rest-bindings)
        bindings
      `(multiple-value-bind ,vars
           ,form
         (multiple-value-let* ,rest-bindings
           ,@body)))))

例:

CL-USER 33 > (walker:walk-form
              '(multiple-value-let* (((one two)    (return-1-and-2))
                                     ((three four) (return-3-and-4)))
                 (list one two three four)))
(MULTIPLE-VALUE-BIND (ONE TWO)
    (RETURN-1-AND-2)
  (MULTIPLE-VALUE-BIND (THREE FOUR)
      (RETURN-3-AND-4)
    (PROGN (LIST ONE TWO THREE FOUR))))