Lambda 避免funcall的双重调用

Lambda 避免funcall的双重调用,lambda,functional-programming,common-lisp,Lambda,Functional Programming,Common Lisp,请考虑Lisp中的以下函数定义: (defun Fct(F L) (cond ((null L) nil) ((funcall F (car L)) (cons (funcall F (car L)) (Fct F (cdr L)) ) ) (T nil) ) ) 给出一个避免双重调用的解决方案(funcall F(car L)) 不使用set、setq、setf。证明答案的正确性 我就是这样重新定义函数的: (defun Fct

请考虑Lisp中的以下函数定义:

(defun Fct(F L)
    (cond
        ((null L) nil)
        ((funcall F (car L)) (cons (funcall F (car L)) (Fct F (cdr L)) ) )
        (T nil)
    )
)
给出一个避免双重调用的解决方案
(funcall F(car L))
不使用set、setq、setf。证明答案的正确性

我就是这样重新定义函数的:

(defun Fct2(F L)
    (funcall #'(lambda (x)
                    (cond
                        ((null L) nil)
                        (x (cons x (Fct2 F (cdr L)) ) )
                        (T nil)
                    )
                )
        (F (car L))
    )
) 
我工作了,但我看不出是否有更多的重复通话。我还看到有人用另一种方式做了这件事:

(defun redefine(f l)
    (funcall #' (lambda (x)                    
                        (cond 
                            ((null l) nil)
                            (x (cons x (Fct f (cdr l))))
                            (t nil)
                        )                   
                )
                (funcall f (car l))
    )
)
(内部使用旧Fct)


但我认为Fct2是继续进行的好方法。我想听听一些意见。

函数
fct
将函数
f
和列表
L
作为参数 并返回
L
元素的
t
s列表,这些元素的计算结果为
f
un
直到
L
耗尽,或者
F
的元素计算结果为false

例如:

(fct#'plusp'(12-34 10))=>(t),
(fct#'listp'((1 2 3)4'(a))=>(t),
(fct#'listp nil)=>nil。
功能
fct2
重定义
不满足此行为

在另一种情况下,为了避免多次计算表达式, 只需将表达式的求值结果绑定到符号。 考虑以下实现,达到预期的结果:

(定义fct-2(功能列表)
(何时列出)
(出租((车头(车单)))
(当头
(犯罪团伙头目(fct-2职能部门(指挥官名单()()))))
当您的if表单没有其他部分时,宏
when
特别有用。 在
fct-2
中,我们将
(funcall func(car list))
的结果绑定到
head
我们稍后使用

旁注:

  • Commonlisp为函数和变量提供了单独的名称空间,因此我们可以使用
    list
    等名称作为变量名,而不会出现任何问题,这可以使程序更清晰,而不是名称 类似于列表的
    L
  • 查看并获取有关编写和格式化(通用)lisp程序的指南

  • Fct2