修改Scheme中的基本if表达式。为什么会进入无限循环呢?

2023-12-12

在Scheme中,我将基本的“if”命令修改为:

(define (modified-if predicate then-clause else-clause)
  (if predicate
      then-clause
      else-clause))

然后我使用 if 的修改版本定义了一个简单的阶乘生成程序:

(define (factorial n)
  (modified-if (= n 0)
               (* n (factorial (- n 1)))))

现在,当我调用上面的函数时,它进入无限循环。为什么会发生这种情况?


方案得到热切评价。这意味着,除非您使用特殊形式(例如if)或宏(例如cond or case)委托给这样一个特殊的形式,all首先评估子表达式。

这意味着你的表达

(modified-if (= n 0)
             1
             (* n (factorial (- n 1))))

the (* n (factorial (- n 1)))首先评估,之前modified-if正在运行。 (它可以在之前或之后运行(= n 0),但无论哪种方式都没关系,无论如何,递归调用仍然会发生。)并且由于这是一个递归调用,这意味着您的程序将无限递归,并且您最终将耗尽堆栈。

这是一个简单的例子:考虑一下:

(if #t
    (display "Yay!")
    (error "Oh noes!"))

Because if是一种特殊形式,它只评估必要的分支,在这种情况下它只会评估(display "Yay!")并且不评价(error "Oh noes!")。但如果你改用你的modified-if,两个表达式都将被计算,并且您的程序将引发错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

修改Scheme中的基本if表达式。为什么会进入无限循环呢? 的相关文章

  • 为什么《小阴谋家》中的所有 lambda 表达式都是如此?

    在从 SICP 学习了一些计划之后 我开始阅读 小计划 我觉得这本书很有趣 并且已经完成了大约四分之一 我注意到我可以在不使用 lambda 的情况下编写许多 大多数 全部 解决方案 而 The Little Scheduleralways
  • 通过递归扩展 Prolog 目标?

    我 最终 实现了一些目标 这些目标将根据开始由 开始之后 and duration 然而 计划目标仅接受规定数量的任务 我想扩展计划目标的功能以接受单个列表并在计划时迭代该列表 不幸的是 我认为这将需要与can run and 冲突目标如下
  • duckmap 到底有什么作用?

    From 文档 https docs perl6 org routine duckmap duckmap将会应用 block每个元素上并返回一个新列表 其中包含块的已定义返回值 对于未定义的返回值 duckmap如果该元素实现了 将尝试下降
  • 在 Slime 中复制/猛拉整个 Lisp 表单

    有没有办法在 Slime Emacs 中复制 猛拉整个表单 例如 如果我有以下功能 myfunc lst myotherfunc lst 我想复制 复制 myotherfunc lst 当我的光标位于该表单的左括号或右括号时 在 Slime
  • 从数据库结果生成多维数组的递归函数

    我正在编写一个函数 它接受页面 类别数组 来自平面数据库结果 并根据父 ID 生成嵌套页面 类别项目数组 我想递归地执行此操作 以便可以完成任何级别的嵌套 例如 我在一个查询中获取所有页面 这就是数据库表的样子 id parent id t
  • typescript 类型最大递归限制为 9

    我终于成功创建了一个通用类型 它为我提供了 json 键列表 值的所有可能组合 我什至准备了一种限制递归的方法 type EditAction
  • Javascript 中的深平面多维数组[重复]

    这个问题在这里已经有答案了 我想编写一个可以深度展平给定数组的函数 例如 deepFlatten deepFlatten 1 2 3 1 2 3 deepFlatten 1 2 3 a b c 1 2 3 1 2 3 a b c 1 2 3
  • Fortran 递归分段错误

    我必须设计并实现一个 Fortran 例程来确定方格上簇的大小 并且递归地编写子例程似乎非常方便 然而 每当我的晶格大小超过某个值 大约 200 边 时 子例程就会始终出现段错误 这是我的集群检测例程 RECURSIVE SUBROUTIN
  • 地形/山地算法未按预期工作

    我想使用一个非常基本的原理创建一个上面有山的地形 如以下高度图所示 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0
  • 如何在 Twig 中渲染树

    我想渲染一棵深度不确定的树 孩子的孩子的孩子等 我需要递归地循环遍历数组 我怎样才能在 Twig 中做到这一点 我玩过domi27的想法 https stackoverflow com questions 8326482 how to re
  • setf中的f代表什么?

    LISP 有setf函数给变量赋值 现在我一直想知道该函数的名称 Theset部分是显而易见的 但是什么是f后缀代表 F的实际含义经常被忘记 根据一些消息来源 f 后缀可以代表 字段 例如参见这个answer https stackover
  • 动态规划的复杂组合条件

    我正在探索动态规划设计方法如何与问题的底层组合属性相关 为此 我正在查看的规范实例硬币找零问题 Let S d 1 d 2 d m and n gt 0是请求的金额 我们可以用多少种方式相加n仅使用中的元素S 如果我们遵循一个动态规划如果要
  • Lisp 中的十进制到二进制 - 制作非嵌套列表

    当达到我的递归情况时 我使用list将未来结果附加到当前结果 但由于递归 我最终得到一个嵌套列表 当我有一个导致递归超过五次的数字时 这会导致错误 任何想法如何我可以在一个简单的非嵌套列表中获得结果 例如 CL 用户 100 8 gt BI
  • Common Lisp 反引号/反引号:如何使用?

    我在使用 Lisp 的反引号读取宏时遇到问题 每当我尝试编写一个似乎需要使用嵌入式反引号的宏时 例如 w x y 来自保罗 格雷厄姆的ANSI 通用 Lisp 第 399 页 我不知道如何以编译的方式编写代码 通常 我的代码会收到一整串错误
  • 为什么删除 else 会减慢我的代码速度?

    考虑以下函数 def fact1 n if n lt 2 return 1 else return n fact1 n 1 def fact2 n if n lt 2 return 1 return n fact2 n 1 它们应该是等价的
  • 递归遍历树视图中的节点?

    我有一个树视图 其中已经填充了另一个过程中的文件 文件夹 我想按照从上到下的确切顺序逐项迭代树视图中的项目 但是 与普通列表不同 我不能仅使用简单的for对此的声明 我必须进入每个节点等 我该怎么做呢 我希望有一种方法可以在不运行递归过程的
  • 为什么 array_merge_recursive 不是递归的?

    我最近在我的应用程序中发现了一个由意外行为引起的错误array merge recursive 让我们看一下这个简单的例子 array1 1 gt 1 gt 100 2 gt 200 2 gt 3 gt 1000 3 gt 1 gt 500
  • 如何在 Lisp 中生成一系列佩尔数而不是特定的数

    如何使用 cons 或其他方式打印列表佩尔数 https en wikipedia org wiki Pell number直到第N个数 defun pellse k if or zerop k k 1 k 2 pellse k 1 pel
  • Lisp:CHAR 既未声明也未绑定

    几天前我决定学习 通用 Lisp 我意识到这是一个相当新手的问题 对于至少有一点经验的人来说可能非常微不足道 所以基本上发生的事情是我加载 Emacs Slime 通过 Lisp in a Box 并编写我的程序 包括在下面 defun l
  • Clojure 尾递归与质因数

    我正在尝试自学 clojure 并使用 Prime Factors Kata 和 TDD 的原则来实现这一目标 通过一系列 Midje 测试 如下所示 fact primefactors 1 gt list fact primefactor

随机推荐