【问题标题】:LISP- simple functions , syntax error?LISP-简单的函数,语法错误?
【发布时间】:2012-05-13 13:17:59
【问题描述】:

我目前正在尝试学习 lisp 并在 linux 上使用 emacs。尽我所能,我写了两个函数。

这两个函数都先删除列表的第一个元素。

  • series 添加给定列表中的所有元素。
  • parallel 1) 取列表中每个数字的倒数,然后 2)添加列表中的所有元素,然后 3) 取元素和的倒数。

代码:

(defun series (lst)
    (apply #'+' (cdr lst)) )

(defun parallel (lst)
    (/ 1 (apply #'+' (apply #'/' (cdr 'lst ) ) ) ))

我可以评估该功能,但是当我尝试使用该功能时,如下所示:

(series (list 3 3 4 5))

我收到错误:值 CDR 不是预期的 NUMBER 类型。 我看到了这一点,我想,为什么 emacs 将 cdr 视为一个数字而不是一个函数? 我是 lisp 和 emacs 的新手,所以我不知道如何修复这个错误。任何帮助将不胜感激。


更新

我在这段代码中有问题,我认为它可以工作......

(defun series (lst)
 (apply #'+ (cdr lst) ))

(defun parallel(lst)
(/ 1 (apply #'+ (mapcar #'/ (make-list (- (length lst) 1) :initial-element 1) (cdr lst)  ) )))

希望我现在尝试做的事情被理解了。

【问题讨论】:

  • Lisp 中的' 符号与带引号的字符串非常不同。没有结束报价。 '<anything> 是一个简写形式,代表列表结构 (quote <anything>)。这很有用,因为在评估 (quote <anything>) 时,值始终是对象 <anything> 本身,无论它是什么。 (quote (+ 2 2)) 的值是列表(+ 2 2) 而不是4。 Lisp 对字符串文字有一个双引号,如"abc",而字符常量有一个'#\'(哈希反斜杠)语法,其中有一些变化,如'#\space' 表示空格和'#\A' 表示大写A。
  • @Kaz 这绝对应该成为您的答案,而不是隐藏在 cmets 中。 :)
  • in Common LISP mapcar 在较短的列表结束时停止。这意味着,循环列表 可用于提供默认参数:(nth 5 (setq b '(1.0) b (rplacd b b))) ==> 1.0。不过不知道emacs-Lisp。顺便说一句,您在使用11.0 时得到相同的答案吗?
  • 嗯.......我对循环列表不熟悉,但这个概念似乎更直观。在这种情况下,mapcar 旁边的两个列表都保证长度相同。我还看到'#1='(1 2 3 . #1#) 是循环列表的一个例子。这行得通吗?

标签: lisp common-lisp


【解决方案1】:

回复:

(defun parallel (lst)
    (/ 1 (apply #'+' (apply #'/' (cdr 'lst ) ) ) ))

为什么你试图丢弃第一个元素。这很好奇。

请注意,即使解决了引用问题,此函数的逻辑也不会起作用。

(apply #'/ (cdr lst)) 会将lst 的剩余部分传递给/ 函数。这个函数会产生一个数字。

然后你实际上是(apply #'+ number),问题是apply 想要一个列表。

您暗示的并行语义不会发生。

也许你想要这个:

 ;; divide the sum of the remaining elements, by the fraction of those elements
 (/ (apply #'+ (cdr lst)) (apply #'/ (cdr lst)))

请注意,在 Emacs Lisp 中,整数除以整数会产生整数,而不是像 Common Lisp 中那样的有理数。

【讨论】:

  • OP 想要“取 [...] 列表中每个数字的倒数”。那是(mapcar #'/ (cdr lst))。名称seriesparallel 可能指的是电路中欧姆电阻的计算。 :)
  • @WillNess 这正是我的本意 :)
  • @Kaz 我已经编辑了我的答案以包含更新的代码,所以我试图完成的事情可以被理解。
  • @WillNess 我昨天在电子学中得到了一个灰泥板徽章,但我没想到。说,我现在手边没有 Emacs 的安装,但是在线查看 GNU Emacs 手册,似乎没有记录 / 函数的单参数形式!在 Common Lisp 中,(/ x) 确实意味着 (/ 1 x),类似于一元减法 (- x) -> (- 0 x)。这是只是有效的东西吗?如果没有,你必须做(mapcar (lambda (num) (/ 1 num)) list)
  • 原来我的旧 emacs 安装也不见了。一两天后,每次尝试使用它时,我都不喜欢左手腕疼痛。 ;)
【解决方案2】:

您有额外的撇号使 LISP 解析器感到困惑。引用+ 函数的语法就是#'+;没有“关闭报价”。

【讨论】:

  • 另外,lst(cdr 'lst) 中没有引用。
  • 啊……我明白了,我写错了。删除多余的引号(如 Kaz 的评论和 Reed 的回答)修复了此代码中的问题。
  • 是的,请注意' 和后面的任何内容之间可以有空格,因此'A' B 实际上与'A 'B 的含义相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2017-03-18
相关资源
最近更新 更多