Lisp/Scheme中空嵌套列表求值疑问:为何(())报错而非返回()
Common Lisp中空列表与嵌套空列表的求值差异解析
在Common Lisp里,括号的核心含义是函数调用(或特殊形式),这是你遇到问题的关键原因:
单独的
()是自求值对象:Common Lisp规定空列表、数字、字符串这类原子(除符号外)会直接返回自身。同时()和nil完全等价,所以(format t "~:a" ())直接输出()。对于
(()):Lisp会把这个形式解析为「调用函数()(也就是nil),无参数」。但nil并不是已定义的可调用函数,因此触发“undefined function NIL”错误。你预期的(())→()是把它当成了包含空列表的数据,但Lisp默认不会把带括号的结构当作纯数据,除非你显式阻止求值。要让
(())作为数据返回,需要用quote阻止求值:(format t "~:a" '(())) ;; => ()对于
((())):Lisp会尝试把最外层列表的第一个元素(())当作函数名,但函数名必须是符号(或可调用对象),而(())是一个列表,因此报错“(NIL) is not a function name; try using a symbol instead”。同样,用quote就能得到你预期的纯数据:(format t "~:a" '((()))) ;; => ((()))
Scheme的情况和Common Lisp一致:括号开头的形式默认是函数调用,()自求值,但(())会尝试调用()作为函数(而Scheme里()也不是可调用函数),因此同样报错。要获取嵌套空列表的数据,同样需要用quote或者list函数构造。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

