避免 funcall 的双重调用
Avoiding double call of funcall
Consider the following function definition in Lisp:
(defun Fct(F L)
(cond
((null L) nil)
((funcall F (car L)) (cons (funcall F (car L)) (Fct F (cdr L)) ) )
(T nil)
)
)
Give a solution to avoid the double call (funcall F (car L))
.You
wil not use set,setq,setf. Justify the answer.
我是这样重新定义函数的:
(defun Fct2(F L)
(funcall #'(lambda (x)
(cond
((null L) nil)
(x (cons x (Fct2 F (cdr L)) ) )
(T nil)
)
)
(F (car L))
)
)
我工作了,但是我看不到后面有没有double call了。我也看到有人用另一种方式做到了:
(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
作为参数
和 returns L
元素的 t
列表,其计算结果为 f
un
的真值
直到 L
耗尽,或者元素对 F
.
的计算结果为 false
例如:
(fct #'plusp '(1 2 -3 4 10)) => (t t),
(fct #'listp '((1 2 3) 4 '(a))) => (t),
(fct #'listp nil) => nil.
函数 fct2
和 redefine
不满足此行为。
为了避免多次计算一个表达式,
简单地将表达式的计算结果绑定到一个符号。
考虑以下实现预期结果的实现:
(defun fct-2 (func list)
(when list
(let ((head (funcall func (car list))))
(when head
(cons head (fct-2 func (cdr list)))))))
宏 when
当您有一个没有 else 部分的 if 表单时特别有用。
在fct-2
中,我们将(funcall func (car list))
的结果绑定到
head
我们稍后会用到。
旁注:
- Commonlisp 为函数和变量提供了独立的命名空间,因此我们可以毫无问题地使用像
list
这样的名称作为变量名,这可以使程序更清晰而不是名称
像列表的 L
。
- 查看 https://mumble.net/~campbell/scheme/style.txt and https://lisp-lang.org/style-guide/ 编写和格式化(通用)lisp 程序的指南。
Consider the following function definition in Lisp:
(defun Fct(F L) (cond ((null L) nil) ((funcall F (car L)) (cons (funcall F (car L)) (Fct F (cdr L)) ) ) (T nil) ) )
Give a solution to avoid the double call
(funcall F (car L))
.You wil not use set,setq,setf. Justify the answer.
我是这样重新定义函数的:
(defun Fct2(F L)
(funcall #'(lambda (x)
(cond
((null L) nil)
(x (cons x (Fct2 F (cdr L)) ) )
(T nil)
)
)
(F (car L))
)
)
我工作了,但是我看不到后面有没有double call了。我也看到有人用另一种方式做到了:
(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
作为参数
和 returns L
元素的 t
列表,其计算结果为 f
un
的真值
直到 L
耗尽,或者元素对 F
.
例如:
(fct #'plusp '(1 2 -3 4 10)) => (t t),
(fct #'listp '((1 2 3) 4 '(a))) => (t),
(fct #'listp nil) => nil.
函数 fct2
和 redefine
不满足此行为。
为了避免多次计算一个表达式, 简单地将表达式的计算结果绑定到一个符号。 考虑以下实现预期结果的实现:
(defun fct-2 (func list)
(when list
(let ((head (funcall func (car list))))
(when head
(cons head (fct-2 func (cdr list)))))))
宏 when
当您有一个没有 else 部分的 if 表单时特别有用。
在fct-2
中,我们将(funcall func (car list))
的结果绑定到
head
我们稍后会用到。
旁注:
- Commonlisp 为函数和变量提供了独立的命名空间,因此我们可以毫无问题地使用像
list
这样的名称作为变量名,这可以使程序更清晰而不是名称 像列表的L
。 - 查看 https://mumble.net/~campbell/scheme/style.txt and https://lisp-lang.org/style-guide/ 编写和格式化(通用)lisp 程序的指南。