【问题标题】:sicp 2.4.3 data directed programming and additivity, schemesicp 2.4.3 数据定向编程和可加性,方案
【发布时间】:2017-06-30 06:15:32
【问题描述】:

能否解释一下the chapter 中描述的复杂算术示例。我有一点不能理解。我将不胜感激任何帮助。 问题如下:

有两个程序包名称相似。 第一个是“(安装矩形包)”。第二个是“(install-polar-package)”。另外,定义了一个过程:
(define (make-from-real-imag x y)
(get 'make-from-real-imag 'rectangular) x y))

我输入方案解释器 (安装矩形包)
(安装极地包)
(根据真实形象制作 3 5)

它有效。我不明白“make-from-real”中的“get”如何在正确的包中找到正确的功能。当字符串 "(get 'make-from-real-imag 'rectangular)" 被执行时,它被 "(lambda (x y) (tag (make-from-real-imag x y))))" 替换,但是它是如何知道的它必须在“(install-rectangular-package)”中调用函数,而不是在“(install-polar-package)”中。

【问题讨论】:

    标签: scheme


    【解决方案1】:

    chapter 包括 some sentences,表示您应该假设过程 putget 存在:

    为了实现这个计划,假设我们有两个过程,putget,用于操作操作和类型表:

    (put <op> <type> <item>)
    

    在表中安装&lt;item&gt;,由&lt;op&gt;&lt;type&gt;索引。

    (get <op> <type>)
    

    在表中查找&lt;op&gt;&lt;type&gt; 条目并返回在那里找到的项目。如果没有找到项目,get 返回 false。

    现在,我们可以假设 putget 包含在我们的语言中。

    所以,现在我们必须要求澄清您的问题:

    1. 您是在问“如何实现像 install-rectangular-package 这样的过程,以便在评估 (install-rectangular-package) 之后,get 过程可以查找所需的操作?”

    2. 或者您是在问“get 本身如何工作?”

    3. 或者您是在问:“即使如果我们假设存在这样一个支持putget 的表,presented code 如何工作,它安装了多个不同的名称为 real-part(和 imag-part 等)的函数,即使一个 real-part 来自矩形包,而另一个 real-part 来自 Polar 包?"


    如果您要问第一个问题,答案是:install-rectangular-package 只需使用适当的参数调用put 以扩展get 将访问的查找表。


    如果你问的是第二个问题,那么你需要看看putget 是如何实现的,这将在第 3 章中讨论。但快速的答案是:你可以使用一个数据结构来存储put 插入的每个 {&lt;op&gt;, &lt;type&gt;, &lt;item&gt;} 三元组的记录。这本书描述了一种方法来做到这一点,你只需建立一个条目列表。

    (putget 的任何实现需要做的主要有趣的事情是命令式地修改一些隐藏状态。本书使用set-cdr! 操作来做到这一点。使用某种形式的命令式操作的要求可能是他们等到第 3 章才描述putget 的实现的原因。)


    如果你问第三个问题,答案是“被lexical scoping的魔力”

    install-rectangular-package 的定义有一个内部定义集合,install-polar-package 有另一个内部定义集合。即使在两个定义中选择的名称之间存在重叠,安装 polar 包不会覆盖之前由 rectangle 包定义的功能。

    (在此区分函数定义中使用的名称与函数值/对象(您可能认为是(lambda (x y) ...))本身很重要。即使install-rectangular-packageinstall-polar-package 重用相同名称,它们正在创建不同的函数值,然后将这些不同的值放入put/get 表中,没有任何附加到最初定义它们的名称的意义。)

    虽然书中put/get表的图片看起来像:

    表中的条目是不是名称。它们是函数对象。 real-partimag-part 的其他本地定义不会影响install-rectangular-packageinstall-polar-package 安装的条目;影响这些条目的唯一方法是调用 put 本身并使用匹配的&lt;op&gt;&lt;type&gt; 参数覆盖表中的前一个单元格。

    关于词法范围和思考本地函数定义的方法的更多讨论,我推荐this part of HtDP(“HtDP”代表“如何设计程序”,它和 SICP 一样,是对编程的介绍,但写在一种比 SICP 更能说明问题的时尚;另见paper comparing SICP and HtDP。)

    【讨论】:

    • 非常感谢您的详细解答。我很感激。
    • 但问题不同。它与第一个问题和第二个问题都不相关。问题是当字符串 "(lambda (x y) (tag (make-from-real-imag x y)))" 以某些给定值(如 x=5 和 y=3 )执行时,它怎么可能是执行适当模块中的适当功能。换句话说,什么机制可以找到并执行正确的功能(有两个同名但在不同的包中)。
    • 啊,我看你确实在问第三个问题。我会相应地更新我的答案。
    • 非常感谢!它有帮助。请让我问一个附带问题。如果这本书是编程入门,你能告诉例如哪一本是高级(或中级)编程书。我想看一下它的内容,因为 SICP 有点不容易阅读,也许我不应该继续阅读它。
    • HTDP 比 SICP 更简单(尽管速度很慢)。我喜欢 SICP,但在我已经了解了它试图教授的内容之后,我才真正欣赏它的内容。我建议你试试 HTDP,因为它们都是免费的。 HTDP 的唯一问题是有时阅读起来有点枯燥。下一版可能会解决这个问题:ccs.neu.edu/home/matthias/HtDP2e
    猜你喜欢
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2021-01-02
    • 2011-03-28
    • 1970-01-01
    相关资源
    最近更新 更多