将函数作为参数传递 - lambda表达式错误?

时间:2017-07-10 17:24:08

标签: function functional-programming lisp parameter-passing common-lisp

我正在尝试创建一个接受列表和函数作为参数的函数,并将该函数应用于List中的每个元素。 这是我的尝试:

(defun filter(fn L)
  (if (eq 0 (length L))
      (print "list empty")
      (print (mapcar (lambda (n) (#'fn n)) L))))
(print (filter #'evenp '(1 2 2 3 4)))

这是第二次尝试:

(defvar R nil)
(defun filter(fn L)
  (if (eq 0 (length L))
      nil
      (cons (R (funcall fn (car L)) filter(fn (cdr L))))))
(print(filter #'evenp '(1 2 2 3 4)))

但是对于一些令人困惑和无法解释的原因, 我得到了第一个错误:

#'FN should be lambda expression.

这是第二个:

Undefined function R

我已经尝试了很多东西,但到目前为止还没有任何工作。

编辑:: 谢谢你的帮助到目前为止。这样:

(defun filter(fn L)
  (if (eq 0 (length L))
      (print "list empty")
      (remove-if-not #'fn '(1 2 3 4 5))))

(print (filter #'evenp '(1 2 2 3 4)))

这应该这样做。但我还是得到了

Undefined function FN

错误。怎么办???

2 个答案:

答案 0 :(得分:10)

如何做你想做的事

filter被称为remove-if-not 在Common Lisp中:

(remove-if-not #'evenp '(1 2 3 4 5))
==> (2 4)

您的代码有什么问题 - 语法

第一次尝试

当您尝试调用存储在变量中的函数(或传递给 作为参数的功能),你需要 使用funcallapply

(mapcar (lambda (n) (funcall #'fn n)) L)

或者只是传递它 到mapcar

(mapcar fn L)

第二次尝试

这是一团糟。 你需要学习Common Lisp语法,有很多好书(见 want to learn common lisp)。

具体问题是R处于功能位置(第一个列表 element)但它没有定义为函数 - 它是一个变量。 即使您解决了这个问题,也存在更多问题。 你应该读一本书然后自己解决,这将是一本书 有用的运动。

基本上,在Common Lisp中,括号是有意义的。 例如,在C中你可以写x+y(x+y)(x)+(y)& c,它们都意味着 相同。 在Common Lisp中R(R)((R))& c非常不同。

第三次尝试(“编辑”)

(defun filter(fn L)
  (if (eq 0 (length L))
      (print "list empty")
      (remove-if-not #'fn '(1 2 3 4 5))))

这里有变量 fn,但您正在使用它,好像它是函数#'fn)。

你需要做

      (remove-if-not fn '(1 2 3 4 5))

代替。

您的代码有什么问题 - 语义

无需print

首先,print是虚拟的 从不在代码中使用正确的函数。使用princprin1或 而是write

第二,Common Lisp REPL 代表Read-Eval- 打印 循环,因此您无需打印 明确返回函数的值。

遵循编码惯例

您可以为其他人(包括您自己6个月后)编写代码,而不仅仅是让计算机运行。 如果遵循约定,包括命名变量和函数, 括号放置,缩进& c,使代码更具可读性。

使用zerop

与0比较

(zerop X)代替(eq 0 X)(实际上,你应该 使用eql表示数字,但这是 现在变得太毛茸茸了。)

length可能很贵

如果您需要知道的是否是,请不要扫描整个列表 空。 IOW,

(if (zero (length l))
    (print "the list is empty")
    (mapcar ... l))

最好写成

(if (null l)
    (print "the list is empty")
    (mapcar ... l))

答案 1 :(得分:2)

  

#'FN应该是lambda表达式。

您的代码中有(fn(cdr L)),而 fn 无法像这样调用。就像之前的那一行一样,你需要做(过滤器fn(cdr L)),而不是过滤器(fn(cdr L))

  

未定义的函数R

这里也是一样的。你有(cons(R ...)),你试图将 R 称为函数,但事实并非如此。对于我用 R 尝试做什么并不是很清楚,所以我无法在那里提供任何帮助。