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)