You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Common Lisp函数仅返回函数名问题排查:Project Euler第1题求解遇阻

问题分析:Project Euler第1题Lisp函数返回函数名的问题

我正在求解projecteuler.net的第1题,但执行以下函数时仅返回函数名称,请问我哪里出错了?

你的代码存在几处关键的语法和逻辑错误,导致函数定义不合法,解释器无法正确创建可执行的函数,所以调用时会返回函数对象的名称而非计算结果。先看你的原始代码:

(defun nSum (n sum) 
  (if ( n = 0) ( sum) ) 
  (cond 
    ( (mod n 5) = 0) ( nSum ( - n 1) (+ sum n)) 
    ( (mod n 3) = 0) (nSum(- n 1) (+ sum n)) 
    (nSum (- n 1) (+ sum n)) 
  ) 
) 
(setq sum (nSum 100 0)) 
(write sum)

具体错误点:

  • 前缀表达式语法错误:Lisp是前缀表达式语言,所有操作符必须放在表达式最前面。你写的(n = 0)应该是(= n 0),(mod n 5) = 0应该是(= (mod n 5) 0)——把判断符=放在最前面,包裹住要比较的两个值。
  • if语句结构错误:Lisp的if格式是(if 条件 真分支 假分支),你现在的if没有假分支,而且(sum)是试图调用名为sum的函数,但sum是你的参数变量,直接写sum即可返回它的值。更关键的是,当前代码里if执行完后会继续运行后面的cond,这完全破坏了递归的终止逻辑。
  • cond分支格式错误:cond的每个分支必须是(条件 执行代码)这样的列表。你把条件和执行代码拆成了独立的元素,比如((mod n 5) = 0)和(nSum ...)是两个分开的元素,这会被解释器当成无效的分支结构。
  • 递归终止逻辑失效:即使n=0,你的代码也会继续执行后面的cond,导致递归无法停止,最终要么报错,要么因为前面的语法错误让函数定义失败。

修正后的代码:

(defun nSum (n sum)
  (if (= n 0)
      sum  ; n为0时返回累计的sum,终止递归
      (cond
        ; 如果n能被3或5整除,累加n后递归
        ((or (= (mod n 5) 0) (= (mod n 3) 0))
         (nSum (- n 1) (+ sum n)))
        ; 其他情况直接递归,不累加
        (t (nSum (- n 1) sum)))))

; 注意:Project Euler第1题是求小于1000的数,这里按你写的100来,实际应该用999
(setq result (nSum 99 0))
(write result)

为什么之前返回函数名称?

当函数定义存在语法错误时,Lisp解释器无法正确编译生成可执行的函数对象。此时你调用nSum,解释器会把它当成对函数符号本身的引用,所以返回函数的名称(比如NSUM)。修正语法后,函数就能正常执行递归计算了。

内容的提问来源于stack exchange,提问作者Peter Timperman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:56:09