用于"让"匹配Clojure的Common Lisp宏

jch*_*eat 3 macros clojure common-lisp

Clojure的let比Common Lisp更简洁,括号更少:

 ;Clojure
(let [a 1 b 2]
     (+ a b))


;Common Lisp
(let ( (a 1) (b 2))
    (+ a b))
Run Code Online (Sandbox Code Playgroud)

你如何在Common Lisp中编写一个宏来等效?:

(letmac ( a 1 b 2)
    (+ a b))
Run Code Online (Sandbox Code Playgroud)

sds*_*sds 10

这不是太难:

(defmacro clojure-let (bindings &body body)
  `(let ,(loop for (a b) on bindings by #'cddr collect (list a b))
     ,@body))
Run Code Online (Sandbox Code Playgroud)

看看它怎么运作:

> (macroexpand-1 '(clojure-let (a b c d) (foo) (bar)))
(LET ((A B) (C D)) (FOO) (BAR)) ;
T
Run Code Online (Sandbox Code Playgroud)

但是,这不是一个好主意(也不是新的!):

您的代码可能是一个Clojure的用户更可读的,但它了利斯佩尔可读.

一个clojurer 可能会得到一种虚假的安全感,而一个lisper 感到困惑.

不要自欺欺人

将Common Lisp代码移植到Clojure比编写一些简单的宏要困难得多.

  • 如果你要模仿Clojure的'let`(一个可疑的想法,我同意),你也可以发出`let*`而不仅仅是`let`,因为Clojure的`let`按顺序执行绑定而不是一次性完成绑定. (3认同)