手册看几遍这一部分,英语渣,大部分看的懂. 反引号`,引用变量前加逗号或者@ 函数前加# 看不懂啊,要么是单词生僻,理解不了,要么是概念模糊,还是理解不了,有哪位大佬帮忙解释下,谢谢
-
`
必须和,
配合使用.,
号后面的表达式会被求值比如 下面的表达式中后一个
(+ 3 4)
会被求值, 但是前一个不会,`(a (+ 3 4) , (+ 3 4)) ; => (a (+ 3 4) 7)
-
,@
必须连在一起使用,,@
之后的表达式的结果必须是列表, 列表会被展开(setq b '(1 2 3)) `(a ,@ b c) ; => (a 1 2 3 c) (setq b 1) `(a ,@ b c) ; => Wrong type argument: sequencep, 1
-
#'
必须一起使用,#'foo
和(function foo)
等价, (#
号还有其他用途不过和这里没什么关系)function is a special form in ‘src/eval.c’.
(function ARG)
Like ‘quote’, but preferred for objects which are functions. In byte compilation, ‘function’ causes its argument to be compiled. ‘quote’ cannot do that.
#'
和quote
基本一样, 只是在 byte-compile 的时候不一样
`
其实是一个宏 backquote
的别名 (backquote.el)
(defalias '\` (symbol-function 'backquote))
比如 `(1 2 3)
其实就是 (backquote (1 2 3))
在 backquote.el 里还定义了三个 symbol
(defconst backquote-backquote-symbol '\`
"Symbol used to represent a backquote or nested backquote.")
(defconst backquote-unquote-symbol '\,
"Symbol used to represent an unquote inside a backquote.")
(defconst backquote-splice-symbol '\,@
"Symbol used to represent a splice inside a backquote.")
,
和 ,@
其实是可以变成其他符号的
看不明白什么问题。你的问题不完整、缺少上下文。
谢谢,基本懂了,剩下的在参照手册,学吧。
有点不明白的地方是,foo本身就是返回自己的函数引用,为何要写成(function foo),它们有区别吗?在scheme中,一般直接写foo,这是不是scheme与lisp的区别所在?
是不是,在elisp中,直接写foo,就从符号定义namespace查找,而(function foo)就是从函数定义namespace中查找的意思?
如果没记错的话, elisp 里函数命名空间和变量命名空间是分开的,就说你可以定义名字是 foo 的函数, 同时也可以定义一个名字是 foo 的变量。 使用 foo 的时候除非是括号第一个位置, 其他位置默认成变量。
刚试了一下
(defun fact (n)
(if (= n 0) 1
(* n (fact (1- n)))))
(defun test (fn n)
(funcall fn n))
(test 'fact 3) => 6
(test #'fact 3) => 6 ;; byte compile
两者都能执行,#’ 第一次compile之后,以后执行应该快一些吧,compile之后的byte code保存在什么地方呢?若没保存的话,岂不是每次都compile。或者,compile之后缓存在自己的buffer里,一旦这个buffer关闭,再次打开的话,第一次遇到这个函数时compile一下。
funcall
会对它的参数求值。无论'foo
或者#'foo
求值的结果都是foo
这个symbol。然后funcall会到foo
的function slot寻找函数定义然后执行。
#'
'
没有实质性的区别。#'
算是一个给字节码编译器的一个提示。如果字节码编译器发现#'foo
的foo
在编译时没有函数定义。会报一个警。
跟buffer没有关系的啊
(defun zx () (print (+ 90 90)))
(symbol-function 'zx)
(byte-compile 'zx)
(symbol-function 'zx)
(fset 'zxc (symbol-function 'zx))
(zxc)
关于这个问题,我另起了一个主题[elisp 符号表 与 namespace]
关于本主题
为了使记号简洁,lisp 中有一个特殊的宏‘,称为 backquote。在这个宏里,所有的表达式都是引用(quote)的,如果要让一个表达式不被直接引用(也就是列表中要计算该表达式的值),需要在前面加 “,”,如果要让一个列表作为整个列表的一部分,可以用“,@”把它展开。
'(a list of ,(+ 2 3) elements) ; => (a list of 5 elements)
(setq some-list ’(2 3)) ; => (2 3)
'(1 ,some-list 4 ,@some-list) ; => (1 (2 3) 4 2 3)
提个问题
(defmacro when (cond &rest body)
(list 'if cond (cons 'progn body)))
; 按理说,是可以替换成
(defmacro when (cond &rest body)
'(if ,cond (progn ,@body)))
; 但提示下面错误
Error running timer 'aggressive-indent--indent-if-changed': (void-function \,)
; 找不到名字为"\,"的函数
macro when
被使用的时候。负责处理lisp解释器解析后的backquote结构的backquote.el
还没被加载呢
是你自己写的宏啊… 我还以为你动手改了subr.el呢。那你应该是写错字了。
好的,谢谢。
不过,以我现在的水平,只看这段代码,看不出哪里写了backquote.el在when之后加载?
写错了吧,应该是
`(if ,cond (progn ,@body))
不是
'(if ,cond (progn ,@body))
我也看不懂。不过subr.el
有不少宏都有类似的提示
正解,非常感谢。
好的,以后我也得仔细看代码和注释了。我感觉看他们的代码,在时间上有些吃不消,你是怎么做到的?
不过我这次的问题是‘ 和 `的问题
获取 “2022-03-26.org” 这个文本, 用过什么 get-text-property, 可能方向错了,
ELISP> (window-list) (#<window 7 on ielm> #<window 9 on 2022-03-26.org> #<window 3 on zzf-7-test-template.el>)
这个是 序列吗, 还是只是1个列表, 还是要用正则来 提取
(mapconcat 'identity (window-list) “”) ;
也不对! 烦请, 那位 专业人士, 帮忙解释下, 给个链接也行, Google 一天多了
(mapconcat
(lambda (x)
(format "%S" x))
(window-list) "")
简单来说, window-list 函数返回一个 对象列表, 每个 window 对象 用 identity 函数处理之后还是原来对象,当然不能当作字符拼接了。
还在忙, 现在正准备写, 写好, 再请教下, 还是要说下, 本人非IT行业