emacs的`let*`是在哪里定义的,或者说有没有`cl-labels*`或`cl-labelsrec`这种玩意儿

目前好像是没有cl-labels*或者cl-labelsrec这种玩意儿的(对应let*或者letrec),就想自己定义一个,况且let*是可以很方便(雾)地用lisp实现的。

不过emacs默认的跳转对于宏来说不是很方便啊,或者说let*不是在lisp里实现的?想参考一下更多的例子,感觉defmacro的参数表和defun一样的话写起来也太麻烦了吧?(可能是我被Scheme惯坏了)

注,原来上面所有的labels原来均错写成了label。。。

cl-let*cl-labels,都是现成的。

你要 letrc 也有。

请问 cl-let* 在哪里可以找到

(fset 'cl-let* #'let*)

你不要为难一个在外面用手机答题的人哇,尤其是一直在写 CL 不怎么碰 elisp 的。:sweat_smile:

但是没有cl-label*

label* 是什么?Common Lisp 和 Scheme 标准里面都没有

Common Lisp 只有 labels

http://clhs.lisp.se/Body/s_flet_.htm#labels

如果指的是早期的用于表示递归标记,很早就弃用了。

主贴说错了,我说的label就是labels*的意思是表中定义的前一项对后一项可见,就像let*之于let一样,所以我在后面加了个*rec的话是列表中每一项对其它都可见。

不需要有 labels*。为什么?因為 labels 只能定义函数。有需要就在 labels 外面套个 let*

的确,全用let+lambda+funcall可以解决问题,不过人都有想尽量少改动代码的时候,我这之后scope的代码全是当普通函数调用写的,要用这个组合的话,后面的都得改。

我本来是在scope,里面用的defun,可是看不惯flycheck在那里有个警告,就找了一下emacs-lisp里local function怎么写才引出了这个问题。

回到正题,没有也行,我想请教一下emacs-lisp里面宏的一些惯用写法,比如let*是怎么实现的?

注,可能你的链接有很好的例子,不过我暂时没时间看,不过关于需不需要,我还是回复一下。。。

Common Lisp 的 let* 是 Special Operator,通常为了性能直接用汇编实現成 primitive 而不是宏。

不過用宏也可以就是了。(按 Scheme 的)隨手写了个宏版。

(defmacro let* (bindings &body body)
  (let ((form body))
      (dolist (clues (nreverse bindings))
        (setf form (list (nconc `(let (,clues)) form))))
    (car form)))

(let* ((x 1) (b (+ x 2)) (c (* x b))) (list x b c))
;; => (1 3 3)
1 个赞

也就是说binding直接相当于表((symbol variable)*)body直接相当于((stmt)*)

其实和defun的区别在于,defmacro的参数全部不求值?有没有别的区别?

太难讲清楚,反正和 pattern match 和 preprocessing 有关。