Common lisp 将函数映射到点对

Common lisp 将函数映射到点对,common-lisp,elisp,Common Lisp,Elisp,我想将一个函数(lambda(x)(+x1))映射到一个点对”(1.2),以获得另一个点对”(2.3)。我已测试了以下代码,但无效: (定义映射点(func coll) ((funcall func(car coll))(funcall func(cdr coll))) ELISP>(mapdot(lambda(x)(+x1))”(1.2)) ***求值错误***无效函数:(funcall func(car coll)) 如何实现这种行为?有一个简单的解决方案我忽略了,因为我不愿意切换到命令

我想将一个函数
(lambda(x)(+x1))
映射到一个点对
”(1.2)
,以获得另一个点对
”(2.3)
。我已测试了以下代码,但无效:

(定义映射点(func coll)
((funcall func(car coll))(funcall func(cdr coll)))
ELISP>(mapdot(lambda(x)(+x1))”(1.2))
***求值错误***无效函数:(funcall func(car coll))

如何实现这种行为?

有一个简单的解决方案我忽略了,因为我不愿意切换到命令式风格:创建一个虚拟列表并手动设置它的
car
cdr

(定义映射点(func coll)
(let((临时列表(12)))
(项目
(setf(汽车温度列表)(funcall func(汽车冷却)))
(setf(cdr临时列表)(funcall func(cdr coll)))
(临时列表)
现在运行正常:

ELISP>(mapdot(lambda(x)(+x1))”(1.2))
(2 . 3)

您第一次尝试时遇到了问题,因为它试图使用
(funcall func(car coll))
作为要调用的函数的名称-这当然不起作用。为了让错误更清楚,就好像你在这样做:

ELISP> ((list))
*** Eval error ***  Invalid function: (list)
解决方案是使用
cons
或准注释:

ELISP> (defun mapdot (func coll)
         (cons (funcall func (car coll)) (funcall func (cdr coll))))
mapdot
ELISP> (mapdot (lambda (x) (+ x 1)) '(1 . 2))
(2 . 3)

我更喜欢使用Quasikote的那个。感谢您指出额外的括号。这通常不是一个好主意,因为代码试图修改文本单元格。它没有分配新的cons单元格。@RainerJoswig True,但cons单元格
1
2
的创建只是为了进行破坏性更新,所以我想
setf
-在这样的限制条件下,分配单个cons单元格可能是可以接受的。@RainerJoswig我还没有完全理解您的评论,但我确实注意到,对
mapdot
的连续调用改变了过去的结果。你的意思是说,
”(12)
事先存在于内存中的某个地方,每次调用
mapdot
,我都会更改该内存块(因此,旧的结果会完全更改)?这在许多其他编程语言中都是一样的:程序修改文本数据。在Common Lisp中,这种行为有未定义的后果,您可能会看到一些令人惊讶的效果,想象代码在ROM(只读内存)中,那么它甚至可能会失败。@RainerJoswig Yes。这是一个肯定会失败的场景。给我印象最深的是,在Lisp中,可以有自修改函数:我在不知不觉中编写了一个。
ELISP> (defun mapdot (func coll)
         `(,(funcall func (car coll)) . ,(funcall func (cdr coll))))
mapdot
ELISP> (mapdot (lambda (x) (+ x 1)) '(1 . 2))
(2 . 3)